diff options
Diffstat (limited to 'src/lua51/ldo.c')
| -rw-r--r-- | src/lua51/ldo.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/lua51/ldo.c b/src/lua51/ldo.c index d1bf786..eac8d03 100644 --- a/src/lua51/ldo.c +++ b/src/lua51/ldo.c @@ -149,6 +149,7 @@ void luaD_reallocstack (lua_State *L, int newsize) { } +//c void luaD_reallocCI (lua_State *L, int newsize) { CallInfo *oldci = L->base_ci; luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); @@ -165,7 +166,8 @@ void luaD_growstack (lua_State *L, int n) { luaD_reallocstack(L, L->stacksize + n); } - +//c 当分配的callinfo数组不够大的,以2的指数扩展它 +//c callinfo的大小不会超过LUAI_MAXCALLS static CallInfo *growCI (lua_State *L) { if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ luaD_throw(L, LUA_ERRERR); @@ -256,12 +258,14 @@ static StkId tryfuncTM (lua_State *L, StkId func) { } - +//c 如果不够大了,扩容;然后返回++L->ci,即下一个ci #define inc_ci(L) \ ((L->ci == L->end_ci) ? growCI(L) : \ (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) +//c 做函数调用前的准备 +//c 将函数原型的指令code放在savedpc中,准备就绪 int luaD_precall (lua_State *L, StkId func, int nresults) { LClosure *cl; ptrdiff_t funcr; @@ -269,7 +273,7 @@ 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; + L->ci->savedpc = L->savedpc;//c 先把当前虚拟机执行的位置保存下来,留给后面调用完函数后luad_poscall恢复到这个位置 if (!cl->isC) { /* Lua function? prepare its call */ CallInfo *ci; StkId st, base; @@ -294,6 +298,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { L->savedpc = p->code; /* starting point */ ci->tailcalls = 0; ci->nresults = nresults; + //c 将多余的参数赋值为nil,比如函数定义需要3个参数,但是只穿了1个,那么另外两个赋值为nil for (st = L->top; st < ci->top; st++) setnilvalue(st); L->top = ci->top; @@ -305,14 +310,20 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { return PCRLUA; } else { /* if is a C function, call it */ + //c 这里能发现两个限制,一个是函数调用的嵌套限制LUAI_MAXCALL,一个是函数调用需要的数据栈大小不能超过 + //c lua_State数据栈的大小BASIC_STACK_SIZE + EXTRA_STACK(在stack_init函数中) + CallInfo *ci; int n; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + //c 找一个新的调用CallInfo对象,如果lua_state的callinfo数组不够大了,扩展它,但不能超过LUAI_MAXCALLS + //c 拿到下一个callinfo对象 ci = inc_ci(L); /* now `enter' new function */ - 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->func = restorestack(L, funcr);//c callinfo的函数原型 + //c 从这里能看出,lua_state的数据栈的base是跟着调用变动的 + L->base = ci->base = ci->func + 1;//c 设置当前调用的数据栈 + ci->top = L->top + LUA_MINSTACK;//c 设置当前调用的最大数据栈容量 + lua_assert(ci->top <= L->stack_last); //c 调用的栈顶不能超过lua数据栈的上限 ci->nresults = nresults; if (L->hookmask & LUA_MASKCALL) luaD_callhook(L, LUA_HOOKCALL, -1); @@ -340,6 +351,7 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { } +//c 函数执行完毕后,将lua_state恢复到上一次函数调用的状态 int luaD_poscall (lua_State *L, StkId firstResult) { StkId res; int wanted, i; @@ -350,7 +362,7 @@ 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 */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ //c 恢复到调用之前的状态,很好理解,在父函数处这个函数执行完了,可以接着走了 /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); @@ -361,6 +373,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) { } +//c 执行代码的入口,不限于函数(因为lua代码段就是封装为了函数) /* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. @@ -374,6 +387,8 @@ void luaD_call (lua_State *L, StkId func, int nResults) { else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ } + //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 */ L->nCcalls--; @@ -453,6 +468,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { } +//c 调用函数 int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t old_top, ptrdiff_t ef) { int status; @@ -488,6 +504,8 @@ struct SParser { /* data to `f_parser' */ const char *name; }; +//c 词法分析和语法分析,调用luaY_parser +//c 执行完后将closure留在栈顶 static void f_parser (lua_State *L, void *ud) { int i; Proto *tf; @@ -499,18 +517,21 @@ static void f_parser (lua_State *L, void *ud) { &p->buff, p->name); cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); cl->l.p = tf; + //c 初始化upvalue for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ cl->l.upvals[i] = luaF_newupval(L); - setclvalue(L, L->top, cl); + setclvalue(L, L->top, cl);//把闭包放在栈顶 incr_top(L); } +//c 保护模式下编译代码 int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { struct SParser p; int status; p.z = z; p.name = name; luaZ_initbuffer(L, &p.buff); + //c在保护模式下执行 f_parser 函数 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); luaZ_freebuffer(L, &p.buff); return status; |
