diff --git a/lcode.c b/lcode.c index 3895b7d8..504f57ef 100644 --- a/lcode.c +++ b/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 */ +} + diff --git a/lcode.h b/lcode.h index 65dea30e..700c47d4 100644 --- a/lcode.h +++ b/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 diff --git a/lopcodes.c b/lopcodes.c index b201238b..dc5be46f 100644 --- a/lopcodes.c +++ b/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 */ diff --git a/lopcodes.h b/lopcodes.h index 697eb5d6..43a90525 100644 --- a/lopcodes.h +++ b/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 ===========================================================================*/ diff --git a/lparser.c b/lparser.c index 06fd8951..501b585b 100644 --- a/lparser.c +++ b/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 */ } diff --git a/lvm.c b/lvm.c index b8483512..65db54a8 100644 --- a/lvm.c +++ b/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--) {