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