mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
616 lines
20 KiB
C++
616 lines
20 KiB
C++
//===--- Alloc.h - Swift Language Allocation ABI ---------------*- C++ -*--===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Swift Allocation ABI
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_RUNTIME_ALLOC_H
|
|
#define SWIFT_RUNTIME_ALLOC_H
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include "swift/Runtime/Config.h"
|
|
|
|
// Bring in the definition of HeapObject
|
|
#include "../../../stdlib/public/SwiftShims/HeapObject.h"
|
|
|
|
namespace swift {
|
|
|
|
struct Metadata;
|
|
struct HeapMetadata;
|
|
struct OpaqueValue;
|
|
|
|
/// Allocates a new heap object. The returned memory is
|
|
/// uninitialized outside of the heap-object header. The object
|
|
/// has an initial retain count of 1, and its metadata is set to
|
|
/// the given value.
|
|
///
|
|
/// At some point "soon after return", it will become an
|
|
/// invariant that metadata->getSize(returnValue) will equal
|
|
/// requiredSize.
|
|
///
|
|
/// Either aborts or throws a swift exception if the allocation fails.
|
|
///
|
|
/// \param requiredSize - the required size of the allocation,
|
|
/// including the header
|
|
/// \param requiredAlignmentMask - the required alignment of the allocation;
|
|
/// always one less than a power of 2 that's at least alignof(void*)
|
|
/// \return never null
|
|
///
|
|
/// POSSIBILITIES: The argument order is fair game. It may be useful
|
|
/// to have a variant which guarantees zero-initialized memory.
|
|
extern "C" HeapObject *swift_allocObject(HeapMetadata const *metadata,
|
|
size_t requiredSize,
|
|
size_t requiredAlignmentMask);
|
|
|
|
/// The structure returned by swift_allocPOD and swift_allocBox.
|
|
struct BoxPair {
|
|
/// The pointer to the heap object.
|
|
HeapObject *heapObject;
|
|
|
|
/// The pointer to the value inside the box.
|
|
OpaqueValue *value;
|
|
|
|
// FIXME: rdar://16257592 arm codegen does't call swift_allocBox correctly.
|
|
// Structs are returned indirectly on these platforms, but we want to return
|
|
// in registers, so cram the result into an unsigned long long.
|
|
// Use an enum class with implicit conversions so we don't dirty C callers
|
|
// too much.
|
|
#if __arm__ || __i386__
|
|
enum class Return : unsigned long long {};
|
|
|
|
operator Return() const {
|
|
union {
|
|
BoxPair value;
|
|
Return mangled;
|
|
} reinterpret = {*this};
|
|
|
|
return reinterpret.mangled;
|
|
}
|
|
|
|
BoxPair() = default;
|
|
BoxPair(HeapObject *h, OpaqueValue *v)
|
|
: heapObject(h), value(v) {}
|
|
|
|
/*implicit*/ BoxPair(Return r) {
|
|
union {
|
|
Return mangled;
|
|
BoxPair value;
|
|
} reinterpret = {r};
|
|
|
|
*this = reinterpret.value;
|
|
}
|
|
#else
|
|
using Return = BoxPair;
|
|
#endif
|
|
};
|
|
|
|
/// Allocates a heap object with POD value semantics. The returned memory is
|
|
/// uninitialized outside of the heap object header. The object has an
|
|
/// initial retain count of 1, and its metadata is set to a predefined
|
|
/// POD heap metadata for which destruction is a no-op.
|
|
///
|
|
/// \param dataSize The size of the data area for the allocation.
|
|
/// Excludes the heap metadata header.
|
|
/// \param dataAlignmentMask The alignment of the data area.
|
|
///
|
|
/// \returns a BoxPair in which the heapObject field points to the newly-created
|
|
/// HeapObject and the value field points to the data area inside the
|
|
/// allocation. The value pointer will have the alignment specified
|
|
/// by the dataAlignmentMask and point to dataSize bytes of memory.
|
|
extern "C" BoxPair::Return
|
|
swift_allocPOD(size_t dataSize, size_t dataAlignmentMask);
|
|
|
|
/// Deallocates a heap object known to have been allocated by swift_allocPOD and
|
|
/// to have no remaining owners.
|
|
extern "C" void swift_deallocPOD(HeapObject *obj);
|
|
|
|
/// Allocates a heap object that can contain a value of the given type.
|
|
/// Returns a Box structure containing a HeapObject* pointer to the
|
|
/// allocated object, and a pointer to the value inside the heap object.
|
|
/// The value pointer points to an uninitialized buffer of size and alignment
|
|
/// appropriate to store a value of the given type.
|
|
/// The heap object has an initial retain count of 1, and its metadata is set
|
|
/// such that destroying the heap object destroys the contained value.
|
|
extern "C" BoxPair::Return swift_allocBox(Metadata const *type);
|
|
|
|
// Allocate plain old memory. This is the generalized entry point
|
|
// Never returns nil. The returned memory is uninitialized.
|
|
//
|
|
// An "alignment mask" is just the alignment (a power of 2) minus 1.
|
|
extern "C" void *swift_slowAlloc(size_t bytes, size_t alignMask);
|
|
|
|
// If the caller cannot promise to zero the object during destruction,
|
|
// then call these corresponding APIs:
|
|
extern "C" void swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask);
|
|
|
|
/// Atomically increments the retain count of an object.
|
|
///
|
|
/// \param object - may be null, in which case this is a no-op
|
|
/// \return its argument value exactly
|
|
///
|
|
/// POSSIBILITIES: We may end up wanting a bunch of different variants:
|
|
/// - the general version which correctly handles null values, swift
|
|
/// objects, and ObjC objects
|
|
/// - a variant that assumes that its operand is a swift object
|
|
/// - a variant that can safely use non-atomic operations
|
|
/// - maybe a variant that can assume a non-null object
|
|
/// It may also prove worthwhile to have this use a custom CC
|
|
/// which preserves a larger set of registers.
|
|
extern "C" HeapObject *swift_retain(HeapObject *object);
|
|
extern "C" void swift_retain_noresult(HeapObject *object);
|
|
|
|
extern "C" HeapObject *swift_retain_n(HeapObject *object, uint32_t n);
|
|
|
|
static inline HeapObject *_swift_retain_inlined(HeapObject *object) {
|
|
if (object) {
|
|
object->refCount.increment();
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/// Atomically increments the reference count of an object, unless it has
|
|
/// already been destroyed. Returns nil if the object is dead.
|
|
extern "C" HeapObject *swift_tryRetain(HeapObject *object);
|
|
|
|
/// Returns true if an object is in the process of being deallocated.
|
|
extern "C" bool swift_isDeallocating(HeapObject *object);
|
|
|
|
/// Attempts to atomically pin an object and increment its reference
|
|
/// count. Returns nil if the object was already pinned.
|
|
///
|
|
/// The standard protocol is that the caller is responsible for
|
|
/// calling swift_unpin on the return value.
|
|
///
|
|
/// The object reference may not be nil.
|
|
extern "C" HeapObject *swift_tryPin(HeapObject *object);
|
|
|
|
/// Given that an object is pinned, atomically unpin it and decrement
|
|
/// the reference count.
|
|
///
|
|
/// The object reference may be nil (to simplify the protocol).
|
|
extern "C" void swift_unpin(HeapObject *object);
|
|
|
|
/// Atomically decrements the retain count of an object. If the
|
|
/// retain count reaches zero, the object is destroyed as follows:
|
|
///
|
|
/// size_t allocSize = object->metadata->destroy(object);
|
|
/// if (allocSize) swift_deallocObject(object, allocSize);
|
|
///
|
|
/// \param object - may be null, in which case this is a no-op
|
|
///
|
|
/// POSSIBILITIES: We may end up wanting a bunch of different variants:
|
|
/// - the general version which correctly handles null values, swift
|
|
/// objects, and ObjC objects
|
|
/// - a variant that assumes that its operand is a swift object
|
|
/// - a variant that can safely use non-atomic operations
|
|
/// - maybe a variant that can assume a non-null object
|
|
/// It's unlikely that a custom CC would be beneficial here.
|
|
extern "C" void swift_release(HeapObject *object);
|
|
|
|
/// Atomically decrements the retain count of an object n times. If the retain
|
|
/// count reaches zero, the object is destroyed
|
|
extern "C" void swift_release_n(HeapObject *object, uint32_t n);
|
|
|
|
/// ObjC compatibility. Never call this.
|
|
extern "C" size_t swift_retainCount(HeapObject *object);
|
|
|
|
/// Is this pointer a non-null unique reference to an object
|
|
/// that uses Swift reference counting?
|
|
extern "C" bool swift_isUniquelyReferencedNonObjC(const void *);
|
|
|
|
/// Is this non-null pointer a unique reference to an object
|
|
/// that uses Swift reference counting?
|
|
extern "C" bool swift_isUniquelyReferencedNonObjC_nonNull(const void *);
|
|
|
|
/// Is this non-null pointer a reference to an object that uses Swift
|
|
/// reference counting and is either uniquely referenced or pinned?
|
|
extern "C" bool swift_isUniquelyReferencedOrPinnedNonObjC_nonNull(const void *);
|
|
|
|
/// Is this non-null BridgeObject a unique reference to an object
|
|
/// that uses Swift reference counting?
|
|
extern "C" bool swift_isUniquelyReferencedNonObjC_nonNull_bridgeObject(
|
|
uintptr_t bits);
|
|
|
|
/// Is this non-null BridgeObject a unique or pinned reference to an
|
|
/// object that uses Swift reference counting?
|
|
extern "C" bool swift_isUniquelyReferencedOrPinnedNonObjC_nonNull_bridgeObject(
|
|
uintptr_t bits);
|
|
|
|
/// Is this native Swift pointer a non-null unique reference to
|
|
/// an object?
|
|
extern "C" bool swift_isUniquelyReferenced_native(const struct HeapObject *);
|
|
|
|
/// Is this native Swift pointer a non-null unique or pinned reference
|
|
/// to an object?
|
|
extern "C" bool swift_isUniquelyReferencedOrPinned_native(
|
|
const struct HeapObject *);
|
|
|
|
/// Is this non-null native Swift pointer a unique reference to
|
|
/// an object?
|
|
extern "C" bool swift_isUniquelyReferenced_nonNull_native(
|
|
const struct HeapObject *);
|
|
|
|
/// Does this non-null native Swift pointer refer to an object that
|
|
/// is either uniquely referenced or pinned?
|
|
extern "C" bool swift_isUniquelyReferencedOrPinned_nonNull_native(
|
|
const struct HeapObject *);
|
|
|
|
/// Deallocate the given memory; it was returned by swift_allocObject
|
|
/// but is otherwise in an unknown state.
|
|
///
|
|
/// \param object - never null
|
|
/// \param allocatedSize - the allocated size of the object from the
|
|
/// program's perspective, i.e. the value
|
|
/// \param allocatedAlignMask - the alignment requirement that was passed
|
|
/// to allocObject
|
|
///
|
|
/// POSSIBILITIES: It may be useful to have a variant which
|
|
/// requires the object to have been fully zeroed from offsets
|
|
/// sizeof(SwiftHeapObject) to allocatedSize.
|
|
extern "C" void swift_deallocObject(HeapObject *object, size_t allocatedSize,
|
|
size_t allocatedAlignMask);
|
|
|
|
/// Deallocate the given class instance; it was returned by swift_allocObject
|
|
/// and possibly used as an Objective-C class instance, but is otherwise in an
|
|
/// unknown state.
|
|
///
|
|
/// \param object - never null
|
|
/// \param allocatedSize - the allocated size of the object from the
|
|
/// program's perspective, i.e. the value
|
|
/// \param allocatedAlignMask - the alignment requirement that was passed
|
|
/// to allocObject
|
|
///
|
|
/// POSSIBILITIES: It may be useful to have a variant which
|
|
/// requires the object to have been fully zeroed from offsets
|
|
/// sizeof(SwiftHeapObject) to allocatedSize.
|
|
extern "C" void swift_deallocClassInstance(HeapObject *object,
|
|
size_t allocatedSize,
|
|
size_t allocatedAlignMask);
|
|
|
|
/// Deallocate the given memory allocated by swift_allocBox; it was returned
|
|
/// by swift_allocBox but is otherwise in an unknown state. The given Metadata
|
|
/// pointer must be the same metadata pointer that was passed to swift_allocBox
|
|
/// when the memory was allocated.
|
|
extern "C" void swift_deallocBox(HeapObject *object);
|
|
|
|
/// Project the value out of a box. `object` must have been allocated
|
|
/// using `swift_allocBox`, or by the compiler using a statically-emitted
|
|
/// box metadata object.
|
|
extern "C" OpaqueValue *swift_projectBox(HeapObject *object);
|
|
|
|
/// RAII object that wraps a Swift heap object and releases it upon
|
|
/// destruction.
|
|
class SwiftRAII {
|
|
HeapObject *object;
|
|
|
|
public:
|
|
SwiftRAII(HeapObject *obj, bool AlreadyRetained) : object(obj) {
|
|
if (!AlreadyRetained)
|
|
swift_retain(obj);
|
|
}
|
|
|
|
~SwiftRAII() {
|
|
if (object)
|
|
swift_release(object);
|
|
}
|
|
|
|
SwiftRAII(const SwiftRAII &other) : object(swift_retain(*other)) {
|
|
;
|
|
}
|
|
SwiftRAII(SwiftRAII &&other) : object(*other) {
|
|
other.object = nullptr;
|
|
}
|
|
SwiftRAII &operator=(const SwiftRAII &other) {
|
|
if (object)
|
|
swift_release(object);
|
|
object = swift_retain(*other);
|
|
return *this;
|
|
}
|
|
SwiftRAII &operator=(SwiftRAII &&other) {
|
|
if (object)
|
|
swift_release(object);
|
|
object = *other;
|
|
other.object = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
HeapObject *operator *() const { return object; }
|
|
};
|
|
|
|
/// Increment the weak retain count.
|
|
extern "C" void swift_weakRetain(HeapObject *value);
|
|
|
|
/// Decrement the weak retain count.
|
|
extern "C" void swift_weakRelease(HeapObject *value);
|
|
|
|
/// Increment the strong retain count of an object which may have been
|
|
/// deallocated.
|
|
extern "C" void swift_retainUnowned(HeapObject *value);
|
|
|
|
/// A weak reference value object. This is ABI.
|
|
struct WeakReference {
|
|
HeapObject *Value;
|
|
};
|
|
|
|
/// Initialize a weak reference.
|
|
///
|
|
/// \param ref - never null
|
|
/// \param value - can be null
|
|
extern "C" void swift_weakInit(WeakReference *ref, HeapObject *value);
|
|
|
|
/// Assign a new value to a weak reference.
|
|
///
|
|
/// \param ref - never null
|
|
/// \param value - can be null
|
|
extern "C" void swift_weakAssign(WeakReference *ref, HeapObject *value);
|
|
|
|
/// Load a value from a weak reference. If the current value is a
|
|
/// non-null object that has begun deallocation, returns null;
|
|
/// otherwise, retains the object before returning.
|
|
///
|
|
/// \param ref - never null
|
|
/// \return can be null
|
|
extern "C" HeapObject *swift_weakLoadStrong(WeakReference *ref);
|
|
|
|
/// Load a value from a weak reference as if by swift_weakLoadStrong,
|
|
/// but leaving the reference in an uninitialized state.
|
|
///
|
|
/// \param ref - never null
|
|
/// \return can be null
|
|
extern "C" HeapObject *swift_weakTakeStrong(WeakReference *ref);
|
|
|
|
/// Destroy a weak reference.
|
|
///
|
|
/// \param ref - never null, but can refer to a null object
|
|
extern "C" void swift_weakDestroy(WeakReference *ref);
|
|
|
|
/// Copy initialize a weak reference.
|
|
///
|
|
/// \param dest - never null, but can refer to a null object
|
|
/// \param src - never null, but can refer to a null object
|
|
extern "C" void swift_weakCopyInit(WeakReference *dest, WeakReference *src);
|
|
|
|
/// Take initialize a weak reference.
|
|
///
|
|
/// \param dest - never null, but can refer to a null object
|
|
/// \param src - never null, but can refer to a null object
|
|
extern "C" void swift_weakTakeInit(WeakReference *dest, WeakReference *src);
|
|
|
|
/// Copy assign a weak reference.
|
|
///
|
|
/// \param dest - never null, but can refer to a null object
|
|
/// \param src - never null, but can refer to a null object
|
|
extern "C" void swift_weakCopyAssign(WeakReference *dest, WeakReference *src);
|
|
|
|
/// Take assign a weak reference.
|
|
///
|
|
/// \param dest - never null, but can refer to a null object
|
|
/// \param src - never null, but can refer to a null object
|
|
extern "C" void swift_weakTakeAssign(WeakReference *dest, WeakReference *src);
|
|
|
|
extern "C" void *swift_bridgeObjectRetain(void *value);
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Increment the strong retain count of an object which might not be a native
|
|
/// Swift object.
|
|
extern "C" void *swift_unknownRetain(void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownRetain(void *value) {
|
|
swift_retain(static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
extern "C" void swift_bridgeObjectRelease(void *value);
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Decrement the strong retain count of an object which might not be a native
|
|
/// Swift object.
|
|
extern "C" void swift_unknownRelease(void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownRelease(void *value) {
|
|
swift_release(static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Increment the strong retain count of an object which may have been
|
|
/// deallocated and which might not be a native Swift object.
|
|
extern "C" void swift_unknownRetainUnowned(void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownRetainUnowned(void *value) {
|
|
swift_retainUnowned(static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Increment the weak-reference count of an object that might not be
|
|
/// a native Swift object.
|
|
extern "C" void swift_unknownWeakRetain(void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakRetain(void *value) {
|
|
swift_weakRetain(static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Decrement the weak-reference count of an object that might not be
|
|
/// a native Swift object.
|
|
extern "C" void swift_unknownWeakRelease(void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakRelease(void *value) {
|
|
swift_weakRelease(static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Initialize a weak reference.
|
|
///
|
|
/// \param ref - never null
|
|
/// \param value - not necessarily a native Swift object; can be null
|
|
extern "C" void swift_unknownWeakInit(WeakReference *ref, void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakInit(WeakReference *ref, void *value) {
|
|
swift_weakInit(ref, static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Assign a new value to a weak reference.
|
|
///
|
|
/// \param ref - never null
|
|
/// \param value - not necessarily a native Swift object; can be null
|
|
extern "C" void swift_unknownWeakAssign(WeakReference *ref, void *value);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakAssign(WeakReference *ref, void *value) {
|
|
swift_weakAssign(ref, static_cast<HeapObject *>(value));
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Load a value from a weak reference, much like swift_weakLoadStrong
|
|
/// but without requiring the variable to refer to a native Swift object.
|
|
///
|
|
/// \param ref - never null
|
|
/// \return can be null
|
|
extern "C" void *swift_unknownWeakLoadStrong(WeakReference *ref);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakLoadStrong(WeakReference *ref) {
|
|
swift_weakLoadStrong(ref);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Load a value from a weak reference as if by
|
|
/// swift_unknownWeakLoadStrong, but leaving the reference in an
|
|
/// uninitialized state.
|
|
///
|
|
/// \param ref - never null
|
|
/// \return can be null
|
|
extern "C" void *swift_unknownWeakTakeStrong(WeakReference *ref);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakTakeStrong(WeakReference *ref) {
|
|
swift_weakTakeStrong(ref);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Destroy a weak reference variable that might not refer to a native
|
|
/// Swift object.
|
|
extern "C" void swift_unknownWeakDestroy(WeakReference *object);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakDestroy(WeakReference *object) {
|
|
swift_weakDestroy(object);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Copy-initialize a weak reference variable from one that might not
|
|
/// refer to a native Swift object.
|
|
extern "C" void swift_unknownWeakCopyInit(WeakReference *dest, WeakReference *src);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakCopyInit(WeakReference *dest, WeakReference *src) {
|
|
swift_weakCopyInit(dest, src);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Take-initialize a weak reference variable from one that might not
|
|
/// refer to a native Swift object.
|
|
extern "C" void swift_unknownWeakTakeInit(WeakReference *dest, WeakReference *src);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakTakeInit(WeakReference *dest, WeakReference *src) {
|
|
swift_weakTakeInit(dest, src);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Copy-assign a weak reference variable from another when either
|
|
/// or both variables might not refer to a native Swift object.
|
|
extern "C" void swift_unknownWeakCopyAssign(WeakReference *dest, WeakReference *src);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakCopyAssign(WeakReference *dest, WeakReference *src) {
|
|
swift_weakCopyAssign(dest, src);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
#if SWIFT_OBJC_INTEROP
|
|
|
|
/// Take-assign a weak reference variable from another when either
|
|
/// or both variables might not refer to a native Swift object.
|
|
extern "C" void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src);
|
|
|
|
#else
|
|
|
|
static inline void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src) {
|
|
swift_weakTakeAssign(dest, src);
|
|
}
|
|
|
|
#endif /* SWIFT_OBJC_INTEROP */
|
|
|
|
} // end namespace swift
|
|
|
|
#endif /* SWIFT_RUNTIME_ALLOC_H */
|