5 #include <objc/runtime.h>
6 #include <objc/objc-internal.h>
8 #if OBJC_HAVE_TAGGED_POINTERS
10 @interface TagSuperclass: TestRoot
16 @implementation TagSuperclass
24 Class classes[OBJC_TAG_Last52BitPayload + 1] = {};
26 __block uintptr_t expectedPayload;
27 __block uintptr_t sawPayload;
30 for (int i = 0; i <= OBJC_TAG_Last52BitPayload; i++) {
31 objc_tag_index_t tag = (objc_tag_index_t)i;
32 if (i > OBJC_TAG_Last60BitPayload && i < OBJC_TAG_First52BitPayload)
34 if (_objc_getClassForTag(tag) != nil)
38 asprintf(&name, "Tag%d", i);
39 classes[i] = objc_allocateClassPair([TagSuperclass class], name, 0);
42 IMP testIMP = imp_implementationWithBlock(^(void *self) {
43 testassert(i == _objc_getTaggedPointerTag(self));
44 testassert(expectedPayload == _objc_getTaggedPointerValue(self));
45 sawPayload = _objc_getTaggedPointerValue(self);
48 class_addMethod(classes[i], @selector(test), testIMP, "v@@");
50 objc_registerClassPair(classes[i]);
51 _objc_registerTaggedPointerClass(tag, classes[i]);
54 for (int i = 0; i <= OBJC_TAG_Last52BitPayload; i++) {
55 objc_tag_index_t tag = (objc_tag_index_t)i;
56 if (classes[i] == nil)
59 for (int byte = 0; byte <= 0xff; byte++) {
61 memset(&payload, byte, sizeof(payload));
63 if (i <= OBJC_TAG_Last60BitPayload)
64 payload >>= _OBJC_TAG_PAYLOAD_RSHIFT;
66 payload >>= _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
68 expectedPayload = payload;
69 id obj = (__bridge id)_objc_makeTaggedPointer(tag, payload);
71 testassert(sawPayload == payload);
72 testassert(sawTag == i);