LUA源码分析八:小总结,完整分析dofile的过程和堆栈
关于一些语法包装的问题不涉及(可见前面某篇),主要对堆栈排列上的分析。
一路跟调到static void f_parser (lua_State *L, void *ud)函数,堆栈记录如下:
+L->top0x003950e8:当前指针
+L->stack0x003950a8
+L->base0x003950b8
+L->ci0x00398e08
跟调到Proto *luaY_parser函数中。该函数主要进行了语法解析,FuncState的建立,最后返回结构体
Proto。里面具体怎么解析语法等我们都不需要关系,我们只需要关注哪些结果被压入了堆栈。
?
int luaD_precall (lua_State *L, StkId func, int nresults) { LClosure *cl; ptrdiff_t funcr; if (!ttisfunction(func)) /* `func' is not a function? */ func = tryfuncTM(L, func); /* check the `function' tag method */ funcr = savestack(L, func); cl = &clvalue(func)->l; L->ci->savedpc = L->savedpc; if (!cl->isC) { /* Lua function? prepare its call */ } else { /* if is a C function, call it */ CallInfo *ci; int n; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = inc_ci(L); /* now `enter' new function */ /* 设置好ci的环境。要执行的起始栈地址为要执行的函数+1,栈顶为L->top+LUA_MINSTACK ci->func:0x003950e8 L->base:0x003950f8 ci->top:0x00395248 */ ci->func = restorestack(L, funcr); L->base = ci->base = ci->func + 1; ci->top = L->top + LUA_MINSTACK; lua_assert(ci->top <= L->stack_last); ci->nresults = nresults; if (L->hookmask & LUA_MASKCALL) luaD_callhook(L, LUA_HOOKCALL, -1); lua_unlock(L); /* 执行到最终的函数 */ n = (*curr_func(L)->c.f)(L); /* do the actual call */ lua_lock(L); if (n < 0) /* yielding? */ return PCRYIELD; else { /* 整理CI的下一次行为.默认结尾时压入一条return的虚拟指令 */ luaD_poscall(L, L->top - n); return PCRC; } }}?