ObjFW  Check-in [2d8aa8b1e6]

Overview
Comment:runtime: Specify m68k registers for most functions
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2d8aa8b1e652cc87796e9ca2cd8860a28da32efd0f8b1e2ff0187fc31317a107
User & Date: js on 2018-04-29 19:26:23
Other Links: manifest | tags
Context
2018-04-29
20:27
runtime: Add glue functions for Amiga library check-in: 4c72b5544f user: js tags: trunk
19:26
runtime: Specify m68k registers for most functions check-in: 2d8aa8b1e6 user: js tags: trunk
18:41
Build Amiga library on AmigaOS 3 check-in: d739fadf58 user: js tags: trunk
Changes

Modified src/runtime/Makefile from [2422525d6a] to [bedf1cf816].

43
44
45
46
47
48
49
50
51
52
		--clib protos.h		\
		--inline $@

CPPFLAGS += -I. -I.. -I../..				\
	    -DOF_COMPILING_OBJFW_RT			\
	    -DOBJFW_RT_LIB_MAJOR=${OBJFW_RT_LIB_MAJOR}	\
	    -DOBJFW_RT_LIB_MINOR=${OBJFW_RT_LIB_MINOR}
AMIGA_LIB_CFLAGS += -DOF_AMIGA_LIBRARY
LD = ${OBJC}
FRAMEWORK_LIBS = ${LIBS}







|


43
44
45
46
47
48
49
50
51
52
		--clib protos.h		\
		--inline $@

CPPFLAGS += -I. -I.. -I../..				\
	    -DOF_COMPILING_OBJFW_RT			\
	    -DOBJFW_RT_LIB_MAJOR=${OBJFW_RT_LIB_MAJOR}	\
	    -DOBJFW_RT_LIB_MINOR=${OBJFW_RT_LIB_MINOR}
AMIGA_LIB_CFLAGS += -DOBJC_AMIGA_LIBRARY
LD = ${OBJC}
FRAMEWORK_LIBS = ${LIBS}

Modified src/runtime/ObjFW_RT.fd from [50739d3a7f] to [d70fc3dd9b].

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
objc_sync_exit_inline()(sysv,r12base)
objc_getProperty_inline()(sysv,r12base)
objc_setProperty_inline()(sysv,r12base)
objc_getPropertyStruct_inline()(sysv,r12base)
objc_setPropertyStruct_inline()(sysv,r12base)
objc_enumerationMutation_inline()(sysv,r12base)
* Functions declared in ObjFW_RT.h
sel_registerName()(sysv,r12base)
sel_getName()(sysv,r12base)
sel_isEqual()(sysv,r12base)
objc_allocateClassPair()(sysv,r12base)
objc_registerClassPair()(sysv,r12base)
objc_getClassList()(sysv,r12base)
objc_copyClassList()(sysv,r12base)
class_isMetaClass()(sysv,r12base)
class_getName()(sysv,r12base)
class_getSuperclass()(sysv,r12base)
class_getInstanceSize()(sysv,r12base)
class_respondsToSelector()(sysv,r12base)
class_conformsToProtocol()(sysv,r12base)
class_getMethodImplementation()(sysv,r12base)
class_getMethodImplementation_stret()(sysv,r12base)
class_getMethodTypeEncoding()(sysv,r12base)
class_addMethod()(sysv,r12base)
class_replaceMethod()(sysv,r12base)
object_getClass()(sysv,r12base)
object_setClass()(sysv,r12base)
object_getClassName()(sysv,r12base)
protocol_getName()(sysv,r12base)
protocol_isEqual()(sysv,r12base)
protocol_conformsToProtocol()(sysv,r12base)
objc_exit()(sysv,r12base)
objc_setUncaughtExceptionHandler()(sysv,r12base)
objc_setForwardHandler()(sysv,r12base)
objc_setEnumerationMutationHandler()(sysv,r12base)
objc_zero_weak_references()(sysv,r12base)
##end







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

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
objc_sync_exit_inline()(sysv,r12base)
objc_getProperty_inline()(sysv,r12base)
objc_setProperty_inline()(sysv,r12base)
objc_getPropertyStruct_inline()(sysv,r12base)
objc_setPropertyStruct_inline()(sysv,r12base)
objc_enumerationMutation_inline()(sysv,r12base)
* Functions declared in ObjFW_RT.h
sel_registerName(name)(A0)
sel_getName(sel)(A0)
sel_isEqual(sel1, sel2)(A0/A1)
objc_allocateClassPair(superclass, name, extra_bytes)(A0/A1/D0)
objc_registerClassPair(cls)(A0)
objc_getClassList(buf, count)(A0/D))
objc_copyClassList(len)(A0)
class_isMetaClass(cls)(A0)
class_getName(cls)(A0)
class_getSuperclass(cls)(A0)
class_getInstanceSize(cls)(A0)
class_respondsToSelector(cls, sel)(A0/A1)
class_conformsToProtocol(cls, p)(A0/A1)
class_getMethodImplementation(cls, sel)(A0/A1)
class_getMethodImplementation_stret(cls, sel)(A0/A1)
class_getMethodTypeEncoding(cls, sel)(A0/A1)
class_addMethod(cls, sel, imp, types)(A0/A1/A2/A3)
class_replaceMethod(cls, sel, imp, types)(A0/A1/A2/A3)
object_getClass(obj)(A0)
object_setClass(obj, cls)(A0/A1)
object_getClassName(obj)(A0)
protocol_getName(p)(A0)
protocol_isEqual(a, b)(A0/A1)
protocol_conformsToProtocol(a, b)(A0/A1)
objc_exit()()
objc_setUncaughtExceptionHandler(handler)(A0)
objc_setForwardHandler(forward, forward_stret)(A0/A1)
objc_setEnumerationMutationHandler(handler)(A0)
objc_zero_weak_references(value)(A0)
##end

