taggedPointersAllClasses.m 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include "testroot.i"
  4. #include <objc/runtime.h>
  5. #include <objc/objc-internal.h>
  6. #if OBJC_HAVE_TAGGED_POINTERS
  7. @interface TagSuperclass: TestRoot
  8. - (void)test;
  9. @end
  10. @implementation TagSuperclass
  11. - (void)test {}
  12. @end
  13. int main()
  14. {
  15. Class classes[OBJC_TAG_Last52BitPayload + 1] = {};
  16. __block uintptr_t expectedPayload;
  17. __block uintptr_t sawPayload;
  18. __block int sawTag;
  19. for (int i = 0; i <= OBJC_TAG_Last52BitPayload; i++) {
  20. objc_tag_index_t tag = (objc_tag_index_t)i;
  21. if (i > OBJC_TAG_Last60BitPayload && i < OBJC_TAG_First52BitPayload)
  22. continue;
  23. if (_objc_getClassForTag(tag) != nil)
  24. continue;
  25. char *name;
  26. asprintf(&name, "Tag%d", i);
  27. classes[i] = objc_allocateClassPair([TagSuperclass class], name, 0);
  28. free(name);
  29. IMP testIMP = imp_implementationWithBlock(^(void *self) {
  30. testassert(i == _objc_getTaggedPointerTag(self));
  31. testassert(expectedPayload == _objc_getTaggedPointerValue(self));
  32. sawPayload = _objc_getTaggedPointerValue(self);
  33. sawTag = i;
  34. });
  35. class_addMethod(classes[i], @selector(test), testIMP, "v@@");
  36. objc_registerClassPair(classes[i]);
  37. _objc_registerTaggedPointerClass(tag, classes[i]);
  38. }
  39. for (int i = 0; i <= OBJC_TAG_Last52BitPayload; i++) {
  40. objc_tag_index_t tag = (objc_tag_index_t)i;
  41. if (classes[i] == nil)
  42. continue;
  43. for (int byte = 0; byte <= 0xff; byte++) {
  44. uintptr_t payload;
  45. memset(&payload, byte, sizeof(payload));
  46. if (i <= OBJC_TAG_Last60BitPayload)
  47. payload >>= _OBJC_TAG_PAYLOAD_RSHIFT;
  48. else
  49. payload >>= _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
  50. expectedPayload = payload;
  51. id obj = (__bridge id)_objc_makeTaggedPointer(tag, payload);
  52. [obj test];
  53. testassert(sawPayload == payload);
  54. testassert(sawTag == i);
  55. }
  56. }
  57. succeed(__FILE__);
  58. }
  59. #else
  60. int main()
  61. {
  62. succeed(__FILE__);
  63. }
  64. #endif