mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Make new.cc definitions weak (#1233)
The STL says that these should be replaceable by user code. new.cc now defines only a few direct functions (including a free wrapper that perplexingly is needed since g++ didn’t want to alias "free".) Now, all of the operators are weak references to those functions.
This commit is contained in:
parent
7e780e57d4
commit
f86e6f8eb0
2 changed files with 64 additions and 78 deletions
131
ctl/new.cc
131
ctl/new.cc
|
@ -20,97 +20,80 @@
|
||||||
|
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
|
||||||
using ctl::align_val_t;
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
namespace {
|
static void*
|
||||||
|
_ctl_alloc(size_t n, size_t a)
|
||||||
constexpr auto a1 = align_val_t(1);
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void*
|
|
||||||
operator new(size_t n, align_val_t a)
|
|
||||||
{
|
{
|
||||||
void* p;
|
void* p;
|
||||||
if (!(p = memalign(static_cast<size_t>(a), n))) {
|
if (!(p = memalign(a, n)))
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
}
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
static void*
|
||||||
operator new[](size_t n, align_val_t a)
|
_ctl_alloc1(size_t n)
|
||||||
{
|
{
|
||||||
return operator new(n, a);
|
return _ctl_alloc(n, 1);
|
||||||
}
|
|
||||||
void*
|
|
||||||
operator new(size_t n)
|
|
||||||
{
|
|
||||||
return operator new(n, a1);
|
|
||||||
}
|
|
||||||
void*
|
|
||||||
operator new[](size_t n)
|
|
||||||
{
|
|
||||||
return operator new(n, a1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
static void*
|
||||||
operator new(size_t, void* p)
|
_ctl_ret(size_t, void* p)
|
||||||
{
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
void*
|
|
||||||
operator new[](size_t, void* p)
|
|
||||||
{
|
{
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
operator delete(void* p) noexcept
|
_ctl_free(void* p)
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete[](void* p) noexcept
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete(void* p, align_val_t) noexcept
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete[](void* p, align_val_t) noexcept
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete(void* p, size_t) noexcept
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete[](void* p, size_t) noexcept
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete(void* p, size_t, align_val_t) noexcept
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete[](void* p, size_t, align_val_t) noexcept
|
|
||||||
{
|
{
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
operator delete(void*, void*) noexcept
|
_ctl_nop(void*, void*)
|
||||||
{
|
|
||||||
}
|
|
||||||
void
|
|
||||||
operator delete[](void*, void*) noexcept
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
|
||||||
|
#undef __weak_reference
|
||||||
|
#define __weak_reference(P, A) P __attribute__((weak, alias(#A)))
|
||||||
|
|
||||||
|
/* The ISO says that these should be replaceable by user code. It also says
|
||||||
|
that the declarations for the first four (i.e. non placement-) operators
|
||||||
|
new are implicitly available in each translation unit, including the std
|
||||||
|
align_val_t parameter. (?) However, <new> also _defines_ the align_val_t
|
||||||
|
type so you can’t just write your own. Our way through this morass is to
|
||||||
|
supply ours as ctl::align_val_t and not implicitly declare anything, for
|
||||||
|
now. If you have any brain cells left after reading this comment then go
|
||||||
|
look at the eight operator delete weak references to free in the below. */
|
||||||
|
|
||||||
|
__weak_reference(void* operator new(size_t, ctl::align_val_t), _ctl_alloc);
|
||||||
|
__weak_reference(void* operator new[](size_t, ctl::align_val_t), _ctl_alloc);
|
||||||
|
__weak_reference(void* operator new(size_t), _ctl_alloc1);
|
||||||
|
__weak_reference(void* operator new[](size_t), _ctl_alloc1);
|
||||||
|
|
||||||
|
// XXX clang-format currently mutilates these for some reason.
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
__weak_reference(void* operator new(size_t, void*), _ctl_ret);
|
||||||
|
__weak_reference(void* operator new[](size_t, void*), _ctl_ret);
|
||||||
|
|
||||||
|
__weak_reference(void operator delete(void*) noexcept, _ctl_free);
|
||||||
|
__weak_reference(void operator delete[](void*) noexcept, _ctl_free);
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wattribute-alias="
|
||||||
|
__weak_reference(void operator delete(void*, ctl::align_val_t) noexcept,
|
||||||
|
_ctl_free);
|
||||||
|
__weak_reference(void operator delete[](void*, ctl::align_val_t) noexcept,
|
||||||
|
_ctl_free);
|
||||||
|
__weak_reference(void operator delete(void*, size_t) noexcept, _ctl_free);
|
||||||
|
__weak_reference(void operator delete[](void*, size_t) noexcept, _ctl_free);
|
||||||
|
__weak_reference(void operator delete(void*, size_t, ctl::align_val_t) noexcept,
|
||||||
|
_ctl_free);
|
||||||
|
__weak_reference(void operator delete[](void*, size_t, ctl::align_val_t)
|
||||||
|
noexcept, _ctl_free);
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
__weak_reference(void operator delete(void*, void*) noexcept, _ctl_nop);
|
||||||
|
__weak_reference(void operator delete[](void*, void*) noexcept, _ctl_nop);
|
||||||
|
|
11
ctl/new.h
11
ctl/new.h
|
@ -3,12 +3,11 @@
|
||||||
#ifndef COSMOPOLITAN_CTL_NEW_H_
|
#ifndef COSMOPOLITAN_CTL_NEW_H_
|
||||||
#define COSMOPOLITAN_CTL_NEW_H_
|
#define COSMOPOLITAN_CTL_NEW_H_
|
||||||
|
|
||||||
// XXX clang-format currently mutilates these for some reason.
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
namespace ctl {
|
namespace ctl {
|
||||||
|
|
||||||
enum class align_val_t : size_t {};
|
enum class align_val_t : size_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ctl
|
} // namespace ctl
|
||||||
|
|
||||||
|
@ -16,6 +15,10 @@ void* operator new(size_t);
|
||||||
void* operator new[](size_t);
|
void* operator new[](size_t);
|
||||||
void* operator new(size_t, ctl::align_val_t);
|
void* operator new(size_t, ctl::align_val_t);
|
||||||
void* operator new[](size_t, ctl::align_val_t);
|
void* operator new[](size_t, ctl::align_val_t);
|
||||||
|
|
||||||
|
// XXX clang-format currently mutilates these for some reason.
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
void* operator new(size_t, void*);
|
void* operator new(size_t, void*);
|
||||||
void* operator new[](size_t, void*);
|
void* operator new[](size_t, void*);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue