Skip to content

Instantly share code, notes, and snippets.

@vikage
Created April 17, 2019 06:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vikage/b005af1cfda86e7eaa3b090ec2c08c16 to your computer and use it in GitHub Desktop.
Save vikage/b005af1cfda86e7eaa3b090ec2c08c16 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main() {
// extra_rc must be the MSB-most field (so it matches carry/overflow flags)
// indexed must be the LSB (fixme or get rid of it)
// shiftcls must occupy the same bits that a real class pointer would
// bits + RC_ONE is equivalent to extra_rc + 1
// RC_HALF is the high bit of extra_rc (i.e. half of its range)
// future expansion:
// uintptr_t fast_rr : 1; // no r/r overrides
// uintptr_t lock : 2; // lock for atomic property, @synch
// uintptr_t extraBytes : 1; // allocated with extra bytes
# if __arm64__
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
struct isa_t {
uintptr_t indexed : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 19;
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
};
NSLog(@"arm64");
static void *someKey = &someKey;
id object = [NSObject new];
struct isa_t *isa = (__bridge struct isa_t *)object;
NSLog(@"%d", isa->has_assoc);
objc_setAssociatedObject(object, someKey, @"Hello World!", OBJC_ASSOCIATION_RETAIN);
NSLog(@"%d", isa->has_assoc);
NSLog(@"%p", *(void * *)(__bridge void *)object);
# elif __x86_64__
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
struct isa_t {
uintptr_t indexed : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8;
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
};
NSLog(@"x86_64");
static void *someKey = &someKey;
id object = [NSObject new];
struct isa_t *isa = (__bridge struct isa_t *)object;
NSLog(@"%d", isa->has_assoc);
objc_setAssociatedObject(object, someKey, @"Hello World!", OBJC_ASSOCIATION_RETAIN);
NSLog(@"%d", isa->has_assoc);
NSLog(@"%p", *(void * *)(__bridge void *)object);
# else
// Available bits in isa field are architecture-specific.
# error unknown architecture
# endif
return 0;
}
@vikage
Copy link
Author

vikage commented Apr 17, 2019

shiftcls must shift left 3 bit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment