1 #include "objc-private.h"
3 // out-of-band parameter to objc_msgForward
5 #define kFwdMsgSendStret 0
7 // objc_msgSend parameters
10 #define SELECTOR 12[ebp]
11 #define FIRST_ARG 16[ebp]
13 // objc_msgSend_stret parameters
14 #define STRUCT_ADDR 8[ebp]
15 #define SELF_STRET 12[ebp]
16 #define SUPER_STRET 12[ebp]
17 #define SELECTOR_STRET 16[ebp]
19 // objc_super parameter to sendSuper
20 #define super_receiver 0
23 // struct objc_class fields
27 // struct objc_method fields
31 // struct objc_cache fields
36 void *_objc_forward_handler = NULL;
37 void *_objc_forward_stret_handler = NULL;
39 __declspec(naked) Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_imp)
48 // CacheLookup WORD_RETURN, CACHE_GET
58 mov eax, buckets[edi][edx*4]
61 cmp ecx, method_name[eax]
75 cmp ecx, method_imp[eax]
84 __declspec(naked) IMP _cache_getImp(Class cls, SEL sel)
93 // CacheLookup WORD_RETURN, CACHE_GET
103 mov eax, buckets[edi][edx*4]
106 cmp ecx, method_name[eax]
121 mov eax, method_imp[eax]
128 OBJC_EXPORT __declspec(naked) id objc_msgSend(id a, SEL b, ...)
134 // load receiver and selector
138 // check whether receiver is nil
142 // receiver (in eax) is non-nil: search the cache
145 // CacheLookup WORD_RETURN, MSG_SEND
154 mov eax, buckets[edi][edx*4]
157 cmp ecx, method_name[eax]
163 mov eax, method_imp[eax]
170 // cache miss: search method lists
177 // MethodTableLookup WORD_RETURN, MSG_SEND
181 call _class_lookupMethodAndLoadCache3
187 // message send to nil: return zero
189 // eax is already zero
197 OBJC_EXPORT __declspec(naked) double objc_msgSend_fpret(id a, SEL b, ...)
203 // load receiver and selector
207 // check whether receiver is nil
211 // receiver (in eax) is non-nil: search the cache
214 // CacheLookup WORD_RETURN, MSG_SEND
223 mov eax, buckets[edi][edx*4]
226 cmp ecx, method_name[eax]
232 mov eax, method_imp[eax]
239 // cache miss: search method lists
246 // MethodTableLookup WORD_RETURN, MSG_SEND
250 call _class_lookupMethodAndLoadCache3
256 // message send to nil: return zero
265 OBJC_EXPORT __declspec(naked) id objc_msgSendSuper(struct objc_super *a, SEL b, ...)
271 // load class and selector
274 mov edx, super_class[eax]
276 // search the cache (class in edx)
277 // CacheLookup WORD_RETURN, MSG_SENDSUPER
286 mov eax, buckets[edi][edx*4]
289 cmp ecx, method_name[eax]
295 mov eax, method_imp[eax]
299 mov edx, super_receiver[edx]
305 // cache miss: search method lists
311 mov edx, super_receiver[eax]
313 mov eax, super_class[eax]
315 // MethodTableLookup WORD_RETURN, MSG_SENDSUPER
319 call _class_lookupMethodAndLoadCache3
328 OBJC_EXPORT __declspec(naked) void objc_msgSend_stret(void)
334 // load receiver and selector
335 mov ecx, SELECTOR_STRET
338 // check whether receiver is nil
342 // receiver (in eax) is non-nil: search the cache
345 // CacheLookup WORD_RETURN, MSG_SEND
354 mov eax, buckets[edi][edx*4]
357 cmp ecx, method_name[eax]
363 mov eax, method_imp[eax]
366 mov edx, kFwdMsgSendStret
370 // cache miss: search method lists
377 // MethodTableLookup WORD_RETURN, MSG_SEND
381 call _class_lookupMethodAndLoadCache3
383 mov edx, kFwdMsgSendStret
387 // message send to nil: return zero
389 // eax is already zero
397 OBJC_EXPORT __declspec(naked) id objc_msgSendSuper_stret(struct objc_super *a, SEL b, ...)
403 // load class and selector
405 mov ecx, SELECTOR_STRET
406 mov edx, super_class[eax]
408 // search the cache (class in edx)
409 // CacheLookup WORD_RETURN, MSG_SENDSUPER
418 mov eax, buckets[edi][edx*4]
421 cmp ecx, method_name[eax]
427 mov eax, method_imp[eax]
431 mov edx, super_receiver[edx]
433 mov edx, kFwdMsgSendStret
437 // cache miss: search method lists
443 mov edx, super_receiver[eax]
445 mov eax, super_class[eax]
447 // MethodTableLookup WORD_RETURN, MSG_SENDSUPER
451 call _class_lookupMethodAndLoadCache3
453 mov edx, kFwdMsgSendStret
460 OBJC_EXPORT __declspec(naked) id _objc_msgForward(id a, SEL b, ...)
463 mov ecx, _objc_forward_handler
468 OBJC_EXPORT __declspec(naked) id _objc_msgForward_stret(id a, SEL b, ...)
471 mov ecx, _objc_forward_stret_handler
477 __declspec(naked) id _objc_msgForward_cached(id a, SEL b, ...)
480 cmp edx, kFwdMsgSendStret
484 jmp _objc_msgForward_stret
489 OBJC_EXPORT __declspec(naked) void method_invoke(void)
496 mov edx, method_name[ecx]
497 mov eax, method_imp[ecx]
506 OBJC_EXPORT __declspec(naked) void method_invoke_stret(void)
512 mov ecx, SELECTOR_STRET
513 mov edx, method_name[ecx]
514 mov eax, method_imp[ecx]
515 mov SELECTOR_STRET, edx