From 0a7fdcb69e8bbc74e8547a8c55bcbb7af928375d Mon Sep 17 00:00:00 2001 From: theraven Date: Sun, 9 Oct 2011 20:53:02 +0000 Subject: [PATCH] Add x86 (32-bit) sret trampoline. --- Test/BlockImpTest.m | 18 ++++++++++++++++++ block_trampolines.S | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/Test/BlockImpTest.m b/Test/BlockImpTest.m index 25b5665..3e7fb66 100644 --- a/Test/BlockImpTest.m +++ b/Test/BlockImpTest.m @@ -1,11 +1,18 @@ #include #include #include +#include + +struct big +{ + int a, b, c, d, e; +}; @interface Foo @end @implementation Foo @end @interface Foo (Dynamic) +(int)count: (int)i; ++(struct big)sret; @end int main(void) @@ -22,5 +29,16 @@ int main(void) assert(6 == [Foo count: 2]); assert(imp_getBlock(imp) == (blk)); imp_removeBlock(blk); + + blk = ^(id self) { + struct big b = {1, 2, 3, 4, 5}; + return b; + }; + imp = imp_implementationWithBlock(blk); + char *type; + asprintf(&type, "%s@:", @encode(struct big)); + class_addMethod((objc_getMetaClass("Foo")), @selector(sret), imp, type); + struct big s = [Foo sret]; + fprintf(stderr, "%d %d %d %d %d\n", s.a, s.b, s.c, s.d, s.e); return 0; } diff --git a/block_trampolines.S b/block_trampolines.S index 1f7914c..b8ef4a8 100644 --- a/block_trampolines.S +++ b/block_trampolines.S @@ -40,6 +40,14 @@ next_line: jmp *-13(%eax) # Call the block function __objc_block_trampoline_end: __objc_block_trampoline_sret: + call next_line2 # Store the instruction pointer on the stack +next_line2: + pop %eax # Load the old instruction pointer + mov 8(%esp), %ebx # Load the self parameter + mov %ebx, 12(%esp) # Store self as the second argument + mov -9(%eax), %ebx # Load the block pointer to %ebx + mov %ebx, 8(%esp) # Store the block pointer in the first argument + jmp *-13(%eax) # Call the block function __objc_block_trampoline_end_sret: #else __objc_block_trampoline: