ObjFW  Check-in [dec9500ab6]

Overview
Comment:runtime: Have the Amiga glue the other way around
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: dec9500ab67e9f4858fa213409f4ed6552ea08fb634fe8166a039e0c8da01cad
User & Date: js on 2018-04-30 10:15:50
Other Links: manifest | tags
Context
2018-04-30
10:47
runtime: Replace .fd file with .sfd file check-in: dca587df1f user: js tags: trunk
10:15
runtime: Have the Amiga glue the other way around check-in: dec9500ab6 user: js tags: trunk
2018-04-29
20:27
runtime: Add glue functions for Amiga library check-in: 4c72b5544f user: js tags: trunk
Changes

Modified src/OFSystemInfo.m from [dad22dd462] to [a9b82e1cd3].

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
#if defined(OF_X86_64) || defined(OF_X86)
static OF_INLINE struct x86_regs OF_CONST_FUNC
x86_cpuid(uint32_t eax, uint32_t ecx)
{
	struct x86_regs regs;

# if defined(OF_X86_64_ASM)
	__asm__(
	    "cpuid"
	    : "=a"(regs.eax), "=b"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx)
	    : "a"(eax), "c"(ecx)
	);
# elif defined(OF_X86_ASM)
	/*
	 * This workaround is required by GCC when using -fPIC, as ebx is a
	 * special register in PIC code. Yes, GCC is indeed not able to just
	 * push a register onto the stack before the __asm__ block and to pop
	 * it afterwards.
	 */
	__asm__(
	    "pushl	%%ebx\n\t"
	    "cpuid\n\t"
	    "movl	%%ebx, %1\n\t"
	    "popl	%%ebx"
	    : "=a"(regs.eax), "=r"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx)
	    : "a"(eax), "c"(ecx)
	);







|











|







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
#if defined(OF_X86_64) || defined(OF_X86)
static OF_INLINE struct x86_regs OF_CONST_FUNC
x86_cpuid(uint32_t eax, uint32_t ecx)
{
	struct x86_regs regs;

# if defined(OF_X86_64_ASM)
	__asm__ (
	    "cpuid"
	    : "=a"(regs.eax), "=b"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx)
	    : "a"(eax), "c"(ecx)
	);
# elif defined(OF_X86_ASM)
	/*
	 * This workaround is required by GCC when using -fPIC, as ebx is a
	 * special register in PIC code. Yes, GCC is indeed not able to just
	 * push a register onto the stack before the __asm__ block and to pop
	 * it afterwards.
	 */
	__asm__ (
	    "pushl	%%ebx\n\t"
	    "cpuid\n\t"
	    "movl	%%ebx, %1\n\t"
	    "popl	%%ebx"
	    : "=a"(regs.eax), "=r"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx)
	    : "a"(eax), "c"(ecx)
	);

Modified src/runtime/ObjFW_RT.h from [f934c05953] to [afbf85daff].

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

/*
 * Used by the compiler, but can also be called manually.
 *
 * These declarations are also required to prevent Clang's implicit
 * declarations which include __declspec(dllimport) on Windows.
 */
struct objc_abi_module;
extern void __objc_exec_class(void *_Nonnull module);
extern IMP _Nonnull objc_msg_lookup(id _Nullable obj, SEL _Nonnull sel);
extern IMP _Nonnull objc_msg_lookup_stret(id _Nullable obj, SEL _Nonnull sel);
extern IMP _Nonnull objc_msg_lookup_super(struct objc_super *_Nonnull super,
    SEL _Nonnull sel);
extern IMP _Nonnull objc_msg_lookup_super_stret(
    struct objc_super *_Nonnull super, SEL _Nonnull sel);







<







290
291
292
293
294
295
296

297
298
299
300
301
302
303

/*
 * Used by the compiler, but can also be called manually.
 *
 * These declarations are also required to prevent Clang's implicit
 * declarations which include __declspec(dllimport) on Windows.
 */

extern void __objc_exec_class(void *_Nonnull module);
extern IMP _Nonnull objc_msg_lookup(id _Nullable obj, SEL _Nonnull sel);
extern IMP _Nonnull objc_msg_lookup_stret(id _Nullable obj, SEL _Nonnull sel);
extern IMP _Nonnull objc_msg_lookup_super(struct objc_super *_Nonnull super,
    SEL _Nonnull sel);
extern IMP _Nonnull objc_msg_lookup_super_stret(
    struct objc_super *_Nonnull super, SEL _Nonnull sel);
313
314
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
354
355
356
357
358
359
360
361
362
363
extern void objc_setProperty(id _Nonnull self, SEL _Nonnull _cmd,
    ptrdiff_t offset, id _Nullable value, bool atomic, signed char copy);
extern void objc_getPropertyStruct(void *_Nonnull dest,
    const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong);
extern void objc_setPropertyStruct(void *_Nonnull dest,
    const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong);
extern void objc_enumerationMutation(id _Nonnull obj);

# ifdef OBJC_AMIGA_LIBRARY
extern void glue___objc_exec_class(void *_Nonnull module OBJC_M68K_REG("a0"));
extern IMP _Nonnull glue_objc_msg_lookup(id _Nullable obj OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nonnull glue_objc_msg_lookup_stret(
    id _Nullable obj OBJC_M68K_REG("a0"), SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nonnull glue_objc_msg_lookup_super(
    struct objc_super *_Nonnull super OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nonnull glue_objc_msg_lookup_super_stret(
    struct objc_super *_Nonnull super OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern id _Nullable glue_objc_lookUpClass(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern id _Nullable glue_objc_getClass(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern id _Nonnull glue_objc_getRequiredClass(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern void glue_objc_exception_throw(id _Nullable object OBJC_M68K_REG("a0"));
extern int glue_objc_sync_enter(id _Nullable object OBJC_M68K_REG("a0"));
extern int glue_objc_sync_exit(id _Nullable object OBJC_M68K_REG("a0"));
extern id _Nullable glue_objc_getProperty(id _Nonnull self OBJC_M68K_REG("a0"),
    SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"),
    bool atomic OBJC_M68K_REG("d1"));
extern void glue_objc_setProperty(id _Nonnull self OBJC_M68K_REG("a0"),
    SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"),
    id _Nullable value OBJC_M68K_REG("a2"), bool atomic OBJC_M68K_REG("d1"),
    signed char copy OBJC_M68K_REG("d2"));
extern void glue_objc_getPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"),
    const void *_Nonnull src OBJC_M68K_REG("a1"),
    ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"),
    bool strong OBJC_M68K_REG("d2"));
extern void glue_objc_setPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"),
    const void *_Nonnull src OBJC_M68K_REG("a1"),
    ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"),
    bool strong OBJC_M68K_REG("d2"));
extern void glue_objc_enumerationMutation(id _Nonnull obj OBJC_M68K_REG("a0"));
# endif
#ifdef __cplusplus
}
#endif

#endif







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





312
313
314
315
316
317
318







































319
320
321
322
323
extern void objc_setProperty(id _Nonnull self, SEL _Nonnull _cmd,
    ptrdiff_t offset, id _Nullable value, bool atomic, signed char copy);
extern void objc_getPropertyStruct(void *_Nonnull dest,
    const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong);
extern void objc_setPropertyStruct(void *_Nonnull dest,
    const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong);
extern void objc_enumerationMutation(id _Nonnull obj);







































#ifdef __cplusplus
}
#endif

#endif

Modified src/runtime/amiga-glue.m from [85119172c8] to [742f84c7f3].

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
#include "config.h"

#import "ObjFW_RT.h"
#import "private.h"
#import "macros.h"

void
__objc_exec_class(void *module)
{
	glue___objc_exec_class(module);
}

IMP
objc_msg_lookup(id obj, SEL sel)
{
	return glue_objc_msg_lookup(obj, sel);
}

IMP
objc_msg_lookup_stret(id obj, SEL sel)

{
	return glue_objc_msg_lookup_stret(obj, sel);
}

IMP
objc_msg_lookup_super(struct objc_super *super, SEL sel)

{
	return glue_objc_msg_lookup_super(super, sel);
}

IMP
objc_msg_lookup_super_stret(struct objc_super *super, SEL sel)

{
	return glue_objc_msg_lookup_super_stret(super, sel);
}


id
objc_lookUpClass(const char *name)
{
	return glue_objc_lookUpClass(name);
}

id
objc_getClass(const char *name)
{
	return glue_objc_getClass(name);
}

id
objc_getRequiredClass(const char *name)
{
	return glue_objc_getRequiredClass(name);
}

void
objc_exception_throw(id object)
{
	glue_objc_exception_throw(object);

	OF_UNREACHABLE
}

int
objc_sync_enter(id object)
{
	return glue_objc_sync_enter(object);
}

int
objc_sync_exit(id object)
{
	return glue_objc_sync_exit(object);
}

id
objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic)

{
	return glue_objc_getProperty(self, _cmd, offset, atomic);
}

void
objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, bool atomic,

    signed char copy)
{
	glue_objc_setProperty(self, _cmd, offset, value, atomic, copy);
}

void
objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,

    bool strong)
{
	glue_objc_getPropertyStruct(dest, src, size, atomic, strong);
}

void
objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,

    bool strong)
{
	glue_objc_setPropertyStruct(dest, src, size, atomic, strong);
}

void
objc_enumerationMutation(id obj)
{
	glue_objc_enumerationMutation(obj);
}







|





|

|



|
>

|



|
>

|



|
>

|
<
|
>

|

|



|

|



|

|



|

|





|

|



|

|



|
>

|



|
>
|

|



|
>
|

|



|
>
|

|



|

|

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
#include "config.h"

#import "ObjFW_RT.h"
#import "private.h"
#import "macros.h"

void
glue___objc_exec_class(void *module OBJC_M68K_REG("a0"))
{
	glue___objc_exec_class(module);
}

IMP
glue_objc_msg_lookup(id obj OBJC_M68K_REG("a0"), SEL sel OBJC_M68K_REG("a1"))
{
	return objc_msg_lookup(obj, sel);
}

IMP
glue_objc_msg_lookup_stret(id obj OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	return objc_msg_lookup_stret(obj, sel);
}

IMP
glue_objc_msg_lookup_super(struct objc_super *super OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	return objc_msg_lookup_super(super, sel);
}

IMP
glue_objc_msg_lookup_super_stret(struct objc_super *super OBJC_M68K_REG("a0"),
    SEL sel OBJC_M68K_REG("a1"))
{
	return objc_msg_lookup_super_stret(super, sel);

}

id
glue_objc_lookUpClass(const char *name OBJC_M68K_REG("a0"))
{
	return objc_lookUpClass(name);
}

id
glue_objc_getClass(const char *name OBJC_M68K_REG("a0"))
{
	return objc_getClass(name);
}

id
glue_objc_getRequiredClass(const char *name OBJC_M68K_REG("a0"))
{
	return objc_getRequiredClass(name);
}

void
glue_objc_exception_throw(id object OBJC_M68K_REG("a0"))
{
	objc_exception_throw(object);

	OF_UNREACHABLE
}

int
glue_objc_sync_enter(id object OBJC_M68K_REG("a0"))
{
	return objc_sync_enter(object);
}

int
glue_objc_sync_exit(id object OBJC_M68K_REG("a0"))
{
	return objc_sync_exit(object);
}

id
glue_objc_getProperty(id self OBJC_M68K_REG("a0"), SEL _cmd OBJC_M68K_REG("a1"),
    ptrdiff_t offset OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"))
{
	return objc_getProperty(self, _cmd, offset, atomic);
}

void
glue_objc_setProperty(id self OBJC_M68K_REG("a0"), SEL _cmd OBJC_M68K_REG("a1"),
    ptrdiff_t offset OBJC_M68K_REG("d0"), id value OBJC_M68K_REG("a2"),
    bool atomic OBJC_M68K_REG("d1"), signed char copy OBJC_M68K_REG("d2"))
{
	objc_setProperty(self, _cmd, offset, value, atomic, copy);
}

void
glue_objc_getPropertyStruct(void *dest OBJC_M68K_REG("a0"),
    const void *src OBJC_M68K_REG("a1"), ptrdiff_t size OBJC_M68K_REG("d0"),
    bool atomic OBJC_M68K_REG("d1"), bool strong OBJC_M68K_REG("d2"))
{
	objc_getPropertyStruct(dest, src, size, atomic, strong);
}

void
glue_objc_setPropertyStruct(void *dest OBJC_M68K_REG("a0"),
    const void *src OBJC_M68K_REG("a1"), ptrdiff_t size OBJC_M68K_REG("d0"),
    bool atomic OBJC_M68K_REG("d1"), bool strong OBJC_M68K_REG("d2"))
{
	objc_setPropertyStruct(dest, src, size, atomic, strong);
}

void
glue_objc_enumerationMutation(id obj OBJC_M68K_REG("a0"))
{
	objc_enumerationMutation(obj);
}

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

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

	process_load_queue();

	objc_global_mutex_unlock();
}

id
OBJC_GLUE(objc_lookUpClass, const char *name OBJC_GLUE_M68K_REG("a0"))
{
	Class cls;

	if ((cls = objc_classname_to_class(name, true)) == NULL)
		return Nil;

	if (cls->info & OBJC_CLASS_INFO_SETUP)







|







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

	process_load_queue();

	objc_global_mutex_unlock();
}

id
objc_lookUpClass(const char *name)
{
	Class cls;

	if ((cls = objc_classname_to_class(name, true)) == NULL)
		return Nil;

	if (cls->info & OBJC_CLASS_INFO_SETUP)
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
	if (!(cls->info & OBJC_CLASS_INFO_SETUP))
		return Nil;

	return cls;
}

id
OBJC_GLUE(objc_getClass, const char *name OBJC_GLUE_M68K_REG("a0"))
{
	return OBJC_GLUE(objc_lookUpClass, name);
}

id
OBJC_GLUE(objc_getRequiredClass, const char *name OBJC_GLUE_M68K_REG("a0"))
{
	Class cls;

	if ((cls = OBJC_GLUE(objc_getClass, name)) == Nil)
		OBJC_ERROR("Class %s not found!", name);

	return cls;
}

Class
objc_lookup_class(const char *name)







|

|



|



|







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
	if (!(cls->info & OBJC_CLASS_INFO_SETUP))
		return Nil;

	return cls;
}

id
objc_getClass(const char *name)
{
	return objc_lookUpClass(name);
}

id
objc_getRequiredClass(const char *name)
{
	Class cls;

	if ((cls = objc_getClass(name)) == Nil)
		OBJC_ERROR("Class %s not found!", name);

	return cls;
}

Class
objc_lookup_class(const char *name)

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

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&emergency_exceptions_spinlock))
		OBJC_ERROR("Cannot unlock spinlock!");
#endif
}

void
OBJC_GLUE(objc_exception_throw, id object OBJC_GLUE_M68K_REG("a0"))
{
	struct objc_exception *e = malloc(sizeof(*e));
	bool emergency = false;

	if (e == NULL) {
#ifdef OF_HAVE_THREADS
		if (!of_spinlock_lock(&emergency_exceptions_spinlock))







|







712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&emergency_exceptions_spinlock))
		OBJC_ERROR("Cannot unlock spinlock!");
#endif
}

void
objc_exception_throw(id object)
{
	struct objc_exception *e = malloc(sizeof(*e));
	bool emergency = false;

	if (e == NULL) {
#ifdef OF_HAVE_THREADS
		if (!of_spinlock_lock(&emergency_exceptions_spinlock))

Modified src/runtime/init.m from [efb27b1cf2] to [9ac67071b3].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#include "config.h"

#import "ObjFW_RT.h"
#import "private.h"

void
OBJC_GLUE(__objc_exec_class, void *module_ OBJC_GLUE_M68K_REG("a0"))
{
	struct objc_abi_module *module = module_;

	objc_global_mutex_lock();

	objc_register_all_selectors(module->symtab);
	objc_register_all_classes(module->symtab);







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#include "config.h"

#import "ObjFW_RT.h"
#import "private.h"

void
__objc_exec_class(void *module_)
{
	struct objc_abi_module *module = module_;

	objc_global_mutex_lock();

	objc_register_all_selectors(module->symtab);
	objc_register_all_classes(module->symtab);

Modified src/runtime/lookup.m from [97e097af52] to [61e54bb565].

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
	if (imp == (IMP)0)
		return not_found(obj, sel);

	return imp;
}

IMP
OBJC_GLUE(objc_msg_lookup, id obj OBJC_GLUE_M68K_REG("a0"),
    SEL sel OBJC_GLUE_M68K_REG("a1"))
{
	return common_lookup(obj, sel, objc_method_not_found);
}

IMP
OBJC_GLUE(objc_msg_lookup_stret, id obj OBJC_GLUE_M68K_REG("a0"),
    SEL sel OBJC_GLUE_M68K_REG("a1"))
{
	return common_lookup(obj, sel, objc_method_not_found_stret);
}

static OF_INLINE IMP
common_lookup_super(struct objc_super *super, SEL sel,
    IMP (*not_found)(id, SEL))







|
<





|
<







154
155
156
157
158
159
160
161

162
163
164
165
166
167

168
169
170
171
172
173
174
	if (imp == (IMP)0)
		return not_found(obj, sel);

	return imp;
}

IMP
objc_msg_lookup(id obj, SEL sel)

{
	return common_lookup(obj, sel, objc_method_not_found);
}

IMP
objc_msg_lookup_stret(id obj, SEL sel)

{
	return common_lookup(obj, sel, objc_method_not_found_stret);
}

static OF_INLINE IMP
common_lookup_super(struct objc_super *super, SEL sel,
    IMP (*not_found)(id, SEL))
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	if (imp == (IMP)0)
		return not_found(super->self, sel);

	return imp;
}

IMP
OBJC_GLUE(objc_msg_lookup_super,
    struct objc_super *super OBJC_GLUE_M68K_REG("a0"),
    SEL sel OBJC_GLUE_M68K_REG("a1"))
{
	return common_lookup_super(super, sel, objc_method_not_found);
}

IMP
OBJC_GLUE(objc_msg_lookup_super_stret,
    struct objc_super *super OBJC_GLUE_M68K_REG("a0"),
    SEL sel OBJC_GLUE_M68K_REG("a1"))
{
	return common_lookup_super(super, sel, objc_method_not_found_stret);
}
#endif







|
<
<





|
<
<




183
184
185
186
187
188
189
190


191
192
193
194
195
196


197
198
199
200
	if (imp == (IMP)0)
		return not_found(super->self, sel);

	return imp;
}

IMP
objc_msg_lookup_super(struct objc_super *super, SEL sel)


{
	return common_lookup_super(super, sel, objc_method_not_found);
}

IMP
objc_msg_lookup_super_stret(struct objc_super *super, SEL sel)


{
	return common_lookup_super(super, sel, objc_method_not_found_stret);
}
#endif

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

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#include "ObjFW_RT.h"
#include "private.h"

static objc_enumeration_mutation_handler enumeration_mutation_handler = NULL;

void
OBJC_GLUE(objc_enumerationMutation, id obj OBJC_GLUE_M68K_REG("a0"))
{
	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;
}







|













22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#include "ObjFW_RT.h"
#include "private.h"

static objc_enumeration_mutation_handler enumeration_mutation_handler = NULL;

void
objc_enumerationMutation(id obj)
{
	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 [51fe416316] to [34219e64f0].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#  define _Nonnull
# endif
# ifndef _Nullable
#  define _Nullable
# endif
#endif

#ifdef OBJC_AMIGA_LIBRARY
# define OBJC_GLUE(name, ...) glue_##name(__VA_ARGS__)
# define OBJC_GLUE_M68K_REG(reg) OBJC_M68K_REG(reg)
#else
# define OBJC_GLUE(name, ...) name(__VA_ARGS__)
# define OBJC_GLUE_M68K_REG(reg)
#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;







<
<
<
<
<
<
<
<







25
26
27
28
29
30
31








32
33
34
35
36
37
38
#  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;
154
155
156
157
158
159
160





































161
162
163
164
165
166
167
	int (*fputs)(const char *, FILE *);
	void (*exit)(int);
	void (*abort)(void);
	FILE *stdout;
	FILE *stderr;
} *objc_libc;
extern FILE *stdout, *stderr;





































