diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-05-24 16:48:43 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-05-24 16:48:43 -0300 |
commit | fc6c74f1004b5f67d0503633ddb74174a3c8d6ad (patch) | |
tree | ea69269504ddf8272257a3544231317b9362e416 | |
parent | 1e6918d553e0d76148f7de0af63fdce326e049b8 (diff) | |
download | lua-fc6c74f1004b5f67d0503633ddb74174a3c8d6ad.tar.gz lua-fc6c74f1004b5f67d0503633ddb74174a3c8d6ad.tar.bz2 lua-fc6c74f1004b5f67d0503633ddb74174a3c8d6ad.zip |
'index2value' more robust
'index2value' accepts pseudo-indices also when called from a Lua
function, through a hook.
-rw-r--r-- | lapi.c | 18 |
1 files changed, 13 insertions, 5 deletions
@@ -53,6 +53,10 @@ const char lua_ident[] = | |||
53 | #define isupvalue(i) ((i) < LUA_REGISTRYINDEX) | 53 | #define isupvalue(i) ((i) < LUA_REGISTRYINDEX) |
54 | 54 | ||
55 | 55 | ||
56 | /* | ||
57 | ** Convert an acceptable index to a pointer to its respective value. | ||
58 | ** Non-valid indices return the special nil value 'G(L)->nilvalue'. | ||
59 | */ | ||
56 | static TValue *index2value (lua_State *L, int idx) { | 60 | static TValue *index2value (lua_State *L, int idx) { |
57 | CallInfo *ci = L->ci; | 61 | CallInfo *ci = L->ci; |
58 | if (idx > 0) { | 62 | if (idx > 0) { |
@@ -70,22 +74,26 @@ static TValue *index2value (lua_State *L, int idx) { | |||
70 | else { /* upvalues */ | 74 | else { /* upvalues */ |
71 | idx = LUA_REGISTRYINDEX - idx; | 75 | idx = LUA_REGISTRYINDEX - idx; |
72 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); | 76 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); |
73 | if (ttislcf(s2v(ci->func))) /* light C function? */ | 77 | if (ttisCclosure(s2v(ci->func))) { /* C closure? */ |
74 | return &G(L)->nilvalue; /* it has no upvalues */ | ||
75 | else { | ||
76 | CClosure *func = clCvalue(s2v(ci->func)); | 78 | CClosure *func = clCvalue(s2v(ci->func)); |
77 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] | 79 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] |
78 | : &G(L)->nilvalue; | 80 | : &G(L)->nilvalue; |
79 | } | 81 | } |
82 | else { /* light C function or Lua function (through a hook)?) */ | ||
83 | api_check(L, ttislcf(s2v(ci->func)), "caller not a C function"); | ||
84 | return &G(L)->nilvalue; /* no upvalues */ | ||
85 | } | ||
80 | } | 86 | } |
81 | } | 87 | } |
82 | 88 | ||
83 | 89 | /* | |
90 | ** Convert a valid actual index (not a pseudo-index) to its address. | ||
91 | */ | ||
84 | static StkId index2stack (lua_State *L, int idx) { | 92 | static StkId index2stack (lua_State *L, int idx) { |
85 | CallInfo *ci = L->ci; | 93 | CallInfo *ci = L->ci; |
86 | if (idx > 0) { | 94 | if (idx > 0) { |
87 | StkId o = ci->func + idx; | 95 | StkId o = ci->func + idx; |
88 | api_check(L, o < L->top, "unacceptable index"); | 96 | api_check(L, o < L->top, "invalid index"); |
89 | return o; | 97 | return o; |
90 | } | 98 | } |
91 | else { /* non-positive index */ | 99 | else { /* non-positive index */ |