|
19 | 19 |
|
20 | 20 | #include <cstddef>
|
21 | 21 | #include <cstdint>
|
| 22 | +#include <new> |
| 23 | +#include <utility> |
22 | 24 | #include "swift/Runtime/Config.h"
|
23 | 25 |
|
24 | 26 | #if SWIFT_OBJC_INTEROP
|
@@ -131,6 +133,49 @@ void *swift_slowAlloc(size_t bytes, size_t alignMask);
|
131 | 133 | SWIFT_RUNTIME_EXPORT
|
132 | 134 | void swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask);
|
133 | 135 |
|
| 136 | +/// Allocate and construct an instance of type \c T. |
| 137 | +/// |
| 138 | +/// \param args The arguments to pass to the constructor for \c T. |
| 139 | +/// |
| 140 | +/// \returns A pointer to a new, fully constructed instance of \c T. This |
| 141 | +/// function never returns \c nullptr. The caller is responsible for |
| 142 | +/// eventually destroying the resulting object by passing it to |
| 143 | +/// \c swift_cxx_deleteObject(). |
| 144 | +/// |
| 145 | +/// This function avoids the use of the global \c operator \c new (which may be |
| 146 | +/// overridden by other code in a process) in favor of calling |
| 147 | +/// \c swift_slowAlloc() and constructing the new object with placement new. |
| 148 | +/// |
| 149 | +/// This function is capable of returning well-aligned memory even on platforms |
| 150 | +/// that do not implement the C++17 "over-aligned new" feature. |
| 151 | +template <typename T, typename... Args> |
| 152 | +static inline T *swift_cxx_newObject(Args &&... args) { |
| 153 | + auto result = reinterpret_cast<T *>(swift_slowAlloc(sizeof(T), |
| 154 | + alignof(T) - 1)); |
| 155 | + ::new (result) T(std::forward<Args>(args)...); |
| 156 | + return result; |
| 157 | +} |
| 158 | + |
| 159 | +/// Destruct and deallocate an instance of type \c T. |
| 160 | +/// |
| 161 | +/// \param ptr A pointer to an instance of type \c T previously created with a |
| 162 | +/// call to \c swift_cxx_newObject(). |
| 163 | +/// |
| 164 | +/// This function avoids the use of the global \c operator \c delete (which may |
| 165 | +/// be overridden by other code in a process) in favor of directly calling the |
| 166 | +/// destructor for \a *ptr and then freeing its memory by calling |
| 167 | +/// \c swift_slowDealloc(). |
| 168 | +/// |
| 169 | +/// The effect of passing a pointer to this function that was \em not returned |
| 170 | +/// from \c swift_cxx_newObject() is undefined. |
| 171 | +template <typename T> |
| 172 | +static inline void swift_cxx_deleteObject(T *ptr) { |
| 173 | + if (ptr) { |
| 174 | + ptr->~T(); |
| 175 | + swift_slowDealloc(ptr, sizeof(T), alignof(T) - 1); |
| 176 | + } |
| 177 | +} |
| 178 | + |
134 | 179 | /// Atomically increments the retain count of an object.
|
135 | 180 | ///
|
136 | 181 | /// \param object - may be null, in which case this is a no-op
|
|
0 commit comments