-
Notifications
You must be signed in to change notification settings - Fork 119
/
objc_msgSend.x86-32.S
132 lines (120 loc) · 3.58 KB
/
objc_msgSend.x86-32.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
.macro MSGSEND receiver, sel, fpret
.cfi_startproc
movl \receiver(%esp), %eax
test %eax, %eax # If the receiver is nil
jz 4f # return nil
test $SMALLOBJ_MASK, %eax # Check if the receiver is a small object
jnz 6f # Get the small object class
mov (%eax), %eax # Load the class
1: # classLoaded
movl \sel(%esp), %ecx
mov DTABLE_OFFSET(%eax), %eax # Load the dtable from the class
mov (%ecx), %ecx # Load the selector index
# Register use at this point:
# %eax: dtable
# %ecx: Selector index
# %edx: selector index fragment
mov SHIFT_OFFSET(%eax), %edx # Load the shift (dtable size)
cmpl $8, %edx # If this is a small dtable, jump to the small dtable handlers
je 2f
cmpl $0, %edx
je 3f
mov %ecx, %edx
shrl $16, %edx
movl DATA_OFFSET(%eax, %edx, 4), %eax
2: # dtable16:
movzbl %ch, %edx
movl DATA_OFFSET(%eax, %edx, 4), %eax
3: # dtable8:
movzbl %cl, %edx
movl DATA_OFFSET(%eax, %edx, 4), %eax
test %eax, %eax
jz 5f # Nil slot - invoke some kind of forwarding mechanism
mov SLOT_OFFSET(%eax), %ecx
#ifdef _MSC_VER
call *CDECL(__guard_check_icall_fptr)
#endif
jmp *%ecx
4: # returnNil:
.if \fpret
fldz
.else
xor %eax, %eax # return 0 (int)
xor %edx, %edx # Return 64-bit zero (%edx is
# caller-save, so it's safe to do this in the general case.
.endif
ret
5: # slowSend:
mov \sel(%esp), %ecx
lea \receiver(%esp), %eax
push %ecx # Unused, stack alignment
push %ecx # _cmd
push %eax # &self
.cfi_def_cfa_offset 16
call CDECL(slowMsgLookup)@PLT
add $12, %esp # restore the stack
#ifdef _MSC_VER
mov %eax, %ecx
call *CDECL(__guard_check_icall_fptr)
jmp *%ecx
#else
jmp *%eax
#endif
6: # smallObject:
push %ebx # Save old %ebx
calll 7f
7:
popl %ebx;
8:
#if __ELF__
# ELF can support GOT-relative addressing;
# PE/COFF and Mach-O need a text relocation.
addl $_GLOBAL_OFFSET_TABLE_+(8b-7b), %ebx
leal SmallObjectClasses@GOTOFF(%ebx), %eax
#else
leal CDECL(SmallObjectClasses), %eax
#endif
mov (%eax), %eax
popl %ebx
jmp 1b
.cfi_endproc
.endm
#ifdef _WIN32
.text
.def @feat.00;
.scl 3;
.type 0;
.endef
.globl @feat.00
@feat.00 = 1
.def _objc_msgSend;
.scl 2;
.type 32;
.endef
.def _objc_msgSend_fpret;
.scl 2;
.type 32;
.endef
.def _objc_msgSend_stret;
.scl 2;
.type 32;
.endef
#endif
.globl CDECL(objc_msgSend_fpret)
TYPE_DIRECTIVE(CDECL(objc_msgSend_fpret), @function)
CDECL(objc_msgSend_fpret):
MSGSEND 4, 8, 1
.globl CDECL(objc_msgSend)
TYPE_DIRECTIVE(CDECL(objc_msgSend), @function)
CDECL(objc_msgSend):
MSGSEND 4, 8, 0
.globl CDECL(objc_msgSend_stret)
TYPE_DIRECTIVE(CDECL(objc_msgSend_stret), @function)
CDECL(objc_msgSend_stret):
MSGSEND 8, 12, 0
#ifdef _WIN32
.section .drectve,"yn"
EXPORT_SYMBOL(objc_msgSend)
EXPORT_SYMBOL(objc_msgSend_stret)
EXPORT_SYMBOL(objc_msgSend_fpret)
#endif