ObjFW
private.h
1 /*
2  * Copyright (c) 2008-2026 Jonathan Schleifer <js@nil.im>
3  *
4  * All rights reserved.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License version 3.0 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13  * version 3.0 for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * version 3.0 along with this program. If not, see
17  * <https://www.gnu.org/licenses/>.
18  */
19 
20 #import "macros.h"
21 
22 #if !defined(__has_feature) || !__has_feature(nullability)
23 # ifndef _Nonnull
24 # define _Nonnull
25 # endif
26 # ifndef _Nullable
27 # define _Nullable
28 # endif
29 #endif
30 
31 typedef uint32_t (*_Nonnull objc_hashtable_hash_func)(
32  const void *_Nonnull key);
33 typedef bool (*_Nonnull objc_hashtable_equal_func)(const void *_Nonnull key1,
34  const void *_Nonnull key2);
35 
36 struct objc_class {
37  Class _Nonnull isa;
38  Class _Nullable superclass;
39  const char *_Nonnull name;
40  unsigned long version;
41  unsigned long info;
42  long instanceSize;
43  struct objc_ivar_list *_Nullable ivars;
44  struct objc_method_list *_Nullable methodList;
45  struct objc_dtable *_Nullable dTable;
46  Class _Nullable *_Nullable subclassList;
47  void *_Nullable siblingClass;
48  struct objc_protocol_list *_Nullable protocols;
49  void *_Nullable GCObjectType;
50  unsigned long ABIVersion;
51  int32_t *_Nonnull *_Nullable ivarOffsets;
52  struct objc_property_list *_Nullable propertyList;
53 };
54 
55 enum _objc_class_info {
56  _OBJC_CLASS_INFO_CLASS = 0x0001,
57  _OBJC_CLASS_INFO_METACLASS = 0x0002,
58  _OBJC_CLASS_INFO_NEW_ABI = 0x0010,
59  _OBJC_CLASS_INFO_SETUP = 0x0100,
60  _OBJC_CLASS_INFO_LOADED = 0x0200,
61  _OBJC_CLASS_INFO_DTABLE = 0x0400,
62  _OBJC_CLASS_INFO_INITIALIZED = 0x0800,
63  _OBJC_CLASS_INFO_RUNTIME_RR = 0x1000
64 };
65 
66 struct objc_object {
67  Class _Nonnull isa;
68 };
69 
70 struct objc_selector {
71  uintptr_t UID;
72  const char *_Nullable typeEncoding;
73 };
74 
75 struct objc_method {
76  struct objc_selector selector;
77  IMP _Nonnull implementation;
78 };
79 
80 struct objc_method_list {
81  struct objc_method_list *_Nullable next;
82  unsigned int count;
83  struct objc_method methods[1];
84 };
85 
86 struct objc_category {
87  const char *_Nonnull categoryName;
88  const char *_Nonnull className;
89  struct objc_method_list *_Nullable instanceMethods;
90  struct objc_method_list *_Nullable classMethods;
91  struct objc_protocol_list *_Nullable protocols;
92 };
93 
94 struct objc_ivar {
95  const char *_Nonnull name;
96  const char *_Nonnull typeEncoding;
97  unsigned int offset;
98 };
99 
100 struct objc_ivar_list {
101  unsigned int count;
102  struct objc_ivar ivars[1];
103 };
104 
105 struct objc_method_description {
106  const char *_Nonnull name;
107  const char *_Nonnull typeEncoding;
108 };
109 
110 struct objc_method_description_list {
111  int count;
112  struct objc_method_description list[1];
113 };
114 
115 struct objc_protocol_list {
116  struct objc_protocol_list *_Nullable next;
117  long count;
118  Protocol *__unsafe_unretained _Nonnull list[1];
119 };
120 
121 #if __has_attribute(__objc_root_class__)
122 __attribute__((__objc_root_class__))
123 #endif
124 @interface Protocol
125 {
126 @public
127  Class _Nonnull isa;
128  const char *_Nonnull name;
129  struct objc_protocol_list *_Nullable protocolList;
130  struct objc_method_description_list *_Nullable instanceMethods;
131  struct objc_method_description_list *_Nullable classMethods;
132 }
133 @end
134 
135 enum _objc_property_attributes {
136  _OBJC_PROPERTY_READONLY = 0x01,
137  _OBJC_PROPERTY_GETTER = 0x02,
138  _OBJC_PROPERTY_ASSIGN = 0x04,
139  _OBJC_PROPERTY_READWRITE = 0x08,
140  _OBJC_PROPERTY_RETAIN = 0x10,
141  _OBJC_PROPERTY_COPY = 0x20,
142  _OBJC_PROPERTY_NONATOMIC = 0x40,
143  _OBJC_PROPERTY_SETTER = 0x80
144 };
145 
146 enum _objc_property_extended_attributes {
147  _OBJC_PROPERTY_SYNTHESIZED = 0x1,
148  _OBJC_PROPERTY_DYNAMIC = 0x2,
149  _OBJC_PROPERTY_PROTOCOL = 0x3,
150  _OBJC_PROPERTY_ATOMIC = 0x4,
151  _OBJC_PROPERTY_WEAK = 0x8,
152  _OBJC_PROPERTY_STRONG = 0x10,
153  _OBJC_PROPERTY_UNSAFE_UNRETAINED = 0x20
154 };
155 
156 struct objc_property {
157  const char *_Nonnull name;
158  unsigned char attributes, extendedAttributes;
159  struct {
160  const char *_Nullable name;
161  const char *_Nullable typeEncoding;
162  } getter, setter;
163 };
164 
165 struct objc_property_list {
166  unsigned int count;
167  struct objc_property_list *_Nullable next;
168  struct objc_property properties[1];
169 };
170 
171 struct objc_static_instances {
172  const char *_Nonnull className;
173  id _Nullable instances[1];
174 };
175 
176 struct objc_symtab {
177  unsigned long unknown;
178  struct objc_selector *_Nullable selectorRefs;
179  uint16_t classDefsCount;
180  uint16_t categoryDefsCount;
181  void *_Nonnull defs[1];
182 };
183 
184 struct objc_module {
185  unsigned long version; /* 9 = non-fragile */
186  unsigned long size;
187  const char *_Nullable name;
188  struct objc_symtab *_Nonnull symtab;
189 };
190 
191 struct objc_hashtable_bucket {
192  const void *_Nonnull key, *_Nonnull object;
193  uint32_t hash;
194 };
195 
196 struct objc_hashtable {
197  objc_hashtable_hash_func hash;
198  objc_hashtable_equal_func equal;
199  uint32_t count, size;
200  struct objc_hashtable_bucket *_Nonnull *_Nullable data;
201 };
202 
203 struct objc_sparsearray {
204  struct objc_sparsearray_data {
205  void *_Nullable next[256];
206  } *_Nonnull data;
207  uint8_t levels;
208 };
209 
210 struct objc_dtable {
211  struct objc_dtable_level2 {
212 #ifdef OF_SELUID24
213  struct objc_dtable_level3 {
214  IMP _Nullable buckets[256];
215  } *_Nonnull buckets[256];
216 #else
217  IMP _Nullable buckets[256];
218 #endif
219  } *_Nonnull buckets[256];
220 };
221 
222 #if defined(OBJC_COMPILING_AMIGA_LIBRARY) || \
223  defined(OBJC_COMPILING_AMIGA_LINKLIB)
224 struct objc_linklib_context {
225  void *_Nullable (*_Nonnull malloc)(size_t);
226  void *_Nullable (*_Nonnull calloc)(size_t, size_t);
227  void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t);
228  void (*_Nonnull free)(void *_Nullable);
229  int (*_Nonnull vfprintf)(FILE *_Nonnull, const char *_Nonnull, va_list);
230  int (*_Nonnull fflush)(FILE *_Nonnull);
231  void (*_Nonnull abort)(void);
232  int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull);
233  void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull);
234  void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)(
235  void *_Nonnull);
236  uintptr_t (*_Nonnull _Unwind_GetRegionStart)(void *_Nonnull);
237  uintptr_t (*_Nonnull _Unwind_GetDataRelBase)(void *_Nonnull);
238  uintptr_t (*_Nonnull _Unwind_GetTextRelBase)(void *_Nonnull);
239  uintptr_t (*_Nonnull _Unwind_GetIP)(void *_Nonnull);
240  uintptr_t (*_Nonnull _Unwind_GetGR)(void *_Nonnull, int);
241  void (*_Nonnull _Unwind_SetIP)(void *_Nonnull, uintptr_t);
242  void (*_Nonnull _Unwind_SetGR)(void *_Nonnull, int, uintptr_t);
243  void (*_Nonnull _Unwind_Resume)(void *_Nonnull);
244  void (*_Nonnull __register_frame)(void *_Nonnull);
245  void (*_Nonnull __deregister_frame)(void *_Nonnull);
246 };
247 
248 extern bool objc_init(unsigned int version,
249  struct objc_linklib_context *_Nonnull ctx);
250 extern void class_registerAlias_np(Class _Nonnull class_,
251  const char *_Nonnull name);
252 # ifdef OF_MORPHOS
253 extern const char *_Nullable _class_getMethodTypeEncoding(Class _Nullable class,
254  SEL _Nonnull selector);
255 # endif
256 #endif
257 
258 extern void _objc_registerAllCategories(struct objc_symtab *_Nonnull)
259  OF_VISIBILITY_INTERNAL;
260 extern struct objc_category *_Nullable *_Nullable
261  _objc_categoriesForClass(Class _Nonnull) OF_VISIBILITY_INTERNAL;
262 extern void _objc_processCategoriesLoadQueue(void) OF_VISIBILITY_INTERNAL;
263 extern void _objc_unregisterAllCategories(void) OF_VISIBILITY_INTERNAL;
264 extern void _objc_initializeClass(Class _Nonnull) OF_VISIBILITY_INTERNAL;
265 extern void _objc_updateDTable(Class _Nonnull) OF_VISIBILITY_INTERNAL;
266 extern void _objc_registerAllClasses(struct objc_symtab *_Nonnull)
267  OF_VISIBILITY_INTERNAL;
268 extern Class _Nullable _objc_classnameToClass(const char *_Nonnull, bool)
269  OF_VISIBILITY_INTERNAL;
270 extern void _objc_unregisterClass(Class _Nonnull) OF_VISIBILITY_INTERNAL;
271 extern void _objc_unregisterAllClasses(void) OF_VISIBILITY_INTERNAL;
272 extern uint32_t _objc_string_hash(const void *_Nonnull) OF_VISIBILITY_INTERNAL;
273 extern bool _objc_string_equal(const void *_Nonnull, const void *_Nonnull)
274  OF_VISIBILITY_INTERNAL;
275 extern struct objc_hashtable *_Nonnull _objc_hashtable_new(
276  objc_hashtable_hash_func, objc_hashtable_equal_func, uint32_t)
277  OF_VISIBILITY_INTERNAL;
278 extern struct objc_hashtable_bucket _objc_deletedBucket OF_VISIBILITY_INTERNAL;
279 extern void _objc_hashtable_set(struct objc_hashtable *_Nonnull,
280  const void *_Nonnull, const void *_Nonnull) OF_VISIBILITY_INTERNAL;
281 extern void *_Nullable _objc_hashtable_get(struct objc_hashtable *_Nonnull,
282  const void *_Nonnull) OF_VISIBILITY_INTERNAL;
283 extern void _objc_hashtable_delete(struct objc_hashtable *_Nonnull,
284  const void *_Nonnull) OF_VISIBILITY_INTERNAL;
285 extern void _objc_hashtable_free(struct objc_hashtable *_Nonnull)
286  OF_VISIBILITY_INTERNAL;
287 extern void _objc_registerSelector(struct objc_selector *_Nonnull)
288  OF_VISIBILITY_INTERNAL;
289 extern void _objc_registerAllSelectors(struct objc_symtab *_Nonnull)
290  OF_VISIBILITY_INTERNAL;
291 extern void _objc_unregisterAllSelectors(void) OF_VISIBILITY_INTERNAL;
292 extern struct objc_sparsearray *_Nonnull _objc_sparsearray_new(uint8_t)
293  OF_VISIBILITY_INTERNAL;
294 extern void *_Nullable _objc_sparsearray_get(struct objc_sparsearray *_Nonnull,
295  uintptr_t) OF_VISIBILITY_INTERNAL;
296 extern void _objc_sparsearray_set(struct objc_sparsearray *_Nonnull, uintptr_t,
297  void *_Nullable) OF_VISIBILITY_INTERNAL;
298 extern void _objc_sparsearray_free(struct objc_sparsearray *_Nonnull)
299  OF_VISIBILITY_INTERNAL;
300 extern struct objc_dtable *_Nonnull _objc_dtable_new(void)
301  OF_VISIBILITY_INTERNAL;
302 extern void _objc_dtable_copy(struct objc_dtable *_Nonnull,
303  struct objc_dtable *_Nonnull) OF_VISIBILITY_INTERNAL;
304 extern void _objc_dtable_set(struct objc_dtable *_Nonnull, uint32_t,
305  IMP _Nullable) OF_VISIBILITY_INTERNAL;
306 extern void _objc_dtable_free(struct objc_dtable *_Nonnull)
307  OF_VISIBILITY_INTERNAL;
308 extern void _objc_dtable_cleanup(void) OF_VISIBILITY_INTERNAL;
309 extern void _objc_initStaticInstances(struct objc_symtab *_Nonnull)
310  OF_VISIBILITY_INTERNAL;
311 extern void _objc_forgetPendingStaticInstances(void) OF_VISIBILITY_INTERNAL;
312 extern void _objc_zeroWeakReferences(id _Nonnull) OF_VISIBILITY_INTERNAL;
313 extern Class _Nullable _object_getTaggedPointerClass(id _Nonnull)
314  OF_VISIBILITY_INTERNAL;
315 #ifdef OF_HAVE_THREADS
316 extern void _objc_globalMutex_lock(void) OF_VISIBILITY_INTERNAL;
317 extern void _objc_globalMutex_unlock(void) OF_VISIBILITY_INTERNAL;
318 extern void _objc_globalMutex_free(void) OF_VISIBILITY_INTERNAL;
319 #else
320 # define _objc_globalMutex_lock()
321 # define _objc_globalMutex_unlock()
322 # define _objc_globalMutex_free()
323 #endif
324 extern char *_Nullable _objc_strdup(const char *_Nonnull string)
325  OF_VISIBILITY_INTERNAL;
326 
327 static OF_INLINE IMP _Nullable
328 _objc_dtable_get(const struct objc_dtable *_Nonnull dtable, uint32_t idx)
329 {
330 #ifdef OF_SELUID24
331  uint8_t i = idx >> 16;
332  uint8_t j = idx >> 8;
333  uint8_t k = idx;
334 
335  return dtable->buckets[i]->buckets[j]->buckets[k];
336 #else
337  uint8_t i = idx >> 8;
338  uint8_t j = idx;
339 
340  return dtable->buckets[i]->buckets[j];
341 #endif
342 }
343 
344 extern void OF_NO_RETURN_FUNC _objc_error(const char *_Nonnull title,
345  const char *_Nonnull format, ...) OF_VISIBILITY_INTERNAL;
346 #define _OBJC_ERROR(...) \
347  _objc_error("ObjFWRT @ " __FILE__ ":" OF_STRINGIFY(__LINE__), \
348  __VA_ARGS__)
349 
350 #if defined(OF_ELF)
351 # if defined(OF_AMD64) || defined(OF_X86) || \
352  defined(OF_POWERPC64) || defined(OF_POWERPC) || \
353  defined(OF_ARM64) || defined(OF_ARM) || \
354  defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
355  defined(OF_SPARC64) || defined(OF_SPARC) || \
356  defined(OF_RISCV64) || defined(OF_LOONGARCH64)
357 # define OF_ASM_LOOKUP
358 # endif
359 #elif defined(OF_MACH_O)
360 # if defined(OF_AMD64)
361 # define OF_ASM_LOOKUP
362 # endif
363 #elif defined(OF_WINDOWS)
364 # if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64)
365 # define OF_ASM_LOOKUP
366 # endif
367 #endif
368 
369 @interface DummyObject
370 {
371  Class _Nonnull isa;
372 }
373 
374 @property (readonly, nonatomic) bool allowsWeakReference;
375 
376 + (void)initialize;
377 + (bool)resolveClassMethod: (nonnull SEL)selector;
378 + (bool)resolveInstanceMethod: (nonnull SEL)selector;
379 - (nonnull id)retain;
380 - (void)release;
381 - (void)dealloc;
382 - (nonnull id)autorelease;
383 - (nonnull id)copy;
384 - (nonnull id)mutableCopy;
385 - (bool)retainWeakReference;
386 - (void)_usesRuntimeRR;
387 @end
A pointer to a class.
Definition: private.h:36
A pointer to any object.
Definition: private.h:66
const struct objc_protocol * Protocol
A protocol.
Definition: ObjFWRT.h:117
id(* IMP)(id object, SEL selector,...)
A method implementation.
Definition: ObjFWRT.h:146