new definitions for closure structures

This commit is contained in:
Roberto Ierusalimschy 2001-10-02 13:45:03 -03:00
parent 6f936bc793
commit 15462edb0f
11 changed files with 137 additions and 156 deletions

8
lapi.c
View File

@ -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);

View File

@ -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 */

15
ldo.c
View File

@ -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; n<nup; n++) /* copy upvalues as extra arguments */
setobj(L->top++, &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;

62
lfunc.c
View File

@ -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; i<cl->nupvalues; 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; i<cl->nupvalues; 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);
}

View File

@ -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);

78
lgc.c
View File

@ -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; i<cl->c.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; i<cl->l.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; i<cl->nupvalues; 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; i<cl->nupvalues; 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);
}
}

View File

@ -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

View File

@ -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))

View File

@ -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; i<p->sizek; 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;

30
lvm.c
View File

@ -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; j<nup; j++, pc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL) {
int n = GETARG_B(*pc);
if (!luaF_isclosed(cl, n))
luaF_openentry(ncl, j);
ncl->u.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);

4
lvm.h
View File

@ -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);