diff --git a/lcode.c b/lcode.c index c2b5fc6d..a1b27a00 100644 --- a/lcode.c +++ b/lcode.c @@ -1337,18 +1337,20 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { ** (everything but logical operators 'and'/'or' and comparison ** operators). ** Expression to produce final result will be encoded in 'e1'. -** Because 'luaK_exp2anyreg' can free registers, its calls must be -** in "stack order" (that is, first on 'e2', which may have more -** recent registers to be released). */ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, - OpCode op, int v2, int k, int line) { + OpCode op, int v2, int k, int line, + OpCode mmop, TMS event) { int v1 = luaK_exp2anyreg(fs, e1); int pc = luaK_codeABCk(fs, op, 0, v1, v2, k); freeexps(fs, e1, e2); e1->u.info = pc; e1->k = VRELOC; /* all those operations are relocatable */ luaK_fixline(fs, line); +if (event != TM_SHL && event != TM_SHR) { + luaK_codeABCk(fs, mmop, v1, v2, event, k); /* to call metamethod */ + luaK_fixline(fs, line); +} } @@ -1359,7 +1361,9 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, static void codebinexpval (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2, int line) { int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ - finishbinexpval(fs, e1, e2, op, v2, 0, line); + lua_assert(OP_ADD <= op && op <= OP_SHR); + finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, + cast(TMS, (op - OP_ADD) + TM_ADD)); } @@ -1367,9 +1371,10 @@ static void codebinexpval (FuncState *fs, OpCode op, ** Code binary operators ('+', '-', ...) with immediate operands. */ static void codebini (FuncState *fs, OpCode op, - expdesc *e1, expdesc *e2, int k, int line) { + expdesc *e1, expdesc *e2, int k, int line, + TMS event) { int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ - finishbinexpval(fs, e1, e2, op, v2, k, line); + finishbinexpval(fs, e1, e2, op, v2, k, line, OP_MMBINI, event); } @@ -1383,16 +1388,18 @@ static void swapexps (expdesc *e1, expdesc *e2) { ** constant in the proper range, use variant opcodes with immediate ** operands or K operands. */ -static void codearith (FuncState *fs, OpCode op, +static void codearith (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2, int flip, int line) { + TMS event = cast(TMS, opr + TM_ADD); if (isSCint(e2)) /* immediate operand? */ - codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); + codebini(fs, cast(OpCode, opr + OP_ADDI), e1, e2, flip, line, event); else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ int v2 = e2->u.info; /* K index */ - op = cast(OpCode, op - OP_ADD + OP_ADDK); - finishbinexpval(fs, e1, e2, op, v2, flip, line); + OpCode op = cast(OpCode, opr + OP_ADDK); + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); } else { /* 'e2' is neither an immediate nor a K operand */ + OpCode op = cast(OpCode, opr + OP_ADD); if (flip) swapexps(e1, e2); /* back to original order */ codebinexpval(fs, op, e1, e2, line); /* use standard operators */ @@ -1405,7 +1412,7 @@ static void codearith (FuncState *fs, OpCode op, ** numeric constant, change order of operands to try to use an ** immediate or K operator. */ -static void codecommutative (FuncState *fs, OpCode op, +static void codecommutative (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2, int line) { int flip = 0; if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ @@ -1430,14 +1437,15 @@ static void codebitwise (FuncState *fs, BinOpr opr, inv = 1; } else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ - op = cast(OpCode, opr - OPR_BAND + OP_BAND); + op = cast(OpCode, opr + OP_ADD); codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ return; } v2 = e2->u.info; /* index in K array */ - op = cast(OpCode, opr - OPR_BAND + OP_BANDK); + op = cast(OpCode, opr + OP_ADDK); lua_assert(ttisinteger(&fs->f->k[v2])); - finishbinexpval(fs, e1, e2, op, v2, inv, line); + finishbinexpval(fs, e1, e2, op, v2, inv, line, OP_MMBINK, + cast(TMS, opr + TM_ADD)); } @@ -1453,7 +1461,7 @@ static void codeshift (FuncState *fs, OpCode op, changedir = 1; e2->u.ival = -(e2->u.ival); } - codebini(fs, OP_SHRI, e1, e2, changedir, line); + codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHL); } else codebinexpval(fs, op, e1, e2, line); @@ -1638,13 +1646,13 @@ void luaK_posfix (FuncState *fs, BinOpr opr, } case OPR_ADD: case OPR_MUL: { if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) - codecommutative(fs, cast(OpCode, opr + OP_ADD), e1, e2, line); + codecommutative(fs, opr, e1, e2, line); break; } case OPR_SUB: case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) - codearith(fs, cast(OpCode, opr + OP_ADD), e1, e2, 0, line); + codearith(fs, opr, e1, e2, 0, line); break; } case OPR_BAND: case OPR_BOR: case OPR_BXOR: { @@ -1656,7 +1664,7 @@ void luaK_posfix (FuncState *fs, BinOpr opr, if (!constfolding(fs, LUA_OPSHL, e1, e2)) { if (isSCint(e1)) { swapexps(e1, e2); - codebini(fs, OP_SHLI, e1, e2, 1, line); + codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); } else codeshift(fs, OP_SHL, e1, e2, line); diff --git a/ldebug.c b/ldebug.c index 9593039b..4e1dc6b9 100644 --- a/ldebug.c +++ b/ldebug.c @@ -471,6 +471,10 @@ static int findsetreg (const Proto *p, int lastpc, int reg) { int pc; int setreg = -1; /* keep last instruction that changed 'reg' */ int jmptarget = 0; /* any code before this address is conditional */ + if (GET_OPCODE(p->code[lastpc]) == OP_MMBIN || + GET_OPCODE(p->code[lastpc]) == OP_MMBINI || + GET_OPCODE(p->code[lastpc]) == OP_MMBINK) + lastpc--; for (pc = 0; pc < lastpc; pc++) { Instruction i = p->code[pc]; OpCode op = GET_OPCODE(i); @@ -620,22 +624,11 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: tm = TM_NEWINDEX; break; - case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI: - case OP_POWI: case OP_DIVI: case OP_IDIVI: { - int offset = GET_OPCODE(i) - OP_ADDI; /* ORDER OP */ - tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ - break; - } - case OP_ADDK: case OP_SUBK: case OP_MULK: case OP_MODK: - case OP_POWK: case OP_DIVK: case OP_IDIVK: - case OP_BANDK: case OP_BORK: case OP_BXORK: { - int offset = GET_OPCODE(i) - OP_ADDK; /* ORDER OP */ - tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ + case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { + tm = cast(TMS, GETARG_C(i)); break; } - case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: - case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: - case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { + case OP_SHL: case OP_SHR: { int offset = GET_OPCODE(i) - OP_ADD; /* ORDER OP */ tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ break; diff --git a/ljumptab.h b/ljumptab.h index 2d4cf28b..1832c809 100644 --- a/ljumptab.h +++ b/ljumptab.h @@ -75,6 +75,9 @@ static void *disptab[NUM_OPCODES] = { &&L_OP_BXOR, &&L_OP_SHL, &&L_OP_SHR, +&&L_OP_MMBIN, +&&L_OP_MMBINI, +&&L_OP_MMBINK, &&L_OP_UNM, &&L_OP_BNOT, &&L_OP_NOT, diff --git a/lopcodes.c b/lopcodes.c index ee795786..aede93a5 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -69,6 +69,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 0, 0, 1, iABC) /* OP_BXOR */ ,opmode(0, 0, 0, 1, iABC) /* OP_SHL */ ,opmode(0, 0, 0, 1, iABC) /* OP_SHR */ + ,opmode(0, 0, 0, 0, iABC) /* OP_MMBIN */ + ,opmode(0, 0, 0, 0, iABC) /* OP_MMBINI*/ + ,opmode(0, 0, 0, 0, iABC) /* OP_MMBINK*/ ,opmode(0, 0, 0, 1, iABC) /* OP_UNM */ ,opmode(0, 0, 0, 1, iABC) /* OP_BNOT */ ,opmode(0, 0, 0, 1, iABC) /* OP_NOT */ diff --git a/lopcodes.h b/lopcodes.h index 26b1850d..fd578c68 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -255,6 +255,10 @@ OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */ OP_SHL,/* A B C R(A) := R(B) << R(C) */ OP_SHR,/* A B C R(A) := R(B) >> R(C) */ +OP_MMBIN,/* A B C call B metamethod for previous bin. operation */ +OP_MMBINI,/* A B C call B metamethod for previous binI. operation */ +OP_MMBINK,/* A B C call B metamethod for previous binK. operation */ + OP_UNM,/* A B R(A) := -R(B) */ OP_BNOT,/* A B R(A) := ~R(B) */ OP_NOT,/* A B R(A) := not R(B) */ diff --git a/lopnames.h b/lopnames.h index 28535fe2..0fc1da1f 100644 --- a/lopnames.h +++ b/lopnames.h @@ -60,6 +60,9 @@ static const char *const opnames[] = { "BXOR", "SHL", "SHR", + "MMBIN", + "MMBINI", + "MMBINK", "UNM", "BNOT", "NOT", diff --git a/ltm.c b/ltm.c index 19233a87..991e62c1 100644 --- a/ltm.c +++ b/ltm.c @@ -173,7 +173,7 @@ void luaT_tryconcatTM (lua_State *L) { void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, - StkId res, int flip, TMS event) { + int flip, StkId res, TMS event) { if (flip) luaT_trybinTM(L, p2, p1, res, event); else @@ -185,7 +185,7 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, int flip, StkId res, TMS event) { TValue aux; setivalue(&aux, i2); - luaT_trybinassocTM(L, p1, &aux, res, flip, event); + luaT_trybinassocTM(L, p1, &aux, flip, res, event); } diff --git a/ltm.h b/ltm.h index 51dfe793..9621e68e 100644 --- a/ltm.h +++ b/ltm.h @@ -77,7 +77,7 @@ LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, StkId res, TMS event); LUAI_FUNC void luaT_tryconcatTM (lua_State *L); LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, - const TValue *p2, StkId res, int inv, TMS event); + const TValue *p2, int inv, StkId res, TMS event); LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, int inv, StkId res, TMS event); LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, diff --git a/lvm.c b/lvm.c index 907417e3..a9e8455e 100644 --- a/lvm.c +++ b/lvm.c @@ -717,18 +717,11 @@ void luaV_finishOp (lua_State *L) { Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ OpCode op = GET_OPCODE(inst); switch (op) { /* finish its execution */ - case OP_ADDI: case OP_SUBI: - case OP_MULI: case OP_DIVI: case OP_IDIVI: - case OP_MODI: case OP_POWI: - case OP_ADDK: case OP_SUBK: - case OP_MULK: case OP_DIVK: case OP_IDIVK: - case OP_MODK: case OP_POWK: - case OP_ADD: case OP_SUB: - case OP_MUL: case OP_DIV: case OP_IDIV: - case OP_BANDK: case OP_BORK: case OP_BXORK: - case OP_BAND: case OP_BOR: case OP_BXOR: + case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { + setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top); + break; + } case OP_SHLI: case OP_SHRI: case OP_SHL: case OP_SHR: - case OP_MOD: case OP_POW: case OP_UNM: case OP_BNOT: case OP_LEN: case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: case OP_GETFIELD: case OP_SELF: { @@ -804,10 +797,8 @@ void luaV_finishOp (lua_State *L) { lua_Number nb; \ if (tonumberns(v1, nb)) { \ lua_Number fimm = cast_num(imm); \ - setfltvalue(s2v(ra), fop(L, nb, fimm)); \ - } \ - else \ - ProtectNT(luaT_trybiniTM(L, v1, imm, flip, ra, tm)); } + pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ + }} /* @@ -827,7 +818,7 @@ void luaV_finishOp (lua_State *L) { int imm = GETARG_sC(i); \ if (ttisinteger(v1)) { \ lua_Integer iv1 = ivalue(v1); \ - setivalue(s2v(ra), iop(L, iv1, imm)); \ + pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ } \ else op_arithfI_aux(L, v1, imm, fop, tm, flip); } @@ -839,10 +830,8 @@ void luaV_finishOp (lua_State *L) { #define op_arithf_aux(L,v1,v2,fop,tm) { \ lua_Number n1; lua_Number n2; \ if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ - setfltvalue(s2v(ra), fop(L, n1, n2)); \ - } \ - else \ - ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } + pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ + }} /* @@ -862,7 +851,7 @@ void luaV_finishOp (lua_State *L) { TValue *v2 = vRC(i); \ if (ttisinteger(v1) && ttisinteger(v2)) { \ lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ - setivalue(s2v(ra), iop(L, i1, i2)); \ + pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ } \ else op_arithf_aux(L, v1, v2, fop, tm); } @@ -875,15 +864,13 @@ void luaV_finishOp (lua_State *L) { TValue *v2 = KC(i); \ if (ttisinteger(v1) && ttisinteger(v2)) { \ lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ - setivalue(s2v(ra), iop(L, i1, i2)); \ + pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ } \ else { \ lua_Number n1; lua_Number n2; \ if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ - setfltvalue(s2v(ra), fop(L, n1, n2)); \ - } \ - else \ - ProtectNT(luaT_trybinassocTM(L, v1, v2, ra, flip, tm)); } } + pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ + }}} /* @@ -894,10 +881,8 @@ void luaV_finishOp (lua_State *L) { TValue *v2 = KC(i); \ lua_Number n1; lua_Number n2; \ if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ - setfltvalue(s2v(ra), fop(L, n1, n2)); \ - } \ - else \ - ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } + pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ + }} /* @@ -909,10 +894,8 @@ void luaV_finishOp (lua_State *L) { lua_Integer i1; \ lua_Integer i2 = ivalue(v2); \ if (tointegerns(v1, &i1)) { \ - setivalue(s2v(ra), op(L, i1, i2)); \ - } \ - else \ - ProtectNT(luaT_trybiniTM(L, v1, i2, TESTARG_k(i), ra, tm)); } + pc++; setivalue(s2v(ra), op(L, i1, i2)); \ + }} /* @@ -923,10 +906,8 @@ void luaV_finishOp (lua_State *L) { TValue *v2 = vRC(i); \ lua_Integer i1; lua_Integer i2; \ if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ - setivalue(s2v(ra), op(L, i1, i2)); \ - } \ - else \ - ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } + pc++; setivalue(s2v(ra), op(L, i1, i2)); \ + }} /* @@ -1443,6 +1424,33 @@ void luaV_execute (lua_State *L, CallInfo *ci) { ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); vmbreak; } + vmcase(OP_MMBIN) { + Instruction pi = *(pc - 2); /* original arith. expression */ + TValue *rb = vRB(i); + TMS tm = (TMS)GETARG_C(i); + StkId result = RA(pi); + lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); + ProtectNT(luaT_trybinTM(L, s2v(ra), rb, result, tm)); + vmbreak; + } + vmcase(OP_MMBINI) { + Instruction pi = *(pc - 2); /* original arith. expression */ + int imm = GETARG_sB(i); + TMS tm = (TMS)GETARG_C(i); + int flip = GETARG_k(i); + StkId result = RA(pi); + ProtectNT(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); + vmbreak; + } + vmcase(OP_MMBINK) { + Instruction pi = *(pc - 2); /* original arith. expression */ + TValue *imm = KB(i); + TMS tm = (TMS)GETARG_C(i); + int flip = GETARG_k(i); + StkId result = RA(pi); + ProtectNT(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); + vmbreak; + } vmcase(OP_UNM) { TValue *rb = vRB(i); lua_Number nb; @@ -1826,4 +1834,3 @@ void luaV_execute (lua_State *L, CallInfo *ci) { } /* }================================================================== */ - diff --git a/testes/code.lua b/testes/code.lua index 3b768f33..fcb5c309 100644 --- a/testes/code.lua +++ b/testes/code.lua @@ -156,9 +156,9 @@ check(function () c.x, a[b] = -((a + d/b - a[b]) ^ a.x), b end, 'LOADNIL', - 'MUL', - 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETFIELD', 'POW', - 'UNM', 'SETTABLE', 'SETFIELD', 'RETURN0') + 'MUL', 'MMBIN', + 'DIV', 'MMBIN', 'ADD', 'MMBIN', 'GETTABLE', 'SUB', 'MMBIN', + 'GETFIELD', 'POW', 'MMBIN', 'UNM', 'SETTABLE', 'SETFIELD', 'RETURN0') -- direct access to constants @@ -188,7 +188,7 @@ check(function () b = a/a b = 5-4 end, - 'LOADNIL', 'SUB', 'DIV', 'LOADI', 'RETURN0') + 'LOADNIL', 'SUB', 'MMBIN', 'DIV', 'MMBIN', 'LOADI', 'RETURN0') check(function () local a,b @@ -292,38 +292,45 @@ checkK(function () return -(border + 1) end, -(sbx + 1.0)) -- immediate operands -checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'RETURN1') -checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1') -checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1') -checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1') -checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1') -checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1') -checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1') -checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1') +checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'MMBINI', 'RETURN1') +checkR(function (x) return 128 + x end, 0.0, 128.0, + 'ADDI', 'MMBINI', 'RETURN1') +checkR(function (x) return x * -127 end, -1.0, 127.0, + 'MULI', 'MMBINI', 'RETURN1') +checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'MMBINI', 'RETURN1') +checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'MMBINI', 'RETURN1') +checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'MMBINI', 'RETURN1') +checkR(function (x) return x // 1 end, 10.0, 10.0, + 'IDIVI', 'MMBINI', 'RETURN1') +checkR(function (x) return x % (100 - 10) end, 91, 1, + 'MODI', 'MMBINI', 'RETURN1') checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'RETURN1') checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1') checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1') -checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1') -checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'RETURN1') -checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'RETURN1') +checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'MMBINK', 'RETURN1') +checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'MMBINK', 'RETURN1') +checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'MMBINK', 'RETURN1') -- K operands in arithmetic operations -checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'RETURN1') --- check(function (x) return 128 + x end, 'ADDK', 'RETURN1') -checkR(function (x) return x * -10000 end, 2, -20000, 'MULK', 'RETURN1') --- check(function (x) return 20 * x end, 'MULK', 'RETURN1') -checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'RETURN1') -checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'RETURN1') -checkR(function (x) return x // 10000 end, 10000, 1, 'IDIVK', 'RETURN1') -checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1') +checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'MMBINK', 'RETURN1') +-- check(function (x) return 128 + x end, 'ADDK', 'MMBINK', 'RETURN1') +checkR(function (x) return x * -10000 end, 2, -20000, + 'MULK', 'MMBINK', 'RETURN1') +-- check(function (x) return 20 * x end, 'MULK', 'MMBINK', 'RETURN1') +checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'MMBINK', 'RETURN1') +checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'MMBINK', 'RETURN1') +checkR(function (x) return x // 10000 end, 10000, 1, + 'IDIVK', 'MMBINK', 'RETURN1') +checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, + 'MODK', 'MMBINK', 'RETURN1') -- no foldings (and immediate operands) check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') -check(function () return k3/0 end, 'LOADI', 'DIVI', 'RETURN1') -check(function () return 0%0 end, 'LOADI', 'MODI', 'RETURN1') -check(function () return -4//0 end, 'LOADI', 'IDIVI', 'RETURN1') +check(function () return k3/0 end, 'LOADI', 'DIVI', 'MMBINI', 'RETURN1') +check(function () return 0%0 end, 'LOADI', 'MODI', 'MMBINI', 'RETURN1') +check(function () return -4//0 end, 'LOADI', 'IDIVI', 'MMBINI', 'RETURN1') check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1') -check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'RETURN1') +check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'MMBIN', 'RETURN1') -- basic 'for' loops check(function () for i = -10, 10.5 do end end, @@ -379,7 +386,7 @@ check(function (a, b) if b then break else a = a + 1 end end end, -'TEST', 'JMP', 'TEST', 'JMP', 'ADDI', 'JMP', 'RETURN0') +'TEST', 'JMP', 'TEST', 'JMP', 'ADDI', 'MMBINI', 'JMP', 'RETURN0') checkequal( function (a) while a < 10 do a = a + 1 end end, diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 48f4c5bf..81d848a3 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua @@ -751,7 +751,7 @@ assert(run(function () return a >> 2 end, {"shr"}) == 10 >> 2) assert(run(function () return 1 >> a end, {"shr"}) == 1 >> 10) assert(run(function () return a << 2 end, {"shl"}) == 10 << 2) assert(run(function () return 1 << a end, {"shl"}) == 1 << 10) -assert(run(function () return a ~ 2 end, {"bxor"}) == 10 ~ 2) +assert(run(function () return 2 ~ a end, {"bxor"}) == 2 ~ 10) assert(run(function () return a..b end, {"concat"}) == "1012")