diff options
| author | chai <chaifix@163.com> | 2020-09-13 20:56:14 +0800 |
|---|---|---|
| committer | chai <chaifix@163.com> | 2020-09-13 20:56:14 +0800 |
| commit | 2dfa15a926f06137f2ba6afcce2e3c1d23300100 (patch) | |
| tree | f86596654a2ec812a39b2c214420ba35db45595b /src/lua51/ldo.c | |
| parent | d9c2d065698641837bc75ded236b23d5aaa36fd4 (diff) | |
*misc
Diffstat (limited to 'src/lua51/ldo.c')
| -rw-r--r-- | src/lua51/ldo.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/src/lua51/ldo.c b/src/lua51/ldo.c index d9b1ea8..2311d41 100644 --- a/src/lua51/ldo.c +++ b/src/lua51/ldo.c @@ -1,3 +1,6 @@ +//c 函数调用及栈管理 + + /* ** $Id: ldo.c,v 2.38.1.4 2012/01/18 02:27:10 roberto Exp $ ** Stack and Call structure of Lua @@ -266,6 +269,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { //c 做函数调用前的准备 //c 将函数原型的指令code放在savedpc中,准备就绪 +//c 在 luaD_call 调用 int luaD_precall (lua_State *L, StkId func, int nresults) { LClosure *cl; ptrdiff_t funcr; @@ -273,11 +277,12 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { func = tryfuncTM(L, func); /* check the `function' tag method */ funcr = savestack(L, func); cl = &clvalue(func)->l; - L->ci->savedpc = L->savedpc;//c 先把当前虚拟机执行的位置保存下来,留给后面调用完函数后luad_poscall恢复到这个位置 + //c 先把当前虚拟机执行的位置保存下来,留给后面调用完函数后luaD_poscall恢复到这个位置 + L->ci->savedpc = L->savedpc; if (!cl->isC) { /* Lua function? prepare its call */ CallInfo *ci; StkId st, base; - Proto *p = cl->p; + Proto *p = cl->p; //c 拿到Proto luaD_checkstack(L, p->maxstacksize); func = restorestack(L, funcr); if (!p->is_vararg) { /* no varargs? */ @@ -290,23 +295,27 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { base = adjust_varargs(L, p, nargs); func = restorestack(L, funcr); /* previous call may change the stack */ } - ci = inc_ci(L); /* now `enter' new function */ + + //c 设置这次调用的CallInfo并将 L 的相关指针设到这个调用上。L和ci的top及base一致 + ci = inc_ci(L); /* now `enter' new function */ //c 申请一个新的CallInfo结构 ci->func = func; - L->base = ci->base = base; + L->base = ci->base = base; //c base 一致 ci->top = L->base + p->maxstacksize; lua_assert(ci->top <= L->stack_last); - L->savedpc = p->code; /* starting point */ + L->savedpc = p->code; /* starting point */ //c 设置savedpc为字节码的首地址 ci->tailcalls = 0; ci->nresults = nresults; - //c 将多余的参数赋值为nil,比如函数定义需要3个参数,但是只穿了1个,那么另外两个赋值为nil + //c 将多余的参数赋值为nil,比如函数定义需要3个参数,但是只传了1个,那么另外两个赋值为nil for (st = L->top; st < ci->top; st++) setnilvalue(st); - L->top = ci->top; + L->top = ci->top; //c top一致 + if (L->hookmask & LUA_MASKCALL) { L->savedpc++; /* hooks assume 'pc' is already incremented */ luaD_callhook(L, LUA_HOOKCALL, -1); L->savedpc--; /* correct 'pc' */ } + return PCRLUA; } else { /* if is a C function, call it */ @@ -352,9 +361,11 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { //c 函数执行完毕后,将lua_state恢复到上一次函数调用的状态 +//c 在lvm.c > luaV_execute() 中当执行到OP_RETURN时调用 int luaD_poscall (lua_State *L, StkId firstResult) { StkId res; int wanted, i; + //c 本次调用的ci CallInfo *ci; if (L->hookmask & LUA_MASKRET) firstResult = callrethooks(L, firstResult); @@ -362,7 +373,8 @@ int luaD_poscall (lua_State *L, StkId firstResult) { res = ci->func; /* res == final position of 1st result */ wanted = ci->nresults; L->base = (ci - 1)->base; /* restore base */ - L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ //c 恢复到调用之前的状态,很好理解,在父函数处这个函数执行完了,可以接着走了 + //c 恢复到调用之前的状态,很好理解,在父函数处这个函数执行完了,可以接着走了 + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); @@ -390,7 +402,8 @@ void luaD_call (lua_State *L, StkId func, int nResults) { //c luad_precall将函数指令放在lua_state的savedpc字段,准备就绪 //c luaV_execute执行函数原型的指令,是执行指令的入口 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ - luaV_execute(L, 1); /* call it */ + luaV_execute(L, 1); /* call it */ //c 虚拟机主函数 + //c 结束之后还会在luaV_execute里调luaD_poscall L->nCcalls--; luaC_checkGC(L); } @@ -504,11 +517,11 @@ struct SParser { /* data to `f_parser' */ const char *name; }; -//c 词法分析和语法分析,调用luaY_parser +//c 对读入的源代码,执行词法分析和语法分析,调用luaY_parser //c 执行完后将closure留在栈顶 static void f_parser (lua_State *L, void *ud) { int i; - Proto *tf; + Proto *tf; //c 闭包对应的函数原型 Closure *cl; struct SParser *p = cast(struct SParser *, ud); int c = luaZ_lookahead(p->z); @@ -517,12 +530,18 @@ static void f_parser (lua_State *L, void *ud) { //c 如果是source,走编译流程 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, &p->buff, p->name); + + //c 编译之后会得到Proto* tf, 所有的信息,包括常量表、upvalue、字节码、local变量数量等等都在里面 + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); - cl->l.p = tf; - //c 初始化upvalue + cl->l.p = tf; //c 设置proto = tf + //c 新建nups个closed upvalue for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ cl->l.upvals[i] = luaF_newupval(L); - setclvalue(L, L->top, cl);//把闭包放在栈顶 + + //c 把闭包放在栈顶 + //c lua_pcall会执行这个闭包 + setclvalue(L, L->top, cl); incr_top(L); } |
