aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-10-04 16:01:53 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-10-04 16:01:53 -0300
commit5ee87acd6b920a6a122277cd817aea4cfd618671 (patch)
tree5e931c1db32c2be6378fde498ffcc5ee9dec0d6a
parent5d834bdf571ef3ee343b21fde2d49de1e4ea08b4 (diff)
downloadlua-5ee87acd6b920a6a122277cd817aea4cfd618671.tar.gz
lua-5ee87acd6b920a6a122277cd817aea4cfd618671.tar.bz2
lua-5ee87acd6b920a6a122277cd817aea4cfd618671.zip
small optimization for boolean constants + new format for SETLIST opcode
-rw-r--r--lcode.c29
-rw-r--r--lcode.h3
-rw-r--r--lopcodes.c6
-rw-r--r--lopcodes.h13
-rw-r--r--lparser.c10
-rw-r--r--lvm.c18
6 files changed, 50 insertions, 29 deletions
diff --git a/lcode.c b/lcode.c
index 3895b7d8..504f57ef 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.5 2004/07/16 13:30:53 roberto Exp roberto $ 2** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -243,7 +243,14 @@ int luaK_numberK (FuncState *fs, lua_Number r) {
243} 243}
244 244
245 245
246static int nil_constant (FuncState *fs) { 246static int boolK (FuncState *fs, int b) {
247 TValue o;
248 setbvalue(&o, b);
249 return addk(fs, &o, &o);
250}
251
252
253static int nilK (FuncState *fs) {
247 TValue k, v; 254 TValue k, v;
248 setnilvalue(&v); 255 setnilvalue(&v);
249 /* cannot use nil as key; instead use table itself to represent nil */ 256 /* cannot use nil as key; instead use table itself to represent nil */
@@ -417,9 +424,11 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
417int luaK_exp2RK (FuncState *fs, expdesc *e) { 424int luaK_exp2RK (FuncState *fs, expdesc *e) {
418 luaK_exp2val(fs, e); 425 luaK_exp2val(fs, e);
419 switch (e->k) { 426 switch (e->k) {
427 case VTRUE:
428 case VFALSE:
420 case VNIL: { 429 case VNIL: {
421 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ 430 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
422 e->info = nil_constant(fs); 431 e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
423 e->k = VK; 432 e->k = VK;
424 return RKASK(e->info); 433 return RKASK(e->info);
425 } 434 }
@@ -735,3 +744,17 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
735 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); 744 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
736} 745}
737 746
747
748void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
749 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
750 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
751 lua_assert(tostore != 0);
752 if (c <= MAXARG_C)
753 luaK_codeABC(fs, OP_SETLIST, base, b, c);
754 else {
755 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
756 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
757 }
758 fs->freereg = base + 1; /* free registers with list values */
759}
760
diff --git a/lcode.h b/lcode.h
index 65dea30e..700c47d4 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp roberto $ 2** $Id: lcode.h,v 1.39 2004/05/31 18:51:50 roberto Exp $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -72,6 +72,7 @@ int luaK_getlabel (FuncState *fs);
72void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 72void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
73void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 73void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
74void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); 74void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
75void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
75 76
76 77
77#endif 78#endif
diff --git a/lopcodes.c b/lopcodes.c
index b201238b..dc5be46f 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.27 2004/05/31 18:51:50 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.28 2004/07/16 13:15:32 roberto Exp $
3** See Copyright Notice in lua.h 3** See Copyright Notice in lua.h
4*/ 4*/
5 5
@@ -49,7 +49,6 @@ const char *const luaP_opnames[NUM_OPCODES] = {
49 "TFORLOOP", 49 "TFORLOOP",
50 "TFORPREP", 50 "TFORPREP",
51 "SETLIST", 51 "SETLIST",
52 "SETLISTO",
53 "CLOSE", 52 "CLOSE",
54 "CLOSURE", 53 "CLOSURE",
55 "VARARG" 54 "VARARG"
@@ -92,8 +91,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
92 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 91 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
93 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ 92 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
94 ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_TFORPREP */ 93 ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_TFORPREP */
95 ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLIST */ 94 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
96 ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */
97 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ 95 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
98 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 96 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
99 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 97 ,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 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.110 2004/06/29 18:49:02 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.111 2004/08/04 20:18:13 roberto Exp $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -198,8 +198,7 @@ OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
198OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next; 198OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
199 pc+=sBx */ 199 pc+=sBx */
200 200
201OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */ 201OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
202OP_SETLISTO,/* A Bx */
203 202
204OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ 203OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
205OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ 204OP_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 */
219 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. 218 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
220 219
221 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and 220 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222 set top (like in OP_CALL). 221 set top (like in OP_CALL with C == 0).
223 222
224 (*) In OP_RETURN, if (B == 0) then return up to `top' 223 (*) In OP_RETURN, if (B == 0) then return up to `top'
225 224
226 (*) For comparisons, B specifies what conditions the test should accept. 225 (*) In OP_SETLIST, if (B == 0) then B = `top';
226 if (C == 0) then next `instruction' is real C
227
228 (*) For comparisons, A specifies what condition the test should accept
229 (true or false).
227 230
228 (*) All `skips' (pc++) assume that next instruction is a jump 231 (*) All `skips' (pc++) assume that next instruction is a jump
229===========================================================================*/ 232===========================================================================*/
diff --git a/lparser.c b/lparser.c
index 06fd8951..501b585b 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $ 2** $Id: lparser.c,v 2.5 2004/05/31 18:51:50 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -475,9 +475,8 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
475 luaK_exp2nextreg(fs, &cc->v); 475 luaK_exp2nextreg(fs, &cc->v);
476 cc->v.k = VVOID; 476 cc->v.k = VVOID;
477 if (cc->tostore == LFIELDS_PER_FLUSH) { 477 if (cc->tostore == LFIELDS_PER_FLUSH) {
478 luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */ 478 luaK_setlist(fs, cc->t->info, cc->na, cc->tostore); /* flush */
479 cc->tostore = 0; /* no more items pending */ 479 cc->tostore = 0; /* no more items pending */
480 fs->freereg = cc->t->info + 1; /* free registers */
481 } 480 }
482} 481}
483 482
@@ -486,15 +485,14 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
486 if (cc->tostore == 0) return; 485 if (cc->tostore == 0) return;
487 if (hasmultret(cc->v.k)) { 486 if (hasmultret(cc->v.k)) {
488 luaK_setmultret(fs, &cc->v); 487 luaK_setmultret(fs, &cc->v);
489 luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); 488 luaK_setlist(fs, cc->t->info, cc->na, LUA_MULTRET);
490 cc->na--; /* do not count last expression (unknown number of elements) */ 489 cc->na--; /* do not count last expression (unknown number of elements) */
491 } 490 }
492 else { 491 else {
493 if (cc->v.k != VVOID) 492 if (cc->v.k != VVOID)
494 luaK_exp2nextreg(fs, &cc->v); 493 luaK_exp2nextreg(fs, &cc->v);
495 luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); 494 luaK_setlist(fs, cc->t->info, cc->na, cc->tostore);
496 } 495 }
497 fs->freereg = cc->t->info + 1; /* free registers */
498} 496}
499 497
500 498
diff --git a/lvm.c b/lvm.c
index b8483512..65db54a8 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.13 2004/08/12 14:19:51 roberto Exp roberto $ 2** $Id: lvm.c,v 2.14 2004/09/15 20:39:42 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -710,21 +710,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
710 dojump(L, pc, GETARG_sBx(i)); 710 dojump(L, pc, GETARG_sBx(i));
711 continue; 711 continue;
712 } 712 }
713 case OP_SETLIST: 713 case OP_SETLIST: {
714 case OP_SETLISTO: { 714 int n = GETARG_B(i);
715 int bc = GETARG_Bx(i); 715 int c = GETARG_C(i);
716 int n, last; 716 int last;
717 Table *h; 717 Table *h;
718 runtime_check(L, ttistable(ra)); 718 runtime_check(L, ttistable(ra));
719 h = hvalue(ra); 719 h = hvalue(ra);
720 if (GET_OPCODE(i) == OP_SETLIST) 720 if (n == 0) {
721 n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
722 else {
723 n = L->top - ra - 1; 721 n = L->top - ra - 1;
724 L->top = L->ci->top; 722 L->top = L->ci->top;
725 } 723 }
726 bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ 724 if (c == 0) c = cast(int, *pc++);
727 last = bc + n + LUA_FIRSTINDEX - 1; 725 last = ((c-1)*LFIELDS_PER_FLUSH) + n + LUA_FIRSTINDEX - 1;
728 if (last > h->sizearray) /* needs more space? */ 726 if (last > h->sizearray) /* needs more space? */
729 luaH_resize(L, h, last, h->lsizenode); /* pre-alloc it at once */ 727 luaH_resize(L, h, last, h->lsizenode); /* pre-alloc it at once */
730 for (; n > 0; n--) { 728 for (; n > 0; n--) {