swiftMetadataInitializer.m 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // TEST_CONFIG MEM=mrc
  2. #include "test.h"
  3. #include "swift-class-def.m"
  4. SWIFT_CLASS(SwiftSuper, NSObject, initSuper);
  5. SWIFT_CLASS(SwiftSub, SwiftSuper, initSub);
  6. // _objc_swiftMetadataInitializer hooks for the fake Swift classes
  7. Class initSuper(Class cls __unused, void *arg __unused)
  8. {
  9. // This test provokes objc's callback out of superclass order.
  10. // SwiftSub's init is first. SwiftSuper's init is never called.
  11. fail("SwiftSuper's init should not have been called");
  12. }
  13. bool isRealized(Class cls)
  14. {
  15. // check the is-realized bits directly
  16. #if __LP64__
  17. # define mask (~(uintptr_t)7)
  18. #else
  19. # define mask (~(uintptr_t)3)
  20. #endif
  21. #define RW_REALIZED (1<<31)
  22. uintptr_t rw = ((uintptr_t *)cls)[4] & mask; // class_t->data
  23. return ((uint32_t *)rw)[0] & RW_REALIZED; // class_rw_t->flags
  24. }
  25. static int SubInits = 0;
  26. Class initSub(Class cls, void *arg)
  27. {
  28. testprintf("initSub callback\n");
  29. testassert(SubInits == 0);
  30. SubInits++;
  31. testassert(arg == nil);
  32. testassert(0 == strcmp(class_getName(cls), "SwiftSub"));
  33. testassert(cls == RawSwiftSub);
  34. testassert(!isRealized(RawSwiftSuper));
  35. testassert(!isRealized(RawSwiftSub));
  36. testprintf("initSub beginning _objc_realizeClassFromSwift\n");
  37. _objc_realizeClassFromSwift(cls, cls);
  38. testprintf("initSub finished _objc_realizeClassFromSwift\n");
  39. testassert(isRealized(RawSwiftSuper));
  40. testassert(isRealized(RawSwiftSub));
  41. return cls;
  42. }
  43. int main()
  44. {
  45. testassert(SubInits == 0);
  46. testprintf("calling [SwiftSub class]\n");
  47. [SwiftSub class];
  48. testprintf("finished [SwiftSub class]\n");
  49. testassert(SubInits == 1);
  50. [SwiftSuper class];
  51. succeed(__FILE__);
  52. }