ObjFW  Diff

Differences From Artifact [ecd4869918]:

To Artifact [5e1eae7608]:


64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
64
65
66
67
68
69
70

71
72

73
74
75
76
77
78
79
80







-


-
+







	return YES;
}

static void
register_selectors(struct objc_abi_class *cls)
{
	struct objc_abi_method_list *ml;
	unsigned int i;

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
		for (unsigned int i = 0; i < ml->count; i++)
			objc_register_selector(
			    (struct objc_abi_selector*)&ml->methods[i]);
}

Class
objc_classname_to_class(const char *name, bool cache)
{
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
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







-
-
+
-

-
-
-
-
+
+
+








-
-
+
-

-
-
-
-
+
+
+








	return cls;
}

static void
call_method(Class cls, const char *method)
{
	struct objc_method_list *ml;
	SEL selector;
	SEL selector = sel_registerName(method);
	unsigned int i;

	selector = sel_registerName(method);

	for (ml = cls->isa->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
	for (struct objc_method_list *ml = cls->isa->methodlist;
	    ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
			if (sel_isEqual((SEL)&ml->methods[i].sel, selector))
				((void(*)(id, SEL))ml->methods[i].imp)(cls,
				    selector);
}

static bool
has_load(Class cls)
{
	struct objc_method_list *ml;
	SEL selector;
	SEL selector = sel_registerName("load");
	unsigned int i;

	selector = sel_registerName("load");

	for (ml = cls->isa->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
	for (struct objc_method_list *ml = cls->isa->methodlist;
	    ml != NULL; ml = ml->next)
		for (size_t i = 0; i < ml->count; i++)
			if (sel_isEqual((SEL)&ml->methods[i].sel, selector))
				return true;

	return false;
}

static void
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

201
202
203
204
205
206
207

208
209
210
211
212
213
214

215
216
217

218
219
220
221
222
223
224
225
226
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
201
202
203

204



205
206

207
208
209
210
211
212
213







-











-
+





-
+
-
-




-
+






-
+
-
-
-
+

-







}

void
objc_update_dtable(Class cls)
{
	struct objc_method_list *ml;
	struct objc_category **cats;
	unsigned int i;

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

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

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

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
		for (unsigned int i = 0; i < ml->count; i++)
			objc_dtable_set(cls->dtable,
			    (uint32_t)ml->methods[i].sel.uid,
			    ml->methods[i].imp);

	if ((cats = objc_categories_for_class(cls)) != NULL) {
		for (i = 0; cats[i] != NULL; i++) {
		for (unsigned int i = 0; cats[i] != NULL; i++) {
			unsigned int j;

			ml = (cls->info & OBJC_CLASS_INFO_CLASS ?
			    cats[i]->instance_methods : cats[i]->class_methods);

			for (; ml != NULL; ml = ml->next)
				for (j = 0; j < ml->count; j++)
				for (unsigned int j = 0; j < ml->count; j++)
					objc_dtable_set(cls->dtable,
					    (uint32_t)ml->methods[j].sel.uid,
					    ml->methods[j].imp);
		}
	}

	if (cls->subclass_list != NULL) {
	if (cls->subclass_list != NULL)
		Class *iter;

		for (iter = cls->subclass_list; *iter != NULL; iter++)
		for (Class *iter = cls->subclass_list; *iter != NULL; iter++)
			objc_update_dtable(*iter);
	}
}

static void
add_subclass(Class cls)
{
	size_t i;

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
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







-
-












-
+







-
+







	cls->superclass->subclass_list[i + 1] = Nil;
}


static void
update_ivar_offsets(Class cls)
{
	unsigned i;

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

	if (cls->instance_size > 0)
		return;

	cls->instance_size = -cls->instance_size;

	if (cls->superclass != Nil) {
		cls->instance_size += cls->superclass->instance_size;

		if (cls->ivars != NULL) {
			for (i = 0; i < cls->ivars->count; i++) {
			for (unsigned int i = 0; i < cls->ivars->count; i++) {
				cls->ivars->ivars[i].offset +=
				    cls->superclass->instance_size;
				*cls->ivar_offsets[i] =
				    cls->ivars->ivars[i].offset;
			}
		}
	} else
		for (i = 0; i < cls->ivars->count; i++)
		for (unsigned int i = 0; i < cls->ivars->count; i++)
			*cls->ivar_offsets[i] = cls->ivars->ivars[i].offset;
}

static void
setup_class(Class cls)
{
	const char *superclass;
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
351
352
353
354
355
356
357



358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374







-
-
-
+








-
+








	objc_global_mutex_unlock();
}

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

	for (i = 0; i < symtab->cls_def_cnt; i++) {
	for (uint16_t i = 0; i < symtab->cls_def_cnt; i++) {
		struct objc_abi_class *cls =
		    (struct objc_abi_class*)symtab->defs[i];

		register_class(cls);
		register_selectors(cls);
		register_selectors(cls->metaclass);
	}

	for (i = 0; i < symtab->cls_def_cnt; i++) {
	for (uint16_t i = 0; i < symtab->cls_def_cnt; i++) {
		Class cls = (Class)symtab->defs[i];

		if (has_load(cls)) {
			setup_class(cls);

			if (cls->info & OBJC_CLASS_INFO_SETUP)
				call_load(cls);
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397







-
+







				load_queue[load_queue_cnt++] = cls;
			}
		} else
			cls->info |= OBJC_CLASS_INFO_LOADED;
	}

	/* Process load queue */
	for (i = 0; i < load_queue_cnt; i++) {
	for (size_t i = 0; i < load_queue_cnt; i++) {
		setup_class(load_queue[i]);

		if (load_queue[i]->info & OBJC_CLASS_INFO_SETUP) {
			call_load(load_queue[i]);

			load_queue_cnt--;

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496

497

498
499
500
501
502
503
504
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487







-









+
-
+







{
	return objc_getRequiredClass(name);
}

unsigned int
objc_getClassList(Class *buf, unsigned int count)
{
	uint32_t i;
	unsigned int j;
	objc_global_mutex_lock();

	if (buf == NULL)
		return classes_cnt;

	if (classes_cnt < count)
		count = classes_cnt;

	j = 0;
	for (i = j = 0; i < classes->size; i++) {
	for (uint32_t i = 0; i < classes->size; i++) {
		void *cls;

		if (j >= count) {
			objc_global_mutex_unlock();
			return j;
		}

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
607
608
609
610
611
612
613

614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641







-







-
+












-
+







}

const char*
class_getMethodTypeEncoding(Class cls, SEL sel)
{
	struct objc_method_list *ml;
	struct objc_category **cats;
	unsigned int i;

	if (cls == Nil)
		return NULL;

	objc_global_mutex_lock();

	for (ml = cls->methodlist; ml != NULL; ml = ml->next) {
		for (i = 0; i < ml->count; i++) {
		for (unsigned int i = 0; i < ml->count; i++) {
			if (sel_isEqual((SEL)&ml->methods[i].sel, sel)) {
				const char *ret = ml->methods[i].sel.types;
				objc_global_mutex_unlock();
				return ret;
			}
		}
	}

	if ((cats = objc_categories_for_class(cls)) != NULL) {
		for (; *cats != NULL; cats++) {
			for (ml = (*cats)->instance_methods; ml != NULL;
			    ml = ml->next) {
				for (i = 0; i < ml->count; i++) {
				for (unsigned int i = 0; i < ml->count; i++) {
					if (ml->methods[i].sel.uid ==
					    sel->uid) {
						const char *ret =
						    ml->methods[i].sel.types;
						objc_global_mutex_unlock();
						return ret;
					}
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
653
654
655
656
657
658
659

660
661
662
663
664

665
666
667
668
669
670
671
672







-





-
+







}

IMP
class_replaceMethod(Class cls, SEL sel, IMP newimp, const char *types)
{
	struct objc_method_list *ml;
	struct objc_category **cats;
	unsigned int i;
	IMP oldimp;

	objc_global_mutex_lock();

	for (ml = cls->methodlist; ml != NULL; ml = ml->next) {
		for (i = 0; i < ml->count; i++) {
		for (unsigned int i = 0; i < ml->count; i++) {
			if (ml->methods[i].sel.uid == sel->uid) {
				oldimp = ml->methods[i].imp;

				ml->methods[i].imp = newimp;
				objc_update_dtable(cls);

				objc_global_mutex_unlock();
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694







-
+







		for (; *cats != NULL; cats++) {
			if (cls->info & OBJC_CLASS_INFO_METACLASS)
				ml = (*cats)->class_methods;
			else
				ml = (*cats)->instance_methods;

			for (; ml != NULL; ml = ml->next) {
				for (i = 0; i < ml->count; i++) {
				for (unsigned int i = 0; i < ml->count; i++) {
					if (ml->methods[i].sel.uid ==
					    sel->uid) {
						oldimp = ml->methods[i].imp;

						ml->methods[i].imp = newimp;
						objc_update_dtable(cls);

838
839
840
841
842
843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
819
820
821
822
823
824
825


826
827
828

829
830
831
832
833
834
835
836







-
-



-
+







	unregister_class(cls);
	unregister_class(cls->isa);
}

void
objc_unregister_all_classes(void)
{
	uint32_t i;

	if (classes == NULL)
		return;

	for (i = 0; i < classes->size; i++) {
	for (uint32_t i = 0; i < classes->size; i++) {
		if (classes->data[i] != NULL &&
		    classes->data[i] != &objc_deleted_bucket) {
			void *cls = (Class)classes->data[i]->obj;

			if (cls == Nil || (uintptr_t)cls & 1)
				continue;