Modified src/runtime/ObjFW_RT.h from [2b0b102111] to [ab282aaff9].

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#define NO  false

#if defined(__amigaos__) && !defined(__MORPHOS__) && !defined(__amigaos4__)
# define OBJC_M68K_REG(reg) __asm__(reg)
#else
# define OBJC_M68K_REG(reg)
#endif
#ifdef __MORPHOS__
# define OBJC_M68K_FUNC(name, args) name(void)
# define OBJC_M68K_ARG(type, name, reg) type name = (type)reg;
#else
# define OBJC_M68K_FUNC(name, ...) name(__VA_ARGS__)
# define OBJC_M68K_ARG(type, name, reg)
#endif








|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#define NO  false

#if defined(__amigaos__) && !defined(__MORPHOS__) && !defined(__amigaos4__)
# define OBJC_M68K_REG(reg) __asm__(reg)
#else
# define OBJC_M68K_REG(reg)
#endif
#if defined(__MORPHOS__) && defined(OBJC_AMIGA_LIBRARY)
# define OBJC_M68K_FUNC(name, args) name(void)
# define OBJC_M68K_ARG(type, name, reg) type name = (type)reg;
#else
# define OBJC_M68K_FUNC(name, ...) name(__VA_ARGS__)
# define OBJC_M68K_ARG(type, name, reg)
#endif

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


254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
	long count;
	Protocol *__unsafe_unretained _Nonnull list[1];
};

#ifdef __cplusplus
extern "C" {
#endif
extern SEL _Nonnull sel_registerName(const char *_Nonnull);

extern const char *_Nonnull sel_getName(SEL _Nonnull);
extern bool sel_isEqual(SEL _Nonnull, SEL _Nonnull);

extern Class _Nonnull objc_allocateClassPair(Class _Nullable,

    const char *_Nonnull, size_t);

extern void objc_registerClassPair(Class _Nonnull);
extern unsigned int objc_getClassList(Class _Nonnull *_Nullable, unsigned int);


extern Class _Nonnull *_Nonnull objc_copyClassList(unsigned int *_Nullable);

extern bool class_isMetaClass(Class _Nullable);
extern const char *_Nullable class_getName(Class _Nullable);










extern Class _Nullable class_getSuperclass(Class _Nullable);
extern unsigned long class_getInstanceSize(Class _Nullable);
extern bool class_respondsToSelector(Class _Nullable, SEL _Nonnull);
extern bool class_conformsToProtocol(Class _Nullable, Protocol *_Nonnull);
extern IMP _Nullable class_getMethodImplementation(Class _Nullable,
    SEL _Nonnull);
extern IMP _Nullable class_getMethodImplementation_stret(Class _Nullable,

    SEL _Nonnull);
extern const char *_Nullable class_getMethodTypeEncoding(Class _Nullable,

    SEL _Nonnull);
extern bool class_addMethod(Class _Nonnull, SEL _Nonnull, IMP _Nonnull,

    const char *_Nullable);
extern IMP _Nullable class_replaceMethod(Class _Nonnull, SEL _Nonnull,


    IMP _Nonnull, const char *_Nullable);
extern Class _Nullable object_getClass(id _Nullable);
extern Class _Nullable object_setClass(id _Nullable, Class _Nonnull);

extern const char *_Nullable object_getClassName(id _Nullable);

extern const char *_Nonnull protocol_getName(Protocol *_Nonnull);

extern bool protocol_isEqual(Protocol *_Nonnull, Protocol *_Nonnull);

extern bool protocol_conformsToProtocol(Protocol *_Nonnull, Protocol *_Nonnull);


extern void objc_exit(void);
extern _Nullable objc_uncaught_exception_handler
    objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler _Nullable);
extern void objc_setForwardHandler(IMP _Nullable, IMP _Nullable);

extern void objc_setEnumerationMutationHandler(
    objc_enumeration_mutation_handler _Nullable);
extern void objc_zero_weak_references(id _Nonnull);
# ifdef OF_AMIGAOS
extern struct Library *ObjFWRTBase;
# endif

