diff options
| -rw-r--r-- | lcode.c | 23 | ||||
| -rw-r--r-- | ldebug.c | 7 | ||||
| -rw-r--r-- | lopcodes.c | 4 | ||||
| -rw-r--r-- | lopcodes.h | 26 | ||||
| -rw-r--r-- | lvm.c | 60 |
5 files changed, 48 insertions, 72 deletions
| @@ -71,7 +71,7 @@ int luaK_jump (FuncState *fs) { | |||
| 71 | 71 | ||
| 72 | static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { | 72 | static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { |
| 73 | luaK_codeABC(fs, op, A, B, C); | 73 | luaK_codeABC(fs, op, A, B, C); |
| 74 | return luaK_codeAsBc(fs, OP_CJMP, 0, NO_JUMP); | 74 | return luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | 77 | ||
| @@ -127,12 +127,11 @@ static int luaK_getjump (FuncState *fs, int pc) { | |||
| 127 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | 127 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { |
| 128 | Instruction *pi = &fs->f->code[pc]; | 128 | Instruction *pi = &fs->f->code[pc]; |
| 129 | OpCode op = GET_OPCODE(*pi); | 129 | OpCode op = GET_OPCODE(*pi); |
| 130 | if (op == OP_CJMP) | 130 | lua_assert(op == OP_JMP || op == OP_FORLOOP || op == OP_TFORLOOP); |
| 131 | if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT)) | ||
| 131 | return pi-1; | 132 | return pi-1; |
| 132 | else { | 133 | else |
| 133 | lua_assert(op == OP_JMP || op == OP_FORLOOP || op == OP_TFORLOOP); | ||
| 134 | return pi; | 134 | return pi; |
| 135 | } | ||
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | 137 | ||
| @@ -312,18 +311,23 @@ static int code_label (FuncState *fs, int A, int b, int jump) { | |||
| 312 | 311 | ||
| 313 | 312 | ||
| 314 | static void dischargejumps (FuncState *fs, expdesc *e, int reg) { | 313 | static void dischargejumps (FuncState *fs, expdesc *e, int reg) { |
| 315 | if (hasjumps(e)) { | 314 | if (e->k == VJMP || hasjumps(e)) { |
| 316 | int final; /* position after whole expression */ | 315 | int final; /* position after whole expression */ |
| 317 | int p_f = NO_JUMP; /* position of an eventual PUSH false */ | 316 | int p_f = NO_JUMP; /* position of an eventual PUSH false */ |
| 318 | int p_t = NO_JUMP; /* position of an eventual PUSH true */ | 317 | int p_t = NO_JUMP; /* position of an eventual PUSH true */ |
| 319 | if (need_value(fs, e->f, OP_TESTF) || need_value(fs, e->t, OP_TESTT)) { | 318 | if (e->k == VJMP || need_value(fs, e->f, OP_TESTF) || |
| 319 | need_value(fs, e->t, OP_TESTT)) { | ||
| 320 | /* expression needs values */ | 320 | /* expression needs values */ |
| 321 | if (e->k != VJMP) { | 321 | if (e->k != VJMP) { |
| 322 | luaK_getlabel(fs); /* these instruction may be jump target */ | 322 | luaK_getlabel(fs); /* these instruction may be jump target */ |
| 323 | luaK_codeAsBc(fs, OP_JMP, 0, 2); /* to jump over both pushes */ | 323 | luaK_codeAsBc(fs, OP_JMP, 0, 2); /* to jump over both pushes */ |
| 324 | } | 324 | } |
| 325 | p_f = code_label(fs, reg, 0, 1); | 325 | else { /* last expression is a conditional (test + jump) */ |
| 326 | p_t = code_label(fs, reg, 1, 0); | 326 | fs->pc--; /* remove its jump */ |
| 327 | lua_assert(testOpMode(GET_OPCODE(fs->f->code[fs->pc - 1]), OpModeT)); | ||
| 328 | } | ||
| 329 | p_t = code_label(fs, reg, 1, 1); | ||
| 330 | p_f = code_label(fs, reg, 0, 0); | ||
| 327 | } | 331 | } |
| 328 | final = luaK_getlabel(fs); | 332 | final = luaK_getlabel(fs); |
| 329 | luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); | 333 | luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); |
| @@ -389,7 +393,6 @@ static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { | |||
| 389 | break; | 393 | break; |
| 390 | } | 394 | } |
| 391 | case VJMP: { | 395 | case VJMP: { |
| 392 | luaK_concat(fs, &e->t, e->u.i.info); /* put this jump in `t' list */ | ||
| 393 | break; | 396 | break; |
| 394 | } | 397 | } |
| 395 | default: { | 398 | default: { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.96 2001/12/18 20:52:30 roberto Exp $ | 2 | ** $Id: ldebug.c,v 1.97 2002/01/09 22:02:47 roberto Exp $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -350,7 +350,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
| 350 | if (a == reg) last = pc; /* change register `a' */ | 350 | if (a == reg) last = pc; /* change register `a' */ |
| 351 | } | 351 | } |
| 352 | if (testOpMode(op, OpModeT)) | 352 | if (testOpMode(op, OpModeT)) |
| 353 | check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP); | 353 | check(pc+2 < pt->sizecode); /* check skip */ |
| 354 | switch (op) { | 354 | switch (op) { |
| 355 | case OP_LOADBOOL: { | 355 | case OP_LOADBOOL: { |
| 356 | check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ | 356 | check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ |
| @@ -381,8 +381,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
| 381 | check(c < MAXSTACK && b < c); | 381 | check(c < MAXSTACK && b < c); |
| 382 | break; | 382 | break; |
| 383 | } | 383 | } |
| 384 | case OP_JMP: | 384 | case OP_JMP: { |
| 385 | case OP_CJMP: { | ||
| 386 | int dest = pc+1+b; | 385 | int dest = pc+1+b; |
| 387 | check(0 <= dest && dest < pt->sizecode); | 386 | check(0 <= dest && dest < pt->sizecode); |
| 388 | /* not full check and jump is forward and do not skip `lastpc'? */ | 387 | /* not full check and jump is forward and do not skip `lastpc'? */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ | 2 | ** $Id: lopcodes.c,v 1.8 2001/12/11 22:48:44 roberto Exp $ |
| 3 | ** extracted automatically from lopcodes.h by mkprint.lua | 3 | ** extracted automatically from lopcodes.h by mkprint.lua |
| 4 | ** DO NOT EDIT | 4 | ** DO NOT EDIT |
| 5 | ** See Copyright Notice in lua.h | 5 | ** See Copyright Notice in lua.h |
| @@ -37,7 +37,6 @@ const char *const luaP_opnames[] = { | |||
| 37 | "NOT", | 37 | "NOT", |
| 38 | "CONCAT", | 38 | "CONCAT", |
| 39 | "JMP", | 39 | "JMP", |
| 40 | "CJMP", | ||
| 41 | "TESTEQ", | 40 | "TESTEQ", |
| 42 | "TESTNE", | 41 | "TESTNE", |
| 43 | "TESTLT", | 42 | "TESTLT", |
| @@ -88,7 +87,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
| 88 | ,opmode(0,0,1,0, 1,0,iABC) /* OP_NOT */ | 87 | ,opmode(0,0,1,0, 1,0,iABC) /* OP_NOT */ |
| 89 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */ | 88 | ,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */ |
| 90 | ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_JMP */ | 89 | ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_JMP */ |
| 91 | ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_CJMP */ | ||
| 92 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTEQ */ | 90 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTEQ */ |
| 93 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTNE */ | 91 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTNE */ |
| 94 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTLT */ | 92 | ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTLT */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ | 2 | ** $Id: lopcodes.h,v 1.85 2002/01/09 22:02:47 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 | */ |
| @@ -156,17 +156,16 @@ OP_NOT,/* A B R(A) := not R(B) */ | |||
| 156 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ | 156 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ |
| 157 | 157 | ||
| 158 | OP_JMP,/* sBc PC += sBc */ | 158 | OP_JMP,/* sBc PC += sBc */ |
| 159 | OP_CJMP,/* sBc if test then PC += sBc (see (1)) */ | ||
| 160 | 159 | ||
| 161 | OP_TESTEQ,/* A C test := (R(A) == R/K(C)) */ | 160 | OP_TESTEQ,/* A C if not (R(A) == R/K(C)) then pc++ */ |
| 162 | OP_TESTNE,/* A C test := (R(A) ~= R/K(C)) */ | 161 | OP_TESTNE,/* A C if not (R(A) ~= R/K(C)) then pc++ */ |
| 163 | OP_TESTLT,/* A C test := (R(A) < R/K(C)) */ | 162 | OP_TESTLT,/* A C if not (R(A) < R/K(C)) then pc++ */ |
| 164 | OP_TESTLE,/* A C test := (R(A) <= R/K(C)) */ | 163 | OP_TESTLE,/* A C if not (R(A) <= R/K(C)) then pc++ */ |
| 165 | OP_TESTGT,/* A C test := (R(A) > R/K(C)) */ | 164 | OP_TESTGT,/* A C if not (R(A) > R/K(C)) then pc++ */ |
| 166 | OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */ | 165 | OP_TESTGE,/* A C if not (R(A) >= R/K(C)) then pc++ */ |
| 167 | 166 | ||
| 168 | OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ | 167 | OP_TESTT,/* A B if (R(B)) then R(A) := R(B) else pc++ */ |
| 169 | OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */ | 168 | OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */ |
| 170 | 169 | ||
| 171 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/ | 170 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/ |
| 172 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ | 171 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ |
| @@ -194,14 +193,11 @@ pseudo-instructions (interruptions): cannot occur in regular code | |||
| 194 | 193 | ||
| 195 | /*=========================================================================== | 194 | /*=========================================================================== |
| 196 | Notes: | 195 | Notes: |
| 197 | (1) In the current implementation there is no `test' variable; | 196 | (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, |
| 198 | instructions OP_TEST* and OP_CJMP must always occur together. | ||
| 199 | |||
| 200 | (2) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, | ||
| 201 | and can be 0: OP_CALL then sets `top' to last_result+1, so | 197 | and can be 0: OP_CALL then sets `top' to last_result+1, so |
| 202 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. | 198 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. |
| 203 | 199 | ||
| 204 | (3) In OP_RETURN, if (B == 0) then return up to `top' | 200 | (2) In OP_RETURN, if (B == 0) then return up to `top' |
| 205 | ===========================================================================*/ | 201 | ===========================================================================*/ |
| 206 | 202 | ||
| 207 | 203 | ||
| @@ -64,7 +64,7 @@ int luaV_tostring (lua_State *L, TObject *obj) { | |||
| 64 | static void traceexec (lua_State *L, lua_Hook linehook) { | 64 | static void traceexec (lua_State *L, lua_Hook linehook) { |
| 65 | CallInfo *ci = L->ci; | 65 | CallInfo *ci = L->ci; |
| 66 | int *lineinfo = ci_func(ci)->l.p->lineinfo; | 66 | int *lineinfo = ci_func(ci)->l.p->lineinfo; |
| 67 | int pc = (int)(*ci->pc - ci_func(ci)->l.p->code) - 1; | 67 | int pc = cast(int, *ci->pc - ci_func(ci)->l.p->code) - 1; |
| 68 | int newline; | 68 | int newline; |
| 69 | if (pc == 0) { /* may be first time? */ | 69 | if (pc == 0) { /* may be first time? */ |
| 70 | ci->line = 1; | 70 | ci->line = 1; |
| @@ -221,9 +221,10 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { | |||
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | 223 | ||
| 224 | void luaV_strconc (lua_State *L, int total, StkId top) { | 224 | void luaV_strconc (lua_State *L, int total, int last) { |
| 225 | luaV_checkGC(L, top); | 225 | luaV_checkGC(L, L->ci->base + last + 1); |
| 226 | do { | 226 | do { |
| 227 | StkId top = L->ci->base + last + 1; | ||
| 227 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 228 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 228 | if (tostring(L, top-2) || tostring(L, top-1)) { | 229 | if (tostring(L, top-2) || tostring(L, top-1)) { |
| 229 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) | 230 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
| @@ -249,7 +250,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
| 249 | setsvalue(top-n, luaS_newlstr(L, buffer, tl)); | 250 | setsvalue(top-n, luaS_newlstr(L, buffer, tl)); |
| 250 | } | 251 | } |
| 251 | total -= n-1; /* got `n' strings to create 1 new */ | 252 | total -= n-1; /* got `n' strings to create 1 new */ |
| 252 | top -= n-1; | 253 | last -= n-1; |
| 253 | } while (total > 1); /* repeat until only 1 result left */ | 254 | } while (total > 1); /* repeat until only 1 result left */ |
| 254 | } | 255 | } |
| 255 | 256 | ||
| @@ -431,71 +432,50 @@ StkId luaV_execute (lua_State *L) { | |||
| 431 | break; | 432 | break; |
| 432 | } | 433 | } |
| 433 | case OP_CONCAT: { | 434 | case OP_CONCAT: { |
| 434 | StkId top = RC(i)+1; | 435 | int b = GETARG_B(i); |
| 435 | StkId rb = RB(i); | 436 | int c = GETARG_C(i); |
| 436 | luaV_strconc(L, top-rb, top); | 437 | luaV_strconc(L, c-b+1, c); |
| 437 | setobj(ra, rb); | 438 | setobj(ra, base+b); |
| 438 | break; | 439 | break; |
| 439 | } | 440 | } |
| 440 | case OP_CJMP: | ||
| 441 | case OP_JMP: { | 441 | case OP_JMP: { |
| 442 | dojump(pc, i); | 442 | dojump(pc, i); |
| 443 | break; | 443 | break; |
| 444 | } | 444 | } |
| 445 | case OP_TESTEQ: { | 445 | case OP_TESTEQ: { /* skip next instruction if test fails */ |
| 446 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 446 | if (!luaO_equalObj(ra, RKC(i))) pc++; |
| 447 | if (luaO_equalObj(ra, RKC(i))) dojump(pc, *pc); | ||
| 448 | pc++; | ||
| 449 | break; | 447 | break; |
| 450 | } | 448 | } |
| 451 | case OP_TESTNE: { | 449 | case OP_TESTNE: { |
| 452 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 450 | if (luaO_equalObj(ra, RKC(i))) pc++; |
| 453 | if (!luaO_equalObj(ra, RKC(i))) dojump(pc, *pc); | ||
| 454 | pc++; | ||
| 455 | break; | 451 | break; |
| 456 | } | 452 | } |
| 457 | case OP_TESTLT: { | 453 | case OP_TESTLT: { |
| 458 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 454 | if (!luaV_lessthan(L, ra, RKC(i))) pc++; |
| 459 | if (luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc); | ||
| 460 | pc++; | ||
| 461 | break; | 455 | break; |
| 462 | } | 456 | } |
| 463 | case OP_TESTLE: { /* b <= c === !(c<b) */ | 457 | case OP_TESTLE: { /* b <= c === !(c<b) */ |
| 464 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 458 | if (luaV_lessthan(L, RKC(i), ra)) pc++; |
| 465 | if (!luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc); | ||
| 466 | pc++; | ||
| 467 | break; | 459 | break; |
| 468 | } | 460 | } |
| 469 | case OP_TESTGT: { /* b > c === (c<b) */ | 461 | case OP_TESTGT: { /* b > c === (c<b) */ |
| 470 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 462 | if (!luaV_lessthan(L, RKC(i), ra)) pc++; |
| 471 | if (luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc); | ||
| 472 | pc++; | ||
| 473 | break; | 463 | break; |
| 474 | } | 464 | } |
| 475 | case OP_TESTGE: { /* b >= c === !(b<c) */ | 465 | case OP_TESTGE: { /* b >= c === !(b<c) */ |
| 476 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 466 | if (luaV_lessthan(L, ra, RKC(i))) pc++; |
| 477 | if (!luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc); | ||
| 478 | pc++; | ||
| 479 | break; | 467 | break; |
| 480 | } | 468 | } |
| 481 | case OP_TESTT: { | 469 | case OP_TESTT: { |
| 482 | StkId rb = RB(i); | 470 | StkId rb = RB(i); |
| 483 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 471 | if (l_isfalse(rb)) pc++; |
| 484 | if (!l_isfalse(rb)) { | 472 | else setobj(ra, rb); |
| 485 | setobj(ra, rb); | ||
| 486 | dojump(pc, *pc); | ||
| 487 | } | ||
| 488 | pc++; | ||
| 489 | break; | 473 | break; |
| 490 | } | 474 | } |
| 491 | case OP_TESTF: { | 475 | case OP_TESTF: { |
| 492 | StkId rb = RB(i); | 476 | StkId rb = RB(i); |
| 493 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); | 477 | if (!l_isfalse(rb)) pc++; |
| 494 | if (l_isfalse(rb)) { | 478 | else setobj(ra, rb); |
| 495 | setobj(ra, rb); | ||
| 496 | dojump(pc, *pc); | ||
| 497 | } | ||
| 498 | pc++; | ||
| 499 | break; | 479 | break; |
| 500 | } | 480 | } |
| 501 | case OP_CALL: { | 481 | case OP_CALL: { |
