//===--- SwiftObject.mm - Native Swift Object root class ------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This implements the Objective-C root class that provides basic `id`-
// compatibility and `NSObject` protocol conformance for pure Swift classes.
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Config.h"

#if SWIFT_OBJC_INTEROP
#include <objc/NSObject.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <objc/objc.h>
#endif
#include "llvm/ADT/StringRef.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Lazy.h"
#include "swift/Runtime/Casting.h"
#include "swift/Runtime/Heap.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/ObjCBridge.h"
#include "swift/Strings.h"
#include "../SwiftShims/RuntimeShims.h"
#include "../SwiftShims/AssertionReporting.h"
#include "Private.h"
#include "SwiftObject.h"
#include "WeakReference.h"
#include "swift/Runtime/Debug.h"
#if SWIFT_OBJC_INTEROP
#include <dlfcn.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unordered_map>
#if SWIFT_OBJC_INTEROP
# import <CoreFoundation/CFBase.h> // for CFTypeID
# import <Foundation/Foundation.h>
# include <malloc/malloc.h>
# include <dispatch/dispatch.h>
#endif

using namespace swift;

#if SWIFT_HAS_ISA_MASKING
OBJC_EXPORT __attribute__((__weak_import__))
const uintptr_t objc_debug_isa_class_mask;

static uintptr_t computeISAMask() {
  // The versions of the Objective-C runtime which use non-pointer
  // ISAs also export this symbol.
  if (auto runtimeSymbol = &objc_debug_isa_class_mask)
    return *runtimeSymbol;
  return ~uintptr_t(0);
}

SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
uintptr_t swift::swift_isaMask = computeISAMask();
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
#endif

const ClassMetadata *swift::_swift_getClass(const void *object) {
#if SWIFT_OBJC_INTEROP
  if (!isObjCTaggedPointer(object))
    return _swift_getClassOfAllocated(object);
  return reinterpret_cast<const ClassMetadata*>(
    object_getClass(id_const_cast(object)));
#else
  return _swift_getClassOfAllocated(object);
#endif
}

#if SWIFT_OBJC_INTEROP

/// \brief Replacement for ObjC object_isClass(), which is unavailable on
/// deployment targets macOS 10.9 and iOS 7.
static bool objcObjectIsClass(id object) {
  // same as object_isClass(object)
  return class_isMetaClass(object_getClass(object));
}

/// Same as _swift_getClassOfAllocated() but returns type Class.
static Class _swift_getObjCClassOfAllocated(const void *object) {
  return class_const_cast(_swift_getClassOfAllocated(object));
}

#endif

/// \brief Fetch the type metadata associated with the formal dynamic
/// type of the given (possibly Objective-C) object.  The formal
/// dynamic type ignores dynamic subclasses such as those introduced
/// by KVO.
///
/// The object pointer may be a tagged pointer, but cannot be null.
const Metadata *swift::swift_getObjectType(HeapObject *object) {
  auto classAsMetadata = _swift_getClass(object);

#if SWIFT_OBJC_INTEROP
  // Walk up the superclass chain skipping over artifical Swift classes.
  // If we find a non-Swift class use the result of [object class] instead.

  while (classAsMetadata && classAsMetadata->isTypeMetadata()) {
    if (!classAsMetadata->isArtificialSubclass())
      return classAsMetadata;
    classAsMetadata = classAsMetadata->Superclass;
  }

  id objcObject = reinterpret_cast<id>(object);
  Class objcClass = [objcObject class];
  if (objcObjectIsClass(objcObject)) {
    // Original object is a class. We want a
    // metaclass but +class doesn't give that to us.
    objcClass = object_getClass(objcClass);
  }
  classAsMetadata = reinterpret_cast<const ClassMetadata *>(objcClass);
  return swift_getObjCClassMetadata(classAsMetadata);
#else
  assert(classAsMetadata &&
         classAsMetadata->isTypeMetadata() &&
         !classAsMetadata->isArtificialSubclass());
  return classAsMetadata;
#endif
}

#if SWIFT_OBJC_INTEROP
static SwiftObject *_allocHelper(Class cls) {
  // XXX FIXME
  // When we have layout information, do precise alignment rounding
  // For now, assume someone is using hardware vector types
#if defined(__x86_64__) || defined(__i386__)
  const size_t mask = 32 - 1;
#else
  const size_t mask = 16 - 1;
#endif
  return reinterpret_cast<SwiftObject *>(swift::swift_allocObject(
    reinterpret_cast<HeapMetadata const *>(cls),
    class_getInstanceSize(cls), mask));
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
NSString *swift_stdlib_getDescription(OpaqueValue *value,
                                      const Metadata *type);

NSString *swift::getDescription(OpaqueValue *value, const Metadata *type) {
  auto result = swift_stdlib_getDescription(value, type);
  SWIFT_CC_PLUSZERO_GUARD(type->vw_destroy(value));
  return [result autorelease];
}

static NSString *_getObjectDescription(SwiftObject *obj) {
  swift_retain((HeapObject*)obj);
  return getDescription((OpaqueValue*)&obj,
                        _swift_getClassOfAllocated(obj));
}

static NSString *_getClassDescription(Class cls) {
  return NSStringFromClass(cls);
}


@implementation SwiftObject
+ (void)initialize {}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
  assert(zone == nullptr);
  return _allocHelper(self);
}

+ (instancetype)alloc {
  // we do not support "placement new" or zones,
  // so there is no need to call allocWithZone
  return _allocHelper(self);
}

+ (Class)class {
  return self;
}
- (Class)class {
  return _swift_getObjCClassOfAllocated(self);
}
+ (Class)superclass {
  return (Class)((const ClassMetadata*) self)->Superclass;
}
- (Class)superclass {
  return (Class)_swift_getClassOfAllocated(self)->Superclass;
}

+ (BOOL)isMemberOfClass:(Class)cls {
  return cls == _swift_getObjCClassOfAllocated(self);
}

- (BOOL)isMemberOfClass:(Class)cls {
  return cls == _swift_getObjCClassOfAllocated(self);
}

- (instancetype)self {
  return self;
}
- (BOOL)isProxy {
  return NO;
}

- (struct _NSZone *)zone {
  auto zone = malloc_zone_from_ptr(self);
  return (struct _NSZone *)(zone ? zone : malloc_default_zone());
}

- (void)doesNotRecognizeSelector: (SEL) sel {
  Class cls = _swift_getObjCClassOfAllocated(self);
  fatalError(/* flags = */ 0,
             "Unrecognized selector %c[%s %s]\n",
             class_isMetaClass(cls) ? '+' : '-',
             class_getName(cls), sel_getName(sel));
}

- (id)retain {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  swift_retain(SELF);
  return self;
}
- (void)release {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  swift_release(SELF);
}
- (id)autorelease {
  return _objc_rootAutorelease(self);
}
- (NSUInteger)retainCount {
  return swift::swift_retainCount(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)_isDeallocating {
  return swift_isDeallocating(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)_tryRetain {
  return swift_tryRetain(reinterpret_cast<HeapObject*>(self)) != nullptr;
}
- (BOOL)allowsWeakReference {
  return !swift_isDeallocating(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)retainWeakReference {
  return swift_tryRetain(reinterpret_cast<HeapObject*>(self)) != nullptr;
}

// Retaining the class object itself is a no-op.
+ (id)retain {
  return self;
}
+ (void)release {
  /* empty */
}
+ (id)autorelease {
  return self;
}
+ (NSUInteger)retainCount {
  return ULONG_MAX;
}
+ (BOOL)_isDeallocating {
  return NO;
}
+ (BOOL)_tryRetain {
  return YES;
}
+ (BOOL)allowsWeakReference {
  return YES;
}
+ (BOOL)retainWeakReference {
  return YES;
}

- (void)dealloc {
  swift_rootObjCDealloc(reinterpret_cast<HeapObject *>(self));
}

- (BOOL)isKindOfClass:(Class)someClass {
  for (auto cls = _swift_getClassOfAllocated(self); cls != nullptr;
       cls = cls->Superclass)
    if (cls == (const ClassMetadata*) someClass)
      return YES;

  return NO;
}

+ (BOOL)isSubclassOfClass:(Class)someClass {
  for (auto cls = (const ClassMetadata*) self; cls != nullptr;
       cls = cls->Superclass)
    if (cls == (const ClassMetadata*) someClass)
      return YES;

  return NO;
}

+ (BOOL)respondsToSelector:(SEL)sel {
  if (!sel) return NO;
  return class_respondsToSelector(_swift_getObjCClassOfAllocated(self), sel);
}

- (BOOL)respondsToSelector:(SEL)sel {
  if (!sel) return NO;
  return class_respondsToSelector(_swift_getObjCClassOfAllocated(self), sel);
}

+ (BOOL)instancesRespondToSelector:(SEL)sel {
  if (!sel) return NO;
  return class_respondsToSelector(self, sel);
}


+ (IMP)methodForSelector:(SEL)sel {
  return class_getMethodImplementation(object_getClass((id)self), sel);
}

- (IMP)methodForSelector:(SEL)sel {
  return class_getMethodImplementation(object_getClass(self), sel);
}

+ (IMP)instanceMethodForSelector:(SEL)sel {
  return class_getMethodImplementation(self, sel);
}


- (BOOL)conformsToProtocol:(Protocol*)proto {
  if (!proto) return NO;
  auto selfClass = _swift_getObjCClassOfAllocated(self);

  // Walk the superclass chain.
  while (selfClass) {
    if (class_conformsToProtocol(selfClass, proto))
      return YES;
    selfClass = class_getSuperclass(selfClass);
  }

  return NO;
}

+ (BOOL)conformsToProtocol:(Protocol*)proto {
  if (!proto) return NO;

  // Walk the superclass chain.
  Class selfClass = self;
  while (selfClass) {
    if (class_conformsToProtocol(selfClass, proto))
      return YES;
    selfClass = class_getSuperclass(selfClass);
  }

  return NO;
}

- (NSUInteger)hash {
  return (NSUInteger)self;
}

- (BOOL)isEqual:(id)object {
  return self == object;
}

- (id)performSelector:(SEL)aSelector {
  return ((id(*)(id, SEL))objc_msgSend)(self, aSelector);
}

- (id)performSelector:(SEL)aSelector withObject:(id)object {
  return ((id(*)(id, SEL, id))objc_msgSend)(self, aSelector, object);
}

- (id)performSelector:(SEL)aSelector withObject:(id)object1
                                     withObject:(id)object2 {
  return ((id(*)(id, SEL, id, id))objc_msgSend)(self, aSelector, object1,
                                                                 object2);
}

- (NSString *)description {
  return _getObjectDescription(self);
}
- (NSString *)debugDescription {
  return _getObjectDescription(self);
}

+ (NSString *)description {
  return _getClassDescription(self);
}
+ (NSString *)debugDescription {
  return _getClassDescription(self);
}

- (NSString *)_copyDescription {
  // The NSObject version of this pushes an autoreleasepool in case -description
  // autoreleases, but we're OK with leaking things if we're at the top level
  // of the main thread with no autorelease pool.
  return [[self description] retain];
}

- (CFTypeID)_cfTypeID {
  // Adopt the same CFTypeID as NSObject.
  static CFTypeID result;
  static dispatch_once_t predicate;
  dispatch_once_f(&predicate, &result, [](void *resultAddr) {
    id obj = [[NSObject alloc] init];
    *(CFTypeID*)resultAddr = [obj _cfTypeID];
    [obj release];
  });
  return result;
}

// Foundation collections expect these to be implemented.
- (BOOL)isNSArray__      { return NO; }
- (BOOL)isNSCFConstantString__  { return NO; }
- (BOOL)isNSData__       { return NO; }
- (BOOL)isNSDate__       { return NO; }
- (BOOL)isNSDictionary__ { return NO; }
- (BOOL)isNSObject__     { return NO; }
- (BOOL)isNSOrderedSet__ { return NO; }
- (BOOL)isNSNumber__     { return NO; }
- (BOOL)isNSSet__        { return NO; }
- (BOOL)isNSString__     { return NO; }
- (BOOL)isNSTimeZone__   { return NO; }
- (BOOL)isNSValue__      { return NO; }

@end

#endif

/// Decide dynamically whether the given class uses native Swift
/// reference-counting.
bool swift::usesNativeSwiftReferenceCounting(const ClassMetadata *theClass) {
#if SWIFT_OBJC_INTEROP
  if (!theClass->isTypeMetadata()) return false;
  return (theClass->getFlags() & ClassFlags::UsesSwiftRefcounting);
#else
  return true;
#endif
}

/// Decide dynamically whether the given type metadata uses native Swift
/// reference-counting.  The metadata is known to correspond to a class
/// type, but note that does not imply being known to be a ClassMetadata
/// due to the existence of ObjCClassWrapper.
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
bool
_objcClassUsesNativeSwiftReferenceCounting(const Metadata *theClass) {
#if SWIFT_OBJC_INTEROP
  // If this is ObjC wrapper metadata, the class is definitely not using
  // Swift ref-counting.
  if (isa<ObjCClassWrapperMetadata>(theClass)) return false;

  // Otherwise, it's class metadata.
  return usesNativeSwiftReferenceCounting(cast<ClassMetadata>(theClass));
#else
  return true;
#endif
}

// The non-pointer bits, excluding the ObjC tag bits.
static auto const unTaggedNonNativeBridgeObjectBits
  = heap_object_abi::SwiftSpareBitsMask
  & ~heap_object_abi::ObjCReservedBitsMask;

#if SWIFT_OBJC_INTEROP

#if defined(__x86_64__)
static uintptr_t const objectPointerIsObjCBit = 0x4000000000000000ULL;
#elif defined(__arm64__)
static uintptr_t const objectPointerIsObjCBit = 0x4000000000000000ULL;
#else
static uintptr_t const objectPointerIsObjCBit = 0x00000002U;
#endif

void *swift::swift_unknownRetain_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_retain_n(static_cast<HeapObject *>(object), n);
  }
  for (int i = 0; i < n; ++i)
    objc_retain(static_cast<id>(object));

  return object;
}

void swift::swift_unknownRelease_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_release_n(static_cast<HeapObject *>(object), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(object));
}