/*
 * Used by the compiler, but can also be called manually.
 *







|
>
|
|
>
|
>
|
>
|
|
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
|
<
<
<
<
|
|
>
|
|
>
|
|
>
|
|
>
>
|
|
|
>
|
>
|
>
|
>
|
>
>



|
|
>

|
|







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
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
	long count;
	Protocol *__unsafe_unretained _Nonnull list[1];
};

#ifdef __cplusplus
extern "C" {
#endif
extern SEL _Nonnull sel_registerName(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern const char *_Nonnull sel_getName(SEL _Nonnull sel OBJC_M68K_REG("a0"));
extern bool sel_isEqual(SEL _Nonnull sel1 OBJC_M68K_REG("a0"),
    SEL _Nonnull sel2 OBJC_M68K_REG("a1"));
extern Class _Nonnull objc_allocateClassPair(
    Class _Nullable superclass OBJC_M68K_REG("a0"),
    const char *_Nonnull name OBJC_M68K_REG("a1"),
    size_t extra_bytes OBJC_M68K_REG("d0"));
extern void objc_registerClassPair(Class _Nonnull cls OBJC_M68K_REG("a0"));
extern unsigned int objc_getClassList(
    Class _Nonnull *_Nullable buf OBJC_M68K_REG("a0"),
    unsigned int count OBJC_M68K_REG("d0"));
extern Class _Nonnull *_Nonnull objc_copyClassList(
    unsigned int *_Nullable OBJC_M68K_REG("a0"));
extern bool class_isMetaClass(Class _Nullable cls OBJC_M68K_REG("a0"));
extern const char *_Nullable class_getName(
    Class _Nullable cls OBJC_M68K_REG("a0"));
extern Class _Nullable class_getSuperclass(
    Class _Nullable cls OBJC_M68K_REG("a0"));
extern unsigned long class_getInstanceSize(
    Class _Nullable cls OBJC_M68K_REG("a0"));
extern bool class_respondsToSelector(Class _Nullable cls OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern bool class_conformsToProtocol(Class _Nullable cls OBJC_M68K_REG("a0"),
    Protocol *_Nonnull p OBJC_M68K_REG("a1"));
extern IMP _Nullable class_getMethodImplementation(
    Class _Nullable cls OBJC_M68K_REG("a0"),




    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nullable class_getMethodImplementation_stret(
    Class _Nullable cls OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern const char *_Nullable class_getMethodTypeEncoding(
    Class _Nullable cls OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern bool class_addMethod(Class _Nonnull cls OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"), IMP _Nonnull imp OBJC_M68K_REG("a2"),
    const char *_Nullable types OBJC_M68K_REG("a3"));
extern IMP _Nullable class_replaceMethod(Class _Nonnull cls OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"),
    IMP _Nonnull imp OBJC_M68K_REG("a2"),
    const char *_Nullable types OBJC_M68K_REG("a3"));
extern Class _Nullable object_getClass(id _Nullable obj OBJC_M68K_REG("a0"));
extern Class _Nullable object_setClass(id _Nullable obj OBJC_M68K_REG("a0"),
    Class _Nonnull OBJC_M68K_REG("a1"));
extern const char *_Nullable object_getClassName(
    id _Nullable obj OBJC_M68K_REG("a0"));
extern const char *_Nonnull protocol_getName(
    Protocol *_Nonnull p OBJC_M68K_REG("a0"));
extern bool protocol_isEqual(Protocol *_Nonnull a OBJC_M68K_REG("a0"),
    Protocol *_Nonnull b OBJC_M68K_REG("a1"));
extern bool protocol_conformsToProtocol(
    Protocol *_Nonnull a OBJC_M68K_REG("a0"),
    Protocol *_Nonnull b OBJC_M68K_REG("a1"));
extern void objc_exit(void);
extern _Nullable objc_uncaught_exception_handler
    objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler _Nullable handler OBJC_M68K_REG("a0"));
extern void objc_setForwardHandler(IMP _Nullable forward OBJC_M68K_REG("a0"),
    IMP _Nullable forward_stret OBJC_M68K_REG("a1"));
extern void objc_setEnumerationMutationHandler(
    objc_enumeration_mutation_handler _Nullable handler OBJC_M68K_REG("a0"));
extern void objc_zero_weak_references(id _Nonnull value OBJC_M68K_REG("a0"));
# ifdef OF_AMIGAOS
extern struct Library *ObjFWRTBase;
# endif

/*
 * Used by the compiler, but can also be called manually.
 *

Modified src/runtime/amiga-library.m from [d7ad72af48] to [27909fb1e5].

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
static BPTR
lib_null(void)
{
	return 0;
}

static void
objc_set_libc(struct objc_libc *libc_)
{
	libc = libc_;

	stdout = libc->stdout;
	stderr = libc->stderr;
}








|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
static BPTR
lib_null(void)
{
	return 0;
}

static void
objc_set_libc(struct objc_libc *libc_ OBJC_M68K_REG("a0"))
{
	libc = libc_;

	stdout = libc->stdout;
	stderr = libc->stderr;
}

Modified src/runtime/arc.m from [50f4a977be] to [13e9a659c3].

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&spinlock))
		OBJC_ERROR("Failed to unlock spinlock!")
#endif
}

void
objc_zero_weak_references(id value)
{
	struct weak_ref *ref;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&spinlock))
		OBJC_ERROR("Failed to lock spinlock!")
#endif







|







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&spinlock))
		OBJC_ERROR("Failed to unlock spinlock!")
#endif
}

void
objc_zero_weak_references(id value OBJC_M68K_REG("a0"))
{
	struct weak_ref *ref;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&spinlock))
		OBJC_ERROR("Failed to lock spinlock!")
#endif

Modified src/runtime/class.m from [8659e5eda9] to [8d78186ef9].

415
416
417
418
419
420
421
422


423
424
425
426
427
428
429
			cls->info |= OBJC_CLASS_INFO_LOADED;
	}

	process_load_queue();
}

Class
objc_allocateClassPair(Class superclass, const char *name, size_t extra_bytes)


{
	struct objc_class *cls, *metaclass;
	Class iter, rootclass = Nil;

	if (extra_bytes > LONG_MAX)
		OBJC_ERROR("extra_bytes out of range!")








|
>
>







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
			cls->info |= OBJC_CLASS_INFO_LOADED;
	}

	process_load_queue();
}

Class
objc_allocateClassPair(Class superclass OBJC_M68K_REG("a0"),
    const char *name OBJC_M68K_REG("a1"),
    size_t extra_bytes OBJC_M68K_REG("d0"))
{
	struct objc_class *cls, *metaclass;
	Class iter, rootclass = Nil;

	if (extra_bytes > LONG_MAX)
		OBJC_ERROR("extra_bytes out of range!")

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
	metaclass->instance_size = (superclass != Nil ?
	    superclass->isa->instance_size : 0) + (long)extra_bytes;

	return cls;
}

void
objc_registerClassPair(Class cls)
{
	objc_global_mutex_lock();

	register_class((struct objc_abi_class *)cls);

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







|







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
	metaclass->instance_size = (superclass != Nil ?
	    superclass->isa->instance_size : 0) + (long)extra_bytes;

	return cls;
}

void
objc_registerClassPair(Class cls OBJC_M68K_REG("a0"))
{
	objc_global_mutex_lock();

	register_class((struct objc_abi_class *)cls);

	if (cls->superclass != Nil) {
		add_subclass(cls);
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
Class
objc_get_class(const char *name)
{
	return objc_getRequiredClass(name);
}

unsigned int
objc_getClassList(Class *buf, unsigned int count)

{
	unsigned int j;
	objc_global_mutex_lock();

	if (buf == NULL)
		return classes_cnt;








|
>







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
Class
objc_get_class(const char *name)
{
	return objc_getRequiredClass(name);
}

unsigned int
objc_getClassList(Class *buf OBJC_M68K_REG("a0"),
    unsigned int count OBJC_M68K_REG("d0"))
{
	unsigned int j;
	objc_global_mutex_lock();

	if (buf == NULL)
		return classes_cnt;

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

	objc_global_mutex_unlock();

	return j;
}

Class *
objc_copyClassList(unsigned int *len)
{
	Class *ret;
	unsigned int count;

	objc_global_mutex_lock();

	if ((ret = malloc((classes_cnt + 1) * sizeof(Class))) == NULL)







|







569
570
571
572
573
574
575
576
577
578
579
580
581
582
583

	objc_global_mutex_unlock();

	return j;
}

Class *
objc_copyClassList(unsigned int *len OBJC_M68K_REG("a0"))
{
	Class *ret;
	unsigned int count;

	objc_global_mutex_lock();

	if ((ret = malloc((classes_cnt + 1) * sizeof(Class))) == NULL)
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
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

	objc_global_mutex_unlock();

	return ret;
}

bool
class_isMetaClass(Class cls)
{
	if (cls == Nil)
		return false;

	return (cls->info & OBJC_CLASS_INFO_METACLASS);
}

const char *
class_getName(Class cls)
{
	if (cls == Nil)
		return "";

	return cls->name;
}

Class
class_getSuperclass(Class cls)
{
	if (cls == Nil)
		return Nil;

	return cls->superclass;
}

unsigned long
class_getInstanceSize(Class cls)
{
	if (cls == Nil)
		return 0;

	return cls->instance_size;
}

IMP
class_getMethodImplementation(Class cls, SEL sel)

{
	/*
	 * We use a dummy object here so that the normal lookup is used, even
	 * though we don't have an object. Doing so is safe, as objc_msg_lookup
	 * does not access the object, but only its class.
	 *
	 * Just looking it up in the dispatch table could result in returning







|








|








|








|








|
>







593
594
595
596
597
598
599
600
601
602
603
604
605
606
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
642
643
644

	objc_global_mutex_unlock();

	return ret;
}

bool
class_isMetaClass(Class cls OBJC_M68K_REG("a0"))
{
	if (cls == Nil)
		return false;

	return (cls->info & OBJC_CLASS_INFO_METACLASS);
}

const char *
class_getName(Class cls OBJC_M68K_REG("a0"))
{
	if (cls == Nil)
		return "";

	return cls->name;
}

Class
class_getSuperclass(Class cls OBJC_M68K_REG("a0"))
{
	if (cls == Nil)
		return Nil;

	return cls->superclass;
}

unsigned long
class_getInstanceSize(Class cls OBJC_M68K_REG("a0"))
{
	if (cls == Nil)
		return 0;

	return cls->instance_size;
}

IMP
class_getMethodImplementation(Class cls OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	/*
	 * We use a dummy object here so that the normal lookup is used, even
	 * though we don't have an object. Doing so is safe, as objc_msg_lookup
	 * does not access the object, but only its class.
	 *
	 * Just looking it up in the dispatch table could result in returning
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
		return NULL;

	dummy.isa = cls;
	return objc_msg_lookup((id)&dummy, sel);
}

IMP
class_getMethodImplementation_stret(Class cls, SEL sel)

{
	/*
	 * Same as above, but use objc_msg_lookup_stret instead, so that the
	 * correct forwarding handler is returned.
	 */
	struct {
		Class isa;







|
>







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
		return NULL;

	dummy.isa = cls;
	return objc_msg_lookup((id)&dummy, sel);
}