#endif

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







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







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
	int (*fputs)(const char *, FILE *);
	void (*exit)(int);
	void (*abort)(void);
	FILE *stdout;
	FILE *stderr;
} *objc_libc;
extern FILE *stdout, *stderr;

extern void glue___objc_exec_class(void *_Nonnull module OBJC_M68K_REG("a0"));
extern IMP _Nonnull glue_objc_msg_lookup(id _Nullable obj OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nonnull glue_objc_msg_lookup_stret(
    id _Nullable obj OBJC_M68K_REG("a0"), SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nonnull glue_objc_msg_lookup_super(
    struct objc_super *_Nonnull super OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern IMP _Nonnull glue_objc_msg_lookup_super_stret(
    struct objc_super *_Nonnull super OBJC_M68K_REG("a0"),
    SEL _Nonnull sel OBJC_M68K_REG("a1"));
extern id _Nullable glue_objc_lookUpClass(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern id _Nullable glue_objc_getClass(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern id _Nonnull glue_objc_getRequiredClass(
    const char *_Nonnull name OBJC_M68K_REG("a0"));
extern void glue_objc_exception_throw(id _Nullable object OBJC_M68K_REG("a0"));
extern int glue_objc_sync_enter(id _Nullable object OBJC_M68K_REG("a0"));
extern int glue_objc_sync_exit(id _Nullable object OBJC_M68K_REG("a0"));
extern id _Nullable glue_objc_getProperty(id _Nonnull self OBJC_M68K_REG("a0"),
    SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"),
    bool atomic OBJC_M68K_REG("d1"));
extern void glue_objc_setProperty(id _Nonnull self OBJC_M68K_REG("a0"),
    SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"),
    id _Nullable value OBJC_M68K_REG("a2"), bool atomic OBJC_M68K_REG("d1"),
    signed char copy OBJC_M68K_REG("d2"));
extern void glue_objc_getPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"),
    const void *_Nonnull src OBJC_M68K_REG("a1"),
    ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"),
    bool strong OBJC_M68K_REG("d2"));
extern void glue_objc_setPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"),
    const void *_Nonnull src OBJC_M68K_REG("a1"),
    ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"),
    bool strong OBJC_M68K_REG("d2"));
extern void glue_objc_enumerationMutation(id _Nonnull obj OBJC_M68K_REG("a0"));
#endif

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

Modified src/runtime/property.m from [d73c3bd6a6] to [e9bfb6f639].

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	for (size_t i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			OBJC_ERROR("Failed to initialize spinlocks!")
}
#endif

id
OBJC_GLUE(objc_getProperty, id self OBJC_GLUE_M68K_REG("a0"),
    SEL _cmd OBJC_GLUE_M68K_REG("a1"),
    ptrdiff_t offset OBJC_GLUE_M68K_REG("d0"),
    bool atomic OBJC_GLUE_M68K_REG("d1"))
{
	if (atomic) {
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));







<
<
|
<







37
38
39
40
41
42
43


44

45
46
47
48
49
50
51
	for (size_t i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			OBJC_ERROR("Failed to initialize spinlocks!")
}
#endif

id


objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic)

{
	if (atomic) {
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#endif
	}

	return *(id *)(void *)((char *)self + offset);
}

void
OBJC_GLUE(objc_setProperty, id self OBJC_GLUE_M68K_REG("a0"),
    SEL _cmd OBJC_GLUE_M68K_REG("a1"),
    ptrdiff_t offset OBJC_GLUE_M68K_REG("d0"),
    id value OBJC_GLUE_M68K_REG("a2"), bool atomic OBJC_GLUE_M68K_REG("d1"),
    signed char copy OBJC_GLUE_M68K_REG("d2"))
{
	if (atomic) {
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));







<
<
|
<
|







59
60
61
62
63
64
65


66

67
68
69
70
71
72
73
74
#endif
	}

	return *(id *)(void *)((char *)self + offset);
}

void


objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, bool atomic,

    signed char copy)
{
	if (atomic) {
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
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
	}

	[old release];
}

/* The following methods are only required for GCC >= 4.6 */
void
OBJC_GLUE(objc_getPropertyStruct, void *dest OBJC_GLUE_M68K_REG("a0"),
    const void *src OBJC_GLUE_M68K_REG("a1"),
    ptrdiff_t size OBJC_GLUE_M68K_REG("d0"),
    bool atomic OBJC_GLUE_M68K_REG("d1"), bool strong OBJC_GLUE_M68K_REG("d2"))
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif
		memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif

		return;
	}

	memcpy(dest, src, size);
}

void
OBJC_GLUE(objc_setPropertyStruct, void *dest OBJC_GLUE_M68K_REG("a0"),
    const void *src OBJC_GLUE_M68K_REG("a1"),
    ptrdiff_t size OBJC_GLUE_M68K_REG("d0"),
    bool atomic OBJC_GLUE_M68K_REG("d1"), bool strong OBJC_GLUE_M68K_REG("d2"))
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif







|
<
<
|



















|
<
<
|







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
	}

	[old release];
}

/* The following methods are only required for GCC >= 4.6 */
void
objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,


    bool strong)
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif
		memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif

		return;
	}

	memcpy(dest, src, size);
}

void
objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,


    bool strong)
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
#endif

Modified src/runtime/static-instances.m from [297c42eb6a] to [88afa289a1].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void
objc_init_static_instances(struct objc_abi_symtab *symtab)
{
	struct objc_abi_static_instances **si;

	/* Check if the class for a static instance became available */
	for (size_t i = 0; i < static_instances_cnt; i++) {
		Class cls = OBJC_GLUE(objc_lookUpClass,
		    static_instances[i]->class_name);

		if (cls != Nil) {
			for (id *instances = static_instances[i]->instances;
			    *instances != nil; instances++)
				object_setClass(*instances, cls);

			static_instances_cnt--;







<
|







29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
void
objc_init_static_instances(struct objc_abi_symtab *symtab)
{
	struct objc_abi_static_instances **si;

	/* Check if the class for a static instance became available */
	for (size_t i = 0; i < static_instances_cnt; i++) {

		Class cls = objc_lookUpClass(static_instances[i]->class_name);

		if (cls != Nil) {
			for (id *instances = static_instances[i]->instances;
			    *instances != nil; instances++)
				object_setClass(*instances, cls);

			static_instances_cnt--;
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
	si = (struct objc_abi_static_instances **)
	    symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];

	if (si == NULL)
		return;

	for (; *si != NULL; si++) {
		Class cls = OBJC_GLUE(objc_lookUpClass, (*si)->class_name);

		if (cls != Nil) {
			for (id *instances = (*si)->instances;
			    *instances != nil; instances++)
				object_setClass(*instances, cls);
		} else {
			static_instances = realloc(static_instances,







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
	si = (struct objc_abi_static_instances **)
	    symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];

	if (si == NULL)
		return;

	for (; *si != NULL; si++) {
		Class cls = objc_lookUpClass((*si)->class_name);

		if (cls != Nil) {
			for (id *instances = (*si)->instances;
			    *instances != nil; instances++)
				object_setClass(*instances, cls);
		} else {
			static_instances = realloc(static_instances,

Modified src/runtime/synchronized.m from [0e4fc2baa0] to [9c9179113a].

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
	if (!of_mutex_new(&mutex))
		OBJC_ERROR("Failed to create mutex!")
}
#endif

int
OBJC_GLUE(objc_sync_enter, id object OBJC_GLUE_M68K_REG("a0"))
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock;








|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
	if (!of_mutex_new(&mutex))
		OBJC_ERROR("Failed to create mutex!")
}
#endif

int
objc_sync_enter(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock;

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
		OBJC_ERROR("Failed to lock mutex!");
#endif

	return 0;
}

int
OBJC_GLUE(objc_sync_exit, id object OBJC_GLUE_M68K_REG("a0"))
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock, *last = NULL;








|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
		OBJC_ERROR("Failed to lock mutex!");
#endif

	return 0;
}

int
objc_sync_exit(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock, *last = NULL;