EXTRA_STACK是给栈额外预留的空间:
c
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
这样top之上的几个位置就可以先用,后面再增加栈空间:
c
static void callTM (lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, const TValue *p3) {
setobj2s(L, L->top, f); /* push function */
setobj2s(L, L->top+1, p1); /* 1st argument */
setobj2s(L, L->top+2, p2); /* 2nd argument */
setobj2s(L, L->top+3, p3); /* 3th argument */
luaD_checkstack(L, 4);
L->top += 4;
luaD_call(L, L->top - 4, 0);
}
我看到这里就想,干嘛不提前luaD_checkstack(L, 4);
:
c
static void callTM (lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, const TValue *p3) {
setobj2s(L, L->top, f); /* push function */
setobj2s(L, L->top+1, p1); /* 1st argument */
setobj2s(L, L->top+2, p2); /* 2nd argument */
setobj2s(L, L->top+3, p3); /* 3th argument */
luaD_checkstack(L, 4);
L->top += 4;
luaD_call(L, L->top - 4, 0);
}
但是用AddressSanitizer工具测试发现,在执行源码自带的trace-globals.lua时,setobj2s(L, L->top+3, p3);
会报使用已free内存。
经过查看代码发现,p3可能是栈上的数据,luaD_checkstack中可能会调用luaD_reallocstack导致p3不可用。
所以luaD_checkstack要放到后面执行。