summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c23
-rw-r--r--ldebug.c7
-rw-r--r--lopcodes.c4
-rw-r--r--lopcodes.h26
-rw-r--r--lvm.c60
5 files changed, 48 insertions, 72 deletions
diff --git a/lcode.c b/lcode.c
index a93b52b9..835dc25d 100644
--- a/lcode.c
+++ b/lcode.c
@@ -71,7 +71,7 @@ int luaK_jump (FuncState *fs) {
71 71
72static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { 72static 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) {
127static Instruction *getjumpcontrol (FuncState *fs, int pc) { 127static 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
314static void dischargejumps (FuncState *fs, expdesc *e, int reg) { 313static 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: {
diff --git a/ldebug.c b/ldebug.c
index 17a0f11a..2edb4860 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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'? */
diff --git a/lopcodes.c b/lopcodes.c
index e52805e5..e9ae53b5 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -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 */
diff --git a/lopcodes.h b/lopcodes.h
index 722e3d6a..6e2103c9 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -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) */
156OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ 156OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
157 157
158OP_JMP,/* sBc PC += sBc */ 158OP_JMP,/* sBc PC += sBc */
159OP_CJMP,/* sBc if test then PC += sBc (see (1)) */
160 159
161OP_TESTEQ,/* A C test := (R(A) == R/K(C)) */ 160OP_TESTEQ,/* A C if not (R(A) == R/K(C)) then pc++ */
162OP_TESTNE,/* A C test := (R(A) ~= R/K(C)) */ 161OP_TESTNE,/* A C if not (R(A) ~= R/K(C)) then pc++ */
163OP_TESTLT,/* A C test := (R(A) < R/K(C)) */ 162OP_TESTLT,/* A C if not (R(A) < R/K(C)) then pc++ */
164OP_TESTLE,/* A C test := (R(A) <= R/K(C)) */ 163OP_TESTLE,/* A C if not (R(A) <= R/K(C)) then pc++ */
165OP_TESTGT,/* A C test := (R(A) > R/K(C)) */ 164OP_TESTGT,/* A C if not (R(A) > R/K(C)) then pc++ */
166OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */ 165OP_TESTGE,/* A C if not (R(A) >= R/K(C)) then pc++ */
167 166
168OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ 167OP_TESTT,/* A B if (R(B)) then R(A) := R(B) else pc++ */
169OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */ 168OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */
170 169
171OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/ 170OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/
172OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ 171OP_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
diff --git a/lvm.c b/lvm.c
index b1dad7a8..b51ea0e0 100644
--- a/lvm.c
+++ b/lvm.c
@@ -64,7 +64,7 @@ int luaV_tostring (lua_State *L, TObject *obj) {
64static void traceexec (lua_State *L, lua_Hook linehook) { 64static 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
224void luaV_strconc (lua_State *L, int total, StkId top) { 224void 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: {