IMP
class_getMethodImplementation_stret(Class cls OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	/*
	 * Same as above, but use objc_msg_lookup_stret instead, so that the
	 * correct forwarding handler is returned.
	 */
	struct {
		Class isa;
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731

	cls->methodlist = ml;

	objc_update_dtable(cls);
}

const char *
class_getMethodTypeEncoding(Class cls, SEL sel)

{
	struct objc_method *method;

	if (cls == Nil)
		return NULL;

	objc_global_mutex_lock();







|
>







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

	cls->methodlist = ml;

	objc_update_dtable(cls);
}

const char *
class_getMethodTypeEncoding(Class cls OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	struct objc_method *method;

	if (cls == Nil)
		return NULL;

	objc_global_mutex_lock();
741
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
	if (cls->superclass != Nil)
		return class_getMethodTypeEncoding(cls->superclass, sel);

	return NULL;
}

bool
class_addMethod(Class cls, SEL sel, IMP imp, const char *types)

{
	bool ret;

	objc_global_mutex_lock();

	if (get_method(cls, sel) == NULL) {
		add_method(cls, sel, imp, types);
		ret = true;
	} else
		ret = false;

	objc_global_mutex_unlock();

	return ret;
}

IMP
class_replaceMethod(Class cls, SEL sel, IMP newimp, const char *types)

{
	struct objc_method *method;
	IMP oldimp;

	objc_global_mutex_lock();

	if ((method = get_method(cls, sel)) != NULL) {







|
>

















|
>







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
	if (cls->superclass != Nil)
		return class_getMethodTypeEncoding(cls->superclass, sel);

	return NULL;
}

bool
class_addMethod(Class cls OBJC_M68K_REG("a0"), SEL sel OBJC_M68K_REG("a1"),
    IMP imp OBJC_M68K_REG("a2"), const char *types OBJC_M68K_REG("a3"))
{
	bool ret;

	objc_global_mutex_lock();

	if (get_method(cls, sel) == NULL) {
		add_method(cls, sel, imp, types);
		ret = true;
	} else
		ret = false;

	objc_global_mutex_unlock();

	return ret;
}

IMP
class_replaceMethod(Class cls OBJC_M68K_REG("a0"), SEL sel OBJC_M68K_REG("a1"),
    IMP newimp OBJC_M68K_REG("a2"), const char *types OBJC_M68K_REG("a3"))
{
	struct objc_method *method;
	IMP oldimp;

	objc_global_mutex_lock();

	if ((method = get_method(cls, sel)) != NULL) {
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825

	objc_global_mutex_unlock();

	return oldimp;
}

Class
object_getClass(id obj_)
{
	struct objc_object *obj;

	if (obj_ == nil)
		return Nil;

	obj = (struct objc_object *)obj_;

	return obj->isa;
}

Class
object_setClass(id obj_, Class cls)
{
	struct objc_object *obj;
	Class old;

	if (obj_ == nil)
		return Nil;

	obj = (struct objc_object *)obj_;

	old = obj->isa;
	obj->isa = cls;

	return old;
}

const char *
object_getClassName(id obj)
{
	return class_getName(object_getClass(obj));
}

static void
unregister_class(Class rcls)
{







|












|
















|







789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833

	objc_global_mutex_unlock();

	return oldimp;
}

Class
object_getClass(id obj_ OBJC_M68K_REG("a0"))
{
	struct objc_object *obj;

	if (obj_ == nil)
		return Nil;

	obj = (struct objc_object *)obj_;

	return obj->isa;
}

Class
object_setClass(id obj_ OBJC_M68K_REG("a0"), Class cls OBJC_M68K_REG("a1"))
{
	struct objc_object *obj;
	Class old;

	if (obj_ == nil)
		return Nil;

	obj = (struct objc_object *)obj_;

	old = obj->isa;
	obj->isa = cls;

	return old;
}

const char *
object_getClassName(id obj OBJC_M68K_REG("a0"))
{
	return class_getName(object_getClass(obj));
}

static void
unregister_class(Class rcls)
{

Modified src/runtime/exception.m from [5d641d7c4e] to [f8288a7f27].

755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
	    uncaught_exception_handler != NULL)
		uncaught_exception_handler(object);

	OBJC_ERROR("_Unwind_RaiseException() returned!")
}

objc_uncaught_exception_handler
objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler)

{
	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}








|
>







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
	    uncaught_exception_handler != NULL)
		uncaught_exception_handler(object);

	OBJC_ERROR("_Unwind_RaiseException() returned!")
}

