From 5938212748636d21d6f4b372481ab3b6dd6c7538 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 28 Sep 2009 13:32:50 -0300 Subject: information about upvalues (where they come from) kept in Proto structure, instead of sequence of pseudo-opcodes after OP_CLOSURE --- lapi.c | 4 ++-- ldebug.c | 11 +++-------- ldo.c | 6 +++--- ldump.c | 17 ++++++++++++++--- lfunc.c | 9 ++++----- lgc.c | 8 ++++---- lobject.h | 16 ++++++++++++---- lopcodes.h | 6 +----- lparser.c | 39 ++++++++++++++++++--------------------- lparser.h | 10 ++-------- ltests.c | 9 ++++----- luaconf.h | 9 +-------- lundump.c | 23 +++++++++++++++++------ lvm.c | 28 ++++++++++++---------------- 14 files changed, 97 insertions(+), 98 deletions(-) diff --git a/lapi.c b/lapi.c index c727cd6c..08a42516 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.90 2009/09/17 18:04:21 roberto Exp roberto $ +** $Id: lapi.c,v 2.91 2009/09/21 12:09:52 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -1043,7 +1043,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val) { Proto *p = f->l.p; if (!(1 <= n && n <= p->sizeupvalues)) return NULL; *val = f->l.upvals[n-1]->v; - return getstr(p->upvalues[n-1]); + return getstr(p->upvalues[n-1].name); } } diff --git a/ldebug.c b/ldebug.c index 00ab2284..80d367cd 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.54 2009/09/23 20:33:05 roberto Exp roberto $ +** $Id: ldebug.c,v 2.55 2009/09/28 12:37:17 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -328,7 +328,8 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, case OP_GETUPVAL: { if (reg == a) { int u = GETARG_B(i); /* upvalue index */ - *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + TString *tn = p->upvalues[u].name; + *name = tn ? getstr(tn) : "?"; what = "upvalue"; } break; @@ -364,12 +365,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, pc += b; /* do the jump */ break; } - case OP_CLOSURE: { - int nup = p->p[GETARG_Bx(i)]->nups; - pc += nup; /* do not 'execute' pseudo-instructions */ - lua_assert(pc <= lastpc); - break; - } default: if (testAMode(op) && reg == a) what = NULL; break; diff --git a/ldo.c b/ldo.c index 913375b0..d3c9906d 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.66 2009/07/15 17:26:14 roberto Exp roberto $ +** $Id: ldo.c,v 2.67 2009/09/14 14:30:39 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -577,10 +577,10 @@ static void f_parser (lua_State *L, void *ud) { : luaY_parser(L, p->z, &p->buff, p->name); setptvalue2s(L, L->top, tf); incr_top(L); - cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L))); cl->l.p = tf; setclvalue(L, L->top - 1, cl); - for (i = 0; i < tf->nups; i++) /* initialize upvalues */ + for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ cl->l.upvals[i] = luaF_newupval(L); } diff --git a/ldump.c b/ldump.c index e17c9363..e8337f03 100644 --- a/ldump.c +++ b/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 2.9 2006/09/11 14:07:24 roberto Exp roberto $ +** $Id: ldump.c,v 2.10 2008/07/03 14:25:05 roberto Exp roberto $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -108,6 +108,17 @@ static void DumpConstants(const Proto* f, DumpState* D) for (i=0; ip[i],f->source,D); } +static void DumpUpvalues(const Proto* f, DumpState* D) +{ + int i,n=f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i].instack, D); + DumpChar(f->upvalues[i].idx, D); + } +} + static void DumpDebug(const Proto* f, DumpState* D) { int i,n; @@ -123,7 +134,7 @@ static void DumpDebug(const Proto* f, DumpState* D) } n= (D->strip) ? 0 : f->sizeupvalues; DumpInt(n,D); - for (i=0; iupvalues[i],D); + for (i=0; iupvalues[i].name,D); } static void DumpFunction(const Proto* f, const TString* p, DumpState* D) @@ -131,12 +142,12 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D) DumpString((f->source==p || D->strip) ? NULL : f->source,D); DumpInt(f->linedefined,D); DumpInt(f->lastlinedefined,D); - DumpChar(f->nups,D); DumpChar(f->numparams,D); DumpChar(f->is_vararg,D); DumpChar(f->maxstacksize,D); DumpCode(f,D); DumpConstants(f,D); + DumpUpvalues(f,D); DumpDebug(f,D); } diff --git a/lfunc.c b/lfunc.c index f4c35a2e..c6c63f2e 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.13 2007/02/07 17:48:52 roberto Exp roberto $ +** $Id: lfunc.c,v 2.14 2009/04/17 14:40:13 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -121,16 +121,15 @@ Proto *luaF_newproto (lua_State *L) { f->sizep = 0; f->code = NULL; f->sizecode = 0; + f->lineinfo = NULL; f->sizelineinfo = 0; - f->sizeupvalues = 0; - f->nups = 0; f->upvalues = NULL; + f->sizeupvalues = 0; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; - f->lineinfo = NULL; - f->sizelocvars = 0; f->locvars = NULL; + f->sizelocvars = 0; f->linedefined = 0; f->lastlinedefined = 0; f->source = NULL; diff --git a/lgc.c b/lgc.c index a3680f1e..06a5a249 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.55 2009/07/16 16:26:09 roberto Exp roberto $ +** $Id: lgc.c,v 2.56 2009/09/28 13:50:34 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -349,8 +349,8 @@ static void traverseproto (global_State *g, Proto *f) { for (i=0; isizek; i++) /* mark literals */ markvalue(g, &f->k[i]); for (i=0; isizeupvalues; i++) { /* mark upvalue names */ - if (f->upvalues[i]) - stringmark(f->upvalues[i]); + if (f->upvalues[i].name) + stringmark(f->upvalues[i].name); } for (i=0; isizep; i++) /* mark nested protos */ markobject(g, f->p[i]); @@ -371,7 +371,7 @@ static void traverseclosure (global_State *g, Closure *cl) { } else { int i; - lua_assert(cl->l.nupvalues == cl->l.p->nups); + lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); markobject(g, cl->l.p); for (i=0; il.nupvalues; i++) /* mark its upvalues */ markobject(g, cl->l.upvals[i]); diff --git a/lobject.h b/lobject.h index 10eb363f..8b93f70a 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.27 2009/06/18 16:36:40 roberto Exp roberto $ +** $Id: lobject.h,v 2.28 2009/07/15 18:37:19 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -227,6 +227,15 @@ typedef union Udata { +/* +** Upvalues from a function prototype +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ +} Upvaldesc; + /* ** Function Prototypes @@ -238,9 +247,9 @@ typedef struct Proto { struct Proto **p; /* functions defined inside the function */ int *lineinfo; /* map from opcodes to source lines */ struct LocVar *locvars; /* information about local variables */ - TString **upvalues; /* upvalue names */ + Upvaldesc *upvalues; /* upvalue information */ TString *source; - int sizeupvalues; + int sizeupvalues; /* size of 'upvalues' */ int sizek; /* size of `k' */ int sizecode; int sizelineinfo; @@ -249,7 +258,6 @@ typedef struct Proto { int linedefined; int lastlinedefined; GCObject *gclist; - lu_byte nups; /* number of upvalues */ lu_byte numparams; lu_byte is_vararg; lu_byte maxstacksize; diff --git a/lopcodes.h b/lopcodes.h index 866c1641..41910d1b 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.129 2009/03/09 15:27:56 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.130 2009/09/23 20:33:05 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -251,10 +251,6 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ (*) All `skips' (pc++) assume that next instruction is a jump. - (*) The OP_CLOSURE instruction is followed by a sequence of - instructions coding the upvalues: OP_MOVE A B if upvalue is local B, - or OP_GETUPVAL A B if upvalue is enclosing upvalue B. - ===========================================================================*/ diff --git a/lparser.c b/lparser.c index 29fd747c..935526ce 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.65 2009/08/10 20:41:04 roberto Exp roberto $ +** $Id: lparser.c,v 2.66 2009/09/23 20:14:00 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -188,23 +188,24 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { int i; Proto *f = fs->f; int oldsize = f->sizeupvalues; - for (i=0; inups; i++) { - if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { - lua_assert(f->upvalues[i] == name); + int instk = (v->k == VLOCAL); + lua_assert(instk || v->k == VUPVAL); + for (i=0; inups; i++) { + if (f->upvalues[i].instack == instk && f->upvalues[i].idx == v->u.s.info) { + lua_assert(f->upvalues[i].name == name); return i; } } /* new one */ - luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); - luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, - TString *, MAX_INT, "upvalues"); - while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; - f->upvalues[f->nups] = name; + luaY_checklimit(fs, fs->nups + 1, UCHAR_MAX, "upvalues"); + luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, UCHAR_MAX, "upvalues"); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; + f->upvalues[fs->nups].name = name; luaC_objbarrier(fs->L, f, name); - lua_assert(v->k == VLOCAL || v->k == VUPVAL); - fs->upvalues[f->nups].k = cast_byte(v->k); - fs->upvalues[f->nups].info = cast_byte(v->u.s.info); - return f->nups++; + f->upvalues[fs->nups].instack = cast_byte(instk); + f->upvalues[fs->nups].idx = cast_byte(v->u.s.info); + return fs->nups++; } @@ -316,17 +317,12 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { FuncState *fs = ls->fs->prev; Proto *f = fs->f; int oldsize = f->sizep; - int i; luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); while (oldsize < f->sizep) f->p[oldsize++] = NULL; f->p[fs->np++] = func->f; luaC_objbarrier(ls->L, f, func->f); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); - for (i=0; if->nups; i++) { - OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; - luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); - } } @@ -343,6 +339,7 @@ static void open_func (LexState *ls, FuncState *fs) { fs->freereg = 0; fs->nk = 0; fs->np = 0; + fs->nups = 0; fs->nlocvars = 0; fs->nactvar = 0; fs->bl = NULL; @@ -376,8 +373,8 @@ static void close_func (LexState *ls) { f->sizep = fs->np; luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); f->sizelocvars = fs->nlocvars; - luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); - f->sizeupvalues = f->nups; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; lua_assert(fs->bl == NULL); ls->fs = fs->prev; L->top -= 2; /* remove table and prototype from the stack */ @@ -402,7 +399,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { close_func(&lexstate); L->top--; lua_assert(funcstate.prev == NULL); - lua_assert(funcstate.f->nups == 0); + lua_assert(funcstate.nups == 0); lua_assert(lexstate.fs == NULL); return funcstate.f; } diff --git a/lparser.h b/lparser.h index 0e06b1ad..5e1856e2 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.57 2006/03/09 18:14:31 roberto Exp roberto $ +** $Id: lparser.h,v 1.58 2008/05/08 15:44:51 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -46,12 +46,6 @@ typedef struct expdesc { } expdesc; -typedef struct upvaldesc { - lu_byte k; - lu_byte info; -} upvaldesc; - - typedef struct vardesc { unsigned short idx; } vardesc; @@ -76,7 +70,7 @@ typedef struct FuncState { int np; /* number of elements in `p' */ short nlocvars; /* number of elements in `locvars' */ lu_byte nactvar; /* number of active local variables */ - upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + lu_byte nups; /* number of upvalues */ vardesc actvar[LUAI_MAXVARS]; /* declared-variable stack */ } FuncState; diff --git a/ltests.c b/ltests.c index 0becc766..77677680 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.71 2009/09/14 14:30:39 roberto Exp roberto $ +** $Id: ltests.c,v 2.72 2009/09/17 18:04:21 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -248,8 +248,8 @@ static void checkproto (global_State *g, Proto *f) { checkobjref(g, fgc, rawtsvalue(f->k+i)); } for (i=0; isizeupvalues; i++) { - if (f->upvalues[i]) - checkobjref(g, fgc, f->upvalues[i]); + if (f->upvalues[i].name) + checkobjref(g, fgc, f->upvalues[i].name); } for (i=0; isizep; i++) { if (f->p[i]) @@ -273,7 +273,7 @@ static void checkclosure (global_State *g, Closure *cl) { } else { int i; - lua_assert(cl->l.nupvalues == cl->l.p->nups); + lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); checkobjref(g, clgc, cl->l.p); for (i=0; il.nupvalues; i++) { if (cl->l.upvals[i]) { @@ -493,7 +493,6 @@ static int get_limits (lua_State *L) { setnameval(L, "LFPF", LFIELDS_PER_FLUSH); setnameval(L, "MAXVARS", LUAI_MAXVARS); setnameval(L, "MAXSTACK", MAXSTACK); - setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES); setnameval(L, "NUM_OPCODES", NUM_OPCODES); return 1; } diff --git a/luaconf.h b/luaconf.h index 1358633d..c18681dc 100644 --- a/luaconf.h +++ b/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.108 2009/07/15 17:57:30 roberto Exp roberto $ +** $Id: luaconf.h,v 1.109 2009/08/25 19:58:08 roberto Exp roberto $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -461,13 +461,6 @@ #define LUAI_MAXVARS 200 -/* -@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function -@* (must be smaller than 250). -*/ -#define LUAI_MAXUPVALUES 60 - - /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. */ diff --git a/lundump.c b/lundump.c index bdebe74b..4ee11ac6 100644 --- a/lundump.c +++ b/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 2.9 2008/04/07 18:44:23 roberto Exp roberto $ +** $Id: lundump.c,v 2.10 2009/04/30 17:42:21 roberto Exp roberto $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -133,6 +133,20 @@ static void LoadConstants(LoadState* S, Proto* f) for (i=0; ip[i]=LoadFunction(S,f->source); } +static void LoadUpvalues(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,Upvaldesc); + f->sizeupvalues=n; + for (i=0; iupvalues[i].name=NULL; + for (i=0; iupvalues[i].instack=LoadChar(S); + f->upvalues[i].idx=LoadChar(S); + } +} + static void LoadDebug(LoadState* S, Proto* f) { int i,n; @@ -151,10 +165,7 @@ static void LoadDebug(LoadState* S, Proto* f) f->locvars[i].endpc=LoadInt(S); } n=LoadInt(S); - f->upvalues=luaM_newvector(S->L,n,TString*); - f->sizeupvalues=n; - for (i=0; iupvalues[i]=NULL; - for (i=0; iupvalues[i]=LoadString(S); + for (i=0; iupvalues[i].name=LoadString(S); } static Proto* LoadFunction(LoadState* S, TString* p) @@ -166,12 +177,12 @@ static Proto* LoadFunction(LoadState* S, TString* p) f->source=LoadString(S); if (f->source==NULL) f->source=p; f->linedefined=LoadInt(S); f->lastlinedefined=LoadInt(S); - f->nups=LoadByte(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); LoadCode(S,f); LoadConstants(S,f); + LoadUpvalues(S,f); LoadDebug(S,f); S->L->top--; G(S->L)->nCcalls--; diff --git a/lvm.c b/lvm.c index f3a452de..7473d73b 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.96 2009/08/07 16:17:41 roberto Exp roberto $ +** $Id: lvm.c,v 2.97 2009/09/23 20:33:05 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -773,22 +773,18 @@ void luaV_execute (lua_State *L) { continue; } case OP_CLOSURE: { - Proto *p; - Closure *ncl; - int nup, j; - p = cl->p->p[GETARG_Bx(i)]; - nup = p->nups; - ncl = luaF_newLclosure(L, nup, cl->env); + Proto *p = cl->p->p[GETARG_Bx(i)]; /* prototype for new closure */ + int nup = p->sizeupvalues; + Closure *ncl = luaF_newLclosure(L, nup, cl->env); + Upvaldesc *uv = p->upvalues; + int j; ncl->l.p = p; - setclvalue(L, ra, ncl); - for (j=0; ju.l.savedpc++; - if (GET_OPCODE(u) == OP_GETUPVAL) - ncl->l.upvals[j] = cl->upvals[GETARG_B(u)]; - else { - lua_assert(GET_OPCODE(u) == OP_MOVE); - ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(u)); - } + setclvalue(L, ra, ncl); /* anchor new closure in stack */ + for (j = 0; j < nup; j++) { /* fill in upvalues */ + if (uv[j].instack) /* upvalue refers to local variable? */ + ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx); + else /* get upvalue from enclosing function */ + ncl->l.upvals[j] = cl->upvals[uv[j].idx]; } Protect(luaC_checkGC(L)); continue; -- cgit v1.2.3-55-g6feb