better organization for fields in struct 'expdesc'

This commit is contained in:
Roberto Ierusalimschy 2010-07-02 17:42:40 -03:00
parent 7631c29b2f
commit 6a02bbe1e2
4 changed files with 67 additions and 62 deletions

85
lcode.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 2.46 2010/04/17 12:46:32 roberto Exp roberto $ ** $Id: lcode.c,v 2.47 2010/06/30 14:11:17 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -266,7 +266,7 @@ static void freereg (FuncState *fs, int reg) {
static void freeexp (FuncState *fs, expdesc *e) { static void freeexp (FuncState *fs, expdesc *e) {
if (e->k == VNONRELOC) if (e->k == VNONRELOC)
freereg(fs, e->u.s.info); freereg(fs, e->u.info);
} }
@ -352,7 +352,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
void luaK_setoneret (FuncState *fs, expdesc *e) { void luaK_setoneret (FuncState *fs, expdesc *e) {
if (e->k == VCALL) { /* expression is an open function call? */ if (e->k == VCALL) { /* expression is an open function call? */
e->k = VNONRELOC; e->k = VNONRELOC;
e->u.s.info = GETARG_A(getcode(fs, e)); e->u.info = GETARG_A(getcode(fs, e));
} }
else if (e->k == VVARARG) { else if (e->k == VVARARG) {
SETARG_B(getcode(fs, e), 2); SETARG_B(getcode(fs, e), 2);
@ -368,20 +368,20 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
break; break;
} }
case VUPVAL: { case VUPVAL: {
e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
e->k = VRELOCABLE; e->k = VRELOCABLE;
break; break;
} }
case VINDEXED: { case VINDEXED: {
freereg(fs, e->u.s.aux); freereg(fs, e->u.ind.idx);
freereg(fs, e->u.s.info); freereg(fs, e->u.ind.t);
e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE; e->k = VRELOCABLE;
break; break;
} }
case VINDEXEDUP: { case VINDEXEDUP: {
freereg(fs, e->u.s.aux); freereg(fs, e->u.ind.idx);
e->u.s.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.s.info, e->u.s.aux); e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE; e->k = VRELOCABLE;
break; break;
} }
@ -413,7 +413,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
break; break;
} }
case VK: { case VK: {
luaK_codek(fs, reg, e->u.s.info); luaK_codek(fs, reg, e->u.info);
break; break;
} }
case VKNUM: { case VKNUM: {
@ -426,8 +426,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
break; break;
} }
case VNONRELOC: { case VNONRELOC: {
if (reg != e->u.s.info) if (reg != e->u.info)
luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
break; break;
} }
default: { default: {
@ -435,7 +435,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
return; /* nothing to do... */ return; /* nothing to do... */
} }
} }
e->u.s.info = reg; e->u.info = reg;
e->k = VNONRELOC; e->k = VNONRELOC;
} }
@ -451,7 +451,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) {
static void exp2reg (FuncState *fs, expdesc *e, int reg) { static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg); discharge2reg(fs, e, reg);
if (e->k == VJMP) if (e->k == VJMP)
luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
if (hasjumps(e)) { if (hasjumps(e)) {
int final; /* position after whole expression */ int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */ int p_f = NO_JUMP; /* position of an eventual LOAD false */
@ -467,7 +467,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
patchlistaux(fs, e->t, final, reg, p_t); patchlistaux(fs, e->t, final, reg, p_t);
} }
e->f = e->t = NO_JUMP; e->f = e->t = NO_JUMP;
e->u.s.info = reg; e->u.info = reg;
e->k = VNONRELOC; e->k = VNONRELOC;
} }
@ -483,14 +483,14 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
int luaK_exp2anyreg (FuncState *fs, expdesc *e) { int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
if (e->k == VNONRELOC) { if (e->k == VNONRELOC) {
if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
exp2reg(fs, e, e->u.s.info); /* put value on it */ exp2reg(fs, e, e->u.info); /* put value on it */
return e->u.s.info; return e->u.info;
} }
} }
luaK_exp2nextreg(fs, e); /* default */ luaK_exp2nextreg(fs, e); /* default */
return e->u.s.info; return e->u.info;
} }
@ -515,20 +515,20 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
case VFALSE: case VFALSE:
case VNIL: { case VNIL: {
if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
e->u.s.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
e->k = VK; e->k = VK;
return RKASK(e->u.s.info); return RKASK(e->u.info);
} }
else break; else break;
} }
case VKNUM: { case VKNUM: {
e->u.s.info = luaK_numberK(fs, e->u.nval); e->u.info = luaK_numberK(fs, e->u.nval);
e->k = VK; e->k = VK;
/* go through */ /* go through */
} }
case VK: { case VK: {
if (e->u.s.info <= MAXINDEXRK) /* constant fits in argC? */ if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
return RKASK(e->u.s.info); return RKASK(e->u.info);
else break; else break;
} }
default: break; default: break;
@ -542,22 +542,22 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var->k) { switch (var->k) {
case VLOCAL: { case VLOCAL: {
freeexp(fs, ex); freeexp(fs, ex);
exp2reg(fs, ex, var->u.s.info); exp2reg(fs, ex, var->u.info);
return; return;
} }
case VUPVAL: { case VUPVAL: {
int e = luaK_exp2anyreg(fs, ex); int e = luaK_exp2anyreg(fs, ex);
luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
break; break;
} }
case VINDEXED: { case VINDEXED: {
int e = luaK_exp2RK(fs, ex); int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); luaK_codeABC(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, e);
break; break;
} }
case VINDEXEDUP: { case VINDEXEDUP: {
int e = luaK_exp2RK(fs, ex); int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETTABUP, var->u.s.info, var->u.s.aux, e); luaK_codeABC(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, e);
break; break;
} }
default: { default: {
@ -574,16 +574,16 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
luaK_exp2anyreg(fs, e); luaK_exp2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
func = fs->freereg; func = fs->freereg;
luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); luaK_codeABC(fs, OP_SELF, func, e->u.info, luaK_exp2RK(fs, key));
freeexp(fs, key); freeexp(fs, key);
luaK_reserveregs(fs, 2); luaK_reserveregs(fs, 2);
e->u.s.info = func; e->u.info = func;
e->k = VNONRELOC; e->k = VNONRELOC;
} }
static void invertjump (FuncState *fs, expdesc *e) { static void invertjump (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e->u.s.info); Instruction *pc = getjumpcontrol(fs, e->u.info);
lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
GET_OPCODE(*pc) != OP_TEST); GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc))); SETARG_A(*pc, !(GETARG_A(*pc)));
@ -601,7 +601,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
} }
discharge2anyreg(fs, e); discharge2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
} }
@ -615,7 +615,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
} }
case VJMP: { case VJMP: {
invertjump(fs, e); invertjump(fs, e);
pc = e->u.s.info; pc = e->u.info;
break; break;
} }
case VFALSE: { case VFALSE: {
@ -645,7 +645,7 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
break; break;
} }
case VJMP: { case VJMP: {
pc = e->u.s.info; pc = e->u.info;
break; break;
} }
case VTRUE: { case VTRUE: {
@ -685,7 +685,7 @@ static void codenot (FuncState *fs, expdesc *e) {
case VNONRELOC: { case VNONRELOC: {
discharge2anyreg(fs, e); discharge2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
e->k = VRELOCABLE; e->k = VRELOCABLE;
break; break;
} }
@ -703,7 +703,8 @@ static void codenot (FuncState *fs, expdesc *e) {
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
lua_assert(!hasjumps(t)); lua_assert(!hasjumps(t));
t->u.s.aux = luaK_exp2RK(fs, k); t->u.ind.t = t->u.info;
t->u.ind.idx = luaK_exp2RK(fs, k);
t->k = (t->k == VUPVAL) ? VINDEXEDUP : VINDEXED; t->k = (t->k == VUPVAL) ? VINDEXEDUP : VINDEXED;
} }
@ -734,7 +735,7 @@ static void codearith (FuncState *fs, OpCode op,
freeexp(fs, e2); freeexp(fs, e2);
freeexp(fs, e1); freeexp(fs, e1);
} }
e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
e1->k = VRELOCABLE; e1->k = VRELOCABLE;
luaK_fixline(fs, line); luaK_fixline(fs, line);
} }
@ -752,7 +753,7 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
cond = 1; cond = 1;
} }
e1->u.s.info = condjump(fs, op, cond, o1, o2); e1->u.info = condjump(fs, op, cond, o1, o2);
e1->k = VJMP; e1->k = VJMP;
} }
@ -828,10 +829,10 @@ void luaK_posfix (FuncState *fs, BinOpr op,
case OPR_CONCAT: { case OPR_CONCAT: {
luaK_exp2val(fs, e2); luaK_exp2val(fs, e2);
if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
freeexp(fs, e1); freeexp(fs, e1);
SETARG_B(getcode(fs, e2), e1->u.s.info); SETARG_B(getcode(fs, e2), e1->u.info);
e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; e1->k = VRELOCABLE; e1->u.info = e2->u.info;
} }
else { else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.h,v 1.53 2010/02/26 20:40:29 roberto Exp roberto $ ** $Id: lcode.h,v 1.54 2010/04/17 12:46:32 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -36,7 +36,7 @@ typedef enum BinOpr {
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) #define getcode(fs,e) ((fs)->f->code[(e)->u.info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 2.87 2010/05/31 16:08:55 roberto Exp roberto $ ** $Id: lparser.c,v 2.88 2010/06/21 16:30:12 roberto Exp roberto $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -138,7 +138,7 @@ static TString *str_checkname (LexState *ls) {
static void init_exp (expdesc *e, expkind k, int i) { static void init_exp (expdesc *e, expkind k, int i) {
e->f = e->t = NO_JUMP; e->f = e->t = NO_JUMP;
e->k = k; e->k = k;
e->u.s.info = i; e->u.info = i;
} }
@ -226,7 +226,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
Upvaldesc, MAXUPVAL, "upvalues"); Upvaldesc, MAXUPVAL, "upvalues");
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
f->upvalues[fs->nups].instack = (v->k == VLOCAL); f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.s.info); f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name; f->upvalues[fs->nups].name = name;
luaC_objbarrier(fs->L, f, name); luaC_objbarrier(fs->L, f, name);
return fs->nups++; return fs->nups++;
@ -518,7 +518,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
checknext(ls, '='); checknext(ls, '=');
rkkey = luaK_exp2RK(fs, &key); rkkey = luaK_exp2RK(fs, &key);
expr(ls, &val); expr(ls, &val);
luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
fs->freereg = reg; /* free registers */ fs->freereg = reg; /* free registers */
} }
@ -528,7 +528,7 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
luaK_exp2nextreg(fs, &cc->v); luaK_exp2nextreg(fs, &cc->v);
cc->v.k = VVOID; cc->v.k = VVOID;
if (cc->tostore == LFIELDS_PER_FLUSH) { if (cc->tostore == LFIELDS_PER_FLUSH) {
luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
cc->tostore = 0; /* no more items pending */ cc->tostore = 0; /* no more items pending */
} }
} }
@ -538,13 +538,13 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
if (cc->tostore == 0) return; if (cc->tostore == 0) return;
if (hasmultret(cc->v.k)) { if (hasmultret(cc->v.k)) {
luaK_setmultret(fs, &cc->v); luaK_setmultret(fs, &cc->v);
luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
cc->na--; /* do not count last expression (unknown number of elements) */ cc->na--; /* do not count last expression (unknown number of elements) */
} }
else { else {
if (cc->v.k != VVOID) if (cc->v.k != VVOID)
luaK_exp2nextreg(fs, &cc->v); luaK_exp2nextreg(fs, &cc->v);
luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
} }
} }
@ -702,7 +702,7 @@ static void funcargs (LexState *ls, expdesc *f, int line) {
} }
} }
lua_assert(f->k == VNONRELOC); lua_assert(f->k == VNONRELOC);
base = f->u.s.info; /* base register for call */ base = f->u.info; /* base register for call */
if (hasmultret(args.k)) if (hasmultret(args.k))
nparams = LUA_MULTRET; /* open call */ nparams = LUA_MULTRET; /* open call */
else { else {
@ -976,20 +976,20 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v,
int conflict = 0; int conflict = 0;
for (; lh; lh = lh->prev) { for (; lh; lh = lh->prev) {
if (lh->v.k == ix) { if (lh->v.k == ix) {
if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ if (lh->v.u.ind.t == v->u.info) { /* conflict? */
conflict = 1; conflict = 1;
lh->v.k = VINDEXED; lh->v.k = VINDEXED;
lh->v.u.s.info = extra; /* previous assignment will use safe copy */ lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
} }
if (v->k == VLOCAL && lh->v.u.s.aux == v->u.s.info) { /* conflict? */ if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { /* conflict? */
conflict = 1; conflict = 1;
lua_assert(lh->v.k == VINDEXED); lua_assert(lh->v.k == VINDEXED);
lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
} }
} }
} }
if (conflict) { if (conflict) {
luaK_codeABC(fs, op, fs->freereg, v->u.s.info, 0); /* make copy */ luaK_codeABC(fs, op, fs->freereg, v->u.info, 0); /* make copy */
luaK_reserveregs(fs, 1); luaK_reserveregs(fs, 1);
} }
} }
@ -1108,7 +1108,7 @@ static int exp1 (LexState *ls) {
expr(ls, &e); expr(ls, &e);
luaK_exp2nextreg(ls->fs, &e); luaK_exp2nextreg(ls->fs, &e);
lua_assert(e.k == VNONRELOC); lua_assert(e.k == VNONRELOC);
reg = e.u.s.info; reg = e.u.info;
return reg; return reg;
} }

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.h,v 1.62 2010/02/26 20:40:29 roberto Exp roberto $ ** $Id: lparser.h,v 1.63 2010/03/12 19:14:06 roberto Exp roberto $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -25,8 +25,8 @@ typedef enum {
VKNUM, /* nval = numerical value */ VKNUM, /* nval = numerical value */
VLOCAL, /* info = local register */ VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in 'upvalues' */ VUPVAL, /* info = index of upvalue in 'upvalues' */
VINDEXED, /* info = table R/K; aux = index R/K */ VINDEXED, /* t = table register; idx = index R/K */
VINDEXEDUP, /* info = table upvalue; aux = R/K */ VINDEXEDUP, /* t = table upvalue; idx = index R/K */
VJMP, /* info = instruction pc */ VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */ VRELOCABLE, /* info = instruction pc */
VNONRELOC, /* info = result register */ VNONRELOC, /* info = result register */
@ -38,7 +38,11 @@ typedef enum {
typedef struct expdesc { typedef struct expdesc {
expkind k; expkind k;
union { union {
struct { int info, aux; } s; struct {
short idx;
lu_byte t;
} ind; /* for indexed variables */
int info;
lua_Number nval; lua_Number nval;
} u; } u;
int t; /* patch list of `exit when true' */ int t; /* patch list of `exit when true' */