ObjFW  Diff

Differences From Artifact [69fcb5506f]:

To Artifact [a8b96cc3b5]:


14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 * file.
 */

#include "config.h"

#include "platform.h"

#if defined(__has_feature) && __has_feature(nullability)
# define OBJC_NONNULL _Nonnull
# define OBJC_NULLABLE _Nullable
#else
# define OBJC_NONNULL
# define OBJC_NULLABLE

#endif

struct objc_abi_class {
	struct objc_abi_class *OBJC_NONNULL metaclass;
	const char *OBJC_NULLABLE superclass;
	const char *OBJC_NONNULL name;
	unsigned long version;
	unsigned long info;
	long instance_size;
	void *OBJC_NULLABLE ivars;
	struct objc_abi_method_list *OBJC_NULLABLE methodlist;
	void *OBJC_NULLABLE dtable;
	void *OBJC_NULLABLE subclass_list;
	void *OBJC_NULLABLE sibling_class;
	void *OBJC_NULLABLE protocols;
	void *OBJC_NULLABLE gc_object_type;
	long abi_version;
	int32_t *OBJC_NONNULL *OBJC_NULLABLE ivar_offsets;
	void *OBJC_NULLABLE properties;
};

struct objc_abi_selector {
	const char *OBJC_NONNULL name;
	const char *OBJC_NULLABLE types;
};

struct objc_abi_method {
	struct objc_abi_selector sel;
	IMP OBJC_NONNULL imp;
};

struct objc_abi_method_list {
	struct objc_abi_method_list *OBJC_NULLABLE next;
	unsigned int count;
	struct objc_abi_method methods[1];
};

struct objc_abi_category {
	const char *OBJC_NONNULL category_name;
	const char *OBJC_NONNULL class_name;
	struct objc_abi_method_list *OBJC_NULLABLE instance_methods;
	struct objc_abi_method_list *OBJC_NULLABLE class_methods;
	struct objc_protocol_list *OBJC_NULLABLE protocols;
};

struct objc_abi_method_description {
	const char *OBJC_NONNULL name;
	const char *OBJC_NONNULL types;
};

struct objc_abi_method_description_list {
	int count;
	struct objc_abi_method_description list[1];
};

struct objc_abi_static_instances {
	const char *OBJC_NONNULL class_name;
	id OBJC_NULLABLE instances[1];
};

struct objc_abi_symtab {
	unsigned long unknown;
	struct objc_abi_selector *OBJC_NULLABLE sel_refs;
	uint16_t cls_def_cnt;
	uint16_t cat_def_cnt;
	void *OBJC_NONNULL defs[1];
};

struct objc_abi_module {
	unsigned long version;	/* 9 = non-fragile */
	unsigned long size;
	const char *OBJC_NULLABLE name;
	struct objc_abi_symtab *OBJC_NONNULL symtab;
};

struct objc_hashtable_bucket {
	const void *OBJC_NONNULL key, *OBJC_NONNULL obj;
	uint32_t hash;
};

struct objc_hashtable {
	uint32_t (*OBJC_NONNULL hash)(const void *OBJC_NONNULL key);
	bool (*OBJC_NONNULL equal)(const void *OBJC_NONNULL key1,
	    const void *OBJC_NONNULL key2);
	uint32_t count, size;
	struct objc_hashtable_bucket *OBJC_NONNULL *OBJC_NULLABLE data;
};

struct objc_sparsearray {
	struct objc_sparsearray_data {
		void *OBJC_NULLABLE next[256];
	} *OBJC_NONNULL data;
	uint8_t index_size;
};

struct objc_dtable {
	struct objc_dtable_level2 {
#ifdef OF_SELUID24
		struct objc_dtable_level3 {
			IMP OBJC_NULLABLE buckets[256];
		} *OBJC_NONNULL buckets[256];
#else
		IMP OBJC_NULLABLE buckets[256];
#endif
	} *OBJC_NONNULL buckets[256];
};

extern void objc_register_all_categories(struct objc_abi_symtab *OBJC_NONNULL);
extern struct objc_category *OBJC_NULLABLE *OBJC_NULLABLE
    objc_categories_for_class(Class OBJC_NONNULL);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class OBJC_NONNULL);
extern void objc_update_dtable(Class OBJC_NONNULL);
extern void objc_register_all_classes(struct objc_abi_symtab *OBJC_NONNULL);
extern Class OBJC_NULLABLE objc_classname_to_class(const char *OBJC_NONNULL,
    bool);
extern void objc_unregister_class(Class OBJC_NONNULL);
extern void objc_unregister_all_classes(void);
extern uint32_t objc_hash_string(const void *OBJC_NONNULL);
extern bool objc_equal_string(const void *OBJC_NONNULL,
    const void *OBJC_NONNULL);
extern struct objc_hashtable *OBJC_NONNULL objc_hashtable_new(
    uint32_t (*OBJC_NONNULL)(const void *OBJC_NONNULL),
    bool (*OBJC_NONNULL)(const void *OBJC_NONNULL, const void *OBJC_NONNULL),
    uint32_t);
extern struct objc_hashtable_bucket objc_deleted_bucket;
extern void objc_hashtable_set(struct objc_hashtable *OBJC_NONNULL,
    const void *OBJC_NONNULL, const void *OBJC_NONNULL);
extern void *OBJC_NULLABLE objc_hashtable_get(
    struct objc_hashtable *OBJC_NONNULL, const void *OBJC_NONNULL);
extern void objc_hashtable_delete(struct objc_hashtable *OBJC_NONNULL,
    const void *OBJC_NONNULL);
extern void objc_hashtable_free(struct objc_hashtable *OBJC_NONNULL);
extern void objc_register_selector(struct objc_abi_selector *OBJC_NONNULL);
extern void objc_register_all_selectors(struct objc_abi_symtab *OBJC_NONNULL);
extern void objc_unregister_all_selectors(void);
extern struct objc_sparsearray *OBJC_NONNULL objc_sparsearray_new(uint8_t);
extern void *OBJC_NULLABLE objc_sparsearray_get(
    struct objc_sparsearray *OBJC_NONNULL, uintptr_t);
extern void objc_sparsearray_set(struct objc_sparsearray *OBJC_NONNULL,
    uintptr_t, void *OBJC_NULLABLE);
extern void objc_sparsearray_free(struct objc_sparsearray *OBJC_NONNULL);
extern struct objc_dtable *OBJC_NONNULL objc_dtable_new(void);
extern void objc_dtable_copy(struct objc_dtable *OBJC_NONNULL,
    struct objc_dtable *OBJC_NONNULL);
extern void objc_dtable_set(struct objc_dtable *OBJC_NONNULL, uint32_t,
    IMP OBJC_NULLABLE);
extern void objc_dtable_free(struct objc_dtable *OBJC_NONNULL);
extern void objc_dtable_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab *OBJC_NONNULL);
extern void objc_forget_pending_static_instances(void);
#ifdef OF_HAVE_THREADS
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
#else
# define objc_global_mutex_lock()
# define objc_global_mutex_unlock()
# define objc_global_mutex_free()
#endif

static inline IMP OBJC_NULLABLE
objc_dtable_get(const struct objc_dtable *OBJC_NONNULL dtable, uint32_t idx)
{
#ifdef OF_SELUID24
	uint8_t i = idx >> 16;
	uint8_t j = idx >>  8;
	uint8_t k = idx;

	return dtable->buckets[i]->buckets[j]->buckets[k];
#else
	uint8_t i = idx >> 8;
	uint8_t j = idx;








|
|
|
|
|
|
>



|
|
|



|
|
|
|
|
|
|

|
|



|
|




|



|





|
|
|
|
|



|
|








|
|




|


|





|
|



|




|
|
|

|




|
|







|
|

|

|


|
|
|

|
|
|
|
<
|

|
|
<
|
|
<
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|

|











|
|



|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146

147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
 * file.
 */

#include "config.h"

#include "platform.h"

#if !defined(__has_feature) || !__has_feature(nullability)
# ifndef _Nonnull
#  define _Nonnull
# endif
# ifndef _Nullable
#  define _Nullable
# endif
#endif

struct objc_abi_class {
	struct objc_abi_class *_Nonnull metaclass;
	const char *_Nullable superclass;
	const char *_Nonnull name;
	unsigned long version;
	unsigned long info;
	long instance_size;
	void *_Nullable ivars;
	struct objc_abi_method_list *_Nullable methodlist;
	void *_Nullable dtable;
	void *_Nullable subclass_list;
	void *_Nullable sibling_class;
	void *_Nullable protocols;
	void *_Nullable gc_object_type;
	long abi_version;
	int32_t *_Nonnull *_Nullable ivar_offsets;
	void *_Nullable properties;
};

struct objc_abi_selector {
	const char *_Nonnull name;
	const char *_Nullable types;
};

struct objc_abi_method {
	struct objc_abi_selector sel;
	IMP _Nonnull imp;
};

struct objc_abi_method_list {
	struct objc_abi_method_list *_Nullable next;
	unsigned int count;
	struct objc_abi_method methods[1];
};

struct objc_abi_category {
	const char *_Nonnull category_name;
	const char *_Nonnull class_name;
	struct objc_abi_method_list *_Nullable instance_methods;
	struct objc_abi_method_list *_Nullable class_methods;
	struct objc_protocol_list *_Nullable protocols;
};

struct objc_abi_method_description {
	const char *_Nonnull name;
	const char *_Nonnull types;
};

struct objc_abi_method_description_list {
	int count;
	struct objc_abi_method_description list[1];
};

struct objc_abi_static_instances {
	const char *_Nonnull class_name;
	id _Nullable instances[1];
};

struct objc_abi_symtab {
	unsigned long unknown;
	struct objc_abi_selector *_Nullable sel_refs;
	uint16_t cls_def_cnt;
	uint16_t cat_def_cnt;
	void *_Nonnull defs[1];
};

struct objc_abi_module {
	unsigned long version;	/* 9 = non-fragile */
	unsigned long size;
	const char *_Nullable name;
	struct objc_abi_symtab *_Nonnull symtab;
};

struct objc_hashtable_bucket {
	const void *_Nonnull key, *_Nonnull obj;
	uint32_t hash;
};

struct objc_hashtable {
	uint32_t (*_Nonnull hash)(const void *_Nonnull key);
	bool (*_Nonnull equal)(const void *_Nonnull key1,
	    const void *_Nonnull key2);
	uint32_t count, size;
	struct objc_hashtable_bucket *_Nonnull *_Nullable data;
};

struct objc_sparsearray {
	struct objc_sparsearray_data {
		void *_Nullable next[256];
	} *_Nonnull data;
	uint8_t index_size;
};

struct objc_dtable {
	struct objc_dtable_level2 {
#ifdef OF_SELUID24
		struct objc_dtable_level3 {
			IMP _Nullable buckets[256];
		} *_Nonnull buckets[256];
#else
		IMP _Nullable buckets[256];
#endif
	} *_Nonnull buckets[256];
};

extern void objc_register_all_categories(struct objc_abi_symtab *_Nonnull);
extern struct objc_category *_Nullable *_Nullable
    objc_categories_for_class(Class _Nonnull);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class _Nonnull);
extern void objc_update_dtable(Class _Nonnull);
extern void objc_register_all_classes(struct objc_abi_symtab *_Nonnull);
extern Class _Nullable objc_classname_to_class(const char *_Nonnull, bool);

extern void objc_unregister_class(Class _Nonnull);
extern void objc_unregister_all_classes(void);
extern uint32_t objc_hash_string(const void *_Nonnull);
extern bool objc_equal_string(const void *_Nonnull, const void *_Nonnull);

extern struct objc_hashtable *_Nonnull objc_hashtable_new(
    uint32_t (*_Nonnull)(const void *_Nonnull),

    bool (*_Nonnull)(const void *_Nonnull, const void *_Nonnull), uint32_t);
extern struct objc_hashtable_bucket objc_deleted_bucket;
extern void objc_hashtable_set(struct objc_hashtable *_Nonnull,
    const void *_Nonnull, const void *_Nonnull);
extern void *_Nullable objc_hashtable_get(struct objc_hashtable *_Nonnull,
    const void *_Nonnull);
extern void objc_hashtable_delete(struct objc_hashtable *_Nonnull,
    const void *_Nonnull);
extern void objc_hashtable_free(struct objc_hashtable *_Nonnull);
extern void objc_register_selector(struct objc_abi_selector *_Nonnull);
extern void objc_register_all_selectors(struct objc_abi_symtab *_Nonnull);
extern void objc_unregister_all_selectors(void);
extern struct objc_sparsearray *_Nonnull objc_sparsearray_new(uint8_t);
extern void *_Nullable objc_sparsearray_get(struct objc_sparsearray *_Nonnull,
    uintptr_t);
extern void objc_sparsearray_set(struct objc_sparsearray *_Nonnull, uintptr_t,
    void *_Nullable);
extern void objc_sparsearray_free(struct objc_sparsearray *_Nonnull);
extern struct objc_dtable *_Nonnull objc_dtable_new(void);
extern void objc_dtable_copy(struct objc_dtable *_Nonnull,
    struct objc_dtable *_Nonnull);
extern void objc_dtable_set(struct objc_dtable *_Nonnull, uint32_t,
    IMP _Nullable);
extern void objc_dtable_free(struct objc_dtable *_Nonnull);
extern void objc_dtable_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab *_Nonnull);
extern void objc_forget_pending_static_instances(void);
#ifdef OF_HAVE_THREADS
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
#else
# define objc_global_mutex_lock()
# define objc_global_mutex_unlock()
# define objc_global_mutex_free()
#endif

static inline IMP _Nullable
objc_dtable_get(const struct objc_dtable *_Nonnull dtable, uint32_t idx)
{
#ifdef OF_SELUID24
	uint8_t i = idx >> 16;
	uint8_t j = idx >> 8;
	uint8_t k = idx;

	return dtable->buckets[i]->buckets[j]->buckets[k];
#else
	uint8_t i = idx >> 8;
	uint8_t j = idx;

222
223
224
225
226
227
228
229
230
231
#define OBJC_ERROR(...)							\
	{								\
		fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__);	\
		fprintf(stderr, __VA_ARGS__);				\
		fputs("\n", stderr);					\
		abort();						\
	}

#undef OBJC_NONNULL
#undef OBJC_NULLABLE







<
<
<
220
221
222
223
224
225
226



#define OBJC_ERROR(...)							\
	{								\
		fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__);	\
		fprintf(stderr, __VA_ARGS__);				\
		fputs("\n", stderr);					\
		abort();						\
	}