objc_uncaught_exception_handler
objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler handler OBJC_M68K_REG("a0"))
{
	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}

Modified src/runtime/lookup.m from [107b957fe8] to [61e54bb565].

113
114
115
116
117
118
119
120

121
122
123
124
125
126
127

128
129
130
131
132
133
134
objc_method_not_found_stret(id obj, SEL sel)
{
	return common_method_not_found(obj, sel, objc_msg_lookup_stret,
	    forward_handler_stret);
}

void
objc_setForwardHandler(IMP forward, IMP forward_stret)

{
	forward_handler = forward;
	forward_handler_stret = forward_stret;
}

bool
class_respondsToSelector(Class cls, SEL sel)

{
	if (cls == Nil)
		return false;

	return (objc_dtable_get(cls->dtable, (uint32_t)sel->uid) != (IMP)0);
}








|
>






|
>







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
objc_method_not_found_stret(id obj, SEL sel)
{
	return common_method_not_found(obj, sel, objc_msg_lookup_stret,
	    forward_handler_stret);
}

void
objc_setForwardHandler(IMP forward OBJC_M68K_REG("a0"),
    IMP forward_stret OBJC_M68K_REG("a1"))
{
	forward_handler = forward;
	forward_handler_stret = forward_stret;
}

bool
class_respondsToSelector(Class cls OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	if (cls == Nil)
		return false;

	return (objc_dtable_get(cls->dtable, (uint32_t)sel->uid) != (IMP)0);
}

Modified src/runtime/misc.m from [c235fc1cd0] to [938c4e7c92].

31
32
33
34
35
36
37
38

39
40
41
	if (enumeration_mutation_handler != NULL)
		enumeration_mutation_handler(obj);
	else
		OBJC_ERROR("Object was mutated during enumeration!");
}

void
objc_setEnumerationMutationHandler(void (*handler)(id))

{
	enumeration_mutation_handler = handler;
}







|
>



31
32
33
34
35
36
37
38
39
40
41
42
	if (enumeration_mutation_handler != NULL)
		enumeration_mutation_handler(obj);
	else
		OBJC_ERROR("Object was mutated during enumeration!");
}

void
objc_setEnumerationMutationHandler(
    objc_enumeration_mutation_handler handler OBJC_M68K_REG("a0"))
{
	enumeration_mutation_handler = handler;
}

Modified src/runtime/private.h from [376e4a974e] to [3320990765].

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
		} *_Nonnull buckets[256];
#else
		IMP _Nullable buckets[256];
#endif
	} *_Nonnull buckets[256];
};

#ifdef OF_AMIGA_LIBRARY
# undef stdout
# undef stderr
extern struct objc_libc {
	void *(*malloc)(size_t);
	void *(*calloc)(size_t, size_t);
	void *(*realloc)(void *, size_t);
	void (*free)(void *);







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
		} *_Nonnull buckets[256];
#else
		IMP _Nullable buckets[256];
#endif
	} *_Nonnull buckets[256];
};

#ifdef OBJC_AMIGA_LIBRARY
# undef stdout
# undef stderr
extern struct objc_libc {
	void *(*malloc)(size_t);
	void *(*calloc)(size_t, size_t);
	void *(*realloc)(void *, size_t);
	void (*free)(void *);

Modified src/runtime/protocol.m from [373c118537] to [17dd02bdde].

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
#import "ObjFW_RT.h"
#import "private.h"

@implementation Protocol
@end

const char *
protocol_getName(Protocol *p)
{
	return p->name;
}

bool
protocol_isEqual(Protocol *a, Protocol *b)

{
	return (strcmp(protocol_getName(a), protocol_getName(b)) == 0);
}

bool
protocol_conformsToProtocol(Protocol *a, Protocol *b)

{
	if (protocol_isEqual(a, b))
		return true;

	for (struct objc_protocol_list *pl = a->protocol_list;
	    pl != NULL; pl = pl->next)
		for (long i = 0; i < pl->count; i++)
			if (protocol_conformsToProtocol(pl->list[i], b))
				return true;

	return false;
}

bool
class_conformsToProtocol(Class cls, Protocol *p)

{
	struct objc_category **cats;

	if (cls == Nil)
		return false;

	for (struct objc_protocol_list *pl = cls->protocols;







|





|
>





|
>














|
>







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
#import "ObjFW_RT.h"
#import "private.h"

@implementation Protocol
@end

const char *
protocol_getName(Protocol *p OBJC_M68K_REG("a0"))
{
	return p->name;
}

bool
protocol_isEqual(Protocol *a OBJC_M68K_REG("a0"),
    Protocol *b OBJC_M68K_REG("a1"))
{
	return (strcmp(protocol_getName(a), protocol_getName(b)) == 0);
}

bool
protocol_conformsToProtocol(Protocol *a OBJC_M68K_REG("a0"),
    Protocol *b OBJC_M68K_REG("a1"))
{
	if (protocol_isEqual(a, b))
		return true;

	for (struct objc_protocol_list *pl = a->protocol_list;
	    pl != NULL; pl = pl->next)
		for (long i = 0; i < pl->count; i++)
			if (protocol_conformsToProtocol(pl->list[i], b))
				return true;

	return false;
}

bool
class_conformsToProtocol(Class cls OBJC_M68K_REG("a0"),
    Protocol *p OBJC_M68K_REG("a1"))
{
	struct objc_category **cats;

	if (cls == Nil)
		return false;

	for (struct objc_protocol_list *pl = cls->protocols;

Modified src/runtime/selector.m from [c1a16c1dcc] to [7ee8175e8f].

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	rsel->uid = selectors_cnt++;

	objc_hashtable_set(selectors, name, rsel);
	objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, (void *)name);
}

SEL
sel_registerName(const char *name)
{
	const struct objc_abi_selector *rsel;
	struct objc_abi_selector *sel;

	objc_global_mutex_lock();

	if (selectors != NULL &&







|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	rsel->uid = selectors_cnt++;

	objc_hashtable_set(selectors, name, rsel);
	objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, (void *)name);
}

SEL
sel_registerName(const char *name OBJC_M68K_REG("a0"))
{
	const struct objc_abi_selector *rsel;
	struct objc_abi_selector *sel;

	objc_global_mutex_lock();

	if (selectors != NULL &&
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
		return;

	for (sel = symtab->sel_refs; sel->name != NULL; sel++)
		objc_register_selector(sel);
}

const char *
sel_getName(SEL sel)
{
	const char *ret;

	objc_global_mutex_lock();
	ret = objc_sparsearray_get(selector_names, (uint32_t)sel->uid);
	objc_global_mutex_unlock();

	return ret;
}

bool
sel_isEqual(SEL sel1, SEL sel2)
{
	return (sel1->uid == sel2->uid);
}

void
objc_unregister_all_selectors(void)
{







|











|







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

	for (sel = symtab->sel_refs; sel->name != NULL; sel++)
		objc_register_selector(sel);
}

const char *
sel_getName(SEL sel OBJC_M68K_REG("a0"))
{
	const char *ret;

	objc_global_mutex_lock();
	ret = objc_sparsearray_get(selector_names, (uint32_t)sel->uid);
	objc_global_mutex_unlock();

	return ret;
}

bool
sel_isEqual(SEL sel1 OBJC_M68K_REG("a0"), SEL sel2 OBJC_M68K_REG("a1"))
{
	return (sel1->uid == sel2->uid);
}

void
objc_unregister_all_selectors(void)
{