Showing the changes to src/lcode.c (1 of 65 files). Show all
Unified · Split
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lcode.c,v 2.12 2005/03/16 16:59:21 roberto Exp $ | |
| 2 | +** $Id: lcode.c,v 2.16 2005/08/29 20:49:21 roberto Exp $ | |
| 3 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -53,6 +53,11 @@ int luaK_jump (FuncState *fs) { · 47 unmodified lines | ||
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | |
| 56 | +void luaK_ret (FuncState *fs, int first, int nret) { | |
| 57 | + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); | |
| 58 | +} | |
| 59 | + | |
| 60 | + | |
| 56 | 61 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { |
| 57 | 62 | luaK_codeABC(fs, op, A, B, C); |
| 58 | 63 | return luaK_jump(fs); |
| @@ -101,49 +106,50 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) { · 42 unmodified lines | ||
| 101 | 106 | ** check whether list has any jump that do not produce a value |
| 102 | 107 | ** (or produce an inverted value) |
| 103 | 108 | */ |
| 104 | −static int need_value (FuncState *fs, int list, int cond) { | |
| 109 | +static int need_value (FuncState *fs, int list) { | |
| 105 | 110 | for (; list != NO_JUMP; list = getjump(fs, list)) { |
| 106 | 111 | Instruction i = *getjumpcontrol(fs, list); |
| 107 | − if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1; | |
| 112 | + if (GET_OPCODE(i) != OP_TESTSET) return 1; | |
| 108 | 113 | } |
| 109 | 114 | return 0; /* not found */ |
| 110 | 115 | } |
| 111 | 116 | |
| 112 | 117 | |
| 113 | 118 | static void patchtestreg (Instruction *i, int reg) { |
| 114 | − if (reg == NO_REG) reg = GETARG_B(*i); | |
| 115 | − SETARG_A(*i, reg); | |
| 119 | + if (reg != NO_REG) | |
| 120 | + SETARG_A(*i, reg); | |
| 121 | + else /* no register to put value; change TESTSET to TEST */ | |
| 122 | + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); | |
| 116 | 123 | } |
| 117 | 124 | |
| 118 | 125 | |
| 119 | −static void patchlistaux (FuncState *fs, int list, | |
| 120 | − int ttarget, int treg, int ftarget, int freg, int dtarget) { | |
| 126 | +static void removevalues (FuncState *fs, int list) { | |
| 127 | + for (; list != NO_JUMP; list = getjump(fs, list)) { | |
| 128 | + Instruction *i = getjumpcontrol(fs, list); | |
| 129 | + if (GET_OPCODE(*i) == OP_TESTSET) | |
| 130 | + patchtestreg(i, NO_REG); | |
| 131 | + } | |
| 132 | +} | |
| 133 | + | |
| 134 | + | |
| 135 | +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, | |
| 136 | + int dtarget) { | |
| 121 | 137 | while (list != NO_JUMP) { |
| 122 | 138 | int next = getjump(fs, list); |
| 123 | 139 | Instruction *i = getjumpcontrol(fs, list); |
| 124 | − if (GET_OPCODE(*i) != OP_TEST) { | |
| 125 | − lua_assert(dtarget != NO_JUMP); | |
| 126 | − fixjump(fs, list, dtarget); /* jump to default target */ | |
| 127 | − } | |
| 128 | − else { | |
| 129 | − if (GETARG_C(*i)) { | |
| 130 | − lua_assert(ttarget != NO_JUMP); | |
| 131 | − patchtestreg(i, treg); | |
| 132 | − fixjump(fs, list, ttarget); | |
| 133 | − } | |
| 134 | − else { | |
| 135 | − lua_assert(ftarget != NO_JUMP); | |
| 136 | − patchtestreg(i, freg); | |
| 137 | − fixjump(fs, list, ftarget); | |
| 138 | − } | |
| 140 | + if (GET_OPCODE(*i) == OP_TESTSET) { | |
| 141 | + patchtestreg(i, reg); | |
| 142 | + fixjump(fs, list, vtarget); | |
| 139 | 143 | } |
| 144 | + else | |
| 145 | + fixjump(fs, list, dtarget); /* jump to default target */ | |
| 140 | 146 | list = next; |
| 141 | 147 | } |
| 142 | 148 | } |
| 143 | 149 | |
| 144 | 150 | |
| 145 | 151 | static void dischargejpc (FuncState *fs) { |
| 146 | − patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc); | |
| 152 | + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); | |
| 147 | 153 | fs->jpc = NO_JUMP; |
| 148 | 154 | } |
| 149 | 155 | |
| @@ -153,7 +159,7 @@ void luaK_patchlist (FuncState *fs, int list, int target) { · 3 unmodified lines | ||
| 153 | 159 | luaK_patchtohere(fs, list); |
| 154 | 160 | else { |
| 155 | 161 | lua_assert(target < fs->pc); |
| 156 | − patchlistaux(fs, list, target, NO_REG, target, NO_REG, target); | |
| 162 | + patchlistaux(fs, list, target, NO_REG, target); | |
| 157 | 163 | } |
| 158 | 164 | } |
| 159 | 165 | |
| @@ -223,7 +229,7 @@ static int addk (FuncState *fs, TValue *k, TValue *v) { · 63 unmodified lines | ||
| 223 | 229 | MAXARG_Bx, "constant table overflow"); |
| 224 | 230 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); |
| 225 | 231 | setobj(L, &f->k[fs->nk], v); |
| 226 | − luaC_barriert(L, f, v); | |
| 232 | + luaC_barrier(L, f, v); | |
| 227 | 233 | return fs->nk++; |
| 228 | 234 | } |
| 229 | 235 | } |
| @@ -373,7 +379,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { · 143 unmodified lines | ||
| 373 | 379 | int final; /* position after whole expression */ |
| 374 | 380 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ |
| 375 | 381 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ |
| 376 | − if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) { | |
| 382 | + if (need_value(fs, e->t) || need_value(fs, e->f)) { | |
| 377 | 383 | int fj = NO_JUMP; /* first jump (over LOAD ops.) */ |
| 378 | 384 | if (e->k != VJMP) |
| 379 | 385 | fj = luaK_jump(fs); |
| @@ -382,8 +388,8 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { · 2 unmodified lines | ||
| 382 | 388 | luaK_patchtohere(fs, fj); |
| 383 | 389 | } |
| 384 | 390 | final = luaK_getlabel(fs); |
| 385 | − patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); | |
| 386 | − patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t); | |
| 391 | + patchlistaux(fs, e->f, final, reg, p_f); | |
| 392 | + patchlistaux(fs, e->t, final, reg, p_t); | |
| 387 | 393 | } |
| 388 | 394 | e->f = e->t = NO_JUMP; |
| 389 | 395 | e->info = reg; |
| @@ -492,7 +498,8 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { · 102 unmodified lines | ||
| 492 | 498 | |
| 493 | 499 | static void invertjump (FuncState *fs, expdesc *e) { |
| 494 | 500 | Instruction *pc = getjumpcontrol(fs, e->info); |
| 495 | − lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TEST); | |
| 501 | + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && | |
| 502 | + GET_OPCODE(*pc) != OP_TEST); | |
| 496 | 503 | SETARG_A(*pc, !(GETARG_A(*pc))); |
| 497 | 504 | } |
| 498 | 505 | |
| @@ -502,13 +509,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { · 3 unmodified lines | ||
| 502 | 509 | Instruction ie = getcode(fs, e); |
| 503 | 510 | if (GET_OPCODE(ie) == OP_NOT) { |
| 504 | 511 | fs->pc--; /* remove previous OP_NOT */ |
| 505 | − return condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); | |
| 512 | + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); | |
| 506 | 513 | } |
| 507 | 514 | /* else go through */ |
| 508 | 515 | } |
| 509 | 516 | discharge2anyreg(fs, e); |
| 510 | 517 | freeexp(fs, e); |
| 511 | − return condjump(fs, OP_TEST, NO_REG, e->info, cond); | |
| 518 | + return condjump(fs, OP_TESTSET, NO_REG, e->info, cond); | |
| 512 | 519 | } |
| 513 | 520 | |
| 514 | 521 | |
| @@ -535,6 +542,8 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 20 unmodified lines | ||
| 535 | 542 | } |
| 536 | 543 | } |
| 537 | 544 | luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ |
| 545 | + luaK_patchtohere(fs, e->t); | |
| 546 | + e->t = NO_JUMP; | |
| 538 | 547 | } |
| 539 | 548 | |
| 540 | 549 | |
| @@ -560,6 +569,8 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) { · 19 unmodified lines | ||
| 560 | 569 | } |
| 561 | 570 | } |
| 562 | 571 | luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ |
| 572 | + luaK_patchtohere(fs, e->f); | |
| 573 | + e->f = NO_JUMP; | |
| 563 | 574 | } |
| 564 | 575 | |
| 565 | 576 | |
| @@ -593,6 +604,8 @@ static void codenot (FuncState *fs, expdesc *e) { · 27 unmodified lines | ||
| 593 | 604 | } |
| 594 | 605 | /* interchange true and false lists */ |
| 595 | 606 | { int temp = e->f; e->f = e->t; e->t = temp; } |
| 607 | + removevalues(fs, e->f); | |
| 608 | + removevalues(fs, e->t); | |
| 596 | 609 | } |
| 597 | 610 | |
| 598 | 611 | |
| @@ -607,7 +620,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { · 8 unmodified lines | ||
| 607 | 620 | case OPR_MINUS: { |
| 608 | 621 | luaK_exp2val(fs, e); |
| 609 | 622 | if (e->k == VK && ttisnumber(&fs->f->k[e->info])) |
| 610 | − e->info = luaK_numberK(fs, luai_numunm(nvalue(&fs->f->k[e->info]))); | |
| 623 | + e->info = luaK_numberK(fs, luai_numunm(L, nvalue(&fs->f->k[e->info]))); | |
| 611 | 624 | else { |
| 612 | 625 | luaK_exp2anyreg(fs, e); |
| 613 | 626 | freeexp(fs, e); |
| @@ -620,10 +633,10 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { · 6 unmodified lines | ||
| 620 | 633 | codenot(fs, e); |
| 621 | 634 | break; |
| 622 | 635 | } |
| 623 | − case OPR_SIZE: { | |
| 636 | + case OPR_LEN: { | |
| 624 | 637 | luaK_exp2anyreg(fs, e); |
| 625 | 638 | freeexp(fs, e); |
| 626 | − e->info = luaK_codeABC(fs, OP_SIZ, 0, e->info, 0); | |
| 639 | + e->info = luaK_codeABC(fs, OP_LEN, 0, e->info, 0); | |
| 627 | 640 | e->k = VRELOCABLE; |
| 628 | 641 | break; |
| 629 | 642 | } |
| @@ -636,14 +649,10 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 6 unmodified lines | ||
| 636 | 649 | switch (op) { |
| 637 | 650 | case OPR_AND: { |
| 638 | 651 | luaK_goiftrue(fs, v); |
| 639 | − luaK_patchtohere(fs, v->t); | |
| 640 | − v->t = NO_JUMP; | |
| 641 | 652 | break; |
| 642 | 653 | } |
| 643 | 654 | case OPR_OR: { |
| 644 | 655 | luaK_goiffalse(fs, v); |
| 645 | − luaK_patchtohere(fs, v->f); | |
| 646 | − v->f = NO_JUMP; | |
| 647 | 656 | break; |
| 648 | 657 | } |
| 649 | 658 | case OPR_CONCAT: { |