summaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-08-27 15:53:35 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-08-27 15:53:35 -0300
commitaf35c7f398e8149b5f2481b63b399674e4ecdf7e (patch)
tree7d74f5c81bb0e2555cab4bce00a94a12a6d78604 /lfunc.c
parent742b7377d38e43224ee5dda4bb83a42763c20af8 (diff)
downloadlua-af35c7f398e8149b5f2481b63b399674e4ecdf7e.tar.gz
lua-af35c7f398e8149b5f2481b63b399674e4ecdf7e.tar.bz2
lua-af35c7f398e8149b5f2481b63b399674e4ecdf7e.zip
upvalues collected by reference count
Diffstat (limited to 'lfunc.c')
-rw-r--r--lfunc.c65
1 files changed, 27 insertions, 38 deletions
diff --git a/lfunc.c b/lfunc.c
index 654344a6..5bbae69c 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 2.34 2013/08/23 13:34:54 roberto Exp roberto $ 2** $Id: lfunc.c,v 2.35 2013/08/26 12:41:10 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -38,32 +38,33 @@ Closure *luaF_newLclosure (lua_State *L, int n) {
38} 38}
39 39
40 40
41UpVal *luaF_newupval (lua_State *L) { 41void luaF_initupvals (lua_State *L, LClosure *cl) {
42 UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), 42 int i;
43 &G(L)->localupv, 0)->uv; 43 for (i = 0; i < cl->nupvalues; i++) {
44 uv->v = &uv->value; 44 UpVal *uv = luaM_new(L, UpVal);
45 setnilvalue(uv->v); 45 uv->refcount = 1;
46 return uv; 46 uv->v = &uv->u.value; /* make it closed */
47 setnilvalue(uv->v);
48 cl->upvals[i] = uv;
49 }
47} 50}
48 51
49 52
50UpVal *luaF_findupval (lua_State *L, StkId level) { 53UpVal *luaF_findupval (lua_State *L, StkId level) {
51 global_State *g = G(L); 54 UpVal **pp = &L->openupval;
52 GCObject **pp = &L->openupval;
53 UpVal *p; 55 UpVal *p;
54 UpVal *uv; 56 UpVal *uv;
55 while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { 57 while (*pp != NULL && (p = *pp)->v >= level) {
56 GCObject *o = obj2gco(p); 58 lua_assert(upisopen(p));
57 lua_assert(p->v != &p->value); 59 if (p->v == level) /* found a corresponding upvalue? */
58 if (p->v == level) { /* found a corresponding upvalue? */ 60 return p; /* return it */
59 if (isdead(g, o)) /* is it dead? */ 61 pp = &p->u.op.next;
60 changewhite(o); /* resurrect it */
61 return p;
62 }
63 pp = &p->next;
64 } 62 }
65 /* not found: create a new one */ 63 /* not found: create a new one */
66 uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; 64 uv = luaM_new(L, UpVal);
65 uv->refcount = 0;
66 uv->u.op.next = *pp;
67 *pp = uv;
67 uv->v = level; /* current value lives in the stack */ 68 uv->v = level; /* current value lives in the stack */
68 return uv; 69 return uv;
69} 70}
@@ -71,27 +72,15 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
71 72
72void luaF_close (lua_State *L, StkId level) { 73void luaF_close (lua_State *L, StkId level) {
73 UpVal *uv; 74 UpVal *uv;
74 global_State *g = G(L); 75 while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
75 while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { 76 lua_assert(upisopen(uv));
76 GCObject *o = obj2gco(uv); 77 L->openupval = uv->u.op.next; /* remove from `open' list */
77 lua_assert(!isblack(o) && uv->v != &uv->value); 78 if (uv->refcount == 0) /* no references? */
78 L->openupval = uv->next; /* remove from `open' list */
79 if (isdead(g, o))
80 luaM_free(L, uv); /* free upvalue */ 79 luaM_free(L, uv); /* free upvalue */
81 else { 80 else {
82 setobj(L, &uv->value, uv->v); /* move value to upvalue slot */ 81 setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
83 uv->v = &uv->value; /* now current value lives here */ 82 uv->v = &uv->u.value; /* now current value lives here */
84 if (islocal(o)) { 83 luaC_upvalbarrier(L, uv);
85 gch(o)->next = g->localupv; /* link upvalue into 'localupv' list */
86 g->localupv = o;
87 resetbit(o->gch.marked, LOCALBLACK);
88 }
89 else { /* link upvalue into 'allgc' list */
90 gch(o)->next = g->allgc;
91 g->allgc = o;
92 }
93 valnolocal(uv->v); /* keep local invariant */
94 luaC_checkupvalcolor(g, uv);
95 } 84 }
96 } 85 }
97} 86}