瀏覽代碼

'index2value' more robust

'index2value' accepts pseudo-indices also when called from a Lua
function, through a hook.
Roberto Ierusalimschy 4 年之前
父節點
當前提交
fc6c74f100
共有 1 個文件被更改,包括 13 次插入5 次删除
  1. 13 5
      lapi.c

+ 13 - 5
lapi.c

@@ -53,6 +53,10 @@ const char lua_ident[] =
 #define isupvalue(i)		((i) < LUA_REGISTRYINDEX)
 #define isupvalue(i)		((i) < LUA_REGISTRYINDEX)
 
 
 
 
+/*
+** Convert an acceptable index to a pointer to its respective value.
+** Non-valid indices return the special nil value 'G(L)->nilvalue'.
+*/
 static TValue *index2value (lua_State *L, int idx) {
 static TValue *index2value (lua_State *L, int idx) {
   CallInfo *ci = L->ci;
   CallInfo *ci = L->ci;
   if (idx > 0) {
   if (idx > 0) {
@@ -70,22 +74,26 @@ static TValue *index2value (lua_State *L, int idx) {
   else {  /* upvalues */
   else {  /* upvalues */
     idx = LUA_REGISTRYINDEX - idx;
     idx = LUA_REGISTRYINDEX - idx;
     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
-    if (ttislcf(s2v(ci->func)))  /* light C function? */
-      return &G(L)->nilvalue;  /* it has no upvalues */
-    else {
+    if (ttisCclosure(s2v(ci->func))) {  /* C closure? */
       CClosure *func = clCvalue(s2v(ci->func));
       CClosure *func = clCvalue(s2v(ci->func));
       return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
       return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
                                       : &G(L)->nilvalue;
                                       : &G(L)->nilvalue;
     }
     }
+    else {  /* light C function or Lua function (through a hook)?) */
+      api_check(L, ttislcf(s2v(ci->func)), "caller not a C function");
+      return &G(L)->nilvalue;  /* no upvalues */
+    }
   }
   }
 }
 }
 
 
-
+/*
+** Convert a valid actual index (not a pseudo-index) to its address.
+*/
 static StkId index2stack (lua_State *L, int idx) {
 static StkId index2stack (lua_State *L, int idx) {
   CallInfo *ci = L->ci;
   CallInfo *ci = L->ci;
   if (idx > 0) {
   if (idx > 0) {
     StkId o = ci->func + idx;
     StkId o = ci->func + idx;
-    api_check(L, o < L->top, "unacceptable index");
+    api_check(L, o < L->top, "invalid index");
     return o;
     return o;
   }
   }
   else {    /* non-positive index */
   else {    /* non-positive index */