我正在使用一些蹦床函数与C/Objective-C中的高级调用一起使用,这与Apple的方式略有不同.
如果您对Objective-C的IMP工作方式一无所知,它基本上是一个函数指针,其中前两个参数是消息的接收者和消息选择器的名称,例如void(*)(id obj, SEL sel, ...).更新版本的运行时允许使用C块在运行时合成方法实现,例如void(^)(id obj, ...).这些块没有选择器; 运行时创建一个trampoline,用接收器覆盖选择器,接收器用块指针覆盖,然后继续执行它.
我想做一些模糊相似的事情,其中涉及没有前两个参数中的任何一个,因此该块的参数与传统方法发送的参数完全相同,加上用于执行目的的块指针,即void(*)(Block *, ...).这只需要复制块指针,我想摆脱一个参数.
__a1a2_tramphead_argonly:
popl %eax
andl $0xFFFFFFF8, %eax
subl $0x1000, %eax
movl 4(%esp), %ecx // self -> ecx
movl %ecx, 8(%esp) // ecx -> _cmd
movl (%eax), %ecx // blockPtr -> ecx
movl %ecx, 4(%esp) // ecx -> self
jmp *12(%ecx) // tail to block->invoke
Run Code Online (Sandbox Code Playgroud)
这是我在ARM上的程序集:
__a1a2_tramphead_argonly:
// calculate the trampoline's index (512 entries, 8 bytes each)
#ifdef …Run Code Online (Sandbox Code Playgroud)