1
0
mirror of https://github.com/lua/lua.git synced 2025-01-14 05:43:00 +08:00

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.
This commit is contained in:
Roberto Ierusalimschy 2019-07-19 11:12:31 -03:00
parent 9cdf6b7082
commit dc07719b0d
5 changed files with 13 additions and 18 deletions

15
lfunc.c
View File

@ -59,14 +59,15 @@ void luaF_initupvals (lua_State *L, LClosure *cl) {
/* /*
** Create a new upvalue with the given tag at the given level, ** Create a new upvalue at the given level, and link it to the list of
** and link it to the list of open upvalues of 'L' after entry 'prev'. ** open upvalues of 'L' after entry 'prev'.
**/ **/
static UpVal *newupval (lua_State *L, int tag, StkId level, UpVal **prev) { static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) {
GCObject *o = luaC_newobj(L, tag, sizeof(UpVal)); GCObject *o = luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal));
UpVal *uv = gco2upv(o); UpVal *uv = gco2upv(o);
UpVal *next = *prev; UpVal *next = *prev;
uv->v = s2v(level); /* current value lives in the stack */ 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.next = next; /* link it to list of open upvalues */
uv->u.open.previous = prev; uv->u.open.previous = prev;
if (next) if (next)
@ -94,7 +95,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
pp = &p->u.open.next; pp = &p->u.open.next;
} }
/* not found: create a new upvalue after 'pp' */ /* 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) { static void trynewtbcupval (lua_State *L, void *ud) {
StkId level = cast(StkId, ud); StkId level = cast(StkId, ud);
lua_assert(L->openupval == NULL || uplevel(L->openupval) < level); 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) { while ((uv = L->openupval) != NULL && uplevel(uv) >= level) {
TValue *slot = &uv->u.value; /* new position for value */ TValue *slot = &uv->u.value; /* new position for value */
lua_assert(uplevel(uv) < L->top); 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 */ /* must run closing method, which may change the stack */
ptrdiff_t levelrel = savestack(L, level); ptrdiff_t levelrel = savestack(L, level);
status = callclosemth(L, uplevel(uv), status); status = callclosemth(L, uplevel(uv), status);

6
lgc.c
View File

@ -273,8 +273,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
gray2black(o); gray2black(o);
break; break;
} }
case LUA_TUPVAL: case LUA_TUPVAL: {
case LUA_TUPVALTBC: {
UpVal *uv = gco2upv(o); UpVal *uv = gco2upv(o);
if (!upisopen(uv)) /* open upvalues are kept gray */ if (!upisopen(uv)) /* open upvalues are kept gray */
gray2black(o); 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 */ for (; o < th->top; o++) /* mark live elements in the stack */
markvalue(g, s2v(o)); markvalue(g, s2v(o));
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) { 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 */ markobject(g, uv); /* cannot be collected */
} }
if (g->gcstate == GCSatomic) { /* final traversal? */ if (g->gcstate == GCSatomic) { /* final traversal? */
@ -706,7 +705,6 @@ static void freeobj (lua_State *L, GCObject *o) {
luaF_freeproto(L, gco2p(o)); luaF_freeproto(L, gco2p(o));
break; break;
case LUA_TUPVAL: case LUA_TUPVAL:
case LUA_TUPVALTBC:
freeupval(L, gco2upv(o)); freeupval(L, gco2upv(o));
break; break;
case LUA_TLCL: case LUA_TLCL:

View File

@ -568,6 +568,7 @@ typedef struct Proto {
*/ */
typedef struct UpVal { typedef struct UpVal {
CommonHeader; CommonHeader;
lu_byte tbc; /* true if it represents a to-be-closed variable */
TValue *v; /* points to stack or to its own value */ TValue *v; /* points to stack or to its own value */
union { union {
struct { /* (when open) */ struct { /* (when open) */
@ -579,9 +580,6 @@ typedef struct UpVal {
} UpVal; } UpVal;
/* variant for "To Be Closed" upvalues */
#define LUA_TUPVALTBC (LUA_TUPVAL | (1 << 4))
#define ClosureHeader \ #define ClosureHeader \
CommonHeader; lu_byte nupvalues; GCObject *gclist CommonHeader; lu_byte nupvalues; GCObject *gclist

View File

@ -335,8 +335,7 @@ union GCUnion {
#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) #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 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 gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
#define gco2upv(o) \ #define gco2upv(o) check_exp((o)->tt == LUA_TUPVAL, &((cast_u(o))->upv))
check_exp(novariant((o)->tt) == LUA_TUPVAL, &((cast_u(o))->upv))
/* /*

View File

@ -397,8 +397,7 @@ static void checkrefs (global_State *g, GCObject *o) {
checkudata(g, gco2u(o)); checkudata(g, gco2u(o));
break; break;
} }
case LUA_TUPVAL: case LUA_TUPVAL: {
case LUA_TUPVALTBC: {
checkvalref(g, o, gco2upv(o)->v); checkvalref(g, o, gco2upv(o)->v);
break; break;
} }