]> git.saurik.com Git - apple/objc4.git/blobdiff - test/swiftMetadataInitializer.m
objc4-756.2.tar.gz
[apple/objc4.git] / test / swiftMetadataInitializer.m
diff --git a/test/swiftMetadataInitializer.m b/test/swiftMetadataInitializer.m
new file mode 100644 (file)
index 0000000..bfa54a8
--- /dev/null
@@ -0,0 +1,70 @@
+// TEST_CONFIG MEM=mrc
+
+#include "test.h"
+#include "swift-class-def.m"
+
+
+// _objc_swiftMetadataInitializer hooks for the classes in swift-class-def.m
+
+Class initSuper(Class cls __unused, void *arg __unused)
+{
+    // This test provokes objc's callback out of superclass order.
+    // SwiftSub's init is first. SwiftSuper's init is never called.
+
+    fail("SwiftSuper's init should not have been called");
+}
+
+bool isRealized(Class cls)
+{
+    // check the is-realized bits directly
+
+#if __LP64__
+# define mask (~(uintptr_t)7)
+#else
+# define mask (~(uintptr_t)3)
+#endif
+#define RW_REALIZED (1<<31)
+    
+    uintptr_t rw = ((uintptr_t *)cls)[4] & mask;  // class_t->data
+    return ((uint32_t *)rw)[0] & RW_REALIZED;  // class_rw_t->flags
+}
+
+static int SubInits = 0;
+Class initSub(Class cls, void *arg)
+{
+    testprintf("initSub callback\n");
+    
+    extern uintptr_t OBJC_CLASS_$_SwiftSuper;
+    extern uintptr_t OBJC_CLASS_$_SwiftSub;
+    Class RawSwiftSuper = (Class)&OBJC_CLASS_$_SwiftSuper;
+    Class RawSwiftSub = (Class)&OBJC_CLASS_$_SwiftSub;
+
+    testassert(SubInits == 0);
+    SubInits++;
+    testassert(arg == nil);
+    testassert(0 == strcmp(class_getName(cls), "SwiftSub"));
+    testassert(cls == RawSwiftSub);
+    testassert(!isRealized(RawSwiftSuper));
+    testassert(!isRealized(RawSwiftSub));
+
+    testprintf("initSub beginning _objc_realizeClassFromSwift\n");
+    _objc_realizeClassFromSwift(cls, cls);
+    testprintf("initSub finished  _objc_realizeClassFromSwift\n");
+
+    testassert(isRealized(RawSwiftSuper));
+    testassert(isRealized(RawSwiftSub));
+    
+    return cls;
+}
+
+
+int main()
+{
+    testassert(SubInits == 0);
+    testprintf("calling [SwiftSub class]\n");
+    [SwiftSub class];
+    testprintf("finished [SwiftSub class]\n");
+    testassert(SubInits == 1);
+    [SwiftSuper class];
+    succeed(__FILE__);
+}