void *swift::swift_unknownRetain(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_retain(static_cast<HeapObject *>(object));
  }
  return objc_retain(static_cast<id>(object));
}

void swift::swift_unknownRelease(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_release(static_cast<HeapObject *>(object));
  return objc_release(static_cast<id>(object));
}

void *swift::swift_nonatomic_unknownRetain_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_nonatomic_retain_n(static_cast<HeapObject *>(object), n);
  }
  for (int i = 0; i < n; ++i)
    objc_retain(static_cast<id>(object));
  return object;
}

void swift::swift_nonatomic_unknownRelease_n(void *object, int n) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_nonatomic_release_n(static_cast<HeapObject *>(object), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(object));
}

void *swift::swift_nonatomic_unknownRetain(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return object;
  if (objectUsesNativeSwiftReferenceCounting(object)) {
    return swift_nonatomic_retain(static_cast<HeapObject *>(object));
  }
  return objc_retain(static_cast<id>(object));
}

void swift::swift_nonatomic_unknownRelease(void *object) {
  if (isObjCTaggedPointerOrNull(object)) return;
  if (objectUsesNativeSwiftReferenceCounting(object))
    return swift_release(static_cast<HeapObject *>(object));
  return objc_release(static_cast<id>(object));
}


/// Return true iff the given BridgeObject is not known to use native
/// reference-counting.
///
/// Precondition: object does not encode a tagged pointer
static bool isNonNative_unTagged_bridgeObject(void *object) {
  static_assert((heap_object_abi::SwiftSpareBitsMask & objectPointerIsObjCBit) ==
                objectPointerIsObjCBit,
                "isObjC bit not within spare bits");
  return (uintptr_t(object) & objectPointerIsObjCBit) != 0;
}
#endif

// Mask out the spare bits in a bridgeObject, returning the object it
// encodes.
///
/// Precondition: object does not encode a tagged pointer
static void* toPlainObject_unTagged_bridgeObject(void *object) {
  return (void*)(uintptr_t(object) & ~unTaggedNonNativeBridgeObjectBits);
}

void *swift::swift_bridgeObjectRetain(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_retain(static_cast<HeapObject *>(objectRef));
    return static_cast<HeapObject *>(objectRef);
  }
  return objc_retain(static_cast<id>(objectRef));
#else
  swift_retain(static_cast<HeapObject *>(objectRef));
  return static_cast<HeapObject *>(objectRef);
#endif
}

SWIFT_RUNTIME_EXPORT
void *swift::swift_nonatomic_bridgeObjectRetain(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_nonatomic_retain(static_cast<HeapObject *>(objectRef));
    return static_cast<HeapObject *>(objectRef);
  }
  return objc_retain(static_cast<id>(objectRef));
#else
  swift_nonatomic_retain(static_cast<HeapObject *>(objectRef));
  return static_cast<HeapObject *>(objectRef);
#endif
}

SWIFT_RUNTIME_EXPORT
void swift::swift_bridgeObjectRelease(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_release(static_cast<HeapObject *>(objectRef));
  return objc_release(static_cast<id>(objectRef));
#else
  swift_release(static_cast<HeapObject *>(objectRef));
#endif
}

void swift::swift_nonatomic_bridgeObjectRelease(void *object) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_nonatomic_release(static_cast<HeapObject *>(objectRef));
  return objc_release(static_cast<id>(objectRef));
#else
  swift_nonatomic_release(static_cast<HeapObject *>(objectRef));
#endif
}

void *swift::swift_bridgeObjectRetain_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  void *objc_ret = nullptr;
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_retain_n(static_cast<HeapObject *>(objectRef), n);
    return static_cast<HeapObject *>(objectRef);
  }
  for (int i = 0;i < n; ++i)
    objc_ret = objc_retain(static_cast<id>(objectRef));
  return objc_ret;
