ObjFW  Check-in [df914ca51d]

Overview
Comment:Correctly update the dtable for the old GNU runtime.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: df914ca51d2a47bd1188118ce623672376c0e4ba0dd5ce964dca33f9cdd7e609
User & Date: js on 2011-07-31 20:03:26
Other Links: manifest | tags
Context
2011-08-01
19:01
Don't use any other classes for +[inheritMethodsFromClass:]. check-in: 7b5b0c8174 user: js tags: trunk
2011-07-31
20:03
Correctly update the dtable for the old GNU runtime. check-in: df914ca51d user: js tags: trunk
19:45
Cleaner -[setImplementation:...] for old GNU runtime. check-in: fbee44d38e user: js tags: trunk
Changes

Modified src/OFObject.m from [c563fc5512] to [7f71e00414].

120
121
122
123
124
125
126



























127
128
129
130
131
132
133
}

/* References for static linking */
void _references_to_categories_of_OFObject(void)
{
	_OFObject_Serialization_reference = 1;
}




























@implementation OFObject
+ (void)load
{
#ifdef NEED_OBJC_SYNC_INIT
	if (!objc_sync_init()) {
		fputs("Runtime error: objc_sync_init() failed!\n", stderr);







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







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
}

/* References for static linking */
void _references_to_categories_of_OFObject(void)
{
	_OFObject_Serialization_reference = 1;
}

#ifdef OF_OLD_GNU_RUNTIME
/*
 * The old GNU runtime is missing functions for changing methods at runtime. It
 * does not even offer a function to update the dtable, so we have to do even
 * that manually. A well designed runtime would not even allow us to touch the
 * dtable, but the old GNU runtime is that crappy that it even forces us to
 * touch it...
 */
static void
update_dtable(Class class)
{
	MethodList_t iter;

	if (class->super_class != Nil)
		update_dtable(class->super_class);

	for (iter = class->methods; iter != NULL; iter = iter->method_next) {
		int i;

		for (i = 0; i < iter->method_count; i++)
			sarray_at_put_safe(class->dtable,
			    (sidx)iter->method_list[i].method_name->sel_id,
			    iter->method_list[i].method_imp);
	}
}
#endif

@implementation OFObject
+ (void)load
{
#ifdef NEED_OBJC_SYNC_INIT
	if (!objc_sync_init()) {
		fputs("Runtime error: objc_sync_init() failed!\n", stderr);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
			if (sel_eq(iter->method_list[i].method_name,
			    selector)) {
				IMP oldImp;

				oldImp = iter->method_list[i].method_imp;
				iter->method_list[i].method_imp = newImp;

				sarray_at_put_safe(
				    ((Class)self->class_pointer)->dtable,
				    (sidx)selector->sel_id, newImp);

				return oldImp;
			}
	}

	assert([self addClassMethod: selector
		   withTypeEncoding: method->method_types







<
|
<







383
384
385
386
387
388
389

390

391
392
393
394
395
396
397
			if (sel_eq(iter->method_list[i].method_name,
			    selector)) {
				IMP oldImp;

				oldImp = iter->method_list[i].method_imp;
				iter->method_list[i].method_imp = newImp;


				update_dtable((Class)self->class_pointer);


				return oldImp;
			}
	}

	assert([self addClassMethod: selector
		   withTypeEncoding: method->method_types
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
			if (sel_eq(iter->method_list[i].method_name,
			    selector)) {
				IMP oldImp;

				oldImp = iter->method_list[i].method_imp;
				iter->method_list[i].method_imp = newImp;

				sarray_at_put_safe(((Class)self)->dtable,
				    (sidx)selector->sel_id, newImp);

				return oldImp;
			}
	}

	assert([self addInstanceMethod: selector
		      withTypeEncoding: method->method_types







|
<







457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
			if (sel_eq(iter->method_list[i].method_name,
			    selector)) {
				IMP oldImp;

				oldImp = iter->method_list[i].method_imp;
				iter->method_list[i].method_imp = newImp;

				update_dtable(self);


				return oldImp;
			}
	}

	assert([self addInstanceMethod: selector
		      withTypeEncoding: method->method_types
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

	methodList->method_list[0].method_name = selector;
	methodList->method_list[0].method_types = typeEncoding;
	methodList->method_list[0].method_imp = implementation;

	((Class)self)->methods = methodList;

	/* Update the dtable */
	sarray_at_put_safe(((Class)self)->dtable,
	    (sidx)selector->sel_id, implementation);

	return YES;
#else
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
#endif
}







|
<
<







529
530
531
532
533
534
535
536


537
538
539
540
541
542
543

	methodList->method_list[0].method_name = selector;
	methodList->method_list[0].method_types = typeEncoding;
	methodList->method_list[0].method_imp = implementation;

	((Class)self)->methods = methodList;

	update_dtable(self);



	return YES;
#else
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
#endif
}
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

	methodList->method_list[0].method_name = selector;
	methodList->method_list[0].method_types = typeEncoding;
	methodList->method_list[0].method_imp = implementation;

	((Class)self->class_pointer)->methods = methodList;

	/* Update the dtable */
	sarray_at_put_safe(((Class)self->class_pointer)->dtable,
	    (sidx)selector->sel_id, implementation);

	return YES;
#else
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
#endif
}







<
|
<







572
573
574
575
576
577
578

579

580
581
582
583
584
585
586

	methodList->method_list[0].method_name = selector;
	methodList->method_list[0].method_types = typeEncoding;
	methodList->method_list[0].method_imp = implementation;

	((Class)self->class_pointer)->methods = methodList;


	update_dtable((Class)self->class_pointer);


	return YES;
#else
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
#endif
}