Skip to content

Instantly share code, notes, and snippets.

@stuartcarnie
Created September 16, 2012 04:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuartcarnie/3730998 to your computer and use it in GitHub Desktop.
Save stuartcarnie/3730998 to your computer and use it in GitHub Desktop.
tail call with fake msgSend in Objective C
#import <Foundation/Foundation.h>
#import <objc/message.h>
extern id fake_msgSend(id, SEL, int) __attribute__((noinline));
@interface Foo : NSObject
- (id)foo:(int)n;
@end
@implementation Foo
-(id) foo:(int)n {
if (n == 0) return @"";
else return fake_msgSend(self, _cmd, n - 1); // tail-call optimization here
}
@end
id fake_msgSend(id f, SEL sel, int n) {
return objc_msgSend(f, sel, n); // tail-call optimization here
}
int main(int argv, char ** argc) {
id f = [Foo new];
[f foo:5];
return 0;
}
"-[Foo foo:]": ## @"\01-[Foo foo:]"
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
testl %edx, %edx
jne LBB0_2
## BB#1:
leaq L__unnamed_cfstring_(%rip), %rax
popq %rbp
ret
LBB0_2:
decl %edx
popq %rbp
jmp _fake_msgSend ## TAILCALL
.cfi_endproc
.globl _fake_msgSend
.align 4, 0x90
_fake_msgSend: ## @fake_msgSend
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp7:
.cfi_def_cfa_offset 16
Ltmp8:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp9:
.cfi_def_cfa_register %rbp
xorb %al, %al
popq %rbp
jmp _objc_msgSend ## TAILCALL
.cfi_endproc
.globl _main
.align 4, 0x90
_main: ## @main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp12:
.cfi_def_cfa_offset 16
Ltmp13:
.cfi_offset %rbp, -16
mov
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment