//===--- SwiftNativeNSXXXBase.mm.gyb - Cocoa classes with fast refcounts --===// // // 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 // //===----------------------------------------------------------------------===// // // Classes derived from ObjC bases but that use native swift reference // counting, layout, and allocation. // // These classes declare a native Swift object header and override the // NSObject methods that do reference counting to use it accordingly. // We can only do this trick with objc classes that are known not to // use the storage where Swift places its native object header. This // takes care of how the classes are handled from Objective-C code. // _NSSwiftArrayBase, _NSSwiftDictionaryBase, _NSSwiftSetBase // _NSSwiftSetBase, _NSSwiftStringBase // // To trick Swift into using its fast refcounting and allocation // directly (rather than going through objc_msgSend to arrive at the // implementations defined here), we define subclasses on the Swift // side but hide the inheritance relationship from the Swift compiler // and only establish it dynamically, in the '+ load' method of each // class defined here. // //===----------------------------------------------------------------------===// #import #import #include #include #if __has_include() #include #endif #include "swift/Runtime/HeapObject.h" #include "swift/Runtime/Metadata.h" #include "swift/Runtime/ObjCBridge.h" #include "llvm/ADT/DenseMap.h" #include "Private.h" #include #include #include // Redeclare these just we check them. extern "C" id _objc_rootAutorelease(id); using namespace swift; % for Class in ('Array', 'Dictionary', 'Set', 'String', 'Enumerator'): @interface _SwiftNativeNS${Class}Base : NS${Class} { // TODO: Workaround for rdar://problem/18950072 // SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS; uint32_t __magic_refCount; uint32_t __magic_weakRefCount; } @end @implementation _SwiftNativeNS${Class}Base + (void)load { // Poke this class into the superclass chain for _SwiftNativeNS${Class} auto subclassName = "_SwiftNativeNS${Class}"; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" // Compute the mangled name of the subclass char subclassMangledName[64]; snprintf( subclassMangledName, sizeof(subclassMangledName), "_TtCSs%d%s", (int)strlen(subclassName), subclassName); auto subclass = objc_getClass(subclassMangledName); auto selfClass = [_SwiftNativeNS${Class}Base class]; class_setSuperclass(subclass, selfClass); #pragma clang diagnostic pop } - (id)retain { auto SELF = reinterpret_cast(self); swift_retain(SELF); return self; } - (oneway void)release { auto SELF = reinterpret_cast(self); swift_release(SELF); } - (id)autorelease { return _objc_rootAutorelease(self); } - (BOOL)_tryRetain { auto SELF = reinterpret_cast(self); return (bool)swift_tryRetain(SELF); } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" - (void)dealloc { _swift_deallocClassInstance(reinterpret_cast(self)); } #pragma clang diagnostic pop @end % end extern "C" bool swift_stdlib_NSObject_isEqual(NSObject *NS_RELEASES_ARGUMENT lhs, NSObject *NS_RELEASES_ARGUMENT rhs) { bool Result = (lhs == rhs) || [lhs isEqual:rhs]; swift_unknownRelease(lhs); swift_unknownRelease(rhs); return Result; } extern "C" int32_t swift_stdlib_compareNSStringDeterministicUnicodeCollation( NSString *NS_RELEASES_ARGUMENT lhs, NSString *NS_RELEASES_ARGUMENT rhs) { // 'kCFCompareNonliteral' actually means "normalize to NFD". int Result = CFStringCompare((__bridge CFStringRef)lhs, (__bridge CFStringRef)rhs, kCFCompareNonliteral); swift_unknownRelease(lhs); swift_unknownRelease(rhs); return Result; } extern "C" size_t swift_stdlib_NSStringNFDHashValue(NSString *NS_RELEASES_ARGUMENT str) { int Result = str.decomposedStringWithCanonicalMapping.hash; swift_unknownRelease(str); return Result; } // For strings we know only have ASCII extern "C" size_t swift_stdlib_NSStringASCIIHashValue(NSString *NS_RELEASES_ARGUMENT str) { int Result = str.hash; swift_unknownRelease(str); return Result; } extern "C" bool swift_stdlib_NSStringHasPrefixNFD(NSString *theString, NSString *prefix) { auto Length = CFStringGetLength((__bridge CFStringRef)theString); int Result = CFStringFindWithOptions( (__bridge CFStringRef)theString, (__bridge CFStringRef)prefix, CFRangeMake(0, Length), kCFCompareAnchored | kCFCompareNonliteral, nullptr); swift_unknownRelease(theString); swift_unknownRelease(prefix); return Result; } extern "C" bool swift_stdlib_NSStringHasSuffixNFD(NSString *NS_RELEASES_ARGUMENT theString, NSString *NS_RELEASES_ARGUMENT suffix) { auto Length = CFStringGetLength((__bridge CFStringRef)theString); int Result = CFStringFindWithOptions( (__bridge CFStringRef)theString, (__bridge CFStringRef)suffix, CFRangeMake(0, Length), kCFCompareAnchored | kCFCompareBackwards | kCFCompareNonliteral, nullptr); swift_unknownRelease(theString); swift_unknownRelease(suffix); return Result; } extern "C" NSString * swift_stdlib_NSStringLowercaseString(NSString *NS_RELEASES_ARGUMENT str) { NSString *Result = str.lowercaseString; swift_unknownRelease(str); return Result; } extern "C" NSString * swift_stdlib_NSStringUppercaseString(NSString *NS_RELEASES_ARGUMENT str) { NSString *Result = str.uppercaseString; swift_unknownRelease(str); return Result; } extern "C" NSString * swift_stdlib_CFStringCreateCopy(NSString *NS_RELEASES_ARGUMENT str) { NSString *Result = (__bridge NSString *)CFStringCreateCopy(nil, (__bridge CFStringRef)str); swift_unknownRelease(str); return Result; } extern "C" size_t swift_stdlib_CFStringGetLength(NSString *NS_RELEASES_ARGUMENT str) { size_t Result = CFStringGetLength((__bridge CFStringRef)str); swift_unknownRelease(str); return Result; } extern "C" const uint16_t * swift_stdlib_CFStringGetCharactersPtr(NSString *NS_RELEASES_ARGUMENT str) { const uint16_t *Result = CFStringGetCharactersPtr((__bridge CFStringRef)str); swift_unknownRelease(str); return Result; } extern "C" void swift_stdlib_CFSetGetValues(NSSet *NS_RELEASES_ARGUMENT set, const void **values) { CFSetGetValues((__bridge CFSetRef)set, values); swift_unknownRelease(set); } // ${'Local Variables'}: // eval: (read-only-mode 1) // End: