ObjFW  Diff

Differences From Artifact [886ace82f1]:

To Artifact [16b932ec92]:


24
25
26
27
28
29
30

31
32
33
34
35
36
37
38






39
40
41
42
43
44
45

#import "runtime.h"
#import "runtime-private.h"

static struct objc_hashtable *classes = NULL;
static Class *load_queue = NULL;
static size_t load_queue_cnt = 0;


static void
register_class(struct objc_abi_class *cls)
{
	if (classes == NULL)
		classes = objc_hashtable_alloc(2);

	objc_hashtable_set(classes, cls->name, cls);






}

BOOL
class_registerAlias_np(Class cls, const char *name)
{
	if (classes == NULL)
		return NO;







>








>
>
>
>
>
>







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

#import "runtime.h"
#import "runtime-private.h"

static struct objc_hashtable *classes = NULL;
static Class *load_queue = NULL;
static size_t load_queue_cnt = 0;
static struct objc_sparsearray *empty_dtable = NULL;

static void
register_class(struct objc_abi_class *cls)
{
	if (classes == NULL)
		classes = objc_hashtable_alloc(2);

	objc_hashtable_set(classes, cls->name, cls);

	if (empty_dtable == NULL)
		empty_dtable = objc_sparsearray_new();

	cls->dtable = empty_dtable;
	cls->metaclass->dtable = empty_dtable;
}

BOOL
class_registerAlias_np(Class cls, const char *name)
{
	if (classes == NULL)
		return NO;
126
127
128
129
130
131
132



133
134
135
136
137
138
139
140
void
objc_update_dtable(Class cls)
{
	struct objc_method_list *ml;
	struct objc_category **cats;
	unsigned int i;




	if (cls->dtable == NULL)
		cls->dtable = objc_sparsearray_new();

	if (cls->superclass != Nil)
		objc_sparsearray_copy(cls->dtable, cls->superclass->dtable);

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)







>
>
>
|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
void
objc_update_dtable(Class cls)
{
	struct objc_method_list *ml;
	struct objc_category **cats;
	unsigned int i;

	if (!(cls->info & OBJC_CLASS_INFO_INITIALIZED))
		return;

	if (cls->dtable == empty_dtable)
		cls->dtable = objc_sparsearray_new();

	if (cls->superclass != Nil)
		objc_sparsearray_copy(cls->dtable, cls->superclass->dtable);

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244



245
246






























247
248
249
250
251
252
253
		cls->isa->superclass = super->isa;

		add_subclass(cls);
		add_subclass(cls->isa);
	} else
		cls->isa->superclass = cls;

	objc_update_dtable(cls);
	objc_update_dtable(cls->isa);

	cls->info |= OBJC_CLASS_INFO_SETUP;
	cls->isa->info |= OBJC_CLASS_INFO_SETUP;
}

static void
initialize_class(Class cls)
{
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

	if (cls->superclass)
		initialize_class(cls->superclass);

	/*
	 * Set it first to prevent calling it recursively due to message sends
	 * in the initialize method
	 */
	cls->info |= OBJC_CLASS_INFO_INITIALIZED;
	cls->isa->info |= OBJC_CLASS_INFO_INITIALIZED;




	call_method(cls, "initialize");
}































void
objc_register_all_classes(struct objc_abi_symtab *symtab)
{
	uint_fast32_t i;

	for (i = 0; i < symtab->cls_def_cnt; i++) {







<
<
<




















>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







225
226
227
228
229
230
231



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
		cls->isa->superclass = super->isa;

		add_subclass(cls);
		add_subclass(cls->isa);
	} else
		cls->isa->superclass = cls;




	cls->info |= OBJC_CLASS_INFO_SETUP;
	cls->isa->info |= OBJC_CLASS_INFO_SETUP;
}

static void
initialize_class(Class cls)
{
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

	if (cls->superclass)
		initialize_class(cls->superclass);

	/*
	 * Set it first to prevent calling it recursively due to message sends
	 * in the initialize method
	 */
	cls->info |= OBJC_CLASS_INFO_INITIALIZED;
	cls->isa->info |= OBJC_CLASS_INFO_INITIALIZED;

	objc_update_dtable(cls);
	objc_update_dtable(cls->isa);

	call_method(cls, "initialize");
}

void
objc_initialize_class(Class cls)
{
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

	objc_global_mutex_lock();

	/*
	 * It's possible that two threads try to initialize a class at the same
	 * time. Make sure that the thread which held the lock did not already
	 * initialize it.
	 */
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED) {
		objc_global_mutex_unlock();
		return;
	}

	setup_class(cls);

	if (!(cls->info & OBJC_CLASS_INFO_SETUP)) {
		objc_global_mutex_unlock();
		return;
	}

	initialize_class(cls);

	objc_global_mutex_unlock();
}

void
objc_register_all_classes(struct objc_abi_symtab *symtab)
{
	uint_fast32_t i;

	for (i = 0; i < symtab->cls_def_cnt; i++) {
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
objc_lookup_class(const char *name)
{
	Class cls = objc_classname_to_class(name);

	if (cls == NULL)
		return Nil;

	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
		return cls;

	objc_global_mutex_lock();

	/*
	 * It's possible that two threads try to get a class at the same time.
	 * Make sure that the thread which held the lock did not already
	 * initialize it.
	 */
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED) {
		objc_global_mutex_unlock();
		return cls;
	}

	setup_class(cls);

	if (!(cls->info & OBJC_CLASS_INFO_SETUP)) {
		objc_global_mutex_unlock();
		return Nil;
	}

	initialize_class(cls);

	objc_global_mutex_unlock();

	return cls;
}

Class
objc_get_class(const char *name)
{







|




<
<
<
<
<
<
<
<
<
<


<
|
<
|
|
<
|
<







355
356
357
358
359
360
361
362
363
364
365
366










367
368

369

370
371

372

373
374
375
376
377
378
379
objc_lookup_class(const char *name)
{
	Class cls = objc_classname_to_class(name);

	if (cls == NULL)
		return Nil;

	if (cls->info & OBJC_CLASS_INFO_SETUP)
		return cls;

	objc_global_mutex_lock();











	setup_class(cls);


	objc_global_mutex_unlock();


	if (!(cls->info & OBJC_CLASS_INFO_SETUP))

		return Nil;


	return cls;
}

Class
objc_get_class(const char *name)
{