swiftMetadataInitializer.m [plain text]
// 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__);
}