#else
  swift_retain_n(static_cast<HeapObject *>(objectRef), n);
  return static_cast<HeapObject *>(objectRef);
#endif
}

void swift::swift_bridgeObjectRelease_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_release_n(static_cast<HeapObject *>(objectRef), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(objectRef));
#else
  swift_release_n(static_cast<HeapObject *>(objectRef), n);
#endif
}

void *swift::swift_nonatomic_bridgeObjectRetain_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return object;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  void *objc_ret = nullptr;
  if (!isNonNative_unTagged_bridgeObject(object)) {
    swift_nonatomic_retain_n(static_cast<HeapObject *>(objectRef), n);
    return static_cast<HeapObject *>(objectRef);
  }
  for (int i = 0;i < n; ++i)
    objc_ret = objc_retain(static_cast<id>(objectRef));
  return objc_ret;
#else
  swift_nonatomic_retain_n(static_cast<HeapObject *>(objectRef), n);
  return static_cast<HeapObject *>(objectRef);
#endif
}

void swift::swift_nonatomic_bridgeObjectRelease_n(void *object, int n) {
#if SWIFT_OBJC_INTEROP
  if (isObjCTaggedPointer(object))
    return;
#endif

  auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
  if (!isNonNative_unTagged_bridgeObject(object))
    return swift_nonatomic_release_n(static_cast<HeapObject *>(objectRef), n);
  for (int i = 0; i < n; ++i)
    objc_release(static_cast<id>(objectRef));
#else
  swift_nonatomic_release_n(static_cast<HeapObject *>(objectRef), n);
#endif
}


#if SWIFT_OBJC_INTEROP

/*****************************************************************************/
/************************ UNKNOWN UNOWNED REFERENCES *************************/
/*****************************************************************************/

// Swift's native unowned references are implemented purely with
// reference-counting: as long as an unowned reference is held to an object,
// it can be destroyed but never deallocated, being that it remains fully safe
// to pass around a pointer and perform further reference-counting operations.
//
// For imported class types (meaning ObjC, for now, but in principle any
// type which supports ObjC-style weak references but not directly Swift-style
// unowned references), we have to implement this on top of the weak-reference
// support, at least for now.  But we'd like to be able to statically take
// advantage of Swift's representational advantages when we know that all the
// objects involved are Swift-native.  That means that whatever scheme we use
// for unowned references needs to interoperate with code just doing naive
// loads and stores, at least when the ObjC case isn't triggered.
//
// We have to be sensitive about making unreasonable assumptions about the
// implementation of ObjC weak references, and we definitely cannot modify
// memory owned by the ObjC runtime.  In the long run, direct support from
// the ObjC runtime can allow an efficient implementation that doesn't violate
// those requirements, both by allowing us to directly check whether a weak
// reference was cleared by deallocation vs. just initialized to nil and by
// guaranteeing a bit pattern that distinguishes Swift references.  In the
// meantime, out-of-band allocation is inefficient but not ridiculously so.
//
// Note that unowned references need not provide guaranteed behavior in
// the presence of read/write or write/write races on the reference itself.
// Furthermore, and unlike weak references, they also do not need to be
// safe against races with the deallocation of the object.  It is the user's
// responsibility to ensure that the reference remains valid at the time
// that the unowned reference is read.

namespace {
  /// An Objective-C unowned reference.  Given an unknown unowned reference
  /// in memory, it is an ObjC unowned reference if the IsObjCFlag bit
  /// is set; if so, the pointer stored in the reference actually points
  /// to out-of-line storage containing an ObjC weak reference.
  ///
  /// It is an invariant that this out-of-line storage is only ever
  /// allocated and constructed for non-null object references, so if the
  /// weak load yields null, it can only be because the object was deallocated.
  struct ObjCUnownedReference : UnownedReference {
    // Pretending that there's a subclass relationship here means that
    // accesses to objects formally constructed as UnownedReferences will
    // technically be aliasing violations.  However, the language runtime
    // will generally not see any such objects.

    enum : uintptr_t { IsObjCMask = 0x1, IsObjCFlag = 0x1 };

    /// The out-of-line storage of an ObjC unowned reference.
    struct Storage {
      /// A weak reference registered with the ObjC runtime.
      mutable id WeakRef;

      Storage(id ref) {
        assert(ref && "creating storage for null reference?");
        objc_initWeak(&WeakRef, ref);
      }

      Storage(const Storage &other) {
        objc_copyWeak(&WeakRef, &other.WeakRef);
      }

      Storage &operator=(const Storage &other) = delete;

      Storage &operator=(id ref) {
        objc_storeWeak(&WeakRef, ref);
        return *this;
      }

      ~Storage() {
        objc_destroyWeak(&WeakRef);
      }

      // Don't use the C++ allocator.
      void *operator new(size_t size) { return malloc(size); }
      void operator delete(void *ptr) { free(ptr); }
    };

    Storage *storage() {
      assert(isa<ObjCUnownedReference>(this));
      return reinterpret_cast<Storage*>(
               reinterpret_cast<uintptr_t>(Value) & ~IsObjCMask);
    }

    static void initialize(UnownedReference *dest, id value) {
      initializeWithStorage(dest, new Storage(value));
    }

    static void initializeWithCopy(UnownedReference *dest, Storage *src) {
      initializeWithStorage(dest, new Storage(*src));
    }

    static void initializeWithStorage(UnownedReference *dest,
                                      Storage *storage) {
      dest->Value = (HeapObject*) (uintptr_t(storage) | IsObjCFlag);
    }

    static bool classof(const UnownedReference *ref) {
      return (uintptr_t(ref->Value) & IsObjCMask) == IsObjCFlag;
    }
  };
}

static bool isObjCForUnownedReference(void *value) {
  return (isObjCTaggedPointer(value) ||
          !objectUsesNativeSwiftReferenceCounting(value));
}

UnownedReference *swift::swift_unknownUnownedInit(UnownedReference *dest,
                                                  void *value) {
  if (!value) {
    dest->Value = nullptr;
  } else if (isObjCForUnownedReference(value)) {
    ObjCUnownedReference::initialize(dest, (id) value);
  } else {
    swift_unownedInit(dest, (HeapObject*) value);
  }
  return dest;
}

UnownedReference *swift::swift_unknownUnownedAssign(UnownedReference *dest,
                                                    void *value) {
  if (!value) {
    swift_unknownUnownedDestroy(dest);
    dest->Value = nullptr;
  } else if (isObjCForUnownedReference(value)) {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      objc_storeWeak(&objcDest->storage()->WeakRef, (id) value);
    } else {
      swift_unownedDestroy(dest);
      ObjCUnownedReference::initialize(dest, (id) value);
    }
  } else {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      delete objcDest->storage();
      swift_unownedInit(dest, (HeapObject*) value);
    } else {
      swift_unownedAssign(dest, (HeapObject*) value);
    }
  }
  return dest;
}

void *swift::swift_unknownUnownedLoadStrong(UnownedReference *ref) {
  if (!ref->Value) {
    return nullptr;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    auto result = (void*) objc_loadWeakRetained(&objcRef->storage()->WeakRef);
    if (result == nullptr) {
      swift::swift_abortRetainUnowned(nullptr);
    }
    return result;
  } else {
    return swift_unownedLoadStrong(ref);
  }
}

void *swift::swift_unknownUnownedTakeStrong(UnownedReference *ref) {
  if (!ref->Value) {
    return nullptr;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    auto storage = objcRef->storage();
    auto result = (void*) objc_loadWeakRetained(&objcRef->storage()->WeakRef);
    if (result == nullptr) {
      swift::swift_abortRetainUnowned(nullptr);
    }
    delete storage;
    return result;
  } else {
    return swift_unownedTakeStrong(ref);
  }
}

void swift::swift_unknownUnownedDestroy(UnownedReference *ref) {
  if (!ref->Value) {
    // Nothing to do.
    return;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    delete objcRef->storage();
  } else {
    swift_unownedDestroy(ref);
  }
}

UnownedReference *swift::swift_unknownUnownedCopyInit(UnownedReference *dest,
                                                      UnownedReference *src) {
  assert(dest != src);
  if (!src->Value) {
    dest->Value = nullptr;
  } else if (auto objcSrc = dyn_cast<ObjCUnownedReference>(src)) {
    ObjCUnownedReference::initializeWithCopy(dest, objcSrc->storage());
  } else {
    swift_unownedCopyInit(dest, src);
  }
  return dest;
}

UnownedReference *swift::swift_unknownUnownedTakeInit(UnownedReference *dest,
                                                      UnownedReference *src) {
  assert(dest != src);
  dest->Value = src->Value;
  return dest;
}

UnownedReference *swift::swift_unknownUnownedCopyAssign(UnownedReference *dest,
                                                        UnownedReference *src) {
  if (dest == src) return dest;

  if (auto objcSrc = dyn_cast<ObjCUnownedReference>(src)) {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      // ObjC unfortunately doesn't expose a copy-assign operation.
      objc_destroyWeak(&objcDest->storage()->WeakRef);
      objc_copyWeak(&objcDest->storage()->WeakRef,
                    &objcSrc->storage()->WeakRef);
      return dest;
    }

    swift_unownedDestroy(dest);
    ObjCUnownedReference::initializeWithCopy(dest, objcSrc->storage());
  } else {
    if (auto objcDest = dyn_cast<ObjCUnownedReference>(dest)) {
      delete objcDest->storage();
      swift_unownedCopyInit(dest, src);
    } else {
      swift_unownedCopyAssign(dest, src);
    }
  }
  return dest;
}

UnownedReference *swift::swift_unknownUnownedTakeAssign(UnownedReference *dest,
                                                        UnownedReference *src) {
  assert(dest != src);

  // There's not really anything more efficient to do here than this.
  swift_unknownUnownedDestroy(dest);
  dest->Value = src->Value;
  return dest;
}

bool swift::swift_unknownUnownedIsEqual(UnownedReference *ref, void *value) {
  if (!ref->Value) {
    return value == nullptr;
  } else if (auto objcRef = dyn_cast<ObjCUnownedReference>(ref)) {
    id refValue = objc_loadWeakRetained(&objcRef->storage()->WeakRef);
    bool isEqual = (void*)refValue == value;
    // This ObjC case has no deliberate unowned check here,
    // unlike the Swift case.
    [refValue release];
    return isEqual;
  } else {
    return swift_unownedIsEqual(ref, (HeapObject *)value);
  }
}

/*****************************************************************************/
/************************** UNKNOWN WEAK REFERENCES **************************/
/*****************************************************************************/

WeakReference *swift::swift_unknownWeakInit(WeakReference *ref, void *value) {
  ref->unknownInit(value);
  return ref;
}

WeakReference *swift::swift_unknownWeakAssign(WeakReference *ref, void *value) {
  ref->unknownAssign(value);
  return ref;
}

void *swift::swift_unknownWeakLoadStrong(WeakReference *ref) {
  return ref->unknownLoadStrong();
}

void *swift::swift_unknownWeakTakeStrong(WeakReference *ref) {
  return ref->unknownTakeStrong();
}

void swift::swift_unknownWeakDestroy(WeakReference *ref) {
  ref->unknownDestroy();
}

WeakReference *swift::swift_unknownWeakCopyInit(WeakReference *dest,
                                                WeakReference *src) {
  dest->unknownCopyInit(src);
  return dest;
}
WeakReference *swift::swift_unknownWeakTakeInit(WeakReference *dest,
                                                WeakReference *src) {
  dest->unknownTakeInit(src);
  return dest;
}
WeakReference *swift::swift_unknownWeakCopyAssign(WeakReference *dest,
                                                  WeakReference *src) {
  dest->unknownCopyAssign(src);
  return dest;
}
WeakReference *swift::swift_unknownWeakTakeAssign(WeakReference *dest,
                                                  WeakReference *src) {
  dest->unknownTakeAssign(src);
  return dest;
}

