diff options
| -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; |
