diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-07 10:13:11 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-07 10:13:11 -0300 |
commit | 031978798cc404c2c6757c564675d43a7da129ee (patch) | |
tree | 993e59994258f1a9176d7d260214b132d0b2baa9 | |
parent | 14251c5a5640f73f8f98d2445900a3c3a8d472fb (diff) | |
download | lua-031978798cc404c2c6757c564675d43a7da129ee.tar.gz lua-031978798cc404c2c6757c564675d43a7da129ee.tar.bz2 lua-031978798cc404c2c6757c564675d43a7da129ee.zip |
more optimizations
-rw-r--r-- | lcode.c | 55 | ||||
-rw-r--r-- | lparser.c | 14 | ||||
-rw-r--r-- | lvm.c | 44 |
3 files changed, 69 insertions, 44 deletions
@@ -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 | ||
89 | static void luaK_gettable (FuncState *fs) { | 89 | static 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 | ||
125 | static void luaK_conc (FuncState *fs) { | 127 | static 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 | ||
138 | static 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 | |||
136 | static void luaK_setlocal (FuncState *fs, int l) { | 148 | static 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 | ||
164 | static void luaK_neq (FuncState *fs) { | 176 | static 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 | ||
216 | static 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 | |||
204 | static void luaK_fixjump (FuncState *fs, int pc, int dest) { | 227 | static 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 | ||
281 | void luaK_adjuststack (FuncState *fs, int n) { | 304 | void 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) { | |||
311 | static int discharge (FuncState *fs, expdesc *var) { | 334 | static 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 | ||
359 | static OpCode invertjump (OpCode op) { | 382 | static 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; |
@@ -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 | } |
@@ -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 | ||
234 | static 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 | |||
234 | static int luaV_strcomp (const TString *ls, const TString *rs) { | 241 | static 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; |