cleaner semantics for test instructions (skips)

This commit is contained in:
Roberto Ierusalimschy
2002-01-16 20:03:57 -02:00
parent 566310fa04
commit 7ab7703b53
5 changed files with 48 additions and 72 deletions

60
lvm.c
View File

@@ -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: {