diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-04-17 14:35:54 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-04-17 14:35:54 -0300 |
commit | beee01b170c5fea9ed4527b28b9221d2df1baaba (patch) | |
tree | 82263b6e128ffe09fe3da63de16c626522320dfc /lapi.c | |
parent | 6473f965ca699719b3b9908008f15da48cc2e6f1 (diff) | |
download | lua-beee01b170c5fea9ed4527b28b9221d2df1baaba.tar.gz lua-beee01b170c5fea9ed4527b28b9221d2df1baaba.tar.bz2 lua-beee01b170c5fea9ed4527b28b9221d2df1baaba.zip |
re-implementation of refs through weak tables
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 76 |
1 files changed, 46 insertions, 30 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.138 2001/04/11 14:42:41 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.139 2001/04/11 18:39:37 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 | */ |
@@ -417,21 +417,18 @@ LUA_API void lua_getglobals (lua_State *L) { | |||
417 | 417 | ||
418 | 418 | ||
419 | LUA_API int lua_getref (lua_State *L, int ref) { | 419 | LUA_API int lua_getref (lua_State *L, int ref) { |
420 | int status = 1; | 420 | int status; |
421 | lua_lock(L); | 421 | lua_lock(L); |
422 | if (ref == LUA_REFNIL) { | 422 | if (ref == LUA_REFNIL) { |
423 | setnilvalue(L->top); | 423 | setnilvalue(L->top); |
424 | api_incr_top(L); | 424 | status = 1; |
425 | } | 425 | } |
426 | else { | 426 | else { |
427 | api_check(L, 0 <= ref && ref < G(L)->nref); | 427 | setobj(L->top, luaH_getnum(G(L)->weakregistry, ref)); |
428 | if (G(L)->refArray[ref].st != LOCK && G(L)->refArray[ref].st != HOLD) | 428 | status = (ttype(L->top) != LUA_TNIL); |
429 | status = 0; | ||
430 | else { | ||
431 | setobj(L->top, &G(L)->refArray[ref].o); | ||
432 | api_incr_top(L); | ||
433 | } | ||
434 | } | 429 | } |
430 | if (status) | ||
431 | api_incr_top(L); | ||
435 | lua_unlock(L); | 432 | lua_unlock(L); |
436 | return status; | 433 | return status; |
437 | } | 434 | } |
@@ -445,6 +442,22 @@ LUA_API void lua_newtable (lua_State *L) { | |||
445 | } | 442 | } |
446 | 443 | ||
447 | 444 | ||
445 | LUA_API void lua_getregistry (lua_State *L) { | ||
446 | lua_lock(L); | ||
447 | sethvalue(L->top, G(L)->registry); | ||
448 | api_incr_top(L); | ||
449 | lua_unlock(L); | ||
450 | } | ||
451 | |||
452 | |||
453 | LUA_API void lua_getweakregistry (lua_State *L) { | ||
454 | lua_lock(L); | ||
455 | sethvalue(L->top, G(L)->weakregistry); | ||
456 | api_incr_top(L); | ||
457 | lua_unlock(L); | ||
458 | } | ||
459 | |||
460 | |||
448 | 461 | ||
449 | /* | 462 | /* |
450 | ** set functions (stack -> Lua) | 463 | ** set functions (stack -> Lua) |
@@ -508,25 +521,26 @@ LUA_API void lua_setglobals (lua_State *L) { | |||
508 | 521 | ||
509 | LUA_API int lua_ref (lua_State *L, int lock) { | 522 | LUA_API int lua_ref (lua_State *L, int lock) { |
510 | int ref; | 523 | int ref; |
511 | lua_lock(L); | 524 | if (lua_isnil(L, -1)) { |
512 | api_checknelems(L, 1); | 525 | lua_pop(L, 1); |
513 | if (ttype(L->top-1) == LUA_TNIL) | ||
514 | ref = LUA_REFNIL; | 526 | ref = LUA_REFNIL; |
527 | } | ||
515 | else { | 528 | else { |
516 | if (G(L)->refFree != NONEXT) { /* is there a free place? */ | 529 | lua_getweakregistry(L); |
517 | ref = G(L)->refFree; | 530 | ref = lua_getn(L, -1) + 1; |
518 | G(L)->refFree = G(L)->refArray[ref].st; | 531 | lua_pushvalue(L, -2); |
519 | } | 532 | lua_rawseti(L, -2, ref); |
520 | else { /* no more free places */ | 533 | if (lock) { |
521 | luaM_growvector(L, G(L)->refArray, G(L)->nref, G(L)->sizeref, struct Ref, | 534 | lua_getregistry(L); |
522 | MAX_INT, l_s("reference table overflow")); | 535 | lua_pushvalue(L, -3); |
523 | ref = G(L)->nref++; | 536 | lua_rawseti(L, -2, ref); |
537 | lua_pop(L, 1); /* remove registry */ | ||
524 | } | 538 | } |
525 | setobj(&G(L)->refArray[ref].o, L->top-1); | 539 | lua_pushliteral(L, "n"); |
526 | G(L)->refArray[ref].st = lock ? LOCK : HOLD; | 540 | lua_pushnumber(L, ref); |
541 | lua_settable(L, -3); | ||
542 | lua_pop(L, 2); | ||
527 | } | 543 | } |
528 | L->top--; | ||
529 | lua_unlock(L); | ||
530 | return ref; | 544 | return ref; |
531 | } | 545 | } |
532 | 546 | ||
@@ -671,13 +685,15 @@ LUA_API void lua_error (lua_State *L, const l_char *s) { | |||
671 | 685 | ||
672 | 686 | ||
673 | LUA_API void lua_unref (lua_State *L, int ref) { | 687 | LUA_API void lua_unref (lua_State *L, int ref) { |
674 | lua_lock(L); | ||
675 | if (ref >= 0) { | 688 | if (ref >= 0) { |
676 | api_check(L, ref < G(L)->nref && G(L)->refArray[ref].st < 0); | 689 | lua_getregistry(L); |
677 | G(L)->refArray[ref].st = G(L)->refFree; | 690 | lua_pushnil(L); |
678 | G(L)->refFree = ref; | 691 | lua_rawseti(L, -2, ref); |
692 | lua_getweakregistry(L); | ||
693 | lua_pushnil(L); | ||
694 | lua_rawseti(L, -2, ref); | ||
695 | lua_pop(L, 2); /* remove both registries */ | ||
679 | } | 696 | } |
680 | lua_unlock(L); | ||
681 | } | 697 | } |
682 | 698 | ||
683 | 699 | ||