From 46b84580d6d7890f4ba813f312e52514fffc38a7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 28 Aug 2019 09:58:03 -0300 Subject: [PATCH] Use of 'MMBIN' opcodes extended to shift operators Plus, this commit removes useless 'tm' parameters in 'op_*' macros. --- lcode.c | 26 ++++++------ ldebug.c | 8 ---- lvm.c | 102 +++++++++++++++++++----------------------------- testes/code.lua | 8 ++-- testes/db.lua | 3 +- 5 files changed, 60 insertions(+), 87 deletions(-) diff --git a/lcode.c b/lcode.c index a1b27a00..2c08409b 100644 --- a/lcode.c +++ b/lcode.c @@ -1339,19 +1339,23 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { ** Expression to produce final result will be encoded in 'e1'. */ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, - OpCode op, int v2, int k, int line, + OpCode op, int v2, int flip, int line, OpCode mmop, TMS event) { int v1 = luaK_exp2anyreg(fs, e1); - int pc = luaK_codeABCk(fs, op, 0, v1, v2, k); + int pc = luaK_codeABCk(fs, op, 0, v1, v2, flip); 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 */ + if (op == OP_SHRI && flip) { + /* For the metamethod, undo the "changedir" did by 'codeshift' */ + event = TM_SHL; + v2 = -(v2 - OFFSET_sC) + OFFSET_sC; + flip = 0; + } + luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ luaK_fixline(fs, line); } -} /* @@ -1371,10 +1375,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 flip, int line, TMS event) { int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ - finishbinexpval(fs, e1, e2, op, v2, k, line, OP_MMBINI, event); + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event); } @@ -1429,12 +1433,12 @@ static void codecommutative (FuncState *fs, BinOpr op, */ static void codebitwise (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2, int line) { - int inv = 0; + int flip = 0; int v2; OpCode op; if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { swapexps(e1, e2); /* 'e2' will be the constant operand */ - inv = 1; + flip = 1; } else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ op = cast(OpCode, opr + OP_ADD); @@ -1444,7 +1448,7 @@ static void codebitwise (FuncState *fs, BinOpr opr, v2 = e2->u.info; /* index in K array */ op = cast(OpCode, opr + OP_ADDK); lua_assert(ttisinteger(&fs->f->k[v2])); - finishbinexpval(fs, e1, e2, op, v2, inv, line, OP_MMBINK, + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, cast(TMS, opr + TM_ADD)); } @@ -1461,7 +1465,7 @@ static void codeshift (FuncState *fs, OpCode op, changedir = 1; e2->u.ival = -(e2->u.ival); } - codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHL); + codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHR); } else codebinexpval(fs, op, e1, e2, line); diff --git a/ldebug.c b/ldebug.c index 4e1dc6b9..aef52e15 100644 --- a/ldebug.c +++ b/ldebug.c @@ -628,11 +628,6 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, tm = cast(TMS, GETARG_C(i)); break; } - case OP_SHL: case OP_SHR: { - int offset = GET_OPCODE(i) - OP_ADD; /* ORDER OP */ - tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ - break; - } case OP_UNM: tm = TM_UNM; break; case OP_BNOT: tm = TM_BNOT; break; case OP_LEN: tm = TM_LEN; break; @@ -641,9 +636,6 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, case OP_LT: case OP_LE: case OP_LTI: case OP_LEI: *name = "order"; /* '<=' can call '__lt', etc. */ return "metamethod"; - case OP_SHRI: case OP_SHLI: - *name = "shift"; - return "metamethod"; case OP_CLOSE: case OP_RETURN: *name = "close"; return "metamethod"; diff --git a/lvm.c b/lvm.c index a9e8455e..71f6ae0d 100644 --- a/lvm.c +++ b/lvm.c @@ -674,6 +674,8 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { /* ** Shift left operation. (Shift right just negates 'y'.) */ +#define luaV_shiftr(x,y) luaV_shiftl(x,-(y)) + lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { if (y < 0) { /* shift right? */ if (y <= -NBITS) return 0; @@ -721,7 +723,6 @@ void luaV_finishOp (lua_State *L) { 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_UNM: case OP_BNOT: case OP_LEN: case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: case OP_GETFIELD: case OP_SELF: { @@ -778,9 +779,9 @@ void luaV_finishOp (lua_State *L) { #define l_addi(L,a,b) intop(+, a, b) #define l_subi(L,a,b) intop(-, a, b) #define l_muli(L,a,b) intop(*, a, b) -#define l_band(L,a,b) intop(&, a, b) -#define l_bor(L,a,b) intop(|, a, b) -#define l_bxor(L,a,b) intop(^, a, b) +#define l_band(a,b) intop(&, a, b) +#define l_bor(a,b) intop(|, a, b) +#define l_bxor(a,b) intop(^, a, b) #define l_lti(a,b) (a < b) #define l_lei(a,b) (a <= b) @@ -827,7 +828,7 @@ void luaV_finishOp (lua_State *L) { ** Auxiliary function for arithmetic operations over floats and others ** with two register operands. */ -#define op_arithf_aux(L,v1,v2,fop,tm) { \ +#define op_arithf_aux(L,v1,v2,fop) { \ lua_Number n1; lua_Number n2; \ if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ @@ -837,29 +838,29 @@ void luaV_finishOp (lua_State *L) { /* ** Arithmetic operations over floats and others with register operands. */ -#define op_arithf(L,fop,tm) { \ +#define op_arithf(L,fop) { \ TValue *v1 = vRB(i); \ TValue *v2 = vRC(i); \ - op_arithf_aux(L, v1, v2, fop, tm); } + op_arithf_aux(L, v1, v2, fop); } /* ** Arithmetic operations with register operands. */ -#define op_arith(L,iop,fop,tm) { \ +#define op_arith(L,iop,fop) { \ TValue *v1 = vRB(i); \ TValue *v2 = vRC(i); \ if (ttisinteger(v1) && ttisinteger(v2)) { \ lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ } \ - else op_arithf_aux(L, v1, v2, fop, tm); } + else op_arithf_aux(L, v1, v2, fop); } /* ** Arithmetic operations with K operands. */ -#define op_arithK(L,iop,fop,tm,flip) { \ +#define op_arithK(L,iop,fop,flip) { \ TValue *v1 = vRB(i); \ TValue *v2 = KC(i); \ if (ttisinteger(v1) && ttisinteger(v2)) { \ @@ -876,7 +877,7 @@ void luaV_finishOp (lua_State *L) { /* ** Arithmetic operations with K operands for floats. */ -#define op_arithfK(L,fop,tm) { \ +#define op_arithfK(L,fop) { \ TValue *v1 = vRB(i); \ TValue *v2 = KC(i); \ lua_Number n1; lua_Number n2; \ @@ -888,25 +889,25 @@ void luaV_finishOp (lua_State *L) { /* ** Bitwise operations with constant operand. */ -#define op_bitwiseK(L,op,tm) { \ +#define op_bitwiseK(L,op) { \ TValue *v1 = vRB(i); \ TValue *v2 = KC(i); \ lua_Integer i1; \ lua_Integer i2 = ivalue(v2); \ if (tointegerns(v1, &i1)) { \ - pc++; setivalue(s2v(ra), op(L, i1, i2)); \ + pc++; setivalue(s2v(ra), op(i1, i2)); \ }} /* ** Bitwise operations with register operands. */ -#define op_bitwise(L,op,tm) { \ +#define op_bitwise(L,op) { \ TValue *v1 = vRB(i); \ TValue *v2 = vRC(i); \ lua_Integer i1; lua_Integer i2; \ if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ - pc++; setivalue(s2v(ra), op(L, i1, i2)); \ + pc++; setivalue(s2v(ra), op(i1, i2)); \ }} @@ -1296,43 +1297,43 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_ADDK) { - op_arithK(L, l_addi, luai_numadd, TM_ADD, GETARG_k(i)); + op_arithK(L, l_addi, luai_numadd, GETARG_k(i)); vmbreak; } vmcase(OP_SUBK) { - op_arithK(L, l_subi, luai_numsub, TM_SUB, 0); + op_arithK(L, l_subi, luai_numsub, 0); vmbreak; } vmcase(OP_MULK) { - op_arithK(L, l_muli, luai_nummul, TM_MUL, GETARG_k(i)); + op_arithK(L, l_muli, luai_nummul, GETARG_k(i)); vmbreak; } vmcase(OP_MODK) { - op_arithK(L, luaV_mod, luaV_modf, TM_MOD, 0); + op_arithK(L, luaV_mod, luaV_modf, 0); vmbreak; } vmcase(OP_POWK) { - op_arithfK(L, luai_numpow, TM_POW); + op_arithfK(L, luai_numpow); vmbreak; } vmcase(OP_DIVK) { - op_arithfK(L, luai_numdiv, TM_DIV); + op_arithfK(L, luai_numdiv); vmbreak; } vmcase(OP_IDIVK) { - op_arithK(L, luaV_idiv, luai_numidiv, TM_IDIV, 0); + op_arithK(L, luaV_idiv, luai_numidiv, 0); vmbreak; } vmcase(OP_BANDK) { - op_bitwiseK(L, l_band, TM_BAND); + op_bitwiseK(L, l_band); vmbreak; } vmcase(OP_BORK) { - op_bitwiseK(L, l_bor, TM_BOR); + op_bitwiseK(L, l_bor); vmbreak; } vmcase(OP_BXORK) { - op_bitwiseK(L, l_bxor, TM_BXOR); + op_bitwiseK(L, l_bxor); vmbreak; } vmcase(OP_SHRI) { @@ -1340,14 +1341,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { int ic = GETARG_sC(i); lua_Integer ib; if (tointegerns(rb, &ib)) { - setivalue(s2v(ra), luaV_shiftl(ib, -ic)); - } - else { - TMS ev = TM_SHR; - if (TESTARG_k(i)) { - ic = -ic; ev = TM_SHL; - } - ProtectNT(luaT_trybiniTM(L, rb, ic, 0, ra, ev)); + pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic)); } vmbreak; } @@ -1356,72 +1350,56 @@ void luaV_execute (lua_State *L, CallInfo *ci) { int ic = GETARG_sC(i); lua_Integer ib; if (tointegerns(rb, &ib)) { - setivalue(s2v(ra), luaV_shiftl(ic, ib)); + pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib)); } - else - ProtectNT(luaT_trybiniTM(L, rb, ic, 1, ra, TM_SHL)); vmbreak; } vmcase(OP_ADD) { - op_arith(L, l_addi, luai_numadd, TM_ADD); + op_arith(L, l_addi, luai_numadd); vmbreak; } vmcase(OP_SUB) { - op_arith(L, l_subi, luai_numsub, TM_SUB); + op_arith(L, l_subi, luai_numsub); vmbreak; } vmcase(OP_MUL) { - op_arith(L, l_muli, luai_nummul, TM_MUL); + op_arith(L, l_muli, luai_nummul); vmbreak; } vmcase(OP_MOD) { - op_arith(L, luaV_mod, luaV_modf, TM_MOD); + op_arith(L, luaV_mod, luaV_modf); vmbreak; } vmcase(OP_POW) { - op_arithf(L, luai_numpow, TM_POW); + op_arithf(L, luai_numpow); vmbreak; } vmcase(OP_DIV) { /* float division (always with floats) */ - op_arithf(L, luai_numdiv, TM_DIV); + op_arithf(L, luai_numdiv); vmbreak; } vmcase(OP_IDIV) { /* floor division */ - op_arith(L, luaV_idiv, luai_numidiv, TM_IDIV); + op_arith(L, luaV_idiv, luai_numidiv); vmbreak; } vmcase(OP_BAND) { - op_bitwise(L, l_band, TM_BAND); + op_bitwise(L, l_band); vmbreak; } vmcase(OP_BOR) { - op_bitwise(L, l_bor, TM_BOR); + op_bitwise(L, l_bor); vmbreak; } vmcase(OP_BXOR) { - op_bitwise(L, l_bxor, TM_BXOR); + op_bitwise(L, l_bxor); vmbreak; } vmcase(OP_SHR) { - TValue *rb = vRB(i); - TValue *rc = vRC(i); - lua_Integer ib; lua_Integer ic; - if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { - setivalue(s2v(ra), luaV_shiftl(ib, -ic)); - } - else - ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); + op_bitwise(L, luaV_shiftr); vmbreak; } vmcase(OP_SHL) { - TValue *rb = vRB(i); - TValue *rc = vRC(i); - lua_Integer ib; lua_Integer ic; - if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { - setivalue(s2v(ra), luaV_shiftl(ib, ic)); - } - else - ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); + op_bitwise(L, luaV_shiftl); vmbreak; } vmcase(OP_MMBIN) { diff --git a/testes/code.lua b/testes/code.lua index fcb5c309..96560166 100644 --- a/testes/code.lua +++ b/testes/code.lua @@ -304,9 +304,9 @@ 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 k1 << x end, 3, 8, 'SHLI', 'MMBINI', 'RETURN1') +checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'MMBINI', 'RETURN1') +checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'MMBINI', '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') @@ -329,7 +329,7 @@ check(function () return -0.0 end, 'LOADF', 'UNM', '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', 'SHR', 'MMBIN', 'RETURN1') check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'MMBIN', 'RETURN1') -- basic 'for' loops diff --git a/testes/db.lua b/testes/db.lua index c43243a6..074a6d0b 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -806,8 +806,7 @@ assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and -a == "unm" and #a == "len" and a&3 == "band") assert(a + 30000 == "add" and a - 3.0 == "sub" and a * 3.0 == "mul" and -a == "unm" and #a == "len" and a & 3 == "band") -assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shift" and - a>>1 == "shift") +assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shl" and a>>1 == "shr") assert (a==b and a.op == "eq") assert (a>=b and a.op == "order") assert (a>b and a.op == "order")