information about upvalues (where they come from) kept in Proto structure,

instead of sequence of pseudo-opcodes after OP_CLOSURE
This commit is contained in:
Roberto Ierusalimschy 2009-09-28 13:32:50 -03:00
parent 1829911d7c
commit 5938212748
14 changed files with 97 additions and 98 deletions

4
lapi.c
View File

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

View File

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

6
ldo.c
View File

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

17
ldump.c
View File

@ -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; i<n; i++) DumpFunction(f->p[i],f->source,D);
}
static void DumpUpvalues(const Proto* f, DumpState* D)
{
int i,n=f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++)
{
DumpChar(f->upvalues[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; i<n; i++) DumpString(f->upvalues[i],D);
for (i=0; i<n; i++) DumpString(f->upvalues[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);
}

View File

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

8
lgc.c
View File

@ -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; i<f->sizek; i++) /* mark literals */
markvalue(g, &f->k[i]);
for (i=0; i<f->sizeupvalues; 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; i<f->sizep; 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; i<cl->l.nupvalues; i++) /* mark its upvalues */
markobject(g, cl->l.upvals[i]);

View File

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

View File

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

View File

@ -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; i<f->nups; 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; i<fs->nups; 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; i<func->f->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;
}

View File

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

View File

@ -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; i<f->sizeupvalues; 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; i<f->sizep; 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; i<cl->l.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;
}

View File

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

View File

@ -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; i<n; i++) f->p[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; i<n; i++) f->upvalues[i].name=NULL;
for (i=0; i<n; i++)
{
f->upvalues[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; i<n; i++) f->upvalues[i]=NULL;
for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
for (i=0; i<n; i++) f->upvalues[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--;

28
lvm.c
View File

@ -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; j<nup; j++) {
Instruction u = *ci->u.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;