summaryrefslogtreecommitdiff
path: root/src/lua51/ldo.c
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-09-13 20:56:14 +0800
committerchai <chaifix@163.com>2020-09-13 20:56:14 +0800
commit2dfa15a926f06137f2ba6afcce2e3c1d23300100 (patch)
treef86596654a2ec812a39b2c214420ba35db45595b /src/lua51/ldo.c
parentd9c2d065698641837bc75ded236b23d5aaa36fd4 (diff)
*misc
Diffstat (limited to 'src/lua51/ldo.c')
-rw-r--r--src/lua51/ldo.c47
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);
}