// SWIFT_OBJC_INTEROP
#endif

/*****************************************************************************/
/******************************* DYNAMIC CASTS *******************************/
/*****************************************************************************/

#if SWIFT_OBJC_INTEROP
const void *
swift::swift_dynamicCastObjCClass(const void *object,
                                  const ClassMetadata *targetType) {
  // FIXME: We need to decide if this is really how we want to treat 'nil'.
  if (object == nullptr)
    return nullptr;

  if ([id_const_cast(object) isKindOfClass:class_const_cast(targetType)]) {
    return object;
  }

  return nullptr;
}

const void *
swift::swift_dynamicCastObjCClassUnconditional(const void *object,
                                             const ClassMetadata *targetType) {
  // FIXME: We need to decide if this is really how we want to treat 'nil'.
  if (object == nullptr)
    return nullptr;

  if ([id_const_cast(object) isKindOfClass:class_const_cast(targetType)]) {
    return object;
  }

  Class sourceType = object_getClass(id_const_cast(object));
  swift_dynamicCastFailure(reinterpret_cast<const Metadata *>(sourceType),
                           targetType);
}

const void *
swift::swift_dynamicCastForeignClass(const void *object,
                                     const ForeignClassMetadata *targetType) {
  // FIXME: Actually compare CFTypeIDs, once they are available in the metadata.
  return object;
}

const void *
swift::swift_dynamicCastForeignClassUnconditional(
         const void *object,
         const ForeignClassMetadata *targetType) {
  // FIXME: Actual compare CFTypeIDs, once they are available in the metadata.
  return object;
}

bool swift::objectConformsToObjCProtocol(const void *theObject,
                                         const ProtocolDescriptor *protocol) {
  return [id_const_cast(theObject)
          conformsToProtocol: protocol_const_cast(protocol)];
}


bool swift::classConformsToObjCProtocol(const void *theClass,
                                        const ProtocolDescriptor *protocol) {
  return [class_const_cast(theClass)
          conformsToProtocol: protocol_const_cast(protocol)];
}

SWIFT_RUNTIME_EXPORT
const Metadata *swift_dynamicCastTypeToObjCProtocolUnconditional(
                                                 const Metadata *type,
                                                 size_t numProtocols,
                                                 Protocol * const *protocols) {
  Class classObject;

  switch (type->getKind()) {
  case MetadataKind::Class:
  case MetadataKind::ObjCClassWrapper:
    // Native class metadata is also the class object.
    // ObjC class wrappers get unwrapped.
    classObject = type->getObjCClassObject();
    break;

  // Other kinds of type can never conform to ObjC protocols.
  case MetadataKind::Struct:
  case MetadataKind::Enum:
  case MetadataKind::Optional:
  case MetadataKind::Opaque:
  case MetadataKind::Tuple:
  case MetadataKind::Function:
  case MetadataKind::Existential:
  case MetadataKind::Metatype:
  case MetadataKind::ExistentialMetatype:
  case MetadataKind::ForeignClass:
    swift_dynamicCastFailure(type, nameForMetadata(type).c_str(),
                             protocols[0], protocol_getName(protocols[0]));

  case MetadataKind::HeapLocalVariable:
  case MetadataKind::HeapGenericLocalVariable:
  case MetadataKind::ErrorObject:
    assert(false && "not type metadata");
    break;
  }

  for (size_t i = 0; i < numProtocols; ++i) {
    if (![classObject conformsToProtocol:protocols[i]]) {
      swift_dynamicCastFailure(type, nameForMetadata(type).c_str(),
                               protocols[i], protocol_getName(protocols[i]));
    }
  }

  return type;
}

SWIFT_RUNTIME_EXPORT
const Metadata *swift_dynamicCastTypeToObjCProtocolConditional(
                                                const Metadata *type,
                                                size_t numProtocols,
                                                Protocol * const *protocols) {
  Class classObject;

  switch (type->getKind()) {
  case MetadataKind::Class:
  case MetadataKind::ObjCClassWrapper:
    // Native class metadata is also the class object.
    // ObjC class wrappers get unwrapped.
    classObject = type->getObjCClassObject();
    break;

  // Other kinds of type can never conform to ObjC protocols.
  case MetadataKind::Struct:
  case MetadataKind::Enum:
  case MetadataKind::Optional:
  case MetadataKind::Opaque:
  case MetadataKind::Tuple:
  case MetadataKind::Function:
  case MetadataKind::Existential:
  case MetadataKind::Metatype:
  case MetadataKind::ExistentialMetatype:
  case MetadataKind::ForeignClass:
    return nullptr;

  case MetadataKind::HeapLocalVariable:
  case MetadataKind::HeapGenericLocalVariable:
  case MetadataKind::ErrorObject:
    assert(false && "not type metadata");
    break;
  }

  for (size_t i = 0; i < numProtocols; ++i) {
    if (![classObject conformsToProtocol:protocols[i]]) {
      return nullptr;
    }
  }

  return type;
}

SWIFT_RUNTIME_EXPORT
id swift_dynamicCastObjCProtocolUnconditional(id object,
                                              size_t numProtocols,
                                              Protocol * const *protocols) {
  for (size_t i = 0; i < numProtocols; ++i) {
    if (![object conformsToProtocol:protocols[i]]) {
      Class sourceType = object_getClass(object);
      swift_dynamicCastFailure(sourceType, class_getName(sourceType),
                               protocols[i], protocol_getName(protocols[i]));
    }
  }

  return object;
}

SWIFT_RUNTIME_EXPORT
id swift_dynamicCastObjCProtocolConditional(id object,
                                            size_t numProtocols,
                                            Protocol * const *protocols) {
  for (size_t i = 0; i < numProtocols; ++i) {
    if (![object conformsToProtocol:protocols[i]]) {
      return nil;
    }
  }

  return object;
}

void swift::swift_instantiateObjCClass(const ClassMetadata *_c) {
  static const objc_image_info ImageInfo = {0, 0};

  // Ensure the superclass is realized.
  Class c = class_const_cast(_c);
  [class_getSuperclass(c) class];

  // Register the class.
  Class registered = objc_readClassPair(c, &ImageInfo);
  assert(registered == c
         && "objc_readClassPair failed to instantiate the class in-place");
  (void)registered;
}

Class swift::swift_getInitializedObjCClass(Class c) {
  // Used when we have class metadata and we want to ensure a class has been
  // initialized by the Objective-C runtime. We need to do this because the
  // class "c" might be valid metadata, but it hasn't been initialized yet.
  return [c class];
}

const ClassMetadata *
swift::swift_dynamicCastObjCClassMetatype(const ClassMetadata *source,
                                          const ClassMetadata *dest) {
  if ([class_const_cast(source) isSubclassOfClass:class_const_cast(dest)])
    return source;
  return nil;
}

const ClassMetadata *
swift::swift_dynamicCastObjCClassMetatypeUnconditional(
                                                   const ClassMetadata *source,
                                                   const ClassMetadata *dest) {
  if ([class_const_cast(source) isSubclassOfClass:class_const_cast(dest)])
    return source;

  swift_dynamicCastFailure(source, dest);
}
#endif

const ClassMetadata *
swift::swift_dynamicCastForeignClassMetatype(const ClassMetadata *sourceType,
                                             const ClassMetadata *targetType) {
  // FIXME: Actually compare CFTypeIDs, once they are available in
  // the metadata.
  return sourceType;
}

const ClassMetadata *
swift::swift_dynamicCastForeignClassMetatypeUnconditional(
  const ClassMetadata *sourceType,
  const ClassMetadata *targetType)
{
  // FIXME: Actually compare CFTypeIDs, once they arae available in
  // the metadata.
  return sourceType;
}

#if SWIFT_OBJC_INTEROP
// Given a non-nil object reference, return true iff the object uses
// native swift reference counting.
static bool usesNativeSwiftReferenceCounting_nonNull(
  const void* object
) {
  assert(object != nullptr);
  return !isObjCTaggedPointer(object) &&
    objectUsesNativeSwiftReferenceCounting(object);
}
#endif

bool swift::swift_isUniquelyReferenced_nonNull_native(const HeapObject *object){
  assert(object != nullptr);
  assert(!object->refCounts.isDeiniting());
  return object->refCounts.isUniquelyReferenced();
}

bool swift::swift_isUniquelyReferenced_native(const HeapObject* object) {
  return object != nullptr
    && swift::swift_isUniquelyReferenced_nonNull_native(object);
}

bool swift::swift_isUniquelyReferencedNonObjC_nonNull(const void* object) {
  assert(object != nullptr);
  return
#if SWIFT_OBJC_INTEROP
    usesNativeSwiftReferenceCounting_nonNull(object) &&
#endif
    swift_isUniquelyReferenced_nonNull_native((const HeapObject*)object);
}

// Given an object reference, return true iff it is non-nil and refers
// to a native swift object with strong reference count of 1.
bool swift::swift_isUniquelyReferencedNonObjC(
  const void* object
) {
  return object != nullptr
    && swift_isUniquelyReferencedNonObjC_nonNull(object);
}

/// Return true if the given bits of a Builtin.BridgeObject refer to a
/// native swift object whose strong reference count is 1.
bool swift::swift_isUniquelyReferencedNonObjC_nonNull_bridgeObject(
  uintptr_t bits
) {
  auto bridgeObject = (void*)bits;

  if (isObjCTaggedPointer(bridgeObject))
    return false;

  const auto object = toPlainObject_unTagged_bridgeObject(bridgeObject);

  // Note: we could just return false if all spare bits are set,
  // but in that case the cost of a deeper check for a unique native
  // object is going to be a negligible cost for a possible big win.
#if SWIFT_OBJC_INTEROP
  return !isNonNative_unTagged_bridgeObject(bridgeObject)
             ? swift_isUniquelyReferenced_nonNull_native(
                   (const HeapObject *)object)
             : swift_isUniquelyReferencedNonObjC_nonNull(object);
#else
  return swift_isUniquelyReferenced_nonNull_native((const HeapObject *)object);
#endif
}

/// Return true if the given bits of a Builtin.BridgeObject refer to a
/// native swift object whose strong reference count is 1.
bool swift::swift_isUniquelyReferencedOrPinnedNonObjC_nonNull_bridgeObject(
  uintptr_t bits
) {
  auto bridgeObject = (void*)bits;

  if (isObjCTaggedPointer(bridgeObject))
    return false;

  const auto object = toPlainObject_unTagged_bridgeObject(bridgeObject);

  // Note: we could just return false if all spare bits are set,
  // but in that case the cost of a deeper check for a unique native
  // object is going to be a negligible cost for a possible big win.
#if SWIFT_OBJC_INTEROP
  if (isNonNative_unTagged_bridgeObject(bridgeObject))
    return swift_isUniquelyReferencedOrPinnedNonObjC_nonNull(object);
#endif
  return swift_isUniquelyReferencedOrPinned_nonNull_native(
                                                   (const HeapObject *)object);
}


/// Given a non-nil object reference, return true if the object is a
/// native swift object and either its strong reference count is 1 or
/// its pinned flag is set.
bool swift::swift_isUniquelyReferencedOrPinnedNonObjC_nonNull(
                                                          const void *object) {
  assert(object != nullptr);
  return
#if SWIFT_OBJC_INTEROP
    usesNativeSwiftReferenceCounting_nonNull(object) &&
#endif
    swift_isUniquelyReferencedOrPinned_nonNull_native(
                                                    (const HeapObject*)object);
}

// Given a non-@objc object reference, return true iff the
// object is non-nil and either has a strong reference count of 1
// or is pinned.
bool swift::swift_isUniquelyReferencedOrPinned_native(const HeapObject *object){
  return object != nullptr &&
         swift_isUniquelyReferencedOrPinned_nonNull_native(object);
}

// Given a non-@objc object reference, return true iff the
// object is non-nil and has a strong reference count greather than 1
bool swift::swift_isEscapingClosureAtFileLocation(const HeapObject *object,
                                                  const unsigned char *filename,
                                                  int32_t filenameLength,
                                                  int32_t line) {
  bool isEscaping =
      object != nullptr && !object->refCounts.isUniquelyReferenced();

  // Print a message if the closure escaped.
  if (isEscaping) {
    auto *message = "Fatal error: closure argument was escaped in "
                              "withoutActuallyEscaping block";
    auto messageLength = strlen(message);

    if (_swift_shouldReportFatalErrorsToDebugger())
      _swift_reportToDebugger(RuntimeErrorFlagFatal, message);

    char *log;
    swift_asprintf(&log, "%.*s: file %.*s, line %" PRIu32 "\n", messageLength,
                   message, filenameLength, filename, line);

    swift_reportError(RuntimeErrorFlagFatal, log);
    free(log);
  }
  return isEscaping;
}

/// Given a non-nil native swift object reference, return true if
/// either the object has a strong reference count of 1 or its
/// pinned flag is set.
bool swift::swift_isUniquelyReferencedOrPinned_nonNull_native(
    const HeapObject *object) {
  assert(object != nullptr);
  assert(!object->refCounts.isDeiniting());
  return object->refCounts.isUniquelyReferencedOrPinned();
}

struct ClassExtents {
  size_t negative;
  size_t positive; 
};

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
ClassExtents
_getSwiftClassInstanceExtents(const Metadata *c) {
  assert(c && c->isClassObject());
  auto metaData = c->getClassObject();
  return ClassExtents{
    metaData->getInstanceAddressPoint(),
    metaData->getInstanceSize() - metaData->getInstanceAddressPoint()
  };
}

#if SWIFT_OBJC_INTEROP

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
ClassExtents
_getObjCClassInstanceExtents(const ClassMetadata* c) {
  // Pure ObjC classes never have negative extents.
  if (c->isPureObjC())
    return ClassExtents{0, class_getInstanceSize(class_const_cast(c))};

  return _getSwiftClassInstanceExtents(c);
}

SWIFT_CC(swift)
SWIFT_RUNTIME_EXPORT
void swift_objc_swift3ImplicitObjCEntrypoint(id self, SEL selector,
                                             const char *filename,
                                             size_t filenameLength,
                                             size_t line, size_t column,
                                             std::atomic<bool> *didLog) {
  // Only log once. We should have been given a unique zero-initialized
  // atomic flag for each entry point.
  if (didLog->exchange(true))
    return;
  
  // Figure out how much reporting we want by querying the environment
  // variable SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT. We have four meaningful
  // levels:
  //
  //   0: Don't report anything
  //   1: Complain about uses of implicit @objc entrypoints.
  //   2: Complain about uses of implicit @objc entrypoints, with backtraces
  //      if possible.
  //   3: Complain about uses of implicit @objc entrypoints, then abort().
  //
  // The actual reportLevel is stored as the above values +1, so that
  // 0 indicates we have not yet checked. It's fine to race through here.
  //
  // The default, if SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT is not set, is 2.
  static int storedReportLevel = 0;
  if (storedReportLevel == 0) {
    auto reportLevelStr = getenv("SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT");
    if (reportLevelStr &&
        reportLevelStr[0] >= '0' && reportLevelStr[0] <= '3' &&
        reportLevelStr[1] == 0)
      storedReportLevel = (reportLevelStr[0] - '0') + 1;
    else
      storedReportLevel = 3;
  }

  int reportLevel = storedReportLevel - 1;
  if (reportLevel < 1) return;

  // Report the error.
  uint32_t flags = 0;
  if (reportLevel >= 2)
    flags |= 1 << 0; // Backtrace
  bool isInstanceMethod = !class_isMetaClass(object_getClass(self));
  void (*reporter)(uint32_t, const char *, ...) =
    reportLevel > 2 ? swift::fatalError : swift::warning;
  
  if (filenameLength > INT_MAX)
    filenameLength = INT_MAX;

  char *message, *nullTerminatedFilename;
  asprintf(&message,
           "implicit Objective-C entrypoint %c[%s %s] is deprecated and will "
           "be removed in Swift 4",
           isInstanceMethod ? '-' : '+',
           class_getName([self class]),
           sel_getName(selector));
  asprintf(&nullTerminatedFilename, "%*s", (int)filenameLength, filename);

  RuntimeErrorDetails::FixIt fixit = {
    .filename = nullTerminatedFilename,
    .startLine = line,
    .endLine = line,
    .startColumn = column,
    .endColumn = column,
    .replacementText = "@objc "
  };
  RuntimeErrorDetails::Note note = {
    .description = "add '@objc' to expose this Swift declaration to Objective-C",
    .numFixIts = 1,
    .fixIts = &fixit
  };
  RuntimeErrorDetails details = {
    .version = RuntimeErrorDetails::currentVersion,
    .errorType = "implicit-objc-entrypoint",
    .framesToSkip = 1,
    .numNotes = 1,
    .notes = &note
  };
  uintptr_t runtime_error_flags = RuntimeErrorFlagNone;
  if (reporter == swift::fatalError)
    runtime_error_flags = RuntimeErrorFlagFatal;
  _swift_reportToDebugger(runtime_error_flags, message, &details);

  reporter(flags,
           "*** %s:%zu:%zu: %s; add explicit '@objc' to the declaration to "
           "emit the Objective-C entrypoint in Swift 4 and suppress this "
           "message\n",
           nullTerminatedFilename, line, column, message);
  free(message);
  free(nullTerminatedFilename);
}

#endif

const ClassMetadata *swift::getRootSuperclass() {
#if SWIFT_OBJC_INTEROP
  static Lazy<const ClassMetadata *> SwiftObjectClass;

  return SwiftObjectClass.get([](void *ptr) {
    *((const ClassMetadata **) ptr) =
        (const ClassMetadata *)[SwiftObject class];
  });
#else
  return nullptr;
#endif
}
