diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-17 19:12:57 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-17 19:12:57 -0200 |
commit | 1e81da51bab87148981486a84b846399050f4ef2 (patch) | |
tree | d2c94326ca096e032d1ae3fa75a5d0605f494cc6 /lapi.c | |
parent | 7cd37142f404462634a5049a840f572e85c5762b (diff) | |
download | lua-1e81da51bab87148981486a84b846399050f4ef2.tar.gz lua-1e81da51bab87148981486a84b846399050f4ef2.tar.bz2 lua-1e81da51bab87148981486a84b846399050f4ef2.zip |
new API for registry and C upvalues + new implementation for references
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 120 |
1 files changed, 56 insertions, 64 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.152 2001/09/07 17:39:10 roberto Exp $ | 2 | ** $Id: lapi.c,v 1.154 2001/10/11 21:40:56 roberto Exp $ |
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,28 @@ const l_char lua_ident[] = | |||
40 | 40 | ||
41 | 41 | ||
42 | 42 | ||
43 | static TObject *negindex (lua_State *L, int index) { | ||
44 | if (index > LUA_REGISTRYINDEX) { | ||
45 | api_check(L, index != 0 && -index <= L->top - L->ci->base); | ||
46 | return L->top+index; | ||
47 | } else if (index == LUA_REGISTRYINDEX) /* pseudo-indices */ | ||
48 | return &G(L)->registry; | ||
49 | else { | ||
50 | TObject *func = (L->ci->base - 1); | ||
51 | index = LUA_REGISTRYINDEX - index; | ||
52 | api_check(L, iscfunction(func) && index <= clvalue(func)->c.nupvalues); | ||
53 | return &clvalue(func)->c.upvalue[index-1]; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | |||
43 | TObject *luaA_index (lua_State *L, int index) { | 58 | TObject *luaA_index (lua_State *L, int index) { |
44 | if (index > 0) { | 59 | if (index > 0) { |
45 | api_check(L, index <= L->top - L->ci->base); | 60 | api_check(L, index <= L->top - L->ci->base); |
46 | return L->ci->base+index-1; | 61 | return L->ci->base+index-1; |
47 | } | 62 | } |
48 | else { | 63 | else |
49 | api_check(L, index != 0 && -index <= L->top - L->ci->base); | 64 | return negindex(L, index); |
50 | return L->top+index; | ||
51 | } | ||
52 | } | 65 | } |
53 | 66 | ||
54 | 67 | ||
@@ -59,10 +72,8 @@ static TObject *luaA_indexAcceptable (lua_State *L, int index) { | |||
59 | if (o >= L->top) return NULL; | 72 | if (o >= L->top) return NULL; |
60 | else return o; | 73 | else return o; |
61 | } | 74 | } |
62 | else { | 75 | else |
63 | api_check(L, index != 0 && -index <= L->top - L->ci->base); | 76 | return negindex(L, index); |
64 | return L->top+index; | ||
65 | } | ||
66 | } | 77 | } |
67 | 78 | ||
68 | 79 | ||
@@ -378,24 +389,6 @@ LUA_API void lua_getglobals (lua_State *L) { | |||
378 | } | 389 | } |
379 | 390 | ||
380 | 391 | ||
381 | LUA_API int lua_getref (lua_State *L, int ref) { | ||
382 | int status; | ||
383 | lua_lock(L); | ||
384 | if (ref == LUA_REFNIL) { | ||
385 | setnilvalue(L->top); | ||
386 | status = 1; | ||
387 | } | ||
388 | else { | ||
389 | setobj(L->top, luaH_getnum(G(L)->weakregistry, ref)); | ||
390 | status = (ttype(L->top) != LUA_TNIL); | ||
391 | } | ||
392 | if (status) | ||
393 | api_incr_top(L); | ||
394 | lua_unlock(L); | ||
395 | return status; | ||
396 | } | ||
397 | |||
398 | |||
399 | LUA_API void lua_newtable (lua_State *L) { | 392 | LUA_API void lua_newtable (lua_State *L) { |
400 | lua_lock(L); | 393 | lua_lock(L); |
401 | sethvalue(L->top, luaH_new(L, 0)); | 394 | sethvalue(L->top, luaH_new(L, 0)); |
@@ -404,22 +397,6 @@ LUA_API void lua_newtable (lua_State *L) { | |||
404 | } | 397 | } |
405 | 398 | ||
406 | 399 | ||
407 | LUA_API void lua_getregistry (lua_State *L) { | ||
408 | lua_lock(L); | ||
409 | sethvalue(L->top, G(L)->registry); | ||
410 | api_incr_top(L); | ||
411 | lua_unlock(L); | ||
412 | } | ||
413 | |||
414 | |||
415 | LUA_API void lua_getweakregistry (lua_State *L) { | ||
416 | lua_lock(L); | ||
417 | sethvalue(L->top, G(L)->weakregistry); | ||
418 | api_incr_top(L); | ||
419 | lua_unlock(L); | ||
420 | } | ||
421 | |||
422 | |||
423 | 400 | ||
424 | /* | 401 | /* |
425 | ** set functions (stack -> Lua) | 402 | ** set functions (stack -> Lua) |
@@ -483,26 +460,25 @@ LUA_API void lua_setglobals (lua_State *L) { | |||
483 | 460 | ||
484 | LUA_API int lua_ref (lua_State *L, int lock) { | 461 | LUA_API int lua_ref (lua_State *L, int lock) { |
485 | int ref; | 462 | int ref; |
463 | if (lock == 0) lua_error(L, l_s("unlocked references are obsolete")); | ||
486 | if (lua_isnil(L, -1)) { | 464 | if (lua_isnil(L, -1)) { |
487 | lua_pop(L, 1); | 465 | lua_pop(L, 1); |
488 | ref = LUA_REFNIL; | 466 | return LUA_REFNIL; |
489 | } | 467 | } |
490 | else { | 468 | lua_rawgeti(L, LUA_REGISTRYINDEX, 0); /* get first free element */ |
491 | lua_getweakregistry(L); | 469 | ref = lua_tonumber(L, -1); |
492 | ref = lua_getn(L, -1) + 1; | 470 | lua_pop(L, 1); /* remove it from stack */ |
493 | lua_pushvalue(L, -2); | 471 | if (ref != 0) { /* some free element? */ |
494 | lua_rawseti(L, -2, ref); | 472 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref); /* remove it from list */ |
495 | if (lock) { | 473 | lua_rawseti(L, LUA_REGISTRYINDEX, 0); |
496 | lua_getregistry(L); | 474 | } |
497 | lua_pushvalue(L, -3); | 475 | else { /* no free elements */ |
498 | lua_rawseti(L, -2, ref); | 476 | ref = lua_getn(L, LUA_REGISTRYINDEX) + 1; /* use next `n' */ |
499 | lua_pop(L, 1); /* remove registry */ | ||
500 | } | ||
501 | lua_pushliteral(L, l_s("n")); | 477 | lua_pushliteral(L, l_s("n")); |
502 | lua_pushnumber(L, ref); | 478 | lua_pushnumber(L, ref); |
503 | lua_settable(L, -3); | 479 | lua_settable(L, LUA_REGISTRYINDEX); /* n = n+1 */ |
504 | lua_pop(L, 2); | ||
505 | } | 480 | } |
481 | lua_rawseti(L, LUA_REGISTRYINDEX, ref); | ||
506 | return ref; | 482 | return ref; |
507 | } | 483 | } |
508 | 484 | ||
@@ -661,13 +637,10 @@ LUA_API void lua_error (lua_State *L, const l_char *s) { | |||
661 | 637 | ||
662 | LUA_API void lua_unref (lua_State *L, int ref) { | 638 | LUA_API void lua_unref (lua_State *L, int ref) { |
663 | if (ref >= 0) { | 639 | if (ref >= 0) { |
664 | lua_getregistry(L); | 640 | lua_rawgeti(L, LUA_REGISTRYINDEX, 0); |
665 | lua_pushnil(L); | 641 | lua_pushnumber(L, ref); |
666 | lua_rawseti(L, -2, ref); | 642 | lua_rawseti(L, LUA_REGISTRYINDEX, 0); |
667 | lua_getweakregistry(L); | 643 | lua_rawseti(L, LUA_REGISTRYINDEX, ref); |
668 | lua_pushnil(L); | ||
669 | lua_rawseti(L, -2, ref); | ||
670 | lua_pop(L, 2); /* remove both registries */ | ||
671 | } | 644 | } |
672 | } | 645 | } |
673 | 646 | ||
@@ -787,3 +760,22 @@ LUA_API void lua_setweakmode (lua_State *L, int mode) { | |||
787 | lua_unlock(L); | 760 | lua_unlock(L); |
788 | } | 761 | } |
789 | 762 | ||
763 | |||
764 | |||
765 | LUA_API void lua_pushupvalues (lua_State *L) { | ||
766 | TObject *func; | ||
767 | int n, i; | ||
768 | lua_lock(L); | ||
769 | func = (L->ci->base - 1); | ||
770 | api_check(L, iscfunction(func)); | ||
771 | n = clvalue(func)->c.nupvalues; | ||
772 | if (LUA_MINSTACK+n > lua_stackspace(L)) | ||
773 | luaD_error(L, l_s("stack overflow")); | ||
774 | for (i=0; i<n; i++) { | ||
775 | setobj(L->top, &clvalue(func)->c.upvalue[i]); | ||
776 | L->top++; | ||
777 | } | ||
778 | lua_unlock(L); | ||
779 | } | ||
780 | |||
781 | |||