Lua5.3 VM 分析(一)字节码运行
来源:互联网 发布:网络春晚2016完整版 编辑:程序博客网 时间:2024/05/29 07:38
Lua5.3 VM 分析(一)字节码运行
luaV_execute 是Lua VM 执行一段字节码的入口。Lua VM 就是一个状态机,从当前调用栈上次运行点开始解释字节码指令,直到下一个 C 边界跳出点(可以是函数执行完毕,也可以是一次协程 yield 操作)。
Lua 函数部分
typedef struct CallInfo { StkId func; /* function index in the stack */ StkId top; /* top for this function */ struct CallInfo *previous, *next; /* dynamic call link */ union { struct { /* only for Lua functions */ StkId base; /* base for this function */ const Instruction *savedpc; } l; struct { /* only for C functions */ lua_KFunction k; /* continuation in case of yields */ ptrdiff_t old_errfunc; lua_KContext ctx; /* context info. in case of yields */ } c; } u; ptrdiff_t extra; short nresults; /* expected number of results from this function */ lu_byte callstatus;} CallInfo;
savepc域 保存着指向当前指令的指针;base 域保存着当前函数的数据栈栈底指针。
每一次进入或退出一层Lua 函数,luaV_execute 并不会产生一次 C 层面的函数调用。也就是说,从Lua 函数中调用另一个Lua 函数,并不会产生一次独立的luaV_execute 调用。
luaV_execute
函数实现如下图
Lua 自己维护数据栈和调用栈,在解析字节码的时候,用 goto 语句来更新栈信息。 在luaV_execute 中定义了 newframe 这个跳转标签,Lua 函数执行 OP_CALL 、OP_TAILCALL 、OP_RETURN 指令都会跳转到这个标签,更新栈帧继续运行。
1. ci 变量从 当前 L 从获取当前正在调用的函数指针。
2. cl 变量是一个Lua 闭包类型,放置调用栈中当前函数对象,从ci->func中获取。
3. k 变量是 TValue 类型,放置当前函数的常量表, 从cl->p->k中获取。
4. base 变量是 StkId类型,放置当前数据栈 栈底的位置,从cl->u.l.base获取。
5. luaV_execute 解释字节码的过程也就是利用一个死循环,依次解析字节码指令,当前 指令 i 从 ci->u.l.savepc 中获取。
所有的指令都会操作寄存器 A ,从 Lua VM 的角度看,寄存器就是数据栈上的变量,所以可以将寄存器 A 所指变量预先取出放到局部变量ra 中。
ra = RA(i)。某些指令操作在 vm 运行过程中会改变数据栈的大小(伸缩),而 ra 是一个指向数据栈的指针,而不是一个索引。这种情况下,一旦数据栈发生变化,就需要重新获取ra 的值。
同理, base 变量 是一个指向数据栈栈底的指针,也会因为某些指令操作发生变化。这个时候就需要重新对 base 重新赋值。 栈底 base 作为基址是一个参考量,一直需要使用,所以重置 base 的值很频繁, Lua 提供了一个 Protect 宏,将重置base的操作包裹起来。
define Protect(x) { {x;}; base = ci->u.l.base; }
在死循环中,利用 C 语言的 switch /case 语句 针对每种OpCode 提供不同的操作。
define vmdispatch(o) switch(o)
define vmcase(l) case l:
define vmbreak break
- Lua5.3 VM 分析(一)字节码运行
- Lua5.3 VM 分析(二)表处理
- Lua5.3 VM 分析(三)表达式运算
- Lua5.3 VM 分析(四)分支和跳转
- Lua5.3 VM 分析(七)生成闭包
- Lua5.3 VM 分析(八)For 循环
- lua5.1字节码文件分析
- Lua5.3 虚拟机指令分析(一)概述
- Java字节码分析(一)
- Lua5.3 虚拟机指令分析(二)赋值指令
- Lua5.3 虚拟机指令分析(三)表达式运算
- Lua5.3 虚拟机指令分析(四)分支与跳转
- Lua5.3 虚拟机指令分析(五)函数调用
- Lua5.3 虚拟机指令分析(六)不定参数
- Lua5.3 虚拟机指令分析(八)循环
- Lua5.3 虚拟机指令分析(十)表相关指令
- Lua5.3 与C交互学习(一)
- Java字节码优化分析框架Soot初探(一)
- nodejs读写文件
- JavaScript indexOf() 方法
- Could not create the view: An unexpected exception was thrown.
- CSS样式的基础知识
- yii2项目实战-了解一下基于角色的访问控制
- Lua5.3 VM 分析(一)字节码运行
- JVM内存分配以及存储总结
- Lua5.3 VM 分析(二)表处理
- RCNN, Fast-RCNN, Faster-RCNN
- 《算法导论》第五章-第4节_练习(参考答案)
- 打扫房间的各种方法 —— Java虚拟机的垃圾收集算法清单
- 1037. 在霍格沃茨找零钱(20)
- 如何更好的做计划-SMART原则
- Lua5.3 VM 分析(三)表达式运算