1 /** 2 * D binding to C++ <new> 3 * 4 * Copyright: Copyright (c) 2019 D Language Foundation 5 * License: Distributed under the 6 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 7 * (See accompanying file LICENSE) 8 * Authors: Manu Evans 9 * Source: $(DRUNTIMESRC core/stdcpp/new_.d) 10 */ 11 12 module core.stdcpp.new_; 13 14 // LDC: empty module for unsupported C++ runtimes 15 version (CppRuntime_Microsoft) version = Supported; 16 else version (CppRuntime_Gcc) version = Supported; 17 else version (CppRuntime_Clang) version = Supported; 18 version (Supported): 19 20 import core.stdcpp.xutility : __cpp_sized_deallocation, __cpp_aligned_new; 21 import core.stdcpp.exception : exception; 22 23 // TODO: this really should come from __traits(getTargetInfo, "defaultNewAlignment") 24 version (D_LP64) 25 enum size_t __STDCPP_DEFAULT_NEW_ALIGNMENT__ = 16; 26 else 27 enum size_t __STDCPP_DEFAULT_NEW_ALIGNMENT__ = 8; 28 29 extern (C++, "std") 30 { 31 /// 32 struct nothrow_t {} 33 34 /// 35 enum align_val_t : size_t { defaultAlignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__ } 36 37 /// 38 class bad_alloc : exception 39 { 40 @nogc: 41 /// 42 this() { super("bad allocation", 1); } 43 } 44 } 45 46 47 /// 48 T* cpp_new(T, Args...)(auto ref Args args) if (!is(T == class)) 49 { 50 import core.lifetime : emplace, forward; 51 52 T* mem = cast(T*)__cpp_new(T.sizeof); 53 return mem.emplace(forward!args); 54 } 55 56 /// 57 T cpp_new(T, Args...)(auto ref Args args) if (is(T == class)) 58 { 59 import core.lifetime : emplace, forward; 60 61 T mem = cast(T)__cpp_new(__traits(classInstanceSize, T)); 62 return mem.emplace(forward!args); 63 } 64 65 /// 66 void cpp_delete(T)(T* ptr) if (!is(T == class)) 67 { 68 destroy!false(*ptr); 69 __cpp_delete(ptr); 70 } 71 72 /// 73 void cpp_delete(T)(T instance) if (is(T == class)) 74 { 75 destroy!false(instance); 76 __cpp_delete(cast(void*) instance); 77 } 78 79 80 // raw C++ functions 81 extern(C++): 82 @nogc: 83 84 /// Binding for ::operator new(std::size_t count) 85 pragma(mangle, __new_mangle) 86 void* __cpp_new(size_t count); 87 88 /// Binding for ::operator new(std::size_t count, const std::nothrow_t&) 89 pragma(mangle, __new_nothrow_mangle) 90 void* __cpp_new_nothrow(size_t count, ref const(nothrow_t) = std_nothrow) nothrow; 91 92 /// Binding for ::operator delete(void* ptr) 93 pragma(mangle, __delete_mangle) 94 void __cpp_delete(void* ptr); 95 96 /// Binding for ::operator delete(void* ptr, const std::nothrow_t& tag) 97 pragma(mangle, __delete_nothrow_mangle) 98 void __cpp_delete_nothrow(void* ptr, ref const(nothrow_t) = std_nothrow) nothrow; 99 100 static if (__cpp_sized_deallocation) 101 { 102 /// Binding for ::operator delete(void* ptr, size_t size) 103 pragma(mangle, __delete_size_mangle) 104 void __cpp_delete_size(void* ptr, size_t size); 105 } 106 static if (__cpp_aligned_new) 107 { 108 /// Binding for ::operator new(std::size_t count, std::align_val_t al) 109 pragma(mangle, __new_align_mangle) 110 void* __cpp_new_aligned(size_t count, align_val_t alignment); 111 112 /// Binding for ::operator new(std::size_t count, std::align_val_t al, const std::nothrow_t&) 113 pragma(mangle, __new_aligned_nothrow_mangle) 114 void* __cpp_new_aligned_nothrow(size_t count, align_val_t alignment, ref const(nothrow_t) = std_nothrow) nothrow; 115 116 /// Binding for ::operator delete(void* ptr, std::align_val_t al) 117 pragma(mangle, __delete_align_mangle) 118 void __cpp_delete_aligned(void* ptr, align_val_t alignment); 119 120 /// Binding for ::operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& tag) 121 pragma(mangle, __delete_align_nothrow_mangle) 122 void __cpp_delete_align_nothrow(void* ptr, align_val_t alignment, ref const(nothrow_t) = std_nothrow) nothrow; 123 124 /// Binding for ::operator delete(void* ptr, size_t size, std::align_val_t al) 125 pragma(mangle, __delete_size_align_mangle) 126 void __cpp_delete_size_aligned(void* ptr, size_t size, align_val_t alignment); 127 } 128 129 private: 130 extern (D): 131 132 __gshared immutable nothrow_t std_nothrow; 133 134 // we have to hard-code the mangling for the global new/delete operators 135 version (CppRuntime_Microsoft) 136 { 137 version (D_LP64) 138 { 139 enum __new_mangle = "??2@YAPEAX_K@Z"; 140 enum __new_nothrow_mangle = "??2@YAPEAX_KAEBUnothrow_t@std@@@Z"; 141 enum __delete_mangle = "??3@YAXPEAX@Z"; 142 enum __delete_nothrow_mangle = "??3@YAXPEAXAEBUnothrow_t@std@@@Z"; 143 enum __delete_size_mangle = "??3@YAXPEAX_K@Z"; 144 enum __new_align_mangle = "??2@YAPEAX_KW4align_val_t@std@@@Z"; 145 enum __new_aligned_nothrow_mangle = "??2@YAPEAX_KW4align_val_t@std@@AEBUnothrow_t@1@@Z"; 146 enum __delete_align_mangle = "??3@YAXPEAXW4align_val_t@std@@@Z"; 147 enum __delete_align_nothrow_mangle = "??3@YAXPEAXW4align_val_t@std@@AEBUnothrow_t@1@@Z"; 148 enum __delete_size_align_mangle = "??3@YAXPEAX_KW4align_val_t@std@@@Z"; 149 } 150 else 151 { 152 enum __new_mangle = "??2@YAPAXI@Z"; 153 enum __new_nothrow_mangle = "??2@YAPAXIABUnothrow_t@std@@@Z"; 154 enum __delete_mangle = "??3@YAXPAX@Z"; 155 enum __delete_nothrow_mangle = "??3@YAXPAXABUnothrow_t@std@@@Z"; 156 enum __delete_size_mangle = "??3@YAXPAXI@Z"; 157 enum __new_align_mangle = "??2@YAPAXIW4align_val_t@std@@@Z"; 158 enum __new_aligned_nothrow_mangle = "??2@YAPAXIW4align_val_t@std@@ABUnothrow_t@1@@Z"; 159 enum __delete_align_mangle = "??3@YAXPAXW4align_val_t@std@@@Z"; 160 enum __delete_align_nothrow_mangle = "??3@YAXPAXW4align_val_t@std@@ABUnothrow_t@1@@Z"; 161 enum __delete_size_align_mangle = "??3@YAXPAXIW4align_val_t@std@@@Z"; 162 } 163 } 164 else 165 { 166 version (D_LP64) 167 { 168 enum __new_mangle = "_Znwm"; 169 enum __new_nothrow_mangle = "_ZnwmRKSt9nothrow_t"; 170 enum __delete_mangle = "_ZdlPv"; 171 enum __delete_nothrow_mangle = "_ZdlPvRKSt9nothrow_t"; 172 enum __delete_size_mangle = "_ZdlPvm"; 173 enum __new_align_mangle = "_ZnwmSt11align_val_t"; 174 enum __new_aligned_nothrow_mangle = "_ZnwmSt11align_val_tRKSt9nothrow_t"; 175 enum __delete_align_mangle = "_ZdlPvSt11align_val_t"; 176 enum __delete_align_nothrow_mangle = "_ZdlPvSt11align_val_tRKSt9nothrow_t"; 177 enum __delete_size_align_mangle = "_ZdlPvmSt11align_val_t"; 178 } 179 else 180 { 181 enum __new_mangle = "_Znwj"; 182 enum __new_nothrow_mangle = "_ZnwjRKSt9nothrow_t"; 183 enum __delete_mangle = "_ZdlPv"; 184 enum __delete_nothrow_mangle = "_ZdlPvRKSt9nothrow_t"; 185 enum __delete_size_mangle = "_ZdlPvj"; 186 enum __new_align_mangle = "_ZnwjSt11align_val_t"; 187 enum __new_aligned_nothrow_mangle = "_ZnwjSt11align_val_tRKSt9nothrow_t"; 188 enum __delete_align_mangle = "_ZdlPvSt11align_val_t"; 189 enum __delete_align_nothrow_mangle = "_ZdlPvSt11align_val_tRKSt9nothrow_t"; 190 enum __delete_size_align_mangle = "_ZdlPvjSt11align_val_t"; 191 } 192 }