diff --git a/lcode.c b/lcode.c index 12dc2505..ccf7b1ae 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.115 2017/04/25 18:28:25 roberto Exp roberto $ +** $Id: lcode.c,v 2.116 2017/04/25 20:01:14 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -963,6 +963,16 @@ static int isKstr (FuncState *fs, expdesc *e) { } +/* +** Check whether expression 'e' is a literal integer in +** proper range +*/ +static int isKint (expdesc *e) { + return (e->k == VKINT && !hasjumps(e) && + l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); +} + + /* ** Create expression 't[k]'. 't' must have its final result already in a ** register or upvalue. Upvalues can only be indexed by literal strings. @@ -1047,10 +1057,24 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { */ static void codebinexpval (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2, int line) { - int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ - int rk1 = luaK_exp2RK(fs, e1); + int v1, v2; + if (op == OP_ADD && (isKint(e1) || isKint(e2))) { + if (isKint(e2)) { + v2 = cast_int(e2->u.ival); + v1 = luaK_exp2anyreg(fs, e1); + } + else { /* exchange operands to make 2nd one a constant */ + v2 = cast_int(e1->u.ival); + v1 = luaK_exp2anyreg(fs, e2) | BITRK; /* K bit signal the exchange */ + } + op = OP_ADDI; + } + else { + v2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ + v1 = luaK_exp2RK(fs, e1); + } freeexps(fs, e1, e2); - e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */ + e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ e1->k = VRELOCABLE; /* all those operations are relocatable */ luaK_fixline(fs, line); } diff --git a/ldebug.c b/ldebug.c index f1835890..4f35d211 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp roberto $ +** $Id: ldebug.c,v 2.121 2016/10/19 12:32:10 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -513,6 +513,9 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, case OP_SETTABUP: case OP_SETTABLE: tm = TM_NEWINDEX; break; + case OP_ADDI: + tm = TM_ADD; + 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: { diff --git a/lopcodes.c b/lopcodes.c index 18199764..f66f209a 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp roberto $ +** $Id: lopcodes.c,v 1.56 2017/04/20 19:53:55 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -32,6 +32,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { "SETTABLE", "NEWTABLE", "SELF", + "ADDI", "ADD", "SUB", "MUL", @@ -88,6 +89,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgR, OpArgU, iABC) /* OP_ADDI */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ diff --git a/lopcodes.h b/lopcodes.h index ed3ea66d..c359581d 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.150 2017/04/20 19:53:55 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.151 2017/04/24 20:26:39 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -90,7 +90,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ ((cast(Instruction, o)<>pos) & MASK1(size,0))) +#define getarg(i,pos,size) (cast(int, ((i)>>(pos)) & MASK1(size,0))) #define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ ((cast(Instruction, v)<