Browse Source

small optimization for boolean constants + new format for SETLIST opcode

v5-2
Roberto Ierusalimschy 20 years ago
parent
commit
5ee87acd6b
  1. 29
      lcode.c
  2. 3
      lcode.h
  3. 6
      lopcodes.c
  4. 13
      lopcodes.h
  5. 10
      lparser.c
  6. 18
      lvm.c

29
lcode.c

@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.5 2004/07/16 13:30:53 roberto Exp roberto $
** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -243,7 +243,14 @@ int luaK_numberK (FuncState *fs, lua_Number r) {
}
static int nil_constant (FuncState *fs) {
static int boolK (FuncState *fs, int b) {
TValue o;
setbvalue(&o, b);
return addk(fs, &o, &o);
}
static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
@ -417,9 +424,11 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
switch (e->k) {
case VTRUE:
case VFALSE:
case VNIL: {
if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
e->info = nil_constant(fs);
e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
e->k = VK;
return RKASK(e->info);
}
@ -735,3 +744,17 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
}
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
int b = (tostore == LUA_MULTRET) ? 0 : tostore;
lua_assert(tostore != 0);
if (c <= MAXARG_C)
luaK_codeABC(fs, OP_SETLIST, base, b, c);
else {
luaK_codeABC(fs, OP_SETLIST, base, b, 0);
luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
}
fs->freereg = base + 1; /* free registers with list values */
}

3
lcode.h

@ -1,5 +1,5 @@
/*
** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp roberto $
** $Id: lcode.h,v 1.39 2004/05/31 18:51:50 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -72,6 +72,7 @@ int luaK_getlabel (FuncState *fs);
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
#endif

6
lopcodes.c

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.c,v 1.27 2004/05/31 18:51:50 roberto Exp roberto $
** $Id: lopcodes.c,v 1.28 2004/07/16 13:15:32 roberto Exp $
** See Copyright Notice in lua.h
*/
@ -49,7 +49,6 @@ const char *const luaP_opnames[NUM_OPCODES] = {
"TFORLOOP",
"TFORPREP",
"SETLIST",
"SETLISTO",
"CLOSE",
"CLOSURE",
"VARARG"
@ -92,8 +91,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_TFORPREP */
,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLIST */
,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */

13
lopcodes.h

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.110 2004/06/29 18:49:02 roberto Exp roberto $
** $Id: lopcodes.h,v 1.111 2004/08/04 20:18:13 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -198,8 +198,7 @@ OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
pc+=sBx */
OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */
OP_SETLISTO,/* A Bx */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
@ -219,11 +218,15 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
set top (like in OP_CALL).
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to `top'
(*) For comparisons, B specifies what conditions the test should accept.
(*) In OP_SETLIST, if (B == 0) then B = `top';
if (C == 0) then next `instruction' is real C
(*) For comparisons, A specifies what condition the test should accept
(true or false).
(*) All `skips' (pc++) assume that next instruction is a jump
===========================================================================*/

10
lparser.c

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $
** $Id: lparser.c,v 2.5 2004/05/31 18:51:50 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@ -475,9 +475,8 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
luaK_exp2nextreg(fs, &cc->v);
cc->v.k = VVOID;
if (cc->tostore == LFIELDS_PER_FLUSH) {
luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */
luaK_setlist(fs, cc->t->info, cc->na, cc->tostore); /* flush */
cc->tostore = 0; /* no more items pending */
fs->freereg = cc->t->info + 1; /* free registers */
}
}
@ -486,15 +485,14 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
if (cc->tostore == 0) return;
if (hasmultret(cc->v.k)) {
luaK_setmultret(fs, &cc->v);
luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
luaK_setlist(fs, cc->t->info, cc->na, LUA_MULTRET);
cc->na--; /* do not count last expression (unknown number of elements) */
}
else {
if (cc->v.k != VVOID)
luaK_exp2nextreg(fs, &cc->v);
luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1);
luaK_setlist(fs, cc->t->info, cc->na, cc->tostore);
}
fs->freereg = cc->t->info + 1; /* free registers */
}

18
lvm.c

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.13 2004/08/12 14:19:51 roberto Exp roberto $
** $Id: lvm.c,v 2.14 2004/09/15 20:39:42 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -710,21 +710,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
dojump(L, pc, GETARG_sBx(i));
continue;
}
case OP_SETLIST:
case OP_SETLISTO: {
int bc = GETARG_Bx(i);
int n, last;
case OP_SETLIST: {
int n = GETARG_B(i);
int c = GETARG_C(i);
int last;
Table *h;
runtime_check(L, ttistable(ra));
h = hvalue(ra);
if (GET_OPCODE(i) == OP_SETLIST)
n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
else {
if (n == 0) {
n = L->top - ra - 1;
L->top = L->ci->top;
}
bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */
last = bc + n + LUA_FIRSTINDEX - 1;
if (c == 0) c = cast(int, *pc++);
last = ((c-1)*LFIELDS_PER_FLUSH) + n + LUA_FIRSTINDEX - 1;
if (last > h->sizearray) /* needs more space? */
luaH_resize(L, h, last, h->lsizenode); /* pre-alloc it at once */
for (; n > 0; n--) {

Loading…
Cancel
Save