From 15462edb0ff86bf1904011b29635420451cab2c5 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 2 Oct 2001 13:45:03 -0300 Subject: [PATCH] new definitions for closure structures --- lapi.c | 8 +++--- ldebug.c | 18 ++++++------- ldo.c | 15 ++++++----- lfunc.c | 62 +++++++++++++++++++++---------------------- lfunc.h | 7 +---- lgc.c | 78 +++++++++++++++++++++++-------------------------------- llimits.h | 9 +++---- lobject.h | 54 ++++++++++++++++++++++---------------- ltests.c | 8 +++--- lvm.c | 30 ++++++++++----------- lvm.h | 4 +-- 11 files changed, 137 insertions(+), 156 deletions(-) diff --git a/lapi.c b/lapi.c index 5c54c60c..8c093685 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.149 2001/07/22 00:59:36 roberto Exp roberto $ +** $Id: lapi.c,v 1.152 2001/09/07 17:39:10 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -248,7 +248,7 @@ LUA_API size_t lua_strlen (lua_State *L, int index) { LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { StkId o = luaA_indexAcceptable(L, index); - return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->u.c.f; + return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f; } @@ -314,10 +314,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { lua_lock(L); api_checknelems(L, n); cl = luaF_newCclosure(L, n); - cl->u.c.f = fn; + cl->c.f = fn; L->top -= n; while (n--) - setobj(&cl->u.c.upvalue[n], L->top+n); + setobj(&cl->c.upvalue[n], L->top+n); setclvalue(L->top, cl); incr_top; lua_unlock(L); diff --git a/ldebug.c b/ldebug.c index cf397bd2..5ddf3d0a 100644 --- a/ldebug.c +++ b/ldebug.c @@ -33,7 +33,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci, static int isLmark (CallInfo *ci) { lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION); - return (ci && ci->prev && !ci_func(ci)->isC); + return (ci && ci->prev && !ci_func(ci)->c.isC); } @@ -117,7 +117,7 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { static int currentpc (CallInfo *ci) { lua_assert(isLmark(ci)); if (ci->pc) - return (*ci->pc - ci_func(ci)->u.l.p->code) - 1; + return (*ci->pc - ci_func(ci)->l.p->code) - 1; else return -1; /* function is not active */ } @@ -127,7 +127,7 @@ static int currentline (CallInfo *ci) { if (!isLmark(ci)) return -1; /* only active lua functions have current-line information */ else { - int *lineinfo = ci_func(ci)->u.l.p->lineinfo; + int *lineinfo = ci_func(ci)->l.p->lineinfo; return luaG_getline(lineinfo, currentpc(ci), 1, NULL); } } @@ -135,7 +135,7 @@ static int currentline (CallInfo *ci) { static Proto *getluaproto (CallInfo *ci) { - return (isLmark(ci) ? ci_func(ci)->u.l.p : NULL); + return (isLmark(ci) ? ci_func(ci)->l.p : NULL); } @@ -193,13 +193,13 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) { luaD_error(L, l_s("value for `lua_getinfo' is not a function")); cl = NULL; /* to avoid warnings */ } - if (cl->isC) { + if (cl->c.isC) { ar->source = l_s("=C"); ar->linedefined = -1; ar->what = l_s("C"); } else - infoLproto(ar, cl->u.l.p); + infoLproto(ar, cl->l.p); luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); if (ar->linedefined == 0) ar->what = l_s("main"); @@ -268,7 +268,7 @@ LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) { break; } case l_c('u'): { - ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->nupvalues : 0; + ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->c.nupvalues : 0; break; } case l_c('n'): { @@ -473,7 +473,7 @@ int luaG_checkcode (const Proto *pt) { static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { CallInfo *ci = ci_stack(L, obj); if (isLmark(ci)) { /* an active Lua function? */ - Proto *p = ci_func(ci)->u.l.p; + Proto *p = ci_func(ci)->l.p; int pc = currentpc(ci); int stackpos = obj - ci->base; Instruction i; @@ -517,7 +517,7 @@ static const l_char *getfuncname (lua_State *L, CallInfo *ci, if (ci == &L->basefunc || !isLmark(ci)) return NULL; /* not an active Lua function */ else { - Proto *p = ci_func(ci)->u.l.p; + Proto *p = ci_func(ci)->l.p; int pc = currentpc(ci); Instruction i; if (pc == -1) return NULL; /* function is not activated */ diff --git a/ldo.c b/ldo.c index ee055a8f..60e5dc2e 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.140 2001/09/07 17:39:10 roberto Exp $ +** $Id: ldo.c,v 1.141 2001/09/25 17:05:49 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -118,14 +118,14 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, } -static StkId callCclosure (lua_State *L, const struct Closure *cl) { +static StkId callCclosure (lua_State *L, const struct CClosure *cl) { int nup = cl->nupvalues; /* number of upvalues */ int n; luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ for (n=0; ntop++, &cl->u.c.upvalue[n]); + setobj(L->top++, &cl->upvalue[n]); lua_unlock(L); - n = (*cl->u.c.f)(L); /* do the actual call */ + n = (*cl->f)(L); /* do the actual call */ lua_lock(L); return L->top - n; /* return index of first result */ } @@ -155,8 +155,9 @@ void luaD_call (lua_State *L, StkId func) { callhook = L->callhook; if (callhook) luaD_callHook(L, callhook, l_s("call")); - firstResult = (clvalue(func)->isC ? callCclosure(L, clvalue(func)) : - luaV_execute(L, clvalue(func), func+1)); + firstResult = (clvalue(func)->c.isC ? + callCclosure(L, &clvalue(func)->c) : + luaV_execute(L, &clvalue(func)->l, func+1)); if (callhook) /* same hook that was active at entry */ luaD_callHook(L, callhook, l_s("return")); L->ci = ci.prev; /* unchain callinfo */ @@ -213,7 +214,7 @@ static void f_parser (lua_State *L, void *ud) { struct SParser *p = cast(struct SParser *, ud); Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); Closure *cl = luaF_newLclosure(L, 0); - cl->u.l.p = tf; + cl->l.p = tf; luaF_LConlist(L, cl); setclvalue(L->top, cl); incr_top; diff --git a/lfunc.c b/lfunc.c index 8c197499..bed67101 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.45 2001/06/28 14:57:17 roberto Exp $ +** $Id: lfunc.c,v 1.47 2001/09/07 17:39:10 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -16,30 +16,29 @@ #include "lstate.h" -#define sizeCclosure(n) (cast(int, sizeof(Closure)) + \ +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ cast(int, sizeof(TObject)*((n)-1))) -#define sizeLclosure(n) (cast(int, sizeof(Closure)) + \ - cast(int, sizeof(TObject *)*((n)-1))) +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(LClosureEntry)*((n)-1))) Closure *luaF_newCclosure (lua_State *L, int nelems) { Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); - c->isC = 1; - c->next = G(L)->rootcl; + c->c.isC = 1; + c->c.next = G(L)->rootcl; G(L)->rootcl = c; - c->mark = c; - c->nupvalues = nelems; + c->c.marked = 0; + c->c.nupvalues = nelems; return c; } Closure *luaF_newLclosure (lua_State *L, int nelems) { Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); - c->isC = 0; - c->mark = c; - c->u.l.isopen = 0; - c->nupvalues = nelems; + c->l.isC = 0; + c->l.marked = 0; + c->l.nupvalues = nelems; return c; } @@ -47,42 +46,38 @@ Closure *luaF_newLclosure (lua_State *L, int nelems) { /* ** returns the open pointer in a closure that points higher into the stack */ -static StkId uppoint (Closure *cl) { +static StkId uppoint (LClosure *cl) { StkId lp = NULL; int i; - lua_assert(cl->u.l.isopen); for (i=0; inupvalues; i++) { - if (!luaF_isclosed(cl, i)) - if (lp == NULL || cl->u.l.upvals[i] > lp) - lp = cl->u.l.upvals[i]; + if (cl->upvals[i].heap == NULL && (lp == NULL || cl->upvals[i].val > lp)) + lp = cl->upvals[i].val; } - lua_assert(lp != NULL); return lp; } void luaF_LConlist (lua_State *L, Closure *cl) { - lua_assert(!cl->isC); - if (cl->u.l.isopen == 0) { /* no more open entries? */ - cl->next = G(L)->rootcl; /* insert in final list */ + StkId cli = uppoint(&cl->l); + if (cli == NULL) { /* no more open entries? */ + cl->l.next = G(L)->rootcl; /* insert in final list */ G(L)->rootcl = cl; } else { /* insert in list of open closures, ordered by decreasing uppoints */ - StkId cli = uppoint(cl); Closure **p = &L->opencl; - while (*p != NULL && uppoint(*p) > cli) p = &(*p)->next; - cl->next = *p; + while (*p != NULL && uppoint(&(*p)->l) > cli) p = &(*p)->l.next; + cl->l.next = *p; *p = cl; } } -static int closeCl (lua_State *L, Closure *cl, StkId level) { +static int closeCl (lua_State *L, LClosure *cl, StkId level) { int got = 0; /* flag: 1 if some pointer in the closure was corrected */ int i; for (i=0; inupvalues; i++) { StkId var; - if (!luaF_isclosed(cl, i) && (var=cl->u.l.upvals[i]) >= level) { + if (cl->upvals[i].heap == NULL && (var=cl->upvals[i].val) >= level) { if (ttype(var) != LUA_TUPVAL) { UpVal *v = luaM_new(L, UpVal); v->val = *var; @@ -91,8 +86,8 @@ static int closeCl (lua_State *L, Closure *cl, StkId level) { G(L)->rootupval = v; setupvalue(var, v); } - cl->u.l.upvals[i] = cast(TObject *, vvalue(var)); - luaF_closeentry(cl, i); + cl->upvals[i].heap = vvalue(var); + cl->upvals[i].val = &vvalue(var)->val; got = 1; } } @@ -104,15 +99,15 @@ void luaF_close (lua_State *L, StkId level) { Closure *affected = NULL; /* closures with open pointers >= level */ Closure *cl; while ((cl=L->opencl) != NULL) { - if (!closeCl(L, cl, level)) break; + if (!closeCl(L, cast(LClosure *, cl), level)) break; /* some pointer in `cl' changed; will re-insert it in original list */ - L->opencl = cl->next; /* remove from original list */ - cl->next = affected; + L->opencl = cl->l.next; /* remove from original list */ + cl->l.next = affected; affected = cl; /* insert in affected list */ } /* re-insert all affected closures in original list */ while ((cl=affected) != NULL) { - affected = cl->next; + affected = cl->l.next; luaF_LConlist(L, cl); } } @@ -154,7 +149,8 @@ void luaF_freeproto (lua_State *L, Proto *f) { void luaF_freeclosure (lua_State *L, Closure *c) { - int size = (c->isC) ? sizeCclosure(c->nupvalues) : sizeLclosure(c->nupvalues); + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); luaM_free(L, c, size); } diff --git a/lfunc.h b/lfunc.h index 385767a2..d7506f84 100644 --- a/lfunc.h +++ b/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 1.15 2001/02/23 17:17:25 roberto Exp $ +** $Id: lfunc.h,v 1.16 2001/09/07 17:39:10 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -11,11 +11,6 @@ #include "lobject.h" -#define luaF_isclosed(c, i) (!((c)->u.l.isopen & (1 << (i)))) -#define luaF_openentry(c, i) ((c)->u.l.isopen |= (1 << (i))) -#define luaF_closeentry(c, i) ((c)->u.l.isopen &= ~(1 << (i))) - - Proto *luaF_newproto (lua_State *L); Closure *luaF_newCclosure (lua_State *L, int nelems); Closure *luaF_newLclosure (lua_State *L, int nelems); diff --git a/lgc.c b/lgc.c index 20d97cf2..cb08df35 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.109 2001/06/28 14:57:17 roberto Exp $ +** $Id: lgc.c,v 1.111 2001/09/07 17:39:10 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -22,7 +22,6 @@ typedef struct GCState { Hash *tmark; /* list of marked tables to be visited */ - Closure *cmark; /* list of marked closures to be visited */ } GCState; @@ -32,6 +31,9 @@ typedef struct GCState { +static void markobject (GCState *st, TObject *o); + + static void protomark (Proto *f) { if (!f->marked) { int i; @@ -51,9 +53,25 @@ static void protomark (Proto *f) { static void markclosure (GCState *st, Closure *cl) { - if (!ismarked(cl)) { - cl->mark = st->cmark; /* chain it for later traversal */ - st->cmark = cl; + if (!cl->c.marked) { + cl->c.marked = 1; + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markobject(st, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nupvalues); + protomark(cl->l.p); + for (i=0; il.nupvalues; i++) { /* mark its upvalues */ + UpVal *u = cl->l.upvals[i].heap; + if (u && !u->marked) { + u->marked = 1; + markobject(st, &u->val); + } + } + } } } @@ -120,29 +138,6 @@ static void marktagmethods (global_State *G, GCState *st) { } -static void traverseclosure (GCState *st, Closure *cl) { - if (cl->isC) { - int i; - for (i=0; inupvalues; i++) /* mark its upvalues */ - markobject(st, &cl->u.c.upvalue[i]); - } - else { - int i; - lua_assert(cl->nupvalues == cl->u.l.p->nupvalues); - protomark(cl->u.l.p); - for (i=0; inupvalues; i++) { /* mark its upvalues */ - if (luaF_isclosed(cl, i)) { - UpVal *u = cast(UpVal *, cl->u.l.upvals[i]); - if (!u->marked) { - u->marked = 1; - markobject(st, &u->val); - } - } - } - } -} - - static void removekey (Node *n) { lua_assert(ttype(val(n)) == LUA_TNIL); if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER) @@ -172,25 +167,16 @@ static void traversetable (GCState *st, Hash *h) { static void markall (lua_State *L) { GCState st; - st.cmark = NULL; st.tmark = NULL; marktagmethods(G(L), &st); /* mark tag methods */ markstacks(L, &st); /* mark all stacks */ marktable(&st, G(L)->type2tag); marktable(&st, G(L)->registry); marktable(&st, G(L)->weakregistry); - for (;;) { /* mark tables and closures */ - if (st.cmark) { - Closure *cl = st.cmark; /* get first closure from list */ - st.cmark = cl->mark; /* remove it from list */ - traverseclosure(&st, cl); - } - else if (st.tmark) { - Hash *h = st.tmark; /* get first table from list */ - st.tmark = h->mark; /* remove it from list */ - traversetable(&st, h); - } - else break; /* nothing else to mark */ + while (st.tmark) { /* mark tables */ + Hash *h = st.tmark; /* get first table from list */ + st.tmark = h->mark; /* remove it from list */ + traversetable(&st, h); } } @@ -204,7 +190,7 @@ static int hasmark (const TObject *o) { case LUA_TTABLE: return ismarked(hvalue(o)); case LUA_TFUNCTION: - return ismarked(clvalue(o)); + return clvalue(o)->c.marked; default: /* number, nil */ return 1; } @@ -252,12 +238,12 @@ static void collectproto (lua_State *L) { static void collectclosure (lua_State *L, Closure **p) { Closure *curr; while ((curr = *p) != NULL) { - if (ismarked(curr)) { - curr->mark = curr; /* unmark */ - p = &curr->next; + if (curr->c.marked) { + curr->c.marked = 0; + p = &curr->c.next; } else { - *p = curr->next; + *p = curr->c.next; luaF_freeclosure(L, curr); } } diff --git a/llimits.h b/llimits.h index 40815404..5b5b0203 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.31 2001/08/27 15:16:28 roberto Exp $ +** $Id: llimits.h,v 1.32 2001/09/07 17:39:10 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -51,9 +51,6 @@ typedef unsigned long lu_mem; /* an integer big enough to count the number of strings in use */ typedef long ls_nstr; -/* a bitmap with one bit for each upvalue used by a function */ -typedef unsigned long ls_bitup; - /* chars used as small naturals (so that `char' is reserved for characteres) */ typedef unsigned char lu_byte; @@ -109,9 +106,9 @@ typedef unsigned long Instruction; #endif -/* maximum number of upvalues */ +/* maximum number of upvalues per function */ #ifndef MAXUPVALUES -#define MAXUPVALUES (sizeof(ls_bitup)*CHAR_BIT) +#define MAXUPVALUES 32 #endif diff --git a/lobject.h b/lobject.h index 234b78b1..359055f3 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.112 2001/09/07 17:39:10 roberto Exp $ +** $Id: lobject.h,v 1.113 2001/09/25 17:08:46 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -38,7 +38,7 @@ typedef union { union TString *ts; union Udata *u; - struct Closure *cl; + union Closure *cl; struct Hash *h; struct UpVal *v; lua_Number n; /* LUA_TNUMBER */ @@ -177,26 +177,38 @@ typedef struct UpVal { /* ** Closures */ -typedef struct Closure { - short isC; /* 0 for Lua functions, 1 for C functions */ - short nupvalues; - struct Closure *next; - struct Closure *mark; /* marked closures (point to itself when not marked) */ - union { - struct { /* C functions */ - lua_CFunction f; - TObject upvalue[1]; - } c; - struct { /* Lua functions */ - struct Proto *p; - ls_bitup isopen; /* bitmap: bit==1 when upvals point to the stack */ - TObject *upvals[1]; /* may point to the stack or to an UpVal */ - } l; - } u; + +typedef struct CClosure { + lu_byte isC; /* 0 for Lua functions, 1 for C functions */ + lu_byte nupvalues; + lu_byte marked; + union Closure *next; + lua_CFunction f; + TObject upvalue[1]; +} CClosure; + + +typedef struct LClosureEntry { + TObject *val; + UpVal *heap; /* NULL when upvalue is still in the stack */ +} LClosureEntry; + +typedef struct LClosure { + lu_byte isC; + lu_byte nupvalues; + lu_byte marked; + union Closure *next; /* first four fields must be equal to CClosure!! */ + struct Proto *p; + LClosureEntry upvals[1]; +} LClosure; + +typedef union Closure { + CClosure c; + LClosure l; } Closure; -#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC) +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) @@ -223,9 +235,7 @@ typedef struct Hash { } Hash; -/* unmarked tables and closures are represented by pointing `mark' to -** themselves -*/ +/* unmarked tables are represented by pointing `mark' to themselves */ #define ismarked(x) ((x)->mark != (x)) diff --git a/ltests.c b/ltests.c index a33a9638..03d65657 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.88 2001/07/12 18:11:58 roberto Exp $ +** $Id: ltests.c,v 1.91 2001/09/07 17:39:10 roberto Exp $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -165,7 +165,7 @@ static int listcode (lua_State *L) { Proto *p; luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, l_s("Lua function expected")); - p = clvalue(luaA_index(L, 1))->u.l.p; + p = clvalue(luaA_index(L, 1))->l.p; lua_newtable(L); setnameval(L, l_s("maxstack"), p->maxstacksize); setnameval(L, l_s("numparams"), p->numparams); @@ -184,7 +184,7 @@ static int listk (lua_State *L) { int i; luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, l_s("Lua function expected")); - p = clvalue(luaA_index(L, 1))->u.l.p; + p = clvalue(luaA_index(L, 1))->l.p; lua_newtable(L); for (i=0; isizek; i++) { lua_pushnumber(L, i+1); @@ -202,7 +202,7 @@ static int listlocals (lua_State *L) { const l_char *name; luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, l_s("Lua function expected")); - p = clvalue(luaA_index(L, 1))->u.l.p; + p = clvalue(luaA_index(L, 1))->l.p; while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) lua_pushstring(L, name); return i-1; diff --git a/lvm.c b/lvm.c index 1fe4aad5..980ed113 100644 --- a/lvm.c +++ b/lvm.c @@ -64,8 +64,8 @@ int luaV_tostring (lua_State *L, TObject *obj) { static void traceexec (lua_State *L, lua_Hook linehook) { CallInfo *ci = L->ci; - int *lineinfo = ci_func(ci)->u.l.p->lineinfo; - int pc = (*ci->pc - ci_func(ci)->u.l.p->code) - 1; + int *lineinfo = ci_func(ci)->l.p->lineinfo; + int pc = (*ci->pc - ci_func(ci)->l.p->code) - 1; int newline; if (pc == 0) { /* may be first time? */ ci->line = 1; @@ -351,8 +351,8 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { ** Executes the given Lua function. Parameters are between [base,top). ** Returns n such that the the results are between [n,top). */ -StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { - const Proto *const tf = cl->u.l.p; +StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { + const Proto *const tf = cl->p; const Instruction *pc; lua_Hook linehook; if (tf->is_vararg) /* varargs? */ @@ -391,8 +391,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_GETUPVAL: { int b = GETARG_B(i); - lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base); - setobj(ra, cl->u.l.upvals[b]); + lua_assert(cl->upvals[b].heap || cl->upvals[b].val < base); + setobj(ra, cl->upvals[b].val); break; } case OP_GETGLOBAL: { @@ -411,8 +411,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_SETUPVAL: { int b = GETARG_B(i); - lua_assert(luaF_isclosed(cl, b) || cl->u.l.upvals[b] < base); - setobj(cl->u.l.upvals[b], ra); + lua_assert(cl->upvals[b].heap || cl->upvals[b].val < base); + setobj(cl->upvals[b].val, ra); break; } case OP_SETTABLE: { @@ -644,18 +644,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { p = tf->p[GETARG_Bc(i)]; nup = p->nupvalues; ncl = luaF_newLclosure(L, nup); - ncl->u.l.p = p; + ncl->l.p = p; for (j=0; ju.l.upvals[j] = cl->u.l.upvals[n]; - } + if (GET_OPCODE(*pc) == OP_GETUPVAL) + ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; else { lua_assert(GET_OPCODE(*pc) == OP_MOVE); - luaF_openentry(ncl, j); - ncl->u.l.upvals[j] = base + GETARG_B(*pc); + ncl->l.upvals[j].heap = NULL; + ncl->l.upvals[j].val = base + GETARG_B(*pc); } } luaF_LConlist(L, ncl); diff --git a/lvm.h b/lvm.h index de3fd45c..a9378de1 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 1.30 2001/06/05 18:17:01 roberto Exp $ +** $Id: lvm.h,v 1.31 2001/09/07 17:39:10 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,7 +22,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); void luaV_getglobal (lua_State *L, TString *s, StkId res); void luaV_setglobal (lua_State *L, TString *s, StkId val); -StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); +StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base); int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); void luaV_strconc (lua_State *L, int total, StkId top);