mirror of https://github.com/rusefi/lua.git
cleaner semantics for test instructions (skips)
This commit is contained in:
parent
566310fa04
commit
7ab7703b53
23
lcode.c
23
lcode.c
|
@ -71,7 +71,7 @@ int luaK_jump (FuncState *fs) {
|
|||
|
||||
static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
|
||||
luaK_codeABC(fs, op, A, B, C);
|
||||
return luaK_codeAsBc(fs, OP_CJMP, 0, NO_JUMP);
|
||||
return luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,12 +127,11 @@ static int luaK_getjump (FuncState *fs, int pc) {
|
|||
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
|
||||
Instruction *pi = &fs->f->code[pc];
|
||||
OpCode op = GET_OPCODE(*pi);
|
||||
if (op == OP_CJMP)
|
||||
lua_assert(op == OP_JMP || op == OP_FORLOOP || op == OP_TFORLOOP);
|
||||
if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
|
||||
return pi-1;
|
||||
else {
|
||||
lua_assert(op == OP_JMP || op == OP_FORLOOP || op == OP_TFORLOOP);
|
||||
else
|
||||
return pi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -312,18 +311,23 @@ static int code_label (FuncState *fs, int A, int b, int jump) {
|
|||
|
||||
|
||||
static void dischargejumps (FuncState *fs, expdesc *e, int reg) {
|
||||
if (hasjumps(e)) {
|
||||
if (e->k == VJMP || hasjumps(e)) {
|
||||
int final; /* position after whole expression */
|
||||
int p_f = NO_JUMP; /* position of an eventual PUSH false */
|
||||
int p_t = NO_JUMP; /* position of an eventual PUSH true */
|
||||
if (need_value(fs, e->f, OP_TESTF) || need_value(fs, e->t, OP_TESTT)) {
|
||||
if (e->k == VJMP || need_value(fs, e->f, OP_TESTF) ||
|
||||
need_value(fs, e->t, OP_TESTT)) {
|
||||
/* expression needs values */
|
||||
if (e->k != VJMP) {
|
||||
luaK_getlabel(fs); /* these instruction may be jump target */
|
||||
luaK_codeAsBc(fs, OP_JMP, 0, 2); /* to jump over both pushes */
|
||||
}
|
||||
p_f = code_label(fs, reg, 0, 1);
|
||||
p_t = code_label(fs, reg, 1, 0);
|
||||
else { /* last expression is a conditional (test + jump) */
|
||||
fs->pc--; /* remove its jump */
|
||||
lua_assert(testOpMode(GET_OPCODE(fs->f->code[fs->pc - 1]), OpModeT));
|
||||
}
|
||||
p_t = code_label(fs, reg, 1, 1);
|
||||
p_f = code_label(fs, reg, 0, 0);
|
||||
}
|
||||
final = luaK_getlabel(fs);
|
||||
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) {
|
|||
break;
|
||||
}
|
||||
case VJMP: {
|
||||
luaK_concat(fs, &e->t, e->u.i.info); /* put this jump in `t' list */
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
7
ldebug.c
7
ldebug.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldebug.c,v 1.96 2001/12/18 20:52:30 roberto Exp $
|
||||
** $Id: ldebug.c,v 1.97 2002/01/09 22:02:47 roberto Exp $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -350,7 +350,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
|
|||
if (a == reg) last = pc; /* change register `a' */
|
||||
}
|
||||
if (testOpMode(op, OpModeT))
|
||||
check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP);
|
||||
check(pc+2 < pt->sizecode); /* check skip */
|
||||
switch (op) {
|
||||
case OP_LOADBOOL: {
|
||||
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) {
|
|||
check(c < MAXSTACK && b < c);
|
||||
break;
|
||||
}
|
||||
case OP_JMP:
|
||||
case OP_CJMP: {
|
||||
case OP_JMP: {
|
||||
int dest = pc+1+b;
|
||||
check(0 <= dest && dest < pt->sizecode);
|
||||
/* not full check and jump is forward and do not skip `lastpc'? */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lopcodes.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** $Id: lopcodes.c,v 1.8 2001/12/11 22:48:44 roberto Exp $
|
||||
** extracted automatically from lopcodes.h by mkprint.lua
|
||||
** DO NOT EDIT
|
||||
** See Copyright Notice in lua.h
|
||||
|
@ -37,7 +37,6 @@ const char *const luaP_opnames[] = {
|
|||
"NOT",
|
||||
"CONCAT",
|
||||
"JMP",
|
||||
"CJMP",
|
||||
"TESTEQ",
|
||||
"TESTNE",
|
||||
"TESTLT",
|
||||
|
@ -88,7 +87,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
|
|||
,opmode(0,0,1,0, 1,0,iABC) /* OP_NOT */
|
||||
,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */
|
||||
,opmode(0,0,0,0, 0,0,iAsBc) /* OP_JMP */
|
||||
,opmode(0,0,0,0, 0,0,iAsBc) /* OP_CJMP */
|
||||
,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTEQ */
|
||||
,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTNE */
|
||||
,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTLT */
|
||||
|
|
26
lopcodes.h
26
lopcodes.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lopcodes.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** $Id: lopcodes.h,v 1.85 2002/01/09 22:02:47 roberto Exp $
|
||||
** Opcodes for Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -156,17 +156,16 @@ OP_NOT,/* A B R(A) := not R(B) */
|
|||
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
|
||||
|
||||
OP_JMP,/* sBc PC += sBc */
|
||||
OP_CJMP,/* sBc if test then PC += sBc (see (1)) */
|
||||
|
||||
OP_TESTEQ,/* A C test := (R(A) == R/K(C)) */
|
||||
OP_TESTNE,/* A C test := (R(A) ~= R/K(C)) */
|
||||
OP_TESTLT,/* A C test := (R(A) < R/K(C)) */
|
||||
OP_TESTLE,/* A C test := (R(A) <= R/K(C)) */
|
||||
OP_TESTGT,/* A C test := (R(A) > R/K(C)) */
|
||||
OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */
|
||||
OP_TESTEQ,/* A C if not (R(A) == R/K(C)) then pc++ */
|
||||
OP_TESTNE,/* A C if not (R(A) ~= R/K(C)) then pc++ */
|
||||
OP_TESTLT,/* A C if not (R(A) < R/K(C)) then pc++ */
|
||||
OP_TESTLE,/* A C if not (R(A) <= R/K(C)) then pc++ */
|
||||
OP_TESTGT,/* A C if not (R(A) > R/K(C)) then pc++ */
|
||||
OP_TESTGE,/* A C if not (R(A) >= R/K(C)) then pc++ */
|
||||
|
||||
OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */
|
||||
OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */
|
||||
OP_TESTT,/* A B if (R(B)) then R(A) := R(B) else pc++ */
|
||||
OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */
|
||||
|
||||
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/
|
||||
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
|
|||
|
||||
/*===========================================================================
|
||||
Notes:
|
||||
(1) In the current implementation there is no `test' variable;
|
||||
instructions OP_TEST* and OP_CJMP must always occur together.
|
||||
|
||||
(2) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
|
||||
(1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
|
||||
and can be 0: OP_CALL then sets `top' to last_result+1, so
|
||||
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
|
||||
|
||||
(3) In OP_RETURN, if (B == 0) then return up to `top'
|
||||
(2) In OP_RETURN, if (B == 0) then return up to `top'
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
|
|
60
lvm.c
60
lvm.c
|
@ -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: {
|
||||
|
|
Loading…
Reference in New Issue