|
@@ -64,7 +64,7 @@ int luaV_tostring (lua_State *L, TObject *obj) {
|
|
|
static void traceexec (lua_State *L, lua_Hook linehook) {
|
|
|
CallInfo *ci = L->ci;
|
|
|
int *lineinfo = ci_func(ci)->l.p->lineinfo;
|
|
|
- int pc = (int)(*ci->pc - ci_func(ci)->l.p->code) - 1;
|
|
|
+ int pc = cast(int, *ci->pc - ci_func(ci)->l.p->code) - 1;
|
|
|
int newline;
|
|
|
if (pc == 0) { /* may be first time? */
|
|
|
ci->line = 1;
|
|
@@ -221,9 +221,10 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-void luaV_strconc (lua_State *L, int total, StkId top) {
|
|
|
- luaV_checkGC(L, top);
|
|
|
+void luaV_strconc (lua_State *L, int total, int last) {
|
|
|
+ luaV_checkGC(L, L->ci->base + last + 1);
|
|
|
do {
|
|
|
+ StkId top = L->ci->base + last + 1;
|
|
|
int n = 2; /* number of elements handled in this pass (at least 2) */
|
|
|
if (tostring(L, top-2) || tostring(L, top-1)) {
|
|
|
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) {
|
|
|
setsvalue(top-n, luaS_newlstr(L, buffer, tl));
|
|
|
}
|
|
|
total -= n-1; /* got `n' strings to create 1 new */
|
|
|
- top -= n-1;
|
|
|
+ last -= n-1;
|
|
|
} while (total > 1); /* repeat until only 1 result left */
|
|
|
}
|
|
|
|
|
@@ -431,71 +432,50 @@ StkId luaV_execute (lua_State *L) {
|
|
|
break;
|
|
|
}
|
|
|
case OP_CONCAT: {
|
|
|
- StkId top = RC(i)+1;
|
|
|
- StkId rb = RB(i);
|
|
|
- luaV_strconc(L, top-rb, top);
|
|
|
- setobj(ra, rb);
|
|
|
+ int b = GETARG_B(i);
|
|
|
+ int c = GETARG_C(i);
|
|
|
+ luaV_strconc(L, c-b+1, c);
|
|
|
+ setobj(ra, base+b);
|
|
|
break;
|
|
|
}
|
|
|
- case OP_CJMP:
|
|
|
case OP_JMP: {
|
|
|
dojump(pc, i);
|
|
|
break;
|
|
|
}
|
|
|
- case OP_TESTEQ: {
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (luaO_equalObj(ra, RKC(i))) dojump(pc, *pc);
|
|
|
- pc++;
|
|
|
+ case OP_TESTEQ: { /* skip next instruction if test fails */
|
|
|
+ if (!luaO_equalObj(ra, RKC(i))) pc++;
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTNE: {
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (!luaO_equalObj(ra, RKC(i))) dojump(pc, *pc);
|
|
|
- pc++;
|
|
|
+ if (luaO_equalObj(ra, RKC(i))) pc++;
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTLT: {
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc);
|
|
|
- pc++;
|
|
|
+ if (!luaV_lessthan(L, ra, RKC(i))) pc++;
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTLE: { /* b <= c === !(c<b) */
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (!luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc);
|
|
|
- pc++;
|
|
|
+ if (luaV_lessthan(L, RKC(i), ra)) pc++;
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTGT: { /* b > c === (c<b) */
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc);
|
|
|
- pc++;
|
|
|
+ if (!luaV_lessthan(L, RKC(i), ra)) pc++;
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTGE: { /* b >= c === !(b<c) */
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (!luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc);
|
|
|
- pc++;
|
|
|
+ if (luaV_lessthan(L, ra, RKC(i))) pc++;
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTT: {
|
|
|
StkId rb = RB(i);
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (!l_isfalse(rb)) {
|
|
|
- setobj(ra, rb);
|
|
|
- dojump(pc, *pc);
|
|
|
- }
|
|
|
- pc++;
|
|
|
+ if (l_isfalse(rb)) pc++;
|
|
|
+ else setobj(ra, rb);
|
|
|
break;
|
|
|
}
|
|
|
case OP_TESTF: {
|
|
|
StkId rb = RB(i);
|
|
|
- lua_assert(GET_OPCODE(*pc) == OP_CJMP);
|
|
|
- if (l_isfalse(rb)) {
|
|
|
- setobj(ra, rb);
|
|
|
- dojump(pc, *pc);
|
|
|
- }
|
|
|
- pc++;
|
|
|
+ if (!l_isfalse(rb)) pc++;
|
|
|
+ else setobj(ra, rb);
|
|
|
break;
|
|
|
}
|
|
|
case OP_CALL: {
|