diff --git a/lcode.c b/lcode.c index 841806fd..c48bc41e 100644 --- a/lcode.c +++ b/lcode.c @@ -1630,6 +1630,8 @@ static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) { void luaK_posfix (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2, int line) { luaK_dischargevars(fs, e2); + if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2)) + return; /* done by folding */ switch (opr) { case OPR_AND: { lua_assert(e1->t == NO_JUMP); /* list closed by 'luaK_infix' */ @@ -1649,35 +1651,29 @@ void luaK_posfix (FuncState *fs, BinOpr opr, break; } case OPR_ADD: case OPR_MUL: { - if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) - codecommutative(fs, opr, 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, opr, e1, e2, 0, line); + codearith(fs, opr, e1, e2, 0, line); break; } case OPR_BAND: case OPR_BOR: case OPR_BXOR: { - if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) - codebitwise(fs, opr, e1, e2, line); + codebitwise(fs, opr, e1, e2, line); break; } case OPR_SHL: { - if (!constfolding(fs, LUA_OPSHL, e1, e2)) { - if (isSCint(e1)) { - swapexps(e1, e2); - codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); - } - else - codeshift(fs, OP_SHL, e1, e2, line); + if (isSCint(e1)) { + swapexps(e1, e2); + codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); } + else + codeshift(fs, OP_SHL, e1, e2, line); break; } case OPR_SHR: { - if (!constfolding(fs, LUA_OPSHR, e1, e2)) - codeshift(fs, OP_SHR, e1, e2, line); + codeshift(fs, OP_SHR, e1, e2, line); break; } case OPR_EQ: case OPR_NE: { diff --git a/lcode.h b/lcode.h index 8cecd538..49c913ab 100644 --- a/lcode.h +++ b/lcode.h @@ -24,19 +24,27 @@ ** grep "ORDER OPR" if you change these enums (ORDER OP) */ typedef enum BinOpr { + /* arithmetic operators */ OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, - OPR_DIV, - OPR_IDIV, + OPR_DIV, OPR_IDIV, + /* bitwise operators */ OPR_BAND, OPR_BOR, OPR_BXOR, OPR_SHL, OPR_SHR, + /* string operator */ OPR_CONCAT, + /* comparison operators */ OPR_EQ, OPR_LT, OPR_LE, OPR_NE, OPR_GT, OPR_GE, + /* logical operators */ OPR_AND, OPR_OR, OPR_NOBINOPR } BinOpr; +/* true if operation is foldable (that is, it is arithmetic or bitwise) */ +#define foldbinop(op) ((op) <= OPR_SHR) + + #define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0)