aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-04-17 14:35:54 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-04-17 14:35:54 -0300
commitbeee01b170c5fea9ed4527b28b9221d2df1baaba (patch)
tree82263b6e128ffe09fe3da63de16c626522320dfc /lapi.c
parent6473f965ca699719b3b9908008f15da48cc2e6f1 (diff)
downloadlua-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.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/lapi.c b/lapi.c
index 243087fe..c715301d 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
419LUA_API int lua_getref (lua_State *L, int ref) { 419LUA_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
445LUA_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
453LUA_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
509LUA_API int lua_ref (lua_State *L, int lock) { 522LUA_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
673LUA_API void lua_unref (lua_State *L, int ref) { 687LUA_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