KSObjCApple.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. //
  2. // KSObjCApple.h
  3. //
  4. // Created by Karl Stenerud on 2012-08-30.
  5. //
  6. // Copyright (c) 2011 Apple Inc. All rights reserved.
  7. //
  8. // This file contains Original Code and/or Modifications of Original Code
  9. // as defined in and that are subject to the Apple Public Source License
  10. // Version 2.0 (the 'License'). You may not use this file except in
  11. // compliance with the License. Please obtain a copy of the License at
  12. // http://www.opensource.apple.com/apsl/ and read it before using this
  13. // file.
  14. //
  15. // This file contains structures and constants copied from Apple header
  16. // files, arranged for use in KSObjC.
  17. #ifndef HDR_KSObjCApple_h
  18. #define HDR_KSObjCApple_h
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. #include <objc/objc.h>
  23. #include <CoreFoundation/CoreFoundation.h>
  24. #define MAKE_LIST_T(TYPE) \
  25. typedef struct TYPE##_list_t { \
  26. uint32_t entsizeAndFlags; \
  27. uint32_t count; \
  28. TYPE##_t first; \
  29. } TYPE##_list_t; \
  30. typedef TYPE##_list_t TYPE##_array_t
  31. #define OBJC_OBJECT(NAME) \
  32. NAME { \
  33. Class isa OBJC_ISA_AVAILABILITY;
  34. // ======================================================================
  35. #pragma mark - objc4-680/runtime/objc-msg-x86_64.s -
  36. // and objc4-680/runtime/objc-msg-arm64.s
  37. // ======================================================================
  38. // Use ISA_MASK_OLD before iOS 9, in and after iOS 9, use ISA_MASK
  39. #if __x86_64__
  40. # define ISA_TAG_MASK 1UL
  41. # define ISA_MASK 0x00007ffffffffff8UL
  42. #elif defined(__arm64__)
  43. # define ISA_TAG_MASK 1UL
  44. # define ISA_MASK_OLD 0x00000001fffffff8UL
  45. # define ISA_MASK 0x0000000ffffffff8UL
  46. #else
  47. # define ISA_TAG_MASK 0UL
  48. # define ISA_MASK ~1UL
  49. #endif
  50. // ======================================================================
  51. #pragma mark - objc4-680/runtime/objc-config.h -
  52. // ======================================================================
  53. // Define SUPPORT_TAGGED_POINTERS=1 to enable tagged pointer objects
  54. // Be sure to edit tagged pointer SPI in objc-internal.h as well.
  55. #if !(__LP64__)
  56. # define SUPPORT_TAGGED_POINTERS 0
  57. #else
  58. # define SUPPORT_TAGGED_POINTERS 1
  59. #endif
  60. // Define SUPPORT_MSB_TAGGED_POINTERS to use the MSB
  61. // as the tagged pointer marker instead of the LSB.
  62. // Be sure to edit tagged pointer SPI in objc-internal.h as well.
  63. #if !SUPPORT_TAGGED_POINTERS || !TARGET_OS_IPHONE
  64. # define SUPPORT_MSB_TAGGED_POINTERS 0
  65. #else
  66. # define SUPPORT_MSB_TAGGED_POINTERS 1
  67. #endif
  68. // ======================================================================
  69. #pragma mark - objc4-680/runtime/objc-object.h -
  70. // ======================================================================
  71. #if SUPPORT_TAGGED_POINTERS
  72. // KS: The original values wouldn't have worked. The slot shift and mask
  73. // were incorrect.
  74. #define TAG_COUNT 8
  75. //#define TAG_SLOT_MASK 0xf
  76. #define TAG_SLOT_MASK 0x07
  77. #if SUPPORT_MSB_TAGGED_POINTERS
  78. # define TAG_MASK (1ULL<<63)
  79. # define TAG_SLOT_SHIFT 60
  80. # define TAG_PAYLOAD_LSHIFT 4
  81. # define TAG_PAYLOAD_RSHIFT 4
  82. #else
  83. # define TAG_MASK 1
  84. //# define TAG_SLOT_SHIFT 0
  85. # define TAG_SLOT_SHIFT 1
  86. # define TAG_PAYLOAD_LSHIFT 0
  87. # define TAG_PAYLOAD_RSHIFT 4
  88. #endif
  89. #endif
  90. // ======================================================================
  91. #pragma mark - objc4-781/runtime/objc-internal.h -
  92. // ======================================================================
  93. #if __ARM_ARCH_7K__ >= 2 || (__arm64__ && !__LP64__)
  94. # define SUPPORT_INDEXED_ISA 1
  95. #else
  96. # define SUPPORT_INDEXED_ISA 0
  97. #endif
  98. // ======================================================================
  99. #pragma mark - objc4-680/runtime/objc-internal.h -
  100. // ======================================================================
  101. enum
  102. {
  103. OBJC_TAG_NSAtom = 0,
  104. OBJC_TAG_1 = 1,
  105. OBJC_TAG_NSString = 2,
  106. OBJC_TAG_NSNumber = 3,
  107. OBJC_TAG_NSIndexPath = 4,
  108. OBJC_TAG_NSManagedObjectID = 5,
  109. OBJC_TAG_NSDate = 6,
  110. OBJC_TAG_7 = 7
  111. };
  112. // ======================================================================
  113. #pragma mark - objc4-680/runtime/objc-os.h -
  114. // ======================================================================
  115. #ifdef __LP64__
  116. # define WORD_SHIFT 3UL
  117. # define WORD_MASK 7UL
  118. # define WORD_BITS 64
  119. #else
  120. # define WORD_SHIFT 2UL
  121. # define WORD_MASK 3UL
  122. # define WORD_BITS 32
  123. #endif
  124. // ======================================================================
  125. #pragma mark - objc4-680/runtime/runtime.h -
  126. // ======================================================================
  127. typedef struct objc_cache *Cache;
  128. // ======================================================================
  129. #pragma mark - objc4-680/runtime/objc-runtime-new.h -
  130. // ======================================================================
  131. typedef struct method_t {
  132. SEL name;
  133. const char *types;
  134. IMP imp;
  135. } method_t;
  136. MAKE_LIST_T(method);
  137. typedef struct ivar_t {
  138. #if __x86_64__
  139. // *offset was originally 64-bit on some x86_64 platforms.
  140. // We read and write only 32 bits of it.
  141. // Some metadata provides all 64 bits. This is harmless for unsigned
  142. // little-endian values.
  143. // Some code uses all 64 bits. class_addIvar() over-allocates the
  144. // offset for their benefit.
  145. #endif
  146. int32_t *offset;
  147. const char *name;
  148. const char *type;
  149. // alignment is sometimes -1; use alignment() instead
  150. uint32_t alignment_raw;
  151. uint32_t size;
  152. } ivar_t;
  153. MAKE_LIST_T(ivar);
  154. typedef struct property_t {
  155. const char *name;
  156. const char *attributes;
  157. } property_t;
  158. MAKE_LIST_T(property);
  159. typedef struct OBJC_OBJECT(protocol_t)
  160. const char *mangledName;
  161. struct protocol_list_t *protocols;
  162. method_list_t *instanceMethods;
  163. method_list_t *classMethods;
  164. method_list_t *optionalInstanceMethods;
  165. method_list_t *optionalClassMethods;
  166. property_list_t *instanceProperties;
  167. uint32_t size; // sizeof(protocol_t)
  168. uint32_t flags;
  169. // Fields below this point are not always present on disk.
  170. const char **extendedMethodTypes;
  171. const char *_demangledName;
  172. } protocol_t;
  173. MAKE_LIST_T(protocol);
  174. // Values for class_ro_t->flags
  175. // These are emitted by the compiler and are part of the ABI.
  176. // class is a metaclass
  177. #define RO_META (1<<0)
  178. // class is a root class
  179. #define RO_ROOT (1<<1)
  180. typedef struct class_ro_t {
  181. uint32_t flags;
  182. uint32_t instanceStart;
  183. uint32_t instanceSize;
  184. #ifdef __LP64__
  185. uint32_t reserved;
  186. #endif
  187. const uint8_t * ivarLayout;
  188. const char * name;
  189. method_list_t * baseMethodList;
  190. protocol_list_t * baseProtocols;
  191. const ivar_list_t * ivars;
  192. const uint8_t * weakIvarLayout;
  193. property_list_t *baseProperties;
  194. } class_ro_t;
  195. struct class_rw_ext_t {
  196. const class_ro_t *ro;
  197. method_array_t methods;
  198. property_array_t properties;
  199. protocol_array_t protocols;
  200. char *demangledName;
  201. uint32_t version;
  202. };
  203. typedef struct class_rw_t {
  204. uint32_t flags;
  205. uint16_t witness;
  206. #if SUPPORT_INDEXED_ISA
  207. uint16_t index;
  208. #endif
  209. uintptr_t ro_or_rw_ext;
  210. Class firstSubclass;
  211. Class nextSiblingClass;
  212. } class_rw_t;
  213. typedef struct class_t {
  214. struct class_t *isa;
  215. struct class_t *superclass;
  216. #pragma clang diagnostic push
  217. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  218. Cache cache;
  219. #pragma clang diagnostic pop
  220. IMP *vtable;
  221. uintptr_t data_NEVER_USE; // class_rw_t * plus custom rr/alloc flags
  222. } class_t;
  223. // ======================================================================
  224. #pragma mark - CF-1153.18/CFRuntime.h -
  225. // ======================================================================
  226. typedef struct __CFRuntimeBase {
  227. uintptr_t _cfisa;
  228. uint8_t _cfinfo[4];
  229. #if __LP64__
  230. uint32_t _rc;
  231. #endif
  232. } CFRuntimeBase;
  233. // ======================================================================
  234. #pragma mark - CF-1153.18/CFInternal.h -
  235. // ======================================================================
  236. #if defined(__BIG_ENDIAN__)
  237. #define __CF_BIG_ENDIAN__ 1
  238. #define __CF_LITTLE_ENDIAN__ 0
  239. #endif
  240. #if defined(__LITTLE_ENDIAN__)
  241. #define __CF_LITTLE_ENDIAN__ 1
  242. #define __CF_BIG_ENDIAN__ 0
  243. #endif
  244. #define CF_INFO_BITS (!!(__CF_BIG_ENDIAN__) * 3)
  245. #define CF_RC_BITS (!!(__CF_LITTLE_ENDIAN__) * 3)
  246. /* Bit manipulation macros */
  247. /* Bits are numbered from 31 on left to 0 on right */
  248. /* May or may not work if you use them on bitfields in types other than UInt32, bitfields the full width of a UInt32, or anything else for which they were not designed. */
  249. /* In the following, N1 and N2 specify an inclusive range N2..N1 with N1 >= N2 */
  250. #define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1))
  251. #define __CFBitfieldGetValue(V, N1, N2) (((V) & __CFBitfieldMask(N1, N2)) >> (N2))
  252. // ======================================================================
  253. #pragma mark - CF-1153.18/CFString.c -
  254. // ======================================================================
  255. // This is separate for C++
  256. struct __notInlineMutable {
  257. void *buffer;
  258. CFIndex length;
  259. CFIndex capacity; // Capacity in bytes
  260. unsigned int hasGap:1; // Currently unused
  261. unsigned int isFixedCapacity:1;
  262. unsigned int isExternalMutable:1;
  263. unsigned int capacityProvidedExternally:1;
  264. #if __LP64__
  265. unsigned long desiredCapacity:60;
  266. #else
  267. unsigned long desiredCapacity:28;
  268. #endif
  269. CFAllocatorRef contentsAllocator; // Optional
  270. }; // The only mutable variant for CFString
  271. /* !!! Never do sizeof(CFString); the union is here just to make it easier to access some fields.
  272. */
  273. struct __CFString {
  274. CFRuntimeBase base;
  275. union { // In many cases the allocated structs are smaller than these
  276. struct __inline1 {
  277. CFIndex length;
  278. } inline1; // Bytes follow the length
  279. struct __notInlineImmutable1 {
  280. void *buffer; // Note that the buffer is in the same place for all non-inline variants of CFString
  281. CFIndex length;
  282. CFAllocatorRef contentsDeallocator; // Optional; just the dealloc func is used
  283. } notInlineImmutable1; // This is the usual not-inline immutable CFString
  284. struct __notInlineImmutable2 {
  285. void *buffer;
  286. CFAllocatorRef contentsDeallocator; // Optional; just the dealloc func is used
  287. } notInlineImmutable2; // This is the not-inline immutable CFString when length is stored with the contents (first byte)
  288. struct __notInlineMutable notInlineMutable;
  289. } variants;
  290. };
  291. /*
  292. I = is immutable
  293. E = not inline contents
  294. U = is Unicode
  295. N = has NULL byte
  296. L = has length byte
  297. D = explicit deallocator for contents (for mutable objects, allocator)
  298. C = length field is CFIndex (rather than UInt32); only meaningful for 64-bit, really
  299. if needed this bit (valuable real-estate) can be given up for another bit elsewhere, since this info is needed just for 64-bit
  300. Also need (only for mutable)
  301. F = is fixed
  302. G = has gap
  303. Cap, DesCap = capacity
  304. B7 B6 B5 B4 B3 B2 B1 B0
  305. U N L C I
  306. B6 B5
  307. 0 0 inline contents
  308. 0 1 E (freed with default allocator)
  309. 1 0 E (not freed)
  310. 1 1 E D
  311. !!! Note: Constant CFStrings use the bit patterns:
  312. C8 (11001000 = default allocator, not inline, not freed contents; 8-bit; has NULL byte; doesn't have length; is immutable)
  313. D0 (11010000 = default allocator, not inline, not freed contents; Unicode; is immutable)
  314. The bit usages should not be modified in a way that would effect these bit patterns.
  315. */
  316. enum {
  317. __kCFFreeContentsWhenDoneMask = 0x020,
  318. __kCFFreeContentsWhenDone = 0x020,
  319. __kCFContentsMask = 0x060,
  320. __kCFHasInlineContents = 0x000,
  321. __kCFNotInlineContentsNoFree = 0x040, // Don't free
  322. __kCFNotInlineContentsDefaultFree = 0x020, // Use allocator's free function
  323. __kCFNotInlineContentsCustomFree = 0x060, // Use a specially provided free function
  324. __kCFHasContentsAllocatorMask = 0x060,
  325. __kCFHasContentsAllocator = 0x060, // (For mutable strings) use a specially provided allocator
  326. __kCFHasContentsDeallocatorMask = 0x060,
  327. __kCFHasContentsDeallocator = 0x060,
  328. __kCFIsMutableMask = 0x01,
  329. __kCFIsMutable = 0x01,
  330. __kCFIsUnicodeMask = 0x10,
  331. __kCFIsUnicode = 0x10,
  332. __kCFHasNullByteMask = 0x08,
  333. __kCFHasNullByte = 0x08,
  334. __kCFHasLengthByteMask = 0x04,
  335. __kCFHasLengthByte = 0x04,
  336. // !!! Bit 0x02 has been freed up
  337. };
  338. // !!! Assumptions:
  339. // Mutable strings are not inline
  340. // Compile-time constant strings are not inline
  341. // Mutable strings always have explicit length (but they might also have length byte and null byte)
  342. // If there is an explicit length, always use that instead of the length byte (length byte is useful for quickly returning pascal strings)
  343. // Never look at the length byte for the length; use __CFStrLength or __CFStrLength2
  344. /* The following set of functions and macros need to be updated on change to the bit configuration
  345. */
  346. CF_INLINE Boolean __CFStrIsMutable(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsMutableMask) == __kCFIsMutable;}
  347. CF_INLINE Boolean __CFStrIsInline(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFContentsMask) == __kCFHasInlineContents;}
  348. CF_INLINE Boolean __CFStrFreeContentsWhenDone(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFFreeContentsWhenDoneMask) == __kCFFreeContentsWhenDone;}
  349. CF_INLINE Boolean __CFStrHasContentsDeallocator(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasContentsDeallocatorMask) == __kCFHasContentsDeallocator;}
  350. CF_INLINE Boolean __CFStrIsUnicode(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsUnicodeMask) == __kCFIsUnicode;}
  351. CF_INLINE Boolean __CFStrIsEightBit(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsUnicodeMask) != __kCFIsUnicode;}
  352. CF_INLINE Boolean __CFStrHasNullByte(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasNullByteMask) == __kCFHasNullByte;}
  353. CF_INLINE Boolean __CFStrHasLengthByte(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasLengthByteMask) == __kCFHasLengthByte;}
  354. CF_INLINE Boolean __CFStrHasExplicitLength(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & (__kCFIsMutableMask | __kCFHasLengthByteMask)) != __kCFHasLengthByte;} // Has explicit length if (1) mutable or (2) not mutable and no length byte
  355. CF_INLINE Boolean __CFStrIsConstant(CFStringRef str) {
  356. #if __LP64__
  357. return str->base._rc == 0;
  358. #else
  359. return (str->base._cfinfo[CF_RC_BITS]) == 0;
  360. #endif
  361. }
  362. /* Returns ptr to the buffer (which might include the length byte).
  363. */
  364. CF_INLINE const void *__CFStrContents(CFStringRef str) {
  365. if (__CFStrIsInline(str)) {
  366. return (const void *)(((uintptr_t)&(str->variants)) + (__CFStrHasExplicitLength(str) ? sizeof(CFIndex) : 0));
  367. } else { // Not inline; pointer is always word 2
  368. return str->variants.notInlineImmutable1.buffer;
  369. }
  370. }
  371. // ======================================================================
  372. #pragma mark - CF-1153.18/CFURL.c -
  373. // ======================================================================
  374. struct __CFURL {
  375. CFRuntimeBase _cfBase;
  376. UInt32 _flags;
  377. CFStringEncoding _encoding; // The encoding to use when asked to remove percent escapes
  378. CFStringRef _string; // Never NULL
  379. CFURLRef _base;
  380. struct _CFURLAdditionalData* _extra;
  381. void *_resourceInfo; // For use by CoreServicesInternal to cache property values. Retained and released by CFURL.
  382. CFRange _ranges[1]; // variable length (1 to 9) array of ranges
  383. };
  384. // ======================================================================
  385. #pragma mark - CF-1153.18/CFDate.c -
  386. // ======================================================================
  387. struct __CFDate {
  388. // According to CFDate.c the structure is a CFRuntimeBase followed
  389. // by the time. In fact, it's only an isa pointer followed by the time.
  390. //struct CFRuntimeBase _base;
  391. uintptr_t _cfisa;
  392. CFAbsoluteTime _time; /* immutable */
  393. };
  394. // ======================================================================
  395. #pragma mark - CF-1153.18/CFNumber.c -
  396. // ======================================================================
  397. struct __CFNumber {
  398. CFRuntimeBase _base;
  399. uint64_t _pad; // need this space here for the constant objects
  400. /* 0 or 8 more bytes allocated here */
  401. };
  402. // ======================================================================
  403. #pragma mark - CF-1153.18/CFArray.c -
  404. // ======================================================================
  405. struct __CFArrayBucket {
  406. const void *_item;
  407. };
  408. struct __CFArrayDeque {
  409. uintptr_t _leftIdx;
  410. uintptr_t _capacity;
  411. /* struct __CFArrayBucket buckets follow here */
  412. };
  413. struct __CFArray {
  414. CFRuntimeBase _base;
  415. CFIndex _count; /* number of objects */
  416. CFIndex _mutations;
  417. int32_t _mutInProgress;
  418. /* __strong */ void *_store; /* can be NULL when MutableDeque */
  419. };
  420. /* Flag bits */
  421. enum { /* Bits 0-1 */
  422. __kCFArrayImmutable = 0,
  423. __kCFArrayDeque = 2,
  424. };
  425. enum { /* Bits 2-3 */
  426. __kCFArrayHasNullCallBacks = 0,
  427. __kCFArrayHasCFTypeCallBacks = 1,
  428. __kCFArrayHasCustomCallBacks = 3 /* callbacks are at end of header */
  429. };
  430. CF_INLINE CFIndex __CFArrayGetType(CFArrayRef array) {
  431. return __CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0);
  432. }
  433. CF_INLINE CFIndex __CFArrayGetSizeOfType(CFIndex t) {
  434. CFIndex size = 0;
  435. size += sizeof(struct __CFArray);
  436. if (__CFBitfieldGetValue((unsigned long)t, 3, 2) == __kCFArrayHasCustomCallBacks) {
  437. size += sizeof(CFArrayCallBacks);
  438. }
  439. return size;
  440. }
  441. /* Only applies to immutable and mutable-deque-using arrays;
  442. * Returns the bucket holding the left-most real value in the latter case. */
  443. CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketsPtr(CFArrayRef array) {
  444. switch (__CFArrayGetType(array)) {
  445. case __kCFArrayImmutable:
  446. return (struct __CFArrayBucket *)((uint8_t *)array + __CFArrayGetSizeOfType(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS]));
  447. case __kCFArrayDeque: {
  448. struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
  449. return (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque) + deque->_leftIdx * sizeof(struct __CFArrayBucket));
  450. }
  451. }
  452. return NULL;
  453. }
  454. // ======================================================================
  455. #pragma mark - CF-1153.18/CFBasicHash.h -
  456. // ======================================================================
  457. typedef struct __CFBasicHash *CFBasicHashRef;
  458. typedef const struct __CFBasicHash *CFConstBasicHashRef;
  459. typedef struct __CFBasicHashCallbacks CFBasicHashCallbacks;
  460. struct __CFBasicHashCallbacks {
  461. uintptr_t (*retainValue)(CFAllocatorRef alloc, uintptr_t stack_value); // Return 2nd arg or new value
  462. uintptr_t (*retainKey)(CFAllocatorRef alloc, uintptr_t stack_key); // Return 2nd arg or new key
  463. void (*releaseValue)(CFAllocatorRef alloc, uintptr_t stack_value);
  464. void (*releaseKey)(CFAllocatorRef alloc, uintptr_t stack_key);
  465. Boolean (*equateValues)(uintptr_t coll_value1, uintptr_t stack_value2); // 1st arg is in-collection value, 2nd arg is probe parameter OR in-collection value for a second collection
  466. Boolean (*equateKeys)(uintptr_t coll_key1, uintptr_t stack_key2); // 1st arg is in-collection key, 2nd arg is probe parameter
  467. CFHashCode (*hashKey)(uintptr_t stack_key);
  468. uintptr_t (*getIndirectKey)(uintptr_t coll_value); // Return key; 1st arg is in-collection value
  469. CFStringRef (*copyValueDescription)(uintptr_t stack_value);
  470. CFStringRef (*copyKeyDescription)(uintptr_t stack_key);
  471. };
  472. // ======================================================================
  473. #pragma mark - CF-1153.18/CFBasicHash.c -
  474. // ======================================================================
  475. // Prime numbers. Values above 100 have been adjusted up so that the
  476. // malloced block size will be just below a multiple of 512; values
  477. // above 1200 have been adjusted up to just below a multiple of 4096.
  478. static const uintptr_t __CFBasicHashTableSizes[64] = {
  479. 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
  480. 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
  481. 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
  482. 6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
  483. 111638519, 180634607, 292272623, 472907251,
  484. #if __LP64__
  485. 765180413UL, 1238087663UL, 2003267557UL, 3241355263UL, 5244622819UL,
  486. #if 0
  487. 8485977589UL, 13730600407UL, 22216578047UL, 35947178479UL,
  488. 58163756537UL, 94110934997UL, 152274691561UL, 246385626107UL,
  489. 398660317687UL, 645045943807UL, 1043706260983UL, 1688752204787UL,
  490. 2732458465769UL, 4421210670577UL, 7153669136377UL,
  491. 11574879807461UL, 18728548943849UL, 30303428750843UL
  492. #endif
  493. #endif
  494. };
  495. typedef union {
  496. uintptr_t neutral;
  497. void* Xstrong; // Changed from type 'id'
  498. void* Xweak; // Changed from type 'id'
  499. } CFBasicHashValue;
  500. struct __CFBasicHash {
  501. CFRuntimeBase base;
  502. struct { // 192 bits
  503. uint16_t mutations;
  504. uint8_t hash_style:2;
  505. uint8_t keys_offset:1;
  506. uint8_t counts_offset:2;
  507. uint8_t counts_width:2;
  508. uint8_t hashes_offset:2;
  509. uint8_t strong_values:1;
  510. uint8_t strong_keys:1;
  511. uint8_t weak_values:1;
  512. uint8_t weak_keys:1;
  513. uint8_t int_values:1;
  514. uint8_t int_keys:1;
  515. uint8_t indirect_keys:1;
  516. uint32_t used_buckets; /* number of used buckets */
  517. uint64_t deleted:16;
  518. uint64_t num_buckets_idx:8; /* index to number of buckets */
  519. uint64_t __kret:10;
  520. uint64_t __vret:10;
  521. uint64_t __krel:10;
  522. uint64_t __vrel:10;
  523. uint64_t __:1;
  524. uint64_t null_rc:1;
  525. uint64_t fast_grow:1;
  526. uint64_t finalized:1;
  527. uint64_t __kdes:10;
  528. uint64_t __vdes:10;
  529. uint64_t __kequ:10;
  530. uint64_t __vequ:10;
  531. uint64_t __khas:10;
  532. uint64_t __kget:10;
  533. } bits;
  534. void *pointers[1];
  535. };
  536. CF_INLINE CFBasicHashValue *__CFBasicHashGetValues(CFConstBasicHashRef ht) {
  537. return (CFBasicHashValue *)ht->pointers[0];
  538. }
  539. CF_INLINE CFBasicHashValue *__CFBasicHashGetKeys(CFConstBasicHashRef ht) {
  540. return (CFBasicHashValue *)ht->pointers[ht->bits.keys_offset];
  541. }
  542. CF_INLINE void *__CFBasicHashGetCounts(CFConstBasicHashRef ht) {
  543. return (void *)ht->pointers[ht->bits.counts_offset];
  544. }
  545. CF_INLINE uintptr_t __CFBasicHashGetSlotCount(CFConstBasicHashRef ht, CFIndex idx) {
  546. void *counts = __CFBasicHashGetCounts(ht);
  547. switch (ht->bits.counts_width) {
  548. case 0: return ((uint8_t *)counts)[idx];
  549. case 1: return ((uint16_t *)counts)[idx];
  550. case 2: return ((uint32_t *)counts)[idx];
  551. case 3: return (uintptr_t)((uint64_t *)counts)[idx];
  552. }
  553. return 0;
  554. }
  555. #ifdef __cplusplus
  556. }
  557. #endif
  558. #endif // HDR_KSObjCApple_h