ObjFW  Check-in [9713ad857d]

Overview
Comment:Add support for objc_msg_lookup_stret.

The assembly implementations of the lookup and forwarding still need to
be adjusted. Those just alias to the non-stret version for now so that
linking works, meaning the behaviour is still the same as without
support for objc_msg_lookup_stret for now.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9713ad857df830fb5b6b0b3586c7f254f4dcc06b91fb0fdc55ec7de6ef3792b9
User & Date: js on 2013-07-26 15:21:45
Other Links: manifest | tags
Context
2013-07-26
15:21
Add objc_msg_lookup_stret for AMD64/ELF. check-in: a56adbb68e user: js tags: trunk
15:21
Add support for objc_msg_lookup_stret. check-in: 9713ad857d user: js tags: trunk
2013-07-25
23:21
Forwarding: Save FP args when using MIPS/EABI. check-in: 3d98184cc2 user: js tags: trunk
Changes

Modified src/OFObject.m from [fd13e3d461] to [7eff738717].

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
# import "atomic.h"
#elif defined(OF_HAVE_THREADS)
# import "threading.h"
#endif

#if defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR)
extern id of_forward(id, SEL, ...);
# ifdef OF_APPLE_RUNTIME
/*
 * Forwarding for methods returning structs only works with the Apple ABI, as
 * with the GNU ABI, there is no way of knowing if a struct is returned and if
 * so how.
 * As forwardingTargetForSelector: only works for architectures for which
 * assembly has been written anyway, it makes sense to switch to
 * objc_msgSend(_{st,fp}ret) for those architectures to solve this problem.
 */
extern struct stret of_forward_stret(id, SEL, ...);
# endif


#endif

struct pre_ivar {
	int32_t retainCount;
	struct pre_mem *firstMem, *lastMem;
#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	of_spinlock_t retainCountSpinlock;







<
<
<
<
<
<
<
<
<

|
>
>







59
60
61
62
63
64
65









66
67
68
69
70
71
72
73
74
75
76
# import "atomic.h"
#elif defined(OF_HAVE_THREADS)
# import "threading.h"
#endif

#if defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR)
extern id of_forward(id, SEL, ...);









extern struct stret of_forward_stret(id, SEL, ...);
#else
# define of_forward NULL
# define of_forward_stret NULL
#endif

struct pre_ivar {
	int32_t retainCount;
	struct pre_mem *firstMem, *lastMem;
#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	of_spinlock_t retainCountSpinlock;
142
143
144
145
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
197
198
199
200
201
202
	 * never return.
	 */
	abort();
}

#ifdef OF_OBJFW_RUNTIME
static IMP
forward_handler(id obj, SEL sel)
{
	/* Try resolveClassMethod:/resolveInstanceMethod: */
	if (class_isMetaClass(object_getClass(obj))) {
		if ([obj respondsToSelector: @selector(resolveClassMethod:)] &&
		    [obj resolveClassMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveClassMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(obj), sel_getName(sel));
				abort();
			}

			return objc_msg_lookup(obj, sel);
		}
	} else {
		Class c = object_getClass(obj);

		if ([c respondsToSelector: @selector(resolveInstanceMethod:)] &&
		    [c resolveInstanceMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveInstanceMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(object_getClass(obj)),
				    sel_getName(sel));
				abort();
			}

			return objc_msg_lookup(obj, sel);
		}
	}

#ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
	if (class_respondsToSelector(object_getClass(obj),
	    @selector(forwardingTargetForSelector:))) {
		id target = [obj forwardingTargetForSelector: sel];

		if (target != nil && target != obj)
			return (IMP)of_forward;
	}
#endif

	of_method_not_found(obj, sel);
	return NULL;
}














#endif

#ifndef HAVE_OBJC_ENUMERATIONMUTATION
void
objc_enumerationMutation(id object)
{
	enumeration_mutation_handler(object);







|













|















|









|






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







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
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
197
198
199
200
201
202
203
204
205
206
207
208
209
	 * never return.
	 */
	abort();
}

#ifdef OF_OBJFW_RUNTIME
static IMP
common_forward_handler(id obj, SEL sel, IMP (*lookup)(id, SEL), IMP forward)
{
	/* Try resolveClassMethod:/resolveInstanceMethod: */
	if (class_isMetaClass(object_getClass(obj))) {
		if ([obj respondsToSelector: @selector(resolveClassMethod:)] &&
		    [obj resolveClassMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveClassMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(obj), sel_getName(sel));
				abort();
			}

			return lookup(obj, sel);
		}
	} else {
		Class c = object_getClass(obj);

		if ([c respondsToSelector: @selector(resolveInstanceMethod:)] &&
		    [c resolveInstanceMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveInstanceMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(object_getClass(obj)),
				    sel_getName(sel));
				abort();
			}

			return lookup(obj, sel);
		}
	}

#ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
	if (class_respondsToSelector(object_getClass(obj),
	    @selector(forwardingTargetForSelector:))) {
		id target = [obj forwardingTargetForSelector: sel];

		if (target != nil && target != obj)
			return forward;
	}
#endif

	of_method_not_found(obj, sel);
	return NULL;
}

static IMP
forward_handler(id obj, SEL sel)
{
	return common_forward_handler(obj, sel,
	    objc_msg_lookup, (IMP)of_forward);
}

static IMP
forward_handler_stret(id obj, SEL sel)
{
	return common_forward_handler(obj, sel,
	    objc_msg_lookup_stret, (IMP)of_forward_stret);
}
#endif

#ifndef HAVE_OBJC_ENUMERATIONMUTATION
void
objc_enumerationMutation(id object)
{
	enumeration_mutation_handler(object);
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
{
#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__)
	objc_setUncaughtExceptionHandler(uncaught_exception_handler);
#endif

#if defined(OF_OBJFW_RUNTIME)
	objc_forward_handler = forward_handler;

#elif defined(OF_APPLE_RUNTIME) && !defined(__ppc64__)
	objc_setForwardHandler(of_forward, of_forward_stret);
#endif

#ifdef HAVE_OBJC_ENUMERATIONMUTATION
	objc_setEnumerationMutationHandler(enumeration_mutation_handler);
#endif








>
|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
{
#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__)
	objc_setUncaughtExceptionHandler(uncaught_exception_handler);
#endif

#if defined(OF_OBJFW_RUNTIME)
	objc_forward_handler = forward_handler;
	objc_forward_handler_stret = forward_handler_stret;
#elif defined(OF_APPLE_RUNTIME) && defined(HAVE_FORWARDING_TARGET_FOR_SELECTOR)
	objc_setForwardHandler(of_forward, of_forward_stret);
#endif

#ifdef HAVE_OBJC_ENUMERATIONMUTATION
	objc_setEnumerationMutationHandler(enumeration_mutation_handler);
#endif

Modified src/forwarding-amd64-elf.S from [1e1ff32102] to [34de21f7d5].

11
12
13
14
15
16
17

18
19
20

21
22
23
24
25
26
27
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward


.section .text
of_forward:

	pushq	%rbp
	movq	%rsp, %rbp

	/* Save all arguments */
	subq	$0xC0, %rsp	/* 16-byte alignment */
	movq	%rax, -0x8(%rbp)
	movq	%rdi, -0x10(%rbp)







>



>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward
.globl of_forward_stret

.section .text
of_forward:
of_forward_stret: /* FIXME */
	pushq	%rbp
	movq	%rsp, %rbp

	/* Save all arguments */
	subq	$0xC0, %rsp	/* 16-byte alignment */
	movq	%rax, -0x8(%rbp)
	movq	%rdi, -0x10(%rbp)

Modified src/forwarding-arm-elf.S from [dd9bbbc357] to [a8e2abaeb9].

11
12
13
14
15
16
17

18
19
20

21
22
23
24
25
26
27
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward


.section .text
of_forward:

	stmfd	sp!, {r0-r3, lr}
	fstmfdd	sp!, {d0-d7}

	ldr	r1, sel_forwardingTargetForSelector__indirect_L0
.L0:
	add	r1, pc
	stmfd	sp!, {r1}







>



>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward
.globl of_forward_stret

.section .text
of_forward:
of_forward_stret: /* FIXME */
	stmfd	sp!, {r0-r3, lr}
	fstmfdd	sp!, {d0-d7}

	ldr	r1, sel_forwardingTargetForSelector__indirect_L0
.L0:
	add	r1, pc
	stmfd	sp!, {r1}

Modified src/forwarding-mips-elf.S from [6394ce1502] to [2f942a63a8].

11
12
13
14
15
16
17

18
19
20

21
22
23
24
25
26
27
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward


.section .text
of_forward:

#ifdef __PIC__
	lui	$gp, %hi(_gp_disp)
	addiu	$gp, $gp, %lo(_gp_disp)
	addu	$gp, $gp, $t9
#endif

	addiu	$sp, $sp, -72







>



>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward
.globl of_forward_stret

.section .text
of_forward:
of_forward_stret: /* FIXME */
#ifdef __PIC__
	lui	$gp, %hi(_gp_disp)
	addiu	$gp, $gp, %lo(_gp_disp)
	addu	$gp, $gp, $t9
#endif

	addiu	$sp, $sp, -72

Modified src/forwarding-x86-elf.S from [58a26639e3] to [05632c83d2].

11
12
13
14
15
16
17

18
19
20

21
22
23
24
25
26
27
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward


.section .text
of_forward:

	pushl	%ebp
	movl	%esp, %ebp

	pushl	%ebx
	subl	$20, %esp

	call	get_eip







>



>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

.globl of_forward
.globl of_forward_stret

.section .text
of_forward:
of_forward_stret: /* FIXME */
	pushl	%ebp
	movl	%esp, %ebp

	pushl	%ebx
	subl	$20, %esp

	call	get_eip

Modified src/runtime/lookup-asm-amd64-elf.S from [ae968a3a5d] to [ecedf45989].

13
14
15
16
17
18
19

20

21
22
23

24
25
26
27
28
29
30
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup

.globl objc_msg_lookup_super


.section .text
objc_msg_lookup:

	testq	%rdi, %rdi
	jz	ret_nil

	movq	(%rdi), %r8
	movq	64(%r8), %r8

lookup:







>

>



>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
.globl objc_msg_lookup_super_stret

.section .text
objc_msg_lookup:
objc_msg_lookup_stret: /* FIXME */
	testq	%rdi, %rdi
	jz	ret_nil

	movq	(%rdi), %r8
	movq	64(%r8), %r8

lookup:
47
48
49
50
51
52
53

54
55
56
57
58
59
60
ret_nil:
	leaq	nil_method(%rip), %rax
	ret
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:

	movq	(%rdi), %rax
	testq	%rax, %rax
	jz	ret_nil

	movq	8(%rdi), %r8
	movq	64(%r8), %r8
	movq	%rdi, %rax







>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
ret_nil:
	leaq	nil_method(%rip), %rax
	ret
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:
objc_msg_lookup_super_stret: /* FIXME */
	movq	(%rdi), %rax
	testq	%rax, %rax
	jz	ret_nil

	movq	8(%rdi), %r8
	movq	64(%r8), %r8
	movq	%rdi, %rax

Modified src/runtime/lookup-asm-amd64-macho.S from [dffd0702ad] to [81a51cd4d7].

13
14
15
16
17
18
19

20

21
22
23

24
25
26
27
28
29
30
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl _objc_msg_lookup

.globl _objc_msg_lookup_super


.section __TEXT, __text, regular, pure_instructions
_objc_msg_lookup:

	testq	%rdi, %rdi
	jz	ret_nil

	movq	(%rdi), %r8
	movq	64(%r8), %r8

lookup:







>

>



>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl _objc_msg_lookup
.globl _objc_msg_lookup_stret
.globl _objc_msg_lookup_super
.globl _objc_msg_lookup_super_stret

.section __TEXT, __text, regular, pure_instructions
_objc_msg_lookup:
_objc_msg_lookup_stret: /* FIXME */
	testq	%rdi, %rdi
	jz	ret_nil

	movq	(%rdi), %r8
	movq	64(%r8), %r8

lookup:
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
	ret

ret_nil:
	leaq	nil_method(%rip), %rax
	ret

_objc_msg_lookup_super:

	movq	(%rdi), %rax
	testq	%rax, %rax
	jz	ret_nil

	movq	8(%rdi), %r8
	movq	64(%r8), %r8
	movq	%rdi, %rax
	jmp	lookup

nil_method:
	movq	%rdi, %rax
	ret







>












48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
	ret

ret_nil:
	leaq	nil_method(%rip), %rax
	ret

_objc_msg_lookup_super:
_objc_msg_lookup_super_stret: /* FIXME */
	movq	(%rdi), %rax
	testq	%rax, %rax
	jz	ret_nil

	movq	8(%rdi), %r8
	movq	64(%r8), %r8
	movq	%rdi, %rax
	jmp	lookup

nil_method:
	movq	%rdi, %rax
	ret

Modified src/runtime/lookup-asm-arm-elf.S from [7ce2f3e70c] to [031638809a].

13
14
15
16
17
18
19

20

21
22
23

24
25
26
27
28
29
30
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup

.globl objc_msg_lookup_super


.section .text
objc_msg_lookup:

	cmp	r0, #0
	beq	ret_nil

	ldr	r2, [r0, #0]
	ldr	r2, [r2, #32]

lookup:







>

>



>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
.globl objc_msg_lookup_super_stret

.section .text
objc_msg_lookup:
objc_msg_lookup_stret: /* FIXME */
	cmp	r0, #0
	beq	ret_nil

	ldr	r2, [r0, #0]
	ldr	r2, [r2, #32]

lookup:
46
47
48
49
50
51
52

53
54
55
56
57
58
59
ret_nil:
	adr	r0, nil_method
	bx	lr
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:

	ldr	r2, [r0, #0]
	cmp	r0, #0
	beq	ret_nil

	ldr	r2, [r0, #4]
	ldr	r2, [r2, #32]








>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
ret_nil:
	adr	r0, nil_method
	bx	lr
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:
objc_msg_lookup_super_stret: /* FIXME */
	ldr	r2, [r0, #0]
	cmp	r0, #0
	beq	ret_nil

	ldr	r2, [r0, #4]
	ldr	r2, [r2, #32]

Modified src/runtime/lookup-asm-mips-elf.S from [b184c8be25] to [591bc89aea].

13
14
15
16
17
18
19

20

21
22
23

24
25
26
27
28
29
30
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup

.globl objc_msg_lookup_super


.section .text
objc_msg_lookup:

	beqz	$a0, ret_nil

	lw	$t0, 0($a0)
	lw	$t0, 32($t0)

lookup:
#if defined(_MIPSEL)







>

>



>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
.globl objc_msg_lookup_super_stret

.section .text
objc_msg_lookup:
objc_msg_lookup_stret: /* FIXME */
	beqz	$a0, ret_nil

	lw	$t0, 0($a0)
	lw	$t0, 32($t0)

lookup:
#if defined(_MIPSEL)
85
86
87
88
89
90
91

92
93
94
95
96
97
98
	lw	$t9, %call16(objc_not_found_handler)($gp)
	jr	$t9
#endif
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:

	lw	$t0, 0($a0)
	beqz	$t0, ret_nil

	lw	$t0, 4($a0)
	lw	$t0, 32($t0)

	b	lookup







>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
	lw	$t9, %call16(objc_not_found_handler)($gp)
	jr	$t9
#endif
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:
objc_msg_lookup_super_stret: /* FIXME */
	lw	$t0, 0($a0)
	beqz	$t0, ret_nil

	lw	$t0, 4($a0)
	lw	$t0, 32($t0)

	b	lookup

Modified src/runtime/lookup-asm-ppc-elf.S from [247bf7e58a] to [92bdb3856b].

13
14
15
16
17
18
19

20

21
22
23

24
25
26
27
28
29
30
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup

.globl objc_msg_lookup_super


.section .text
objc_msg_lookup:

	cmpwi	%r3, 0
	beq-	ret_nil

	lwz	%r5, 0(%r3)
	lwz	%r5, 32(%r5)

lookup:







>

>



>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
.globl objc_msg_lookup_super_stret

.section .text
objc_msg_lookup:
objc_msg_lookup_stret: /* FIXME */
	cmpwi	%r3, 0
	beq-	ret_nil

	lwz	%r5, 0(%r3)
	lwz	%r5, 32(%r5)

lookup:
54
55
56
57
58
59
60

61
62
63
64
65
66
67
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

forward:
	b	objc_not_found_handler@plt

objc_msg_lookup_super:

	lwz	%r5, 0(%r3)
	cmpwi	%r5, 0
	beq-	ret_nil

	lwz	%r5, 4(%r3)
	lwz	%r5, 32(%r5)








>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

forward:
	b	objc_not_found_handler@plt

objc_msg_lookup_super:
objc_msg_lookup_super_stret: /* FIXME */
	lwz	%r5, 0(%r3)
	cmpwi	%r5, 0
	beq-	ret_nil

	lwz	%r5, 4(%r3)
	lwz	%r5, 32(%r5)

Modified src/runtime/lookup-asm-x86-elf.S from [63ce010867] to [18adc64486].

13
14
15
16
17
18
19

20

21
22
23

24
25
26
27
28
29
30
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup

.globl objc_msg_lookup_super


.section .text
objc_msg_lookup:

	movl	4(%esp), %edx
	testl	%edx, %edx
	jz	ret_nil

	movl	(%edx), %edx
	movl	32(%edx), %edx








>

>



>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
.globl objc_msg_lookup_super_stret

.section .text
objc_msg_lookup:
objc_msg_lookup: /* FIXME */
	movl	4(%esp), %edx
	testl	%edx, %edx
	jz	ret_nil

	movl	(%edx), %edx
	movl	32(%edx), %edx

60
61
62
63
64
65
66

67
68
69
70
71
72
73
get_eip:
	movl	(%esp), %eax
	ret
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:

	movl	4(%esp), %edx
	cmpl	$0, (%edx)
	je	ret_nil

	movl	4(%edx), %edx
	movl	32(%edx), %edx
	jmp	lookup







>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
get_eip:
	movl	(%esp), %eax
	ret
.type objc_msg_lookup, %function
.size objc_msg_lookup, .-objc_msg_lookup

objc_msg_lookup_super:
objc_msg_lookup_super_stret: /* FIXME */
	movl	4(%esp), %edx
	cmpl	$0, (%edx)
	je	ret_nil

	movl	4(%edx), %edx
	movl	32(%edx), %edx
	jmp	lookup

Modified src/runtime/lookup.m from [7a62dc26ba] to [1c3a42c0f8].

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

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

IMP (*objc_forward_handler)(id, SEL) = NULL;


IMP
objc_not_found_handler(id obj, SEL sel)

{
	bool is_class = object_getClass(obj)->info & OBJC_CLASS_INFO_METACLASS;

	if (!(object_getClass(obj)->info & OBJC_CLASS_INFO_INITIALIZED)) {
		Class cls = (is_class ? (Class)obj : object_getClass(obj));

		objc_initialize_class(cls);

		if (!(cls->info & OBJC_CLASS_INFO_SETUP)) {
			if (is_class)
				return objc_msg_lookup(nil, sel);
			else
				OBJC_ERROR("Could not dispatch message for "
				    "incomplete class %s!", cls->name);
		}

		/*
		 * We don't need to handle the case that super was called.
		 * The reason for this is that a call to super is not possible
		 * before a message to the class has been sent and it thus has
		 * been initialized together with its superclasses.
		 */
		return objc_msg_lookup(obj, sel);
	}

	if (objc_forward_handler != NULL)
		return objc_forward_handler(obj, sel);

	OBJC_ERROR("Selector %c[%s] is not implemented for class %s!",
	    (is_class ? '+' : '-'), sel_getName(sel), object_getClassName(obj));
}















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

	return (objc_sparsearray_get(cls->dtable, (uint32_t)sel->uid) != NULL);
}

#ifndef OF_ASM_LOOKUP
static id
nil_method(id self, SEL _cmd)
{
	return nil;
}

IMP
objc_msg_lookup(id obj, SEL sel)
{
	IMP imp;

	if (obj == nil)
		return (IMP)nil_method;

	imp = objc_sparsearray_get(object_getClass(obj)->dtable,
	    (uint32_t)sel->uid);

	if (imp == NULL)
		return objc_not_found_handler(obj, sel);

	return imp;
}

IMP












objc_msg_lookup_super(struct objc_super *super, SEL sel)

{
	IMP imp;

	if (super->self == nil)
		return (IMP)nil_method;

	imp = objc_sparsearray_get(super->cls->dtable, (uint32_t)sel->uid);

	if (imp == NULL)
		return objc_not_found_handler(super->self, sel);

	return imp;
}












#endif







>

|
|
>










|











|


|
|




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

















|
|










|





>
>
>
>
>
>
>
>
>
>
>
>
|
>









|



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

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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdlib.h>

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

IMP (*objc_forward_handler)(id, SEL) = NULL;
IMP (*objc_forward_handler_stret)(id, SEL) = NULL;

static IMP
common_not_found_handler(id obj, SEL sel, IMP (*lookup)(id, SEL),
    IMP (*forward_handler)(id, SEL))
{
	bool is_class = object_getClass(obj)->info & OBJC_CLASS_INFO_METACLASS;

	if (!(object_getClass(obj)->info & OBJC_CLASS_INFO_INITIALIZED)) {
		Class cls = (is_class ? (Class)obj : object_getClass(obj));

		objc_initialize_class(cls);

		if (!(cls->info & OBJC_CLASS_INFO_SETUP)) {
			if (is_class)
				return lookup(nil, sel);
			else
				OBJC_ERROR("Could not dispatch message for "
				    "incomplete class %s!", cls->name);
		}

		/*
		 * We don't need to handle the case that super was called.
		 * The reason for this is that a call to super is not possible
		 * before a message to the class has been sent and it thus has
		 * been initialized together with its superclasses.
		 */
		return lookup(obj, sel);
	}

	if (forward_handler != NULL)
		return forward_handler(obj, sel);

	OBJC_ERROR("Selector %c[%s] is not implemented for class %s!",
	    (is_class ? '+' : '-'), sel_getName(sel), object_getClassName(obj));
}

IMP
objc_not_found_handler(id obj, SEL sel)
{
	return common_not_found_handler(obj, sel, objc_msg_lookup,
	    objc_forward_handler);
}

IMP
objc_not_found_handler_stret(id obj, SEL sel)
{
	return common_not_found_handler(obj, sel, objc_msg_lookup_stret,
	    objc_forward_handler_stret);
}

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

	return (objc_sparsearray_get(cls->dtable, (uint32_t)sel->uid) != NULL);
}

#ifndef OF_ASM_LOOKUP
static id
nil_method(id self, SEL _cmd)
{
	return nil;
}

static OF_INLINE IMP
common_lookup(id obj, SEL sel, IMP (*not_found_handler)(id, SEL))
{
	IMP imp;

	if (obj == nil)
		return (IMP)nil_method;

	imp = objc_sparsearray_get(object_getClass(obj)->dtable,
	    (uint32_t)sel->uid);

	if (imp == NULL)
		return not_found_handler(obj, sel);

	return imp;
}

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

IMP
objc_msg_lookup_stret(id obj, SEL sel)
{
	return common_lookup(obj, sel, objc_not_found_handler_stret);
}

static OF_INLINE IMP
common_lookup_super(struct objc_super *super, SEL sel,
    IMP (*not_found_handler)(id, SEL))
{
	IMP imp;

	if (super->self == nil)
		return (IMP)nil_method;

	imp = objc_sparsearray_get(super->cls->dtable, (uint32_t)sel->uid);

	if (imp == NULL)
		return not_found_handler(super->self, sel);

	return imp;
}

IMP
objc_msg_lookup_super(struct objc_super *super, SEL sel)
{
	return common_lookup_super(super, sel, objc_not_found_handler);
}

IMP
objc_msg_lookup_super_stret(struct objc_super *super, SEL sel)
{
	return common_lookup_super(super, sel, objc_not_found_handler_stret);
}
#endif

Modified src/runtime/runtime.h from [d76a124e2f] to [8b0a6c7397].

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
extern IMP class_getMethodImplementation(Class, SEL);
extern IMP class_replaceMethod(Class, SEL, IMP, const char*);
extern const char* objc_get_type_encoding(Class, SEL);
extern Class object_getClass(id);
extern Class object_setClass(id, Class);
extern const char* object_getClassName(id);
extern IMP objc_msg_lookup(id, SEL);

extern IMP objc_msg_lookup_super(struct objc_super*, SEL);

extern const char* protocol_getName(Protocol*);
extern bool protocol_isEqual(Protocol*, Protocol*);
extern bool protocol_conformsToProtocol(Protocol*, Protocol*);
extern void objc_exit(void);
extern objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler);
extern IMP (*objc_forward_handler)(id, SEL);

extern id objc_autorelease(id);
extern void* objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void*);
extern id _objc_rootAutorelease(id);
#ifdef __cplusplus
}
#endif

#undef OBJC_UNSAFE_UNRETAINED

#endif







>

>







>











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
extern IMP class_getMethodImplementation(Class, SEL);
extern IMP class_replaceMethod(Class, SEL, IMP, const char*);
extern const char* objc_get_type_encoding(Class, SEL);
extern Class object_getClass(id);
extern Class object_setClass(id, Class);
extern const char* object_getClassName(id);
extern IMP objc_msg_lookup(id, SEL);
extern IMP objc_msg_lookup_stret(id, SEL);
extern IMP objc_msg_lookup_super(struct objc_super*, SEL);
extern IMP objc_msg_lookup_super_stret(struct objc_super*, SEL);
extern const char* protocol_getName(Protocol*);
extern bool protocol_isEqual(Protocol*, Protocol*);
extern bool protocol_conformsToProtocol(Protocol*, Protocol*);
extern void objc_exit(void);
extern objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler);
extern IMP (*objc_forward_handler)(id, SEL);
extern IMP (*objc_forward_handler_stret)(id, SEL);
extern id objc_autorelease(id);
extern void* objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void*);
extern id _objc_rootAutorelease(id);
#ifdef __cplusplus
}
#endif

#undef OBJC_UNSAFE_UNRETAINED

#endif