diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-05-09 17:16:54 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-05-09 17:16:54 -0300 |
commit | f966404ed636c1e61b4ab5ee5e7715739cc4ab49 (patch) | |
tree | 9732959ae217a23648c205d3e1d322a15db1cb65 /lapi.c | |
parent | ee07ad346dde41180a4e27a3029940c89ce42bf0 (diff) | |
download | lua-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.c | 174 |
1 files changed, 81 insertions, 93 deletions
@@ -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 | ||
48 | static TObject *negindex (lua_State *L, int idx) { | 49 | static 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 | ||
68 | static 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 | |||
81 | static 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 | |||
93 | void luaA_pushobject (lua_State *L, const TObject *o) { | 75 | void 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 | ||
199 | LUA_API void lua_replace (lua_State *L, int idx) { | 183 | LUA_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 | ||
222 | LUA_API int lua_type (lua_State *L, int idx) { | 209 | LUA_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 | ||
234 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 221 | LUA_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 | ||
240 | LUA_API int lua_isnumber (lua_State *L, int idx) { | 227 | LUA_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 | ||
253 | LUA_API int lua_isuserdata (lua_State *L, int idx) { | 240 | LUA_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 | ||
259 | LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { | 246 | LUA_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 | ||
294 | LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { | 281 | LUA_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 | ||
304 | LUA_API int lua_toboolean (lua_State *L, int idx) { | 291 | LUA_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 | ||
310 | LUA_API const char *lua_tostring (lua_State *L, int idx) { | 297 | LUA_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 | ||
327 | LUA_API size_t lua_strlen (lua_State *L, int idx) { | 312 | LUA_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 | ||
343 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 326 | LUA_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 | ||
349 | LUA_API void *lua_touserdata (lua_State *L, int idx) { | 332 | LUA_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 | ||
360 | LUA_API lua_State *lua_tothread (lua_State *L, int idx) { | 342 | LUA_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 | ||
366 | LUA_API const void *lua_topointer (lua_State *L, int idx) { | 348 | LUA_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); |