Runtime-LLVM的中间代码


void test(int a)
{
    
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    [super forwardInvocation:anInvocation];
    
    int a  = 10;
    test(a);
    
}

查看super的底层调用什么
我们转成c++看到是调用的objc_msgSend2方法

((void (*)(__rw_objc_super *, SEL, NSInvocation *))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Person"))}, sel_registerName("forwardInvocation:"), (NSInvocation *)anInvocation);
//简化成
objc_msgSendSuper{(id)self, (id)class_getSuperclass(objc_getClass("Person"))}, sel_registerName("forwardInvocation:"), (NSInvocation *)anInvocation);

通过汇编代码查看的是
打断点,然后进入debug->Debug Workflow->Always Show Disassembly


    0x100000e49 <+73>:  callq  0x100000ef4               ; symbol stub for: objc_msgSendSuper2

objc_msgSendSuper2(struct,@selector(sss),invocation)

Product->perform Action ->assemble "文件"
现在LLVM编译器
会想讲OC->中间代码(.ll文件)->汇编->机器代码
可以使用以下命令行指令生成中间代码
clang -emit-llvm -S main.m
因为这个中间代码是支持不同平台的,他转成汇编的时候,会根据不同的平台(不同平台的cpu架构不一样),生成不同汇编代码,所以我们生成中间的代码的时候不用指定平台,
我们平时转成的cpp文件只能用来参考,因为C++语法跟OC比较像,大家比较容易读懂,大部分代码都是可以转成C++代码来看他的底层实现的

语法简介
   @ - 全局变量
   % - 局部变量
   alloca - 在当前执行的函数的堆栈帧中分配内存,当该函数返回到其调用者时,将自动释放内存
   i32 - 32位4字节的整数
   align - 对齐
   load - 读出,store 写入
   icmp - 两个整数值比较,返回布尔值
   br - 选择分支,根据条件来转向label,不根据条件跳转的话类似 goto
   label - 代码标签
   call - 调用函数

具体可以参考官方文档:https://llvm.org/docs/LangRef.html

你可能感兴趣的:(Runtime-LLVM的中间代码)