Lua中关于C API的内容。

Iapi.c

index2addr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static TValue *index2addr (lua_State *L, int idx) {
CallInfo *ci = L->ci;
if (idx > 0) {
TValue *o = ci->func + idx;
api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
if (o >= L->top) return NONVALIDVALUE;
else return o;
}
else if (!ispseudo(idx)) { /* negative index */
api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
return L->top + idx;
}
else if (idx == LUA_REGISTRYINDEX)
return &G(L)->l_registry;
else { /* upvalues */
idx = LUA_REGISTRYINDEX - idx;
api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
if (ttislcf(ci->func)) /* light C function? */
return NONVALIDVALUE; /* it has no upvalues */
else {
CClosure *func = clCvalue(ci->func);
return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
}
}
}

这个index2addr函数的作用就是通过给定的 index 参数取出对应的TValue类型的对象指针。

情况 执行
当 index > 0 时 在当前function的栈空间找对应的TValue
当 LUA_REGISTRYINDEX < index <= 0 时 在当前function的栈空间逆向找对应的TValue
当LUA_REGISTRYINDEX == index 时 返回registry(注册表)
否则当 LUA_REGISTRYINDEX > index 时 查找upvalues