summaryrefslogtreecommitdiff
path: root/src/lua51/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua51/ldo.c')
-rw-r--r--src/lua51/ldo.c39
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;