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 | |||
