mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +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"
|
||||
|
||||
using ctl::align_val_t;
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto a1 = align_val_t(1);
|
||||
|
||||
} // namespace
|
||||
|
||||
void*
|
||||
operator new(size_t n, align_val_t a)
|
||||
static void*
|
||||
_ctl_alloc(size_t n, size_t a)
|
||||
{
|
||||
void* p;
|
||||
if (!(p = memalign(static_cast<size_t>(a), n))) {
|
||||
if (!(p = memalign(a, n)))
|
||||
__builtin_trap();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void*
|
||||
operator new[](size_t n, align_val_t a)
|
||||
static void*
|
||||
_ctl_alloc1(size_t n)
|
||||
{
|
||||
return operator new(n, a);
|
||||
}
|
||||
void*
|
||||
operator new(size_t n)
|
||||
{
|
||||
return operator new(n, a1);
|
||||
}
|
||||
void*
|
||||
operator new[](size_t n)
|
||||
{
|
||||
return operator new(n, a1);
|
||||
return _ctl_alloc(n, 1);
|
||||
}
|
||||
|
||||
void*
|
||||
operator new(size_t, void* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
void*
|
||||
operator new[](size_t, void* p)
|
||||
static void*
|
||||
_ctl_ret(size_t, void* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
operator delete(void* p) noexcept
|
||||
{
|
||||
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
|
||||
static void
|
||||
_ctl_free(void* p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
void
|
||||
operator delete(void*, void*) noexcept
|
||||
{
|
||||
}
|
||||
void
|
||||
operator delete[](void*, void*) noexcept
|
||||
static void
|
||||
_ctl_nop(void*, void*)
|
||||
{
|
||||
}
|
||||
|
||||
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_
|
||||
#define COSMOPOLITAN_CTL_NEW_H_
|
||||
|
||||
// XXX clang-format currently mutilates these for some reason.
|
||||
// clang-format off
|
||||
|
||||
namespace ctl {
|
||||
|
||||
enum class align_val_t : size_t {};
|
||||
enum class align_val_t : size_t
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace ctl
|
||||
|
||||
|
@ -16,6 +15,10 @@ 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);
|
||||
|
||||
// XXX clang-format currently mutilates these for some reason.
|
||||
// clang-format off
|
||||
|
||||
void* operator new(size_t, void*);
|
||||
void* operator new[](size_t, void*);
|
||||
|
||||
|
|
Loading…
Reference in a new issue