readClassPair.m 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. TEST_RUN_OUTPUT
  3. objc\[\d+\]: Class Sub is implemented in both [^\s]+ \(0x[0-9a-f]+\) and [^\s]+ \(0x[0-9a-f]+\)\. One of the two will be used\. Which one is undefined\.
  4. OK: readClassPair.m
  5. END
  6. */
  7. #include "test.h"
  8. #include <objc/objc-internal.h>
  9. // Reuse evil-class-def.m as a non-evil class definition.
  10. #define EVIL_SUPER 0
  11. #define EVIL_SUPER_META 0
  12. #define EVIL_SUB 0
  13. #define EVIL_SUB_META 0
  14. #define OMIT_SUPER 1
  15. #define OMIT_NL_SUPER 1
  16. #define OMIT_SUB 1
  17. #define OMIT_NL_SUB 1
  18. #include "evil-class-def.m"
  19. int main()
  20. {
  21. // This definition is ABI and is never allowed to change.
  22. testassert(OBJC_MAX_CLASS_SIZE == 32*sizeof(void*));
  23. struct objc_image_info ii = { 0, 0 };
  24. // Read a root class.
  25. testassert(!objc_getClass("Super"));
  26. extern intptr_t OBJC_CLASS_$_Super[OBJC_MAX_CLASS_SIZE/sizeof(void*)];
  27. Class Super = objc_readClassPair((__bridge Class)(void*)&OBJC_CLASS_$_Super, &ii);
  28. testassert(Super);
  29. testassert(objc_getClass("Super") == Super);
  30. testassert(0 == strcmp(class_getName(Super), "Super"));
  31. testassert(class_getSuperclass(Super) == nil);
  32. testassert(class_getClassMethod(Super, @selector(load)));
  33. testassert(class_getInstanceMethod(Super, @selector(load)));
  34. testassert(class_getInstanceVariable(Super, "super_ivar"));
  35. testassert(class_getInstanceSize(Super) == sizeof(void*));
  36. [Super load];
  37. // Read a non-root class.
  38. testassert(!objc_getClass("Sub"));
  39. extern intptr_t OBJC_CLASS_$_Sub[OBJC_MAX_CLASS_SIZE/sizeof(void*)];
  40. // Make a duplicate of class Sub for use later.
  41. intptr_t Sub2_buf[OBJC_MAX_CLASS_SIZE/sizeof(void*)];
  42. memcpy(Sub2_buf, &OBJC_CLASS_$_Sub, sizeof(Sub2_buf));
  43. Class Sub = objc_readClassPair((__bridge Class)(void*)&OBJC_CLASS_$_Sub, &ii);
  44. testassert(Sub);
  45. testassert(0 == strcmp(class_getName(Sub), "Sub"));
  46. testassert(objc_getClass("Sub") == Sub);
  47. testassert(class_getSuperclass(Sub) == Super);
  48. testassert(class_getClassMethod(Sub, @selector(load)));
  49. testassert(class_getInstanceMethod(Sub, @selector(load)));
  50. testassert(class_getInstanceVariable(Sub, "sub_ivar"));
  51. testassert(class_getInstanceSize(Sub) == 2*sizeof(void*));
  52. [Sub load];
  53. // Reading a class whose name already exists succeeds
  54. // with a duplicate warning.
  55. Class Sub2 = objc_readClassPair((__bridge Class)(void*)Sub2_buf, &ii);
  56. testassert(Sub2);
  57. testassert(Sub2 != Sub);
  58. testassert(objc_getClass("Sub") == Sub); // didn't change
  59. testassert(0 == strcmp(class_getName(Sub2), "Sub"));
  60. testassert(class_getSuperclass(Sub2) == Super);
  61. testassert(class_getClassMethod(Sub2, @selector(load)));
  62. testassert(class_getInstanceMethod(Sub2, @selector(load)));
  63. testassert(class_getInstanceVariable(Sub2, "sub_ivar"));
  64. testassert(class_getInstanceSize(Sub2) == 2*sizeof(void*));
  65. [Sub2 load];
  66. succeed(__FILE__);
  67. }