summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-19 11:12:31 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-19 11:12:31 -0300
commitdc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3 (patch)
tree9f9a73b2bccb0b7bf07ac32476e1127f46d222d9
parent9cdf6b7082c49e6bf7daf8c7c4c649bcaacf9fad (diff)
downloadlua-dc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3.tar.gz
lua-dc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3.tar.bz2
lua-dc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3.zip
Tag LUA_TUPVALTBC replaced by a flag
It is simpler to signal a to-be-closed upvalue with a boolean flag, instead of using a different tag.
-rw-r--r--lfunc.c15
-rw-r--r--lgc.c6
-rw-r--r--lobject.h4
-rw-r--r--lstate.h3
-rw-r--r--ltests.c3
5 files changed, 13 insertions, 18 deletions
diff --git a/lfunc.c b/lfunc.c
index c07e9b35..9f91ad4f 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -59,14 +59,15 @@ void luaF_initupvals (lua_State *L, LClosure *cl) {
59 59
60 60
61/* 61/*
62** Create a new upvalue with the given tag at the given level, 62** Create a new upvalue at the given level, and link it to the list of
63** and link it to the list of open upvalues of 'L' after entry 'prev'. 63** open upvalues of 'L' after entry 'prev'.
64**/ 64**/
65static UpVal *newupval (lua_State *L, int tag, StkId level, UpVal **prev) { 65static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) {
66 GCObject *o = luaC_newobj(L, tag, sizeof(UpVal)); 66 GCObject *o = luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal));
67 UpVal *uv = gco2upv(o); 67 UpVal *uv = gco2upv(o);
68 UpVal *next = *prev; 68 UpVal *next = *prev;
69 uv->v = s2v(level); /* current value lives in the stack */ 69 uv->v = s2v(level); /* current value lives in the stack */
70 uv->tbc = tbc;
70 uv->u.open.next = next; /* link it to list of open upvalues */ 71 uv->u.open.next = next; /* link it to list of open upvalues */
71 uv->u.open.previous = prev; 72 uv->u.open.previous = prev;
72 if (next) 73 if (next)
@@ -94,7 +95,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
94 pp = &p->u.open.next; 95 pp = &p->u.open.next;
95 } 96 }
96 /* not found: create a new upvalue after 'pp' */ 97 /* not found: create a new upvalue after 'pp' */
97 return newupval(L, LUA_TUPVAL, level, pp); 98 return newupval(L, 0, level, pp);
98} 99}
99 100
100 101
@@ -170,7 +171,7 @@ static int callclosemth (lua_State *L, StkId level, int status) {
170static void trynewtbcupval (lua_State *L, void *ud) { 171static void trynewtbcupval (lua_State *L, void *ud) {
171 StkId level = cast(StkId, ud); 172 StkId level = cast(StkId, ud);
172 lua_assert(L->openupval == NULL || uplevel(L->openupval) < level); 173 lua_assert(L->openupval == NULL || uplevel(L->openupval) < level);
173 newupval(L, LUA_TUPVALTBC, level, &L->openupval); 174 newupval(L, 1, level, &L->openupval);
174} 175}
175 176
176 177
@@ -204,7 +205,7 @@ int luaF_close (lua_State *L, StkId level, int status) {
204 while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { 205 while ((uv = L->openupval) != NULL && uplevel(uv) >= level) {
205 TValue *slot = &uv->u.value; /* new position for value */ 206 TValue *slot = &uv->u.value; /* new position for value */
206 lua_assert(uplevel(uv) < L->top); 207 lua_assert(uplevel(uv) < L->top);
207 if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) { 208 if (uv->tbc && status != NOCLOSINGMETH) {
208 /* must run closing method, which may change the stack */ 209 /* must run closing method, which may change the stack */
209 ptrdiff_t levelrel = savestack(L, level); 210 ptrdiff_t levelrel = savestack(L, level);
210 status = callclosemth(L, uplevel(uv), status); 211 status = callclosemth(L, uplevel(uv), status);
diff --git a/lgc.c b/lgc.c
index 6562c928..c5babfed 100644
--- a/lgc.c
+++ b/lgc.c
@@ -273,8 +273,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
273 gray2black(o); 273 gray2black(o);
274 break; 274 break;
275 } 275 }
276 case LUA_TUPVAL: 276 case LUA_TUPVAL: {
277 case LUA_TUPVALTBC: {
278 UpVal *uv = gco2upv(o); 277 UpVal *uv = gco2upv(o);
279 if (!upisopen(uv)) /* open upvalues are kept gray */ 278 if (!upisopen(uv)) /* open upvalues are kept gray */
280 gray2black(o); 279 gray2black(o);
@@ -571,7 +570,7 @@ static int traversethread (global_State *g, lua_State *th) {
571 for (; o < th->top; o++) /* mark live elements in the stack */ 570 for (; o < th->top; o++) /* mark live elements in the stack */
572 markvalue(g, s2v(o)); 571 markvalue(g, s2v(o));
573 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) { 572 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) {
574 if (uv->tt == LUA_TUPVALTBC) /* to be closed? */ 573 if (uv->tbc) /* to be closed? */
575 markobject(g, uv); /* cannot be collected */ 574 markobject(g, uv); /* cannot be collected */
576 } 575 }
577 if (g->gcstate == GCSatomic) { /* final traversal? */ 576 if (g->gcstate == GCSatomic) { /* final traversal? */
@@ -706,7 +705,6 @@ static void freeobj (lua_State *L, GCObject *o) {
706 luaF_freeproto(L, gco2p(o)); 705 luaF_freeproto(L, gco2p(o));
707 break; 706 break;
708 case LUA_TUPVAL: 707 case LUA_TUPVAL:
709 case LUA_TUPVALTBC:
710 freeupval(L, gco2upv(o)); 708 freeupval(L, gco2upv(o));
711 break; 709 break;
712 case LUA_TLCL: 710 case LUA_TLCL:
diff --git a/lobject.h b/lobject.h
index f21e8a91..a22148c0 100644
--- a/lobject.h
+++ b/lobject.h
@@ -568,6 +568,7 @@ typedef struct Proto {
568*/ 568*/
569typedef struct UpVal { 569typedef struct UpVal {
570 CommonHeader; 570 CommonHeader;
571 lu_byte tbc; /* true if it represents a to-be-closed variable */
571 TValue *v; /* points to stack or to its own value */ 572 TValue *v; /* points to stack or to its own value */
572 union { 573 union {
573 struct { /* (when open) */ 574 struct { /* (when open) */
@@ -579,9 +580,6 @@ typedef struct UpVal {
579} UpVal; 580} UpVal;
580 581
581 582
582/* variant for "To Be Closed" upvalues */
583#define LUA_TUPVALTBC (LUA_TUPVAL | (1 << 4))
584
585 583
586#define ClosureHeader \ 584#define ClosureHeader \
587 CommonHeader; lu_byte nupvalues; GCObject *gclist 585 CommonHeader; lu_byte nupvalues; GCObject *gclist
diff --git a/lstate.h b/lstate.h
index 2a95dd16..03448b82 100644
--- a/lstate.h
+++ b/lstate.h
@@ -335,8 +335,7 @@ union GCUnion {
335#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) 335#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
336#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) 336#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
337#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) 337#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
338#define gco2upv(o) \ 338#define gco2upv(o) check_exp((o)->tt == LUA_TUPVAL, &((cast_u(o))->upv))
339 check_exp(novariant((o)->tt) == LUA_TUPVAL, &((cast_u(o))->upv))
340 339
341 340
342/* 341/*
diff --git a/ltests.c b/ltests.c
index cb8c422a..09876ee7 100644
--- a/ltests.c
+++ b/ltests.c
@@ -397,8 +397,7 @@ static void checkrefs (global_State *g, GCObject *o) {
397 checkudata(g, gco2u(o)); 397 checkudata(g, gco2u(o));
398 break; 398 break;
399 } 399 }
400 case LUA_TUPVAL: 400 case LUA_TUPVAL: {
401 case LUA_TUPVALTBC: {
402 checkvalref(g, o, gco2upv(o)->v); 401 checkvalref(g, o, gco2upv(o)->v);
403 break; 402 break;
404 } 403 }