summaryrefslogtreecommitdiff
path: root/src/lua51/lvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua51/lvm.c')
-rw-r--r--src/lua51/lvm.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/src/lua51/lvm.c b/src/lua51/lvm.c
index 85e214a..21de678 100644
--- a/src/lua51/lvm.c
+++ b/src/lua51/lvm.c
@@ -373,7 +373,7 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
}
-
+//c 虚拟机主入口
//c 执行lua函数(不含C函数,C函数在luaD_precall执行)
//c 读取字节码并运行,沟通前端和后端的桥梁
//c 在ldo.c->luaD_call函数中执行,前一步是luaD_precall()
@@ -390,7 +390,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
pc = L->savedpc;//c 最开始是luaD_precall中赋值的函数原型的指令开头
cl = &clvalue(L->ci->func)->l;
- base = L->base;
+ base = L->base; //c base是寄存器开始地址,每个方法被调用时都会得到自己的一组虚拟寄存器
k = cl->p->k; //c 当前函数原型的常量,所有函数调用都会用到的
/* main loop of interpreter */
@@ -407,7 +407,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
base = L->base;
}
/* warning!! several calls may realloc the stack and invalidate `ra' */
- ra = RA(i);
+ ra = RA(i); //c 从指令中拿到ra
lua_assert(base == L->base && L->base == L->ci->base);
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
@@ -729,18 +729,56 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
case OP_CLOSURE: {
- Proto *p;
+ Proto *p; //c 函数原型首地址
Closure *ncl;
int nup, j;
- p = cl->p->p[GETARG_Bx(i)];
- nup = p->nups;
+ p = cl->p->p[GETARG_Bx(i)]; //c 根据索引得到函数原型地址
+ //c lua的每个函数会记录这个函数的信息:参数个数、使用到的stack slot数目、upvalue数目、局部变量数目、常数表、局部函数
+ nup = p->nups; //c number of upvalues,
+ //c 创建闭包new closure
ncl = luaF_newLclosure(L, nup, cl->env);
- ncl->l.p = p;
+ ncl->l.p = p; // 设置函数原型
+ /* //c 一个闭包的创建如下
+-----------------------------------
+1 local a = 10
+2 local b = 20
+3
+4 function foo ()
+5 return a + b
+6 end
+7
+8 local c = 30
+9 foo()
+-----------------------------------
+main <main.lua:0,0> (10 instructions, 40 bytes at 009512A8)
+0+ params, 4 slots, 0 upvalues, 3 locals, 4 constants, 1 function
+ 1 [1] LOADK 0 -1 ; 10
+ 2 [2] LOADK 1 -2 ; 20
+ 3 [6] CLOSURE 2 0 ; 00951CC0
+ 4 [6] MOVE 0 0
+ 5 [6] MOVE 0 1
+ 6 [4] SETGLOBAL 2 -3 ; foo
+ 7 [8] LOADK 2 -4 ; 30
+ 8 [9] GETGLOBAL 3 -3 ; foo
+ 9 [9] CALL 3 1 1
+ 10 [9] RETURN 0 1
+
+function <main.lua:4,6> (5 instructions, 20 bytes at 00951CC0)
+0 params, 2 slots, 2 upvalues, 0 locals, 0 constants, 0 functions
+ 1 [5] GETUPVAL 0 0 ; a
+ 2 [5] GETUPVAL 1 1 ; b
+ 3 [5] ADD 0 0 1
+ 4 [5] RETURN 0 2
+ 5 [6] RETURN 0 1
+-----------------------------------
+012712A8的[6]是闭包的创建过程,两个MOVE指令用来设置闭包的upvalue,两个MOVE的第一个操作数无用
+ */
+ //c 设置闭包的upvalue值
for (j=0; j<nup; j++, pc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL)
ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
else {
- lua_assert(GET_OPCODE(*pc) == OP_MOVE);
+ lua_assert(GET_OPCODE(*pc) == OP_MOVE);
ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
}
}