diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-19 11:12:31 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-19 11:12:31 -0300 |
commit | dc07719b0dbc4f2df0f42e34e18be1e0ac4fa2c3 (patch) | |
tree | 9f9a73b2bccb0b7bf07ac32476e1127f46d222d9 | |
parent | 9cdf6b7082c49e6bf7daf8c7c4c649bcaacf9fad (diff) | |
download | lua-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.c | 15 | ||||
-rw-r--r-- | lgc.c | 6 | ||||
-rw-r--r-- | lobject.h | 4 | ||||
-rw-r--r-- | lstate.h | 3 | ||||
-rw-r--r-- | ltests.c | 3 |
5 files changed, 13 insertions, 18 deletions
@@ -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 | **/ |
65 | static UpVal *newupval (lua_State *L, int tag, StkId level, UpVal **prev) { | 65 | static 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) { | |||
170 | static void trynewtbcupval (lua_State *L, void *ud) { | 171 | static 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); |
@@ -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: |
@@ -568,6 +568,7 @@ typedef struct Proto { | |||
568 | */ | 568 | */ |
569 | typedef struct UpVal { | 569 | typedef 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 |
@@ -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 | /* |
@@ -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 | } |