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:
parent
9cdf6b7082
commit
dc07719b0d
15
lfunc.c
15
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,
|
** 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
6
lgc.c
@ -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:
|
||||||
|
@ -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
|
||||||
|
3
lstate.h
3
lstate.h
@ -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))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
3
ltests.c
3
ltests.c
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user