The OpenD Programming Language

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 }