aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-10-19 12:52:46 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-10-19 12:52:46 -0300
commitad5da6ba1456b5d4d1abbd52d4e04dc78fb41c45 (patch)
tree760608d5359868e76b30e5f973ed4005be78520e
parent86b39206d998a184a105bfb63b630ed28e1c81bc (diff)
downloadlua-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'
-rw-r--r--lapi.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/lapi.c b/lapi.c
index 0468f34b..34856950 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
46static TValue *index2addr (lua_State *L, int idx) { 55static 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*/
144LUA_API int lua_absindex (lua_State *L, int idx) { 153LUA_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 */