]> git.saurik.com Git - apple/objc4.git/blob - runtime/Messengers.subproj/objc-msg-simulator-i386.s
objc4-680.tar.gz
[apple/objc4.git] / runtime / Messengers.subproj / objc-msg-simulator-i386.s
1 /*
2 * Copyright (c) 1999-2009 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <TargetConditionals.h>
25 #if defined(__i386__) && TARGET_IPHONE_SIMULATOR
26
27 #include "objc-config.h"
28
29 .data
30
31 // _objc_entryPoints and _objc_exitPoints are used by objc
32 // to get the critical regions for which method caches
33 // cannot be garbage collected.
34
35 .align 2
36 .private_extern _objc_entryPoints
37 _objc_entryPoints:
38 .long _cache_getImp
39 .long _objc_msgSend
40 .long _objc_msgSend_fpret
41 .long _objc_msgSend_stret
42 .long _objc_msgSendSuper
43 .long _objc_msgSendSuper2
44 .long _objc_msgSendSuper_stret
45 .long _objc_msgSendSuper2_stret
46 .long 0
47
48 .private_extern _objc_exitPoints
49 _objc_exitPoints:
50 .long LGetImpExit
51 .long LMsgSendExit
52 .long LMsgSendFpretExit
53 .long LMsgSendStretExit
54 .long LMsgSendSuperExit
55 .long LMsgSendSuper2Exit
56 .long LMsgSendSuperStretExit
57 .long LMsgSendSuper2StretExit
58 .long 0
59
60
61 /********************************************************************
62 * List every exit insn from every messenger for debugger use.
63 * Format:
64 * (
65 * 1 word instruction's address
66 * 1 word type (ENTER or FAST_EXIT or SLOW_EXIT or NIL_EXIT)
67 * )
68 * 1 word zero
69 *
70 * ENTER is the start of a dispatcher
71 * FAST_EXIT is method dispatch
72 * SLOW_EXIT is uncached method lookup
73 * NIL_EXIT is returning zero from a message sent to nil
74 * These must match objc-gdb.h.
75 ********************************************************************/
76
77 #define ENTER 1
78 #define FAST_EXIT 2
79 #define SLOW_EXIT 3
80 #define NIL_EXIT 4
81
82 .section __DATA,__objc_msg_break
83 .globl _gdb_objc_messenger_breakpoints
84 _gdb_objc_messenger_breakpoints:
85 // contents populated by the macros below
86
87 .macro MESSENGER_START
88 4:
89 .section __DATA,__objc_msg_break
90 .long 4b
91 .long ENTER
92 .text
93 .endmacro
94 .macro MESSENGER_END_FAST
95 4:
96 .section __DATA,__objc_msg_break
97 .long 4b
98 .long FAST_EXIT
99 .text
100 .endmacro
101 .macro MESSENGER_END_SLOW
102 4:
103 .section __DATA,__objc_msg_break
104 .long 4b
105 .long SLOW_EXIT
106 .text
107 .endmacro
108 .macro MESSENGER_END_NIL
109 4:
110 .section __DATA,__objc_msg_break
111 .long 4b
112 .long NIL_EXIT
113 .text
114 .endmacro
115
116
117 /********************************************************************
118 * Names for relative labels
119 * DO NOT USE THESE LABELS ELSEWHERE
120 * Reserved labels: 5: 6: 7: 8: 9:
121 ********************************************************************/
122 #define LCacheMiss 5
123 #define LCacheMiss_f 5f
124 #define LCacheMiss_b 5b
125 #define LNilTestDone 6
126 #define LNilTestDone_f 6f
127 #define LNilTestDone_b 6b
128 #define LNilTestSlow 7
129 #define LNilTestSlow_f 7f
130 #define LNilTestSlow_b 7b
131 #define LGetIsaDone 8
132 #define LGetIsaDone_f 8f
133 #define LGetIsaDone_b 8b
134 #define LGetIsaSlow 9
135 #define LGetIsaSlow_f 9f
136 #define LGetIsaSlow_b 9b
137
138 /********************************************************************
139 * Macro parameters
140 ********************************************************************/
141
142 #define NORMAL 0
143 #define FPRET 1
144 #define GETIMP 3
145 #define STRET 4
146 #define SUPER 5
147 #define SUPER_STRET 6
148
149
150 /********************************************************************
151 *
152 * Structure definitions.
153 *
154 ********************************************************************/
155
156 // Offsets from %esp
157 #define self 4
158 #define super 4
159 #define selector 8
160 #define marg_size 12
161 #define marg_list 16
162 #define first_arg 12
163
164 #define struct_addr 4
165
166 #define self_stret 8
167 #define super_stret 8
168 #define selector_stret 12
169 #define marg_size_stret 16
170 #define marg_list_stret 20
171
172 // objc_super parameter to sendSuper
173 #define receiver 0
174 #define class 4
175
176 // Selected field offsets in class structure
177 #define isa 0
178 #define superclass 4
179
180 // Method descriptor
181 #define method_name 0
182 #define method_imp 8
183
184
185 //////////////////////////////////////////////////////////////////////
186 //
187 // ENTRY functionName
188 //
189 // Assembly directives to begin an exported function.
190 //
191 // Takes: functionName - name of the exported function
192 //////////////////////////////////////////////////////////////////////
193
194 .macro ENTRY
195 .text
196 .globl $0
197 .align 2, 0x90
198 $0:
199 .cfi_startproc
200 .endmacro
201
202 .macro STATIC_ENTRY
203 .text
204 .private_extern $0
205 .align 4, 0x90
206 $0:
207 .cfi_startproc
208 .endmacro
209
210 //////////////////////////////////////////////////////////////////////
211 //
212 // END_ENTRY functionName
213 //
214 // Assembly directives to end an exported function. Just a placeholder,
215 // a close-parenthesis for ENTRY, until it is needed for something.
216 //
217 // Takes: functionName - name of the exported function
218 //////////////////////////////////////////////////////////////////////
219
220 .macro END_ENTRY
221 .cfi_endproc
222 .endmacro
223
224
225 /////////////////////////////////////////////////////////////////////
226 //
227 // CacheLookup return-type
228 //
229 // Locate the implementation for a selector in a class method cache.
230 //
231 // Takes:
232 // $0 = NORMAL, FPRET, STRET, SUPER, SUPER_STRET, GETIMP
233 // ecx = selector to search for
234 // edx = class to search
235 //
236 // On exit: ecx clobbered
237 // (found) calls or returns IMP in eax, eq/ne set for forwarding
238 // (not found) jumps to LCacheMiss, class still in edx
239 //
240 /////////////////////////////////////////////////////////////////////
241
242 .macro CacheHit
243
244 // CacheHit must always be preceded by a not-taken `jne` instruction
245 // in case the imp is _objc_msgForward_impcache.
246
247 .if $0 == GETIMP
248 movl 4(%eax), %eax // return imp
249 call 4f
250 4: pop %edx
251 leal __objc_msgSend_uncached_impcache-4b(%edx), %edx
252 cmpl %edx, %eax
253 jne 4f
254 xor %eax, %eax // don't return msgSend_uncached
255 4: ret
256 .elseif $0 == NORMAL || $0 == FPRET
257 // eq already set for forwarding by `jne`
258 MESSENGER_END_FAST
259 jmp *4(%eax) // call imp
260 .elseif $0 == STRET
261 test %eax, %eax // set ne for stret forwarding
262 MESSENGER_END_FAST
263 jmp *4(%eax) // call imp
264 .elseif $0 == SUPER
265 // replace "super" arg with "receiver"
266 movl super(%esp), %ecx // get super structure
267 movl receiver(%ecx), %ecx // get messaged object
268 movl %ecx, super(%esp) // make it the first argument
269 cmp %eax, %eax // set eq for non-stret forwarding
270 MESSENGER_END_FAST
271 jmp *4(%eax) // call imp
272 .elseif $0 == SUPER_STRET
273 // replace "super" arg with "receiver"
274 movl super_stret(%esp), %ecx // get super structure
275 movl receiver(%ecx), %ecx // get messaged object
276 movl %ecx, super_stret(%esp) // make it the first argument
277 test %eax, %eax // set ne for stret forwarding
278 MESSENGER_END_FAST
279 jmp *4(%eax) // call imp
280 .else
281 .abort oops
282 .endif
283
284 .endmacro
285
286
287 .macro CacheLookup
288
289 movzwl 12(%edx), %eax // eax = mask
290 andl %ecx, %eax // eax = SEL & mask
291 shll $$3, %eax // eax = offset = (SEL & mask) * 8
292 addl 8(%edx), %eax // eax = bucket = cache->buckets+offset
293 cmpl (%eax), %ecx // if (bucket->sel != SEL)
294 jne 1f // scan more
295 // The `jne` above sets flags for CacheHit
296 CacheHit $0 // call or return imp
297
298 1:
299 // loop
300 cmpl $$1, (%eax)
301 jbe 3f // if (bucket->sel <= 1) wrap or miss
302
303 addl $$8, %eax // bucket++
304 2:
305 cmpl (%eax), %ecx // if (bucket->sel != sel)
306 jne 1b // scan more
307 // The `jne` above sets flags for CacheHit
308 CacheHit $0 // call or return imp
309
310 3:
311 // wrap or miss
312 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
313 // wrap
314 movl 4(%eax), %eax // bucket->imp is really first bucket
315 jmp 2f
316
317 // Clone scanning loop to miss instead of hang when cache is corrupt.
318 // The slow path may detect any corruption and halt later.
319
320 1:
321 // loop
322 cmpq $$1, (%eax)
323 jbe 3f // if (bucket->sel <= 1) wrap or miss
324
325 addl $$8, %eax // bucket++
326 2:
327 cmpl (%eax), %ecx // if (bucket->sel != sel)
328 jne 1b // scan more
329 // The `jne` above sets flags for CacheHit
330 CacheHit $0 // call or return imp
331
332 3:
333 // double wrap or miss
334 jmp LCacheMiss_f
335
336 .endmacro
337
338
339 /////////////////////////////////////////////////////////////////////
340 //
341 // MethodTableLookup
342 //
343 // Takes:
344 // $0 = NORMAL, FPRET, STRET, SUPER, SUPER_STRET
345 // eax = receiver
346 // ecx = selector
347 // edx = class to search
348 //
349 // On exit: calls IMP, eq/ne set for forwarding
350 //
351 /////////////////////////////////////////////////////////////////////
352
353 .macro MethodTableLookup
354 MESSENGER_END_SLOW
355 pushl %ebp
356 .cfi_def_cfa_offset 8
357 .cfi_offset ebp, -8
358
359 movl %esp, %ebp
360 .cfi_def_cfa_register ebp
361
362 subl $$(8+5*16), %esp
363
364 movdqa %xmm3, 4*16(%esp)
365 movdqa %xmm2, 3*16(%esp)
366 movdqa %xmm1, 2*16(%esp)
367 movdqa %xmm0, 1*16(%esp)
368
369 movl %edx, 8(%esp) // class
370 movl %ecx, 4(%esp) // selector
371 movl %eax, 0(%esp) // receiver
372 call __class_lookupMethodAndLoadCache3
373
374 // imp in eax
375
376 movdqa 4*16(%esp), %xmm3
377 movdqa 3*16(%esp), %xmm2
378 movdqa 2*16(%esp), %xmm1
379 movdqa 1*16(%esp), %xmm0
380
381 leave
382 .cfi_def_cfa esp, 4
383 .cfi_same_value ebp
384
385 .if $0 == SUPER
386 // replace "super" arg with "receiver"
387 movl super(%esp), %ecx // get super structure
388 movl receiver(%ecx), %ecx // get messaged object
389 movl %ecx, super(%esp) // make it the first argument
390 .elseif $0 == SUPER_STRET
391 // replace "super" arg with "receiver"
392 movl super_stret(%esp), %ecx // get super structure
393 movl receiver(%ecx), %ecx // get messaged object
394 movl %ecx, super_stret(%esp) // make it the first argument
395 .endif
396
397 .if $0 == STRET || $0 == SUPER_STRET
398 // set ne (stret) for forwarding; eax != 0
399 test %eax, %eax
400 jmp *%eax // call imp
401 .else
402 // set eq (non-stret) for forwarding
403 cmp %eax, %eax
404 jmp *%eax // call imp
405 .endif
406
407 .endmacro
408
409
410 /////////////////////////////////////////////////////////////////////
411 //
412 // NilTest return-type
413 //
414 // Takes: $0 = NORMAL or FPRET or STRET
415 // eax = receiver
416 //
417 // On exit: Loads non-nil receiver in eax and self(esp) or self_stret(esp),
418 // or returns zero.
419 //
420 // NilTestSupport return-type
421 //
422 // Takes: $0 = NORMAL or FPRET or STRET
423 // eax = receiver
424 //
425 // On exit: Loads non-nil receiver in eax and self(esp) or self_stret(esp),
426 // or returns zero.
427 //
428 /////////////////////////////////////////////////////////////////////
429
430 .macro NilTest
431 testl %eax, %eax
432 jz LNilTestSlow_f
433 LNilTestDone:
434 .endmacro
435
436 .macro NilTestSupport
437 .align 3
438 LNilTestSlow:
439
440 .if $0 == FPRET
441 fldz
442 MESSENGER_END_NIL
443 ret
444 .elseif $0 == STRET
445 MESSENGER_END_NIL
446 ret $$4
447 .elseif $0 == NORMAL
448 // eax is already zero
449 xorl %edx, %edx
450 xorps %xmm0, %xmm0
451 xorps %xmm1, %xmm1
452 MESSENGER_END_NIL
453 ret
454 .endif
455 .endmacro
456
457
458 /********************************************************************
459 * IMP _cache_getImp(Class cls, SEL sel)
460 *
461 * If found, returns method implementation.
462 * If not found, returns NULL.
463 ********************************************************************/
464
465 STATIC_ENTRY _cache_getImp
466
467 // load the class and selector
468 movl selector(%esp), %ecx
469 movl self(%esp), %edx
470
471 CacheLookup GETIMP // returns IMP on success
472
473 LCacheMiss:
474 // cache miss, return nil
475 xorl %eax, %eax
476 ret
477
478 LGetImpExit:
479 END_ENTRY _cache_getImp
480
481
482 /********************************************************************
483 *
484 * id objc_msgSend(id self, SEL _cmd,...);
485 *
486 ********************************************************************/
487
488 ENTRY _objc_msgSend
489 MESSENGER_START
490
491 movl selector(%esp), %ecx
492 movl self(%esp), %eax
493
494 NilTest NORMAL
495
496 movl isa(%eax), %edx // class = self->isa
497 CacheLookup NORMAL // calls IMP on success
498
499 NilTestSupport NORMAL
500
501 LCacheMiss:
502 // isa still in edx
503 movl selector(%esp), %ecx
504 movl self(%esp), %eax
505 MethodTableLookup NORMAL // calls IMP
506
507 LMsgSendExit:
508 END_ENTRY _objc_msgSend
509
510
511 /********************************************************************
512 *
513 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
514 *
515 * struct objc_super {
516 * id receiver;
517 * Class class;
518 * };
519 ********************************************************************/
520
521 ENTRY _objc_msgSendSuper
522 MESSENGER_START
523
524 movl selector(%esp), %ecx
525 movl super(%esp), %eax // struct objc_super
526 movl class(%eax), %edx // struct objc_super->class
527 CacheLookup SUPER // calls IMP on success
528
529 LCacheMiss:
530 // class still in edx
531 movl selector(%esp), %ecx
532 movl super(%esp), %eax
533 movl receiver(%eax), %eax
534 MethodTableLookup SUPER // calls IMP
535
536 LMsgSendSuperExit:
537 END_ENTRY _objc_msgSendSuper
538
539
540 ENTRY _objc_msgSendSuper2
541 MESSENGER_START
542
543 movl selector(%esp), %ecx
544 movl super(%esp), %eax // struct objc_super
545 movl class(%eax), %eax // struct objc_super->class
546 mov superclass(%eax), %edx // edx = objc_super->class->super_class
547 CacheLookup SUPER // calls IMP on success
548
549 LCacheMiss:
550 // class still in edx
551 movl selector(%esp), %ecx
552 movl super(%esp), %eax
553 movl receiver(%eax), %eax
554 MethodTableLookup SUPER // calls IMP
555
556 LMsgSendSuper2Exit:
557 END_ENTRY _objc_msgSendSuper2
558
559
560 /********************************************************************
561 *
562 * double objc_msgSend_fpret(id self, SEL _cmd,...);
563 *
564 ********************************************************************/
565
566 ENTRY _objc_msgSend_fpret
567 MESSENGER_START
568
569 movl selector(%esp), %ecx
570 movl self(%esp), %eax
571
572 NilTest FPRET
573
574 movl isa(%eax), %edx // class = self->isa
575 CacheLookup FPRET // calls IMP on success
576
577 NilTestSupport FPRET
578
579 LCacheMiss:
580 // class still in edx
581 movl selector(%esp), %ecx
582 movl self(%esp), %eax
583 MethodTableLookup FPRET // calls IMP
584
585 LMsgSendFpretExit:
586 END_ENTRY _objc_msgSend_fpret
587
588
589 /********************************************************************
590 *
591 * void objc_msgSend_stret(void *st_addr , id self, SEL _cmd, ...);
592 *
593 *
594 * objc_msgSend_stret is the struct-return form of msgSend.
595 * The ABI calls for (sp+4) to be used as the address of the structure
596 * being returned, with the parameters in the succeeding locations.
597 *
598 * On entry: (sp+4)is the address where the structure is returned,
599 * (sp+8) is the message receiver,
600 * (sp+12) is the selector
601 ********************************************************************/
602
603 ENTRY _objc_msgSend_stret
604 MESSENGER_START
605
606 movl selector_stret(%esp), %ecx
607 movl self_stret(%esp), %eax
608
609 NilTest STRET
610
611 movl isa(%eax), %edx // class = self->isa
612 CacheLookup STRET // calls IMP on success
613
614 NilTestSupport STRET
615
616 LCacheMiss:
617 // class still in edx
618 movl selector_stret(%esp), %ecx
619 movl self_stret(%esp), %eax
620 MethodTableLookup STRET // calls IMP
621
622 LMsgSendStretExit:
623 END_ENTRY _objc_msgSend_stret
624
625
626 /********************************************************************
627 *
628 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
629 *
630 * struct objc_super {
631 * id receiver;
632 * Class class;
633 * };
634 *
635 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
636 * The ABI calls for (sp+4) to be used as the address of the structure
637 * being returned, with the parameters in the succeeding registers.
638 *
639 * On entry: (sp+4)is the address where the structure is returned,
640 * (sp+8) is the address of the objc_super structure,
641 * (sp+12) is the selector
642 *
643 ********************************************************************/
644
645 ENTRY _objc_msgSendSuper_stret
646 MESSENGER_START
647
648 movl selector_stret(%esp), %ecx
649 movl super_stret(%esp), %eax // struct objc_super
650 movl class(%eax), %edx // struct objc_super->class
651 CacheLookup SUPER_STRET // calls IMP on success
652
653 LCacheMiss:
654 // class still in edx
655 movl selector_stret(%esp), %ecx
656 movl super_stret(%esp), %eax
657 movl receiver(%eax), %eax
658 MethodTableLookup SUPER_STRET // calls IMP
659
660 LMsgSendSuperStretExit:
661 END_ENTRY _objc_msgSendSuper_stret
662
663
664 ENTRY _objc_msgSendSuper2_stret
665 MESSENGER_START
666
667 movl selector_stret(%esp), %ecx
668 movl super_stret(%esp), %eax // struct objc_super
669 movl class(%eax), %eax // struct objc_super->class
670 mov superclass(%eax), %edx // edx = objc_super->class->super_class
671 CacheLookup SUPER_STRET // calls IMP on success
672
673 // cache miss: go search the method lists
674 LCacheMiss:
675 // class still in edx
676 movl selector_stret(%esp), %ecx
677 movl super_stret(%esp), %eax
678 movl receiver(%eax), %eax
679 MethodTableLookup SUPER_STRET // calls IMP
680
681 LMsgSendSuper2StretExit:
682 END_ENTRY _objc_msgSendSuper2_stret
683
684
685 /********************************************************************
686 *
687 * _objc_msgSend_uncached_impcache
688 * _objc_msgSend_uncached
689 * _objc_msgSend_stret_uncached
690 *
691 * Used to erase method cache entries in-place by
692 * bouncing them to the uncached lookup.
693 *
694 ********************************************************************/
695
696 STATIC_ENTRY __objc_msgSend_uncached_impcache
697 // Method cache version
698
699 // THIS IS NOT A CALLABLE C FUNCTION
700 // Out-of-band condition register is NE for stret, EQ otherwise.
701 // Out-of-band edx is the searched class
702
703 MESSENGER_START
704 nop
705 MESSENGER_END_SLOW
706
707 jne __objc_msgSend_stret_uncached
708 jmp __objc_msgSend_uncached
709
710 END_ENTRY __objc_msgSend_uncached_impcache
711
712
713 STATIC_ENTRY __objc_msgSend_uncached
714
715 // THIS IS NOT A CALLABLE C FUNCTION
716 // Out-of-band edx is the searched class
717
718 // edx is already the class to search
719 movl selector(%esp), %ecx
720 MethodTableLookup NORMAL // calls IMP
721
722 END_ENTRY __objc_msgSend_uncached
723
724
725 STATIC_ENTRY __objc_msgSend_stret_uncached
726
727 // THIS IS NOT A CALLABLE C FUNCTION
728 // Out-of-band edx is the searched class
729
730 // edx is already the class to search
731 movl selector_stret(%esp), %ecx
732 MethodTableLookup STRET // calls IMP
733
734 END_ENTRY __objc_msgSend_stret_uncached
735
736
737
738 /********************************************************************
739 *
740 * id _objc_msgForward(id self, SEL _cmd,...);
741 *
742 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
743 * functions returned by things like method_getImplementation().
744 * _objc_msgForward_impcache is the function pointer actually stored in
745 * method caches.
746 *
747 ********************************************************************/
748
749 .non_lazy_symbol_pointer
750 L_forward_handler:
751 .indirect_symbol __objc_forward_handler
752 .long 0
753 L_forward_stret_handler:
754 .indirect_symbol __objc_forward_stret_handler
755 .long 0
756
757 STATIC_ENTRY __objc_msgForward_impcache
758 // Method cache version
759
760 // THIS IS NOT A CALLABLE C FUNCTION
761 // Out-of-band condition register is NE for stret, EQ otherwise.
762
763 MESSENGER_START
764 nop
765 MESSENGER_END_SLOW
766
767 jne __objc_msgForward_stret
768 jmp __objc_msgForward
769
770 END_ENTRY _objc_msgForward_impcache
771
772
773 ENTRY __objc_msgForward
774 // Non-struct return version
775
776 call 1f
777 1: popl %edx
778 movl L_forward_handler-1b(%edx), %edx
779 jmp *(%edx)
780
781 END_ENTRY __objc_msgForward
782
783
784 ENTRY __objc_msgForward_stret
785 // Struct return version
786
787 call 1f
788 1: popl %edx
789 movl L_forward_stret_handler-1b(%edx), %edx
790 jmp *(%edx)
791
792 END_ENTRY __objc_msgForward_stret
793
794
795 ENTRY _objc_msgSend_debug
796 jmp _objc_msgSend
797 END_ENTRY _objc_msgSend_debug
798
799 ENTRY _objc_msgSendSuper2_debug
800 jmp _objc_msgSendSuper2
801 END_ENTRY _objc_msgSendSuper2_debug
802
803 ENTRY _objc_msgSend_stret_debug
804 jmp _objc_msgSend_stret
805 END_ENTRY _objc_msgSend_stret_debug
806
807 ENTRY _objc_msgSendSuper2_stret_debug
808 jmp _objc_msgSendSuper2_stret
809 END_ENTRY _objc_msgSendSuper2_stret_debug
810
811 ENTRY _objc_msgSend_fpret_debug
812 jmp _objc_msgSend_fpret
813 END_ENTRY _objc_msgSend_fpret_debug
814
815
816 ENTRY _objc_msgSend_noarg
817 jmp _objc_msgSend
818 END_ENTRY _objc_msgSend_noarg
819
820
821 ENTRY _method_invoke
822
823 movl selector(%esp), %ecx
824 movl method_name(%ecx), %edx
825 movl method_imp(%ecx), %eax
826 movl %edx, selector(%esp)
827 jmp *%eax
828
829 END_ENTRY _method_invoke
830
831
832 ENTRY _method_invoke_stret
833
834 movl selector_stret(%esp), %ecx
835 movl method_name(%ecx), %edx
836 movl method_imp(%ecx), %eax
837 movl %edx, selector_stret(%esp)
838 jmp *%eax
839
840 END_ENTRY _method_invoke_stret
841
842 #if DEBUG
843 STATIC_ENTRY __objc_ignored_method
844
845 movl self(%esp), %eax
846 ret
847
848 END_ENTRY __objc_ignored_method
849 #endif
850
851
852 .section __DATA,__objc_msg_break
853 .long 0
854 .long 0
855
856 #endif