diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-10-19 12:52:46 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-10-19 12:52:46 -0300 |
| commit | ad5da6ba1456b5d4d1abbd52d4e04dc78fb41c45 (patch) | |
| tree | 760608d5359868e76b30e5f973ed4005be78520e /lapi.c | |
| parent | 86b39206d998a184a105bfb63b630ed28e1c81bc (diff) | |
| download | lua-ad5da6ba1456b5d4d1abbd52d4e04dc78fb41c45.tar.gz lua-ad5da6ba1456b5d4d1abbd52d4e04dc78fb41c45.tar.bz2 lua-ad5da6ba1456b5d4d1abbd52d4e04dc78fb41c45.zip | |
API functions get acceptable indices except when not possible (when
they modify the value at that index) + new macro 'ispseudo' +
specific test 'api_checkstackindex'
Diffstat (limited to '')
| -rw-r--r-- | lapi.c | 31 |
1 files changed, 16 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.165 2012/08/14 18:12:34 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.166 2012/09/11 18:21:44 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -40,7 +40,16 @@ const char lua_ident[] = | |||
| 40 | /* corresponding test */ | 40 | /* corresponding test */ |
| 41 | #define isvalid(o) ((o) != luaO_nilobject) | 41 | #define isvalid(o) ((o) != luaO_nilobject) |
| 42 | 42 | ||
| 43 | #define api_checkvalidindex(L, i) api_check(L, isvalid(i), "invalid index") | 43 | /* test for pseudo index */ |
| 44 | #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) | ||
| 45 | |||
| 46 | /* test for valid but not pseudo index */ | ||
| 47 | #define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) | ||
| 48 | |||
| 49 | #define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") | ||
| 50 | |||
| 51 | #define api_checkstackindex(L, i, o) \ | ||
| 52 | api_check(L, isstackindex(i, o), "index not in the stack") | ||
| 44 | 53 | ||
| 45 | 54 | ||
| 46 | static TValue *index2addr (lua_State *L, int idx) { | 55 | static TValue *index2addr (lua_State *L, int idx) { |
| @@ -51,7 +60,7 @@ static TValue *index2addr (lua_State *L, int idx) { | |||
| 51 | if (o >= L->top) return NONVALIDVALUE; | 60 | if (o >= L->top) return NONVALIDVALUE; |
| 52 | else return o; | 61 | else return o; |
| 53 | } | 62 | } |
| 54 | else if (idx > LUA_REGISTRYINDEX) { | 63 | else if (!ispseudo(idx)) { /* negative index */ |
| 55 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); | 64 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
| 56 | return L->top + idx; | 65 | return L->top + idx; |
| 57 | } | 66 | } |
| @@ -142,7 +151,7 @@ LUA_API const lua_Number *lua_version (lua_State *L) { | |||
| 142 | ** convert an acceptable stack index into an absolute index | 151 | ** convert an acceptable stack index into an absolute index |
| 143 | */ | 152 | */ |
| 144 | LUA_API int lua_absindex (lua_State *L, int idx) { | 153 | LUA_API int lua_absindex (lua_State *L, int idx) { |
| 145 | return (idx > 0 || idx <= LUA_REGISTRYINDEX) | 154 | return (idx > 0 || ispseudo(idx)) |
| 146 | ? idx | 155 | ? idx |
| 147 | : cast_int(L->top - L->ci->func + idx); | 156 | : cast_int(L->top - L->ci->func + idx); |
| 148 | } | 157 | } |
| @@ -174,7 +183,7 @@ LUA_API void lua_remove (lua_State *L, int idx) { | |||
| 174 | StkId p; | 183 | StkId p; |
| 175 | lua_lock(L); | 184 | lua_lock(L); |
| 176 | p = index2addr(L, idx); | 185 | p = index2addr(L, idx); |
| 177 | api_checkvalidindex(L, p); | 186 | api_checkstackindex(L, idx, p); |
| 178 | while (++p < L->top) setobjs2s(L, p-1, p); | 187 | while (++p < L->top) setobjs2s(L, p-1, p); |
| 179 | L->top--; | 188 | L->top--; |
| 180 | lua_unlock(L); | 189 | lua_unlock(L); |
| @@ -186,7 +195,7 @@ LUA_API void lua_insert (lua_State *L, int idx) { | |||
| 186 | StkId q; | 195 | StkId q; |
| 187 | lua_lock(L); | 196 | lua_lock(L); |
| 188 | p = index2addr(L, idx); | 197 | p = index2addr(L, idx); |
| 189 | api_checkvalidindex(L, p); | 198 | api_checkstackindex(L, idx, p); |
| 190 | for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); | 199 | for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); |
| 191 | setobjs2s(L, p, L->top); | 200 | setobjs2s(L, p, L->top); |
| 192 | lua_unlock(L); | 201 | lua_unlock(L); |
| @@ -217,7 +226,6 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | |||
| 217 | TValue *fr; | 226 | TValue *fr; |
| 218 | lua_lock(L); | 227 | lua_lock(L); |
| 219 | fr = index2addr(L, fromidx); | 228 | fr = index2addr(L, fromidx); |
| 220 | api_checkvalidindex(L, fr); | ||
| 221 | moveto(L, fr, toidx); | 229 | moveto(L, fr, toidx); |
| 222 | lua_unlock(L); | 230 | lua_unlock(L); |
| 223 | } | 231 | } |
| @@ -611,7 +619,6 @@ LUA_API void lua_gettable (lua_State *L, int idx) { | |||
| 611 | StkId t; | 619 | StkId t; |
| 612 | lua_lock(L); | 620 | lua_lock(L); |
| 613 | t = index2addr(L, idx); | 621 | t = index2addr(L, idx); |
| 614 | api_checkvalidindex(L, t); | ||
| 615 | luaV_gettable(L, t, L->top - 1, L->top - 1); | 622 | luaV_gettable(L, t, L->top - 1, L->top - 1); |
| 616 | lua_unlock(L); | 623 | lua_unlock(L); |
| 617 | } | 624 | } |
| @@ -621,7 +628,6 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { | |||
| 621 | StkId t; | 628 | StkId t; |
| 622 | lua_lock(L); | 629 | lua_lock(L); |
| 623 | t = index2addr(L, idx); | 630 | t = index2addr(L, idx); |
| 624 | api_checkvalidindex(L, t); | ||
| 625 | setsvalue2s(L, L->top, luaS_new(L, k)); | 631 | setsvalue2s(L, L->top, luaS_new(L, k)); |
| 626 | api_incr_top(L); | 632 | api_incr_top(L); |
| 627 | luaV_gettable(L, t, L->top - 1, L->top - 1); | 633 | luaV_gettable(L, t, L->top - 1, L->top - 1); |
| @@ -709,7 +715,6 @@ LUA_API void lua_getuservalue (lua_State *L, int idx) { | |||
| 709 | StkId o; | 715 | StkId o; |
| 710 | lua_lock(L); | 716 | lua_lock(L); |
| 711 | o = index2addr(L, idx); | 717 | o = index2addr(L, idx); |
| 712 | api_checkvalidindex(L, o); | ||
| 713 | api_check(L, ttisuserdata(o), "userdata expected"); | 718 | api_check(L, ttisuserdata(o), "userdata expected"); |
| 714 | if (uvalue(o)->env) { | 719 | if (uvalue(o)->env) { |
| 715 | sethvalue(L, L->top, uvalue(o)->env); | 720 | sethvalue(L, L->top, uvalue(o)->env); |
| @@ -743,7 +748,6 @@ LUA_API void lua_settable (lua_State *L, int idx) { | |||
| 743 | lua_lock(L); | 748 | lua_lock(L); |
| 744 | api_checknelems(L, 2); | 749 | api_checknelems(L, 2); |
| 745 | t = index2addr(L, idx); | 750 | t = index2addr(L, idx); |
| 746 | api_checkvalidindex(L, t); | ||
| 747 | luaV_settable(L, t, L->top - 2, L->top - 1); | 751 | luaV_settable(L, t, L->top - 2, L->top - 1); |
| 748 | L->top -= 2; /* pop index and value */ | 752 | L->top -= 2; /* pop index and value */ |
| 749 | lua_unlock(L); | 753 | lua_unlock(L); |
| @@ -755,7 +759,6 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { | |||
| 755 | lua_lock(L); | 759 | lua_lock(L); |
| 756 | api_checknelems(L, 1); | 760 | api_checknelems(L, 1); |
| 757 | t = index2addr(L, idx); | 761 | t = index2addr(L, idx); |
| 758 | api_checkvalidindex(L, t); | ||
| 759 | setsvalue2s(L, L->top++, luaS_new(L, k)); | 762 | setsvalue2s(L, L->top++, luaS_new(L, k)); |
| 760 | luaV_settable(L, t, L->top - 1, L->top - 2); | 763 | luaV_settable(L, t, L->top - 1, L->top - 2); |
| 761 | L->top -= 2; /* pop value and key */ | 764 | L->top -= 2; /* pop value and key */ |
| @@ -811,7 +814,6 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
| 811 | lua_lock(L); | 814 | lua_lock(L); |
| 812 | api_checknelems(L, 1); | 815 | api_checknelems(L, 1); |
| 813 | obj = index2addr(L, objindex); | 816 | obj = index2addr(L, objindex); |
| 814 | api_checkvalidindex(L, obj); | ||
| 815 | if (ttisnil(L->top - 1)) | 817 | if (ttisnil(L->top - 1)) |
| 816 | mt = NULL; | 818 | mt = NULL; |
| 817 | else { | 819 | else { |
| @@ -850,7 +852,6 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { | |||
| 850 | lua_lock(L); | 852 | lua_lock(L); |
| 851 | api_checknelems(L, 1); | 853 | api_checknelems(L, 1); |
| 852 | o = index2addr(L, idx); | 854 | o = index2addr(L, idx); |
| 853 | api_checkvalidindex(L, o); | ||
| 854 | api_check(L, ttisuserdata(o), "userdata expected"); | 855 | api_check(L, ttisuserdata(o), "userdata expected"); |
| 855 | if (ttisnil(L->top - 1)) | 856 | if (ttisnil(L->top - 1)) |
| 856 | uvalue(o)->env = NULL; | 857 | uvalue(o)->env = NULL; |
| @@ -937,7 +938,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, | |||
| 937 | func = 0; | 938 | func = 0; |
| 938 | else { | 939 | else { |
| 939 | StkId o = index2addr(L, errfunc); | 940 | StkId o = index2addr(L, errfunc); |
| 940 | api_checkvalidindex(L, o); | 941 | api_checkstackindex(L, errfunc, o); |
| 941 | func = savestack(L, o); | 942 | func = savestack(L, o); |
| 942 | } | 943 | } |
| 943 | c.func = L->top - (nargs+1); /* function to be called */ | 944 | c.func = L->top - (nargs+1); /* function to be called */ |
