aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-05-09 17:16:54 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-05-09 17:16:54 -0300
commitf966404ed636c1e61b4ab5ee5e7715739cc4ab49 (patch)
tree9732959ae217a23648c205d3e1d322a15db1cb65 /lapi.c
parentee07ad346dde41180a4e27a3029940c89ce42bf0 (diff)
downloadlua-f966404ed636c1e61b4ab5ee5e7715739cc4ab49.tar.gz
lua-f966404ed636c1e61b4ab5ee5e7715739cc4ab49.tar.bz2
lua-f966404ed636c1e61b4ab5ee5e7715739cc4ab49.zip
simpler implementation for valid/acceptable indices
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c174
1 files changed, 81 insertions, 93 deletions
diff --git a/lapi.c b/lapi.c
index a4a2b647..b4ccd8dc 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.236 2003/04/28 19:58:06 roberto Exp roberto $ 2** $Id: lapi.c,v 1.237 2003/05/05 18:39:57 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,15 +40,22 @@ const char lua_ident[] =
40 40
41#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) 41#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
42 42
43#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} 43#define api_checkvalidindex(L, i) api_check(L, (i) != &luaO_nilobject)
44 44
45#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
45 46
46 47
47 48
48static TObject *negindex (lua_State *L, int idx) { 49static TObject *luaA_index (lua_State *L, int idx) {
49 if (idx > LUA_REGISTRYINDEX) { 50 if (idx > 0) {
51 TObject *o = L->base + (idx - 1);
52 api_check(L, idx <= L->stack_last - L->base);
53 if (o >= L->top) return cast(TObject *, &luaO_nilobject);
54 else return o;
55 }
56 else if (idx > LUA_REGISTRYINDEX) {
50 api_check(L, idx != 0 && -idx <= L->top - L->base); 57 api_check(L, idx != 0 && -idx <= L->top - L->base);
51 return L->top+idx; 58 return L->top + idx;
52 } 59 }
53 else switch (idx) { /* pseudo-indices */ 60 else switch (idx) { /* pseudo-indices */
54 case LUA_REGISTRYINDEX: return registry(L); 61 case LUA_REGISTRYINDEX: return registry(L);
@@ -59,37 +66,12 @@ static TObject *negindex (lua_State *L, int idx) {
59 lua_assert(iscfunction(func)); 66 lua_assert(iscfunction(func));
60 return (idx <= clvalue(func)->c.nupvalues) 67 return (idx <= clvalue(func)->c.nupvalues)
61 ? &clvalue(func)->c.upvalue[idx-1] 68 ? &clvalue(func)->c.upvalue[idx-1]
62 : NULL; 69 : cast(TObject *, &luaO_nilobject);
63 } 70 }
64 } 71 }
65} 72}
66 73
67 74
68static TObject *luaA_index (lua_State *L, int idx) {
69 if (idx > 0) {
70 api_check(L, idx <= L->top - L->base);
71 return L->base + idx - 1;
72 }
73 else {
74 TObject *o = negindex(L, idx);
75 api_check(L, o != NULL);
76 return o;
77 }
78}
79
80
81static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
82 if (idx > 0) {
83 TObject *o = L->base+(idx-1);
84 api_check(L, idx <= L->stack_last - L->base);
85 if (o >= L->top) return NULL;
86 else return o;
87 }
88 else
89 return negindex(L, idx);
90}
91
92
93void luaA_pushobject (lua_State *L, const TObject *o) { 75void luaA_pushobject (lua_State *L, const TObject *o) {
94 setobj2s(L->top, o); 76 setobj2s(L->top, o);
95 incr_top(L); 77 incr_top(L);
@@ -179,6 +161,7 @@ LUA_API void lua_remove (lua_State *L, int idx) {
179 StkId p; 161 StkId p;
180 lua_lock(L); 162 lua_lock(L);
181 p = luaA_index(L, idx); 163 p = luaA_index(L, idx);
164 api_checkvalidindex(L, p);
182 while (++p < L->top) setobjs2s(p-1, p); 165 while (++p < L->top) setobjs2s(p-1, p);
183 L->top--; 166 L->top--;
184 lua_unlock(L); 167 lua_unlock(L);
@@ -190,6 +173,7 @@ LUA_API void lua_insert (lua_State *L, int idx) {
190 StkId q; 173 StkId q;
191 lua_lock(L); 174 lua_lock(L);
192 p = luaA_index(L, idx); 175 p = luaA_index(L, idx);
176 api_checkvalidindex(L, p);
193 for (q = L->top; q>p; q--) setobjs2s(q, q-1); 177 for (q = L->top; q>p; q--) setobjs2s(q, q-1);
194 setobjs2s(p, L->top); 178 setobjs2s(p, L->top);
195 lua_unlock(L); 179 lua_unlock(L);
@@ -197,9 +181,12 @@ LUA_API void lua_insert (lua_State *L, int idx) {
197 181
198 182
199LUA_API void lua_replace (lua_State *L, int idx) { 183LUA_API void lua_replace (lua_State *L, int idx) {
184 StkId o;
200 lua_lock(L); 185 lua_lock(L);
201 api_checknelems(L, 1); 186 api_checknelems(L, 1);
202 setobj(luaA_index(L, idx), L->top - 1); /* write barrier */ 187 o = luaA_index(L, idx);
188 api_checkvalidindex(L, o);
189 setobj(o, L->top - 1); /* write barrier */
203 L->top--; 190 L->top--;
204 lua_unlock(L); 191 lua_unlock(L);
205} 192}
@@ -220,8 +207,8 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
220 207
221 208
222LUA_API int lua_type (lua_State *L, int idx) { 209LUA_API int lua_type (lua_State *L, int idx) {
223 StkId o = luaA_indexAcceptable(L, idx); 210 StkId o = luaA_index(L, idx);
224 return (o == NULL) ? LUA_TNONE : ttype(o); 211 return (o == &luaO_nilobject) ? LUA_TNONE : ttype(o);
225} 212}
226 213
227 214
@@ -232,15 +219,15 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
232 219
233 220
234LUA_API int lua_iscfunction (lua_State *L, int idx) { 221LUA_API int lua_iscfunction (lua_State *L, int idx) {
235 StkId o = luaA_indexAcceptable(L, idx); 222 StkId o = luaA_index(L, idx);
236 return (o == NULL) ? 0 : iscfunction(o); 223 return iscfunction(o);
237} 224}
238 225
239 226
240LUA_API int lua_isnumber (lua_State *L, int idx) { 227LUA_API int lua_isnumber (lua_State *L, int idx) {
241 TObject n; 228 TObject n;
242 const TObject *o = luaA_indexAcceptable(L, idx); 229 const TObject *o = luaA_index(L, idx);
243 return (o != NULL && tonumber(o, &n)); 230 return tonumber(o, &n);
244} 231}
245 232
246 233
@@ -251,16 +238,16 @@ LUA_API int lua_isstring (lua_State *L, int idx) {
251 238
252 239
253LUA_API int lua_isuserdata (lua_State *L, int idx) { 240LUA_API int lua_isuserdata (lua_State *L, int idx) {
254 const TObject *o = luaA_indexAcceptable(L, idx); 241 const TObject *o = luaA_index(L, idx);
255 return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o))); 242 return (ttisuserdata(o) || ttislightuserdata(o));
256} 243}
257 244
258 245
259LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { 246LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
260 StkId o1 = luaA_indexAcceptable(L, index1); 247 StkId o1 = luaA_index(L, index1);
261 StkId o2 = luaA_indexAcceptable(L, index2); 248 StkId o2 = luaA_index(L, index2);
262 return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ 249 return (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0
263 : luaO_rawequalObj(o1, o2); 250 : luaO_rawequalObj(o1, o2);
264} 251}
265 252
266 253
@@ -268,10 +255,10 @@ LUA_API int lua_equal (lua_State *L, int index1, int index2) {
268 StkId o1, o2; 255 StkId o1, o2;
269 int i; 256 int i;
270 lua_lock(L); /* may call tag method */ 257 lua_lock(L); /* may call tag method */
271 o1 = luaA_indexAcceptable(L, index1); 258 o1 = luaA_index(L, index1);
272 o2 = luaA_indexAcceptable(L, index2); 259 o2 = luaA_index(L, index2);
273 i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ 260 i = (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0
274 : equalobj(L, o1, o2); 261 : equalobj(L, o1, o2);
275 lua_unlock(L); 262 lua_unlock(L);
276 return i; 263 return i;
277} 264}
@@ -281,10 +268,10 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
281 StkId o1, o2; 268 StkId o1, o2;
282 int i; 269 int i;
283 lua_lock(L); /* may call tag method */ 270 lua_lock(L); /* may call tag method */
284 o1 = luaA_indexAcceptable(L, index1); 271 o1 = luaA_index(L, index1);
285 o2 = luaA_indexAcceptable(L, index2); 272 o2 = luaA_index(L, index2);
286 i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ 273 i = (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0
287 : luaV_lessthan(L, o1, o2); 274 : luaV_lessthan(L, o1, o2);
288 lua_unlock(L); 275 lua_unlock(L);
289 return i; 276 return i;
290} 277}
@@ -293,8 +280,8 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
293 280
294LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { 281LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
295 TObject n; 282 TObject n;
296 const TObject *o = luaA_indexAcceptable(L, idx); 283 const TObject *o = luaA_index(L, idx);
297 if (o != NULL && tonumber(o, &n)) 284 if (tonumber(o, &n))
298 return nvalue(o); 285 return nvalue(o);
299 else 286 else
300 return 0; 287 return 0;
@@ -302,16 +289,14 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
302 289
303 290
304LUA_API int lua_toboolean (lua_State *L, int idx) { 291LUA_API int lua_toboolean (lua_State *L, int idx) {
305 const TObject *o = luaA_indexAcceptable(L, idx); 292 const TObject *o = luaA_index(L, idx);
306 return (o != NULL) && !l_isfalse(o); 293 return !l_isfalse(o);
307} 294}
308 295
309 296
310LUA_API const char *lua_tostring (lua_State *L, int idx) { 297LUA_API const char *lua_tostring (lua_State *L, int idx) {
311 StkId o = luaA_indexAcceptable(L, idx); 298 StkId o = luaA_index(L, idx);
312 if (o == NULL) 299 if (ttisstring(o))
313 return NULL;
314 else if (ttisstring(o))
315 return svalue(o); 300 return svalue(o);
316 else { 301 else {
317 const char *s; 302 const char *s;
@@ -325,10 +310,8 @@ LUA_API const char *lua_tostring (lua_State *L, int idx) {
325 310
326 311
327LUA_API size_t lua_strlen (lua_State *L, int idx) { 312LUA_API size_t lua_strlen (lua_State *L, int idx) {
328 StkId o = luaA_indexAcceptable(L, idx); 313 StkId o = luaA_index(L, idx);
329 if (o == NULL) 314 if (ttisstring(o))
330 return 0;
331 else if (ttisstring(o))
332 return tsvalue(o)->tsv.len; 315 return tsvalue(o)->tsv.len;
333 else { 316 else {
334 size_t l; 317 size_t l;
@@ -341,14 +324,13 @@ LUA_API size_t lua_strlen (lua_State *L, int idx) {
341 324
342 325
343LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { 326LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
344 StkId o = luaA_indexAcceptable(L, idx); 327 StkId o = luaA_index(L, idx);
345 return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f; 328 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
346} 329}
347 330
348 331
349LUA_API void *lua_touserdata (lua_State *L, int idx) { 332LUA_API void *lua_touserdata (lua_State *L, int idx) {
350 StkId o = luaA_indexAcceptable(L, idx); 333 StkId o = luaA_index(L, idx);
351 if (o == NULL) return NULL;
352 switch (ttype(o)) { 334 switch (ttype(o)) {
353 case LUA_TUSERDATA: return (uvalue(o) + 1); 335 case LUA_TUSERDATA: return (uvalue(o) + 1);
354 case LUA_TLIGHTUSERDATA: return pvalue(o); 336 case LUA_TLIGHTUSERDATA: return pvalue(o);
@@ -358,24 +340,21 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) {
358 340
359 341
360LUA_API lua_State *lua_tothread (lua_State *L, int idx) { 342LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
361 StkId o = luaA_indexAcceptable(L, idx); 343 StkId o = luaA_index(L, idx);
362 return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o); 344 return (!ttisthread(o)) ? NULL : thvalue(o);
363} 345}
364 346
365 347
366LUA_API const void *lua_topointer (lua_State *L, int idx) { 348LUA_API const void *lua_topointer (lua_State *L, int idx) {
367 StkId o = luaA_indexAcceptable(L, idx); 349 StkId o = luaA_index(L, idx);
368 if (o == NULL) return NULL; 350 switch (ttype(o)) {
369 else { 351 case LUA_TTABLE: return hvalue(o);
370 switch (ttype(o)) { 352 case LUA_TFUNCTION: return clvalue(o);
371 case LUA_TTABLE: return hvalue(o); 353 case LUA_TTHREAD: return thvalue(o);
372 case LUA_TFUNCTION: return clvalue(o); 354 case LUA_TUSERDATA:
373 case LUA_TTHREAD: return thvalue(o); 355 case LUA_TLIGHTUSERDATA:
374 case LUA_TUSERDATA: 356 return lua_touserdata(L, idx);
375 case LUA_TLIGHTUSERDATA: 357 default: return NULL;
376 return lua_touserdata(L, idx);
377 default: return NULL;
378 }
379 } 358 }
380} 359}
381 360
@@ -485,6 +464,7 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
485 StkId t; 464 StkId t;
486 lua_lock(L); 465 lua_lock(L);
487 t = luaA_index(L, idx); 466 t = luaA_index(L, idx);
467 api_checkvalidindex(L, t);
488 luaV_gettable(L, t, L->top - 1, L->top - 1); 468 luaV_gettable(L, t, L->top - 1, L->top - 1);
489 lua_unlock(L); 469 lua_unlock(L);
490} 470}
@@ -525,16 +505,14 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
525 Table *mt = NULL; 505 Table *mt = NULL;
526 int res; 506 int res;
527 lua_lock(L); 507 lua_lock(L);
528 obj = luaA_indexAcceptable(L, objindex); 508 obj = luaA_index(L, objindex);
529 if (obj != NULL) { 509 switch (ttype(obj)) {
530 switch (ttype(obj)) { 510 case LUA_TTABLE:
531 case LUA_TTABLE: 511 mt = hvalue(obj)->metatable;
532 mt = hvalue(obj)->metatable; 512 break;
533 break; 513 case LUA_TUSERDATA:
534 case LUA_TUSERDATA: 514 mt = uvalue(obj)->uv.metatable;
535 mt = uvalue(obj)->uv.metatable; 515 break;
536 break;
537 }
538 } 516 }
539 if (mt == NULL || mt == hvalue(defaultmeta(L))) 517 if (mt == NULL || mt == hvalue(defaultmeta(L)))
540 res = 0; 518 res = 0;
@@ -552,6 +530,7 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
552 StkId o; 530 StkId o;
553 lua_lock(L); 531 lua_lock(L);
554 o = luaA_index(L, idx); 532 o = luaA_index(L, idx);
533 api_checkvalidindex(L, o);
555 setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L)); 534 setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
556 api_incr_top(L); 535 api_incr_top(L);
557 lua_unlock(L); 536 lua_unlock(L);
@@ -568,6 +547,7 @@ LUA_API void lua_settable (lua_State *L, int idx) {
568 lua_lock(L); 547 lua_lock(L);
569 api_checknelems(L, 2); 548 api_checknelems(L, 2);
570 t = luaA_index(L, idx); 549 t = luaA_index(L, idx);
550 api_checkvalidindex(L, t);
571 luaV_settable(L, t, L->top - 2, L->top - 1); 551 luaV_settable(L, t, L->top - 2, L->top - 1);
572 L->top -= 2; /* pop index and value */ 552 L->top -= 2; /* pop index and value */
573 lua_unlock(L); 553 lua_unlock(L);
@@ -604,6 +584,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
604 lua_lock(L); 584 lua_lock(L);
605 api_checknelems(L, 1); 585 api_checknelems(L, 1);
606 obj = luaA_index(L, objindex); 586 obj = luaA_index(L, objindex);
587 api_checkvalidindex(L, obj);
607 mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L); 588 mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
608 api_check(L, ttistable(mt)); 589 api_check(L, ttistable(mt));
609 switch (ttype(obj)) { 590 switch (ttype(obj)) {
@@ -632,6 +613,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
632 lua_lock(L); 613 lua_lock(L);
633 api_checknelems(L, 1); 614 api_checknelems(L, 1);
634 o = luaA_index(L, idx); 615 o = luaA_index(L, idx);
616 api_checkvalidindex(L, o);
635 L->top--; 617 L->top--;
636 api_check(L, ttistable(L->top)); 618 api_check(L, ttistable(L->top));
637 if (isLfunction(o)) { 619 if (isLfunction(o)) {
@@ -679,7 +661,13 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
679 int status; 661 int status;
680 ptrdiff_t func; 662 ptrdiff_t func;
681 lua_lock(L); 663 lua_lock(L);
682 func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc)); 664 if (errfunc == 0)
665 func = 0;
666 else {
667 StkId o = luaA_index(L, errfunc);
668 api_checkvalidindex(L, o);
669 func = savestack(L, o);
670 }
683 c.func = L->top - (nargs+1); /* function to be called */ 671 c.func = L->top - (nargs+1); /* function to be called */
684 c.nresults = nresults; 672 c.nresults = nresults;
685 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); 673 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);