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) { /* -** Create a new upvalue with the given tag at the given level, -** and link it to the list of open upvalues of 'L' after entry 'prev'. +** Create a new upvalue at the given level, and link it to the list of +** open upvalues of 'L' after entry 'prev'. **/ -static UpVal *newupval (lua_State *L, int tag, StkId level, UpVal **prev) { - GCObject *o = luaC_newobj(L, tag, sizeof(UpVal)); +static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) { + GCObject *o = luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal)); UpVal *uv = gco2upv(o); UpVal *next = *prev; uv->v = s2v(level); /* current value lives in the stack */ + uv->tbc = tbc; uv->u.open.next = next; /* link it to list of open upvalues */ uv->u.open.previous = prev; if (next) @@ -94,7 +95,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { pp = &p->u.open.next; } /* not found: create a new upvalue after 'pp' */ - return newupval(L, LUA_TUPVAL, level, pp); + return newupval(L, 0, level, pp); } @@ -170,7 +171,7 @@ static int callclosemth (lua_State *L, StkId level, int status) { static void trynewtbcupval (lua_State *L, void *ud) { StkId level = cast(StkId, ud); lua_assert(L->openupval == NULL || uplevel(L->openupval) < level); - newupval(L, LUA_TUPVALTBC, level, &L->openupval); + newupval(L, 1, level, &L->openupval); } @@ -204,7 +205,7 @@ int luaF_close (lua_State *L, StkId level, int status) { while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { TValue *slot = &uv->u.value; /* new position for value */ lua_assert(uplevel(uv) < L->top); - if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) { + if (uv->tbc && status != NOCLOSINGMETH) { /* must run closing method, which may change the stack */ ptrdiff_t levelrel = savestack(L, level); 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) { gray2black(o); break; } - case LUA_TUPVAL: - case LUA_TUPVALTBC: { + case LUA_TUPVAL: { UpVal *uv = gco2upv(o); if (!upisopen(uv)) /* open upvalues are kept gray */ gray2black(o); @@ -571,7 +570,7 @@ static int traversethread (global_State *g, lua_State *th) { for (; o < th->top; o++) /* mark live elements in the stack */ markvalue(g, s2v(o)); for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) { - if (uv->tt == LUA_TUPVALTBC) /* to be closed? */ + if (uv->tbc) /* to be closed? */ markobject(g, uv); /* cannot be collected */ } if (g->gcstate == GCSatomic) { /* final traversal? */ @@ -706,7 +705,6 @@ static void freeobj (lua_State *L, GCObject *o) { luaF_freeproto(L, gco2p(o)); break; case LUA_TUPVAL: - case LUA_TUPVALTBC: freeupval(L, gco2upv(o)); break; 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 { */ typedef struct UpVal { CommonHeader; + lu_byte tbc; /* true if it represents a to-be-closed variable */ TValue *v; /* points to stack or to its own value */ union { struct { /* (when open) */ @@ -579,9 +580,6 @@ typedef struct UpVal { } UpVal; -/* variant for "To Be Closed" upvalues */ -#define LUA_TUPVALTBC (LUA_TUPVAL | (1 << 4)) - #define ClosureHeader \ 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 { #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) -#define gco2upv(o) \ - check_exp(novariant((o)->tt) == LUA_TUPVAL, &((cast_u(o))->upv)) +#define gco2upv(o) check_exp((o)->tt == LUA_TUPVAL, &((cast_u(o))->upv)) /* 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) { checkudata(g, gco2u(o)); break; } - case LUA_TUPVAL: - case LUA_TUPVALTBC: { + case LUA_TUPVAL: { checkvalref(g, o, gco2upv(o)->v); break; }