aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-07 10:13:11 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-07 10:13:11 -0300
commit031978798cc404c2c6757c564675d43a7da129ee (patch)
tree993e59994258f1a9176d7d260214b132d0b2baa9
parent14251c5a5640f73f8f98d2445900a3c3a8d472fb (diff)
downloadlua-031978798cc404c2c6757c564675d43a7da129ee.tar.gz
lua-031978798cc404c2c6757c564675d43a7da129ee.tar.bz2
lua-031978798cc404c2c6757c564675d43a7da129ee.zip
more optimizations
-rw-r--r--lcode.c55
-rw-r--r--lparser.c14
-rw-r--r--lvm.c44
3 files changed, 69 insertions, 44 deletions
diff --git a/lcode.c b/lcode.c
index 750def9a..157724d1 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.20 2000/04/05 17:51:58 roberto Exp roberto $ 2** $Id: lcode.c,v 1.21 2000/04/06 17:36:52 roberto Exp roberto $
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*/
@@ -88,9 +88,11 @@ static void luaK_minus (FuncState *fs) {
88 88
89static void luaK_gettable (FuncState *fs) { 89static void luaK_gettable (FuncState *fs) {
90 /* PUSHSTRING u; GETTABLE -> GETDOTTED u (t.x) */ 90 /* PUSHSTRING u; GETTABLE -> GETDOTTED u (t.x) */
91 /* GETLOCAL u; GETTABLE -> GETINDEXED u (t[i]) */
91 Instruction previous = prepare(fs, CREATE_0(OP_GETTABLE), -1); 92 Instruction previous = prepare(fs, CREATE_0(OP_GETTABLE), -1);
92 switch(GET_OPCODE(previous)) { 93 switch(GET_OPCODE(previous)) {
93 case OP_PUSHSTRING: SET_OPCODE(previous, OP_GETDOTTED); break; 94 case OP_PUSHSTRING: SET_OPCODE(previous, OP_GETDOTTED); break;
95 case OP_GETLOCAL: SET_OPCODE(previous, OP_GETINDEXED); break;
94 default: return; 96 default: return;
95 } 97 }
96 setprevious(fs, previous); 98 setprevious(fs, previous);
@@ -123,22 +125,32 @@ static void luaK_sub (FuncState *fs) {
123 125
124 126
125static void luaK_conc (FuncState *fs) { 127static void luaK_conc (FuncState *fs) {
126 /* CONC u; CONC 2 -> CONC u+1 (a..b..c) */ 128 /* CONCAT u; CONCAT 2 -> CONCAT u+1 (a..b..c) */
127 Instruction previous = prepare(fs, CREATE_U(OP_CONC, 2), -1); 129 Instruction previous = prepare(fs, CREATE_U(OP_CONCAT, 2), -1);
128 switch(GET_OPCODE(previous)) { 130 switch(GET_OPCODE(previous)) {
129 case OP_CONC: SETARG_U(previous, GETARG_U(previous)+1); break; 131 case OP_CONCAT: SETARG_U(previous, GETARG_U(previous)+1); break;
130 default: return; 132 default: return;
131 } 133 }
132 setprevious(fs, previous); 134 setprevious(fs, previous);
133} 135}
134 136
135 137
138static void luaK_getlocal (FuncState *fs, int l) {
139 /* SETLOCAL l 1; GETLOCAL l -> SETLOCAL l 0 */
140 Instruction previous = prepare(fs, CREATE_U(OP_GETLOCAL, l), 1);
141 if (previous == CREATE_AB(OP_SETLOCAL, l, 1)) {
142 SETARG_B(previous, 0);
143 setprevious(fs, previous);
144 }
145}
146
147
136static void luaK_setlocal (FuncState *fs, int l) { 148static void luaK_setlocal (FuncState *fs, int l) {
137 /* PUSHLOCAL l; ADDI k, SETLOCAL l -> INCLOCAL k, l ((local)a=a+k) */ 149 /* GETLOCAL l; ADDI k, SETLOCAL l -> INCLOCAL k, l ((local)a=a+k) */
138 Instruction *code = fs->f->code; 150 Instruction *code = fs->f->code;
139 int pc = fs->pc; 151 int pc = fs->pc;
140 if (pc-1 > fs->lasttarget && /* no jumps in-between instructions? */ 152 if (pc-1 > fs->lasttarget && /* no jumps in-between instructions? */
141 code[pc-2] == CREATE_U(OP_PUSHLOCAL, l) && 153 code[pc-2] == CREATE_U(OP_GETLOCAL, l) &&
142 GET_OPCODE(code[pc-1]) == OP_ADDI && 154 GET_OPCODE(code[pc-1]) == OP_ADDI &&
143 abs(GETARG_S(code[pc-1])) <= MAXARG_sA) { 155 abs(GETARG_S(code[pc-1])) <= MAXARG_sA) {
144 int inc = GETARG_S(code[pc-1]); 156 int inc = GETARG_S(code[pc-1]);
@@ -147,7 +159,7 @@ static void luaK_setlocal (FuncState *fs, int l) {
147 luaK_deltastack(fs, -1); 159 luaK_deltastack(fs, -1);
148 } 160 }
149 else 161 else
150 luaK_U(fs, OP_SETLOCAL, l, -1); 162 luaK_AB(fs, OP_SETLOCAL, l, 1, -1);
151} 163}
152 164
153 165
@@ -162,8 +174,8 @@ static void luaK_eq (FuncState *fs) {
162 174
163 175
164static void luaK_neq (FuncState *fs) { 176static void luaK_neq (FuncState *fs) {
165 /* PUSHNIL 1; JMPNEQ -> JMPT (a~=nil) */ 177 /* PUSHNIL 1; JMPNE -> JMPT (a~=nil) */
166 Instruction previous = prepare(fs, CREATE_S(OP_JMPNEQ, NO_JUMP), -2); 178 Instruction previous = prepare(fs, CREATE_S(OP_JMPNE, NO_JUMP), -2);
167 if (previous == CREATE_U(OP_PUSHNIL, 1)) { 179 if (previous == CREATE_U(OP_PUSHNIL, 1)) {
168 setprevious(fs, CREATE_S(OP_JMPT, NO_JUMP)); 180 setprevious(fs, CREATE_S(OP_JMPT, NO_JUMP));
169 } 181 }
@@ -201,6 +213,17 @@ static void luaK_pushnil (FuncState *fs, int n) {
201} 213}
202 214
203 215
216static void luaK_pop (FuncState *fs, int n) {
217 Instruction previous = prepare(fs, CREATE_U(OP_POP, n), -n);
218 switch(GET_OPCODE(previous)) {
219 case OP_SETTABLE: SETARG_B(previous, GETARG_B(previous)+n); break;
220 case OP_SETLOCAL: SETARG_B(previous, GETARG_B(previous)+n); break;
221 default: return;
222 }
223 setprevious(fs, previous);
224}
225
226
204static void luaK_fixjump (FuncState *fs, int pc, int dest) { 227static void luaK_fixjump (FuncState *fs, int pc, int dest) {
205 Instruction *jmp = &fs->f->code[pc]; 228 Instruction *jmp = &fs->f->code[pc];
206 if (dest == NO_JUMP) 229 if (dest == NO_JUMP)
@@ -280,7 +303,7 @@ void luaK_number (FuncState *fs, Number f) {
280 303
281void luaK_adjuststack (FuncState *fs, int n) { 304void luaK_adjuststack (FuncState *fs, int n) {
282 if (n > 0) 305 if (n > 0)
283 luaK_U(fs, OP_POP, n, -n); 306 luaK_pop(fs, n);
284 else if (n < 0) 307 else if (n < 0)
285 luaK_pushnil(fs, -n); 308 luaK_pushnil(fs, -n);
286} 309}
@@ -311,7 +334,7 @@ static void assertglobal (FuncState *fs, int index) {
311static int discharge (FuncState *fs, expdesc *var) { 334static int discharge (FuncState *fs, expdesc *var) {
312 switch (var->k) { 335 switch (var->k) {
313 case VLOCAL: 336 case VLOCAL:
314 luaK_U(fs, OP_PUSHLOCAL, var->u.index, 1); 337 luaK_getlocal(fs, var->u.index);
315 break; 338 break;
316 case VGLOBAL: 339 case VGLOBAL:
317 luaK_U(fs, OP_GETGLOBAL, var->u.index, 1); 340 luaK_U(fs, OP_GETGLOBAL, var->u.index, 1);
@@ -347,8 +370,8 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
347 luaK_U(fs, OP_SETGLOBAL, var->u.index, -1); 370 luaK_U(fs, OP_SETGLOBAL, var->u.index, -1);
348 assertglobal(fs, var->u.index); /* make sure that there is a global */ 371 assertglobal(fs, var->u.index); /* make sure that there is a global */
349 break; 372 break;
350 case VINDEXED: 373 case VINDEXED: /* table is at top-3; pop 3 elements after operation */
351 luaK_0(fs, OP_SETTABLEPOP, -3); 374 luaK_AB(fs, OP_SETTABLE, 3, 3, -3);
352 break; 375 break;
353 default: 376 default:
354 LUA_INTERNALERROR(ls->L, "invalid var kind to store"); 377 LUA_INTERNALERROR(ls->L, "invalid var kind to store");
@@ -358,8 +381,8 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
358 381
359static OpCode invertjump (OpCode op) { 382static OpCode invertjump (OpCode op) {
360 switch (op) { 383 switch (op) {
361 case OP_JMPNEQ: return OP_JMPEQ; 384 case OP_JMPNE: return OP_JMPEQ;
362 case OP_JMPEQ: return OP_JMPNEQ; 385 case OP_JMPEQ: return OP_JMPNE;
363 case OP_JMPLT: return OP_JMPGE; 386 case OP_JMPLT: return OP_JMPGE;
364 case OP_JMPLE: return OP_JMPGT; 387 case OP_JMPLE: return OP_JMPGT;
365 case OP_JMPGT: return OP_JMPLE; 388 case OP_JMPGT: return OP_JMPLE;
@@ -566,7 +589,7 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
566 case '*': luaK_0(fs, OP_MULT, -1); break; 589 case '*': luaK_0(fs, OP_MULT, -1); break;
567 case '/': luaK_0(fs, OP_DIV, -1); break; 590 case '/': luaK_0(fs, OP_DIV, -1); break;
568 case '^': luaK_0(fs, OP_POW, -1); break; 591 case '^': luaK_0(fs, OP_POW, -1); break;
569 case TK_CONC: luaK_conc(fs); break; 592 case TK_CONCAT: luaK_conc(fs); break;
570 case TK_EQ: luaK_eq(fs); break; 593 case TK_EQ: luaK_eq(fs); break;
571 case TK_NE: luaK_neq(fs); break; 594 case TK_NE: luaK_neq(fs); break;
572 case '>': luaK_S(fs, OP_JMPGT, NO_JUMP, -2); break; 595 case '>': luaK_S(fs, OP_JMPGT, NO_JUMP, -2); break;
diff --git a/lparser.c b/lparser.c
index 3fbffb05..85799240 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.76 2000/04/05 17:51:58 roberto Exp roberto $ 2** $Id: lparser.c,v 1.77 2000/04/06 17:36:52 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -751,7 +751,7 @@ static int get_priority (int op, int *rp) {
751 751
752 case '+': case '-': *rp = 5; return 5; 752 case '+': case '-': *rp = 5; return 5;
753 753
754 case TK_CONC: *rp = 3; return 4; /* right associative (?) */ 754 case TK_CONCAT: *rp = 3; return 4; /* right associative (?) */
755 755
756 case TK_EQ: case TK_NE: case '>': case '<': case TK_LE: case TK_GE: 756 case TK_EQ: case TK_NE: case '>': case '<': case TK_LE: case TK_GE:
757 *rp = 2; return 2; 757 *rp = 2; return 2;
@@ -832,13 +832,11 @@ static int assignment (LexState *ls, expdesc *v, int nvars) {
832 nexps = explist1(ls); 832 nexps = explist1(ls);
833 adjust_mult_assign(ls, nvars, nexps); 833 adjust_mult_assign(ls, nvars, nexps);
834 } 834 }
835 if (v->k != VINDEXED || left+(nvars-1) == 0) { 835 if (v->k != VINDEXED)
836 /* global/local var or indexed var without values in between */
837 luaK_storevar(ls, v); 836 luaK_storevar(ls, v);
838 } 837 else { /* there may be garbage between table-index and value */
839 else { /* indexed var with values in between*/ 838 luaK_AB(ls->fs, OP_SETTABLE, left+nvars+2, 1, -1);
840 luaK_U(ls->fs, OP_SETTABLE, left+(nvars-1), -1); 839 left += 2;
841 left += 2; /* table&index are not popped, because they aren't on top */
842 } 840 }
843 return left; 841 return left;
844} 842}
diff --git a/lvm.c b/lvm.c
index 2a8e2484..fc8cb262 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.98 2000/03/29 20:19:20 roberto Exp roberto $ 2** $Id: lvm.c,v 1.99 2000/04/04 20:48:44 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -231,6 +231,13 @@ static void call_arith (lua_State *L, StkId top, IMS event) {
231} 231}
232 232
233 233
234static void addK (lua_State *L, StkId top, int k) {
235 ttype(top) = TAG_NUMBER;
236 nvalue(top) = (Number)k;
237 call_arith(L, top+1, IM_ADD);
238}
239
240
234static int luaV_strcomp (const TString *ls, const TString *rs) { 241static int luaV_strcomp (const TString *ls, const TString *rs) {
235 const char *l = ls->str; 242 const char *l = ls->str;
236 long ll = ls->u.s.len; 243 long ll = ls->u.s.len;
@@ -403,7 +410,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
403 *top++ = cl->consts[GETARG_U(i)]; 410 *top++ = cl->consts[GETARG_U(i)];
404 break; 411 break;
405 412
406 case OP_PUSHLOCAL: 413 case OP_GETLOCAL:
407 *top++ = *(base+GETARG_U(i)); 414 *top++ = *(base+GETARG_U(i));
408 break; 415 break;
409 416
@@ -424,6 +431,12 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
424 top--; 431 top--;
425 break; 432 break;
426 433
434 case OP_GETINDEXED:
435 *top++ = *(base+GETARG_U(i));
436 luaV_gettable(L, top);
437 top--;
438 break;
439
427 case OP_PUSHSELF: { 440 case OP_PUSHSELF: {
428 TObject receiver; 441 TObject receiver;
429 receiver = *(top-1); 442 receiver = *(top-1);
@@ -443,7 +456,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
443 break; 456 break;
444 457
445 case OP_SETLOCAL: 458 case OP_SETLOCAL:
446 *(base+GETARG_U(i)) = *(--top); 459 *(base+GETARG_A(i)) = *(top-1);
460 top -= GETARG_B(i);
447 break; 461 break;
448 462
449 case OP_SETGLOBAL: 463 case OP_SETGLOBAL:
@@ -451,14 +465,9 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
451 top--; 465 top--;
452 break; 466 break;
453 467
454 case OP_SETTABLEPOP:
455 luaV_settable(L, top-3, top);
456 top -= 3; /* pop table, index, and value */
457 break;
458
459 case OP_SETTABLE: 468 case OP_SETTABLE:
460 luaV_settable(L, top-3-GETARG_U(i), top); 469 luaV_settable(L, top-GETARG_A(i), top);
461 top--; /* pop value */ 470 top -= GETARG_B(i); /* pop values */
462 break; 471 break;
463 472
464 case OP_SETLIST: { 473 case OP_SETLIST: {
@@ -496,9 +505,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
496 int n = GETARG_sA(i); 505 int n = GETARG_sA(i);
497 if (tonumber(var)) { 506 if (tonumber(var)) {
498 *top = *var; /* PUSHLOCAL */ 507 *top = *var; /* PUSHLOCAL */
499 ttype(top+1) = TAG_NUMBER; 508 addK(L, top+1, n);
500 nvalue(top+1) = (Number)n; /* PUSHINT */
501 call_arith(L, top+2, IM_ADD);
502 *var = *top; /* SETLOCAL */ 509 *var = *top; /* SETLOCAL */
503 } 510 }
504 else 511 else
@@ -507,11 +514,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
507 } 514 }
508 515
509 case OP_ADDI: 516 case OP_ADDI:
510 if (tonumber(top-1)) { 517 if (tonumber(top-1))
511 ttype(top) = TAG_NUMBER; 518 addK(L, top, GETARG_S(i));
512 nvalue(top) = (Number)GETARG_S(i);
513 call_arith(L, top+1, IM_ADD);
514 }
515 else 519 else
516 nvalue(top-1) += (Number)GETARG_S(i); 520 nvalue(top-1) += (Number)GETARG_S(i);
517 break; 521 break;
@@ -545,7 +549,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
545 top--; 549 top--;
546 break; 550 break;
547 551
548 case OP_CONC: { 552 case OP_CONCAT: {
549 int n = GETARG_U(i); 553 int n = GETARG_U(i);
550 strconc(L, n, top); 554 strconc(L, n, top);
551 top -= n-1; 555 top -= n-1;
@@ -569,7 +573,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, register StkId base) {
569 nvalue(top-1) = 1; 573 nvalue(top-1) = 1;
570 break; 574 break;
571 575
572 case OP_JMPNEQ: 576 case OP_JMPNE:
573 top -= 2; 577 top -= 2;
574 if (!luaO_equalObj(top, top+1)) pc += GETARG_S(i); 578 if (!luaO_equalObj(top, top+1)) pc += GETARG_S(i);
575 break; 579 break;