Przeglądaj źródła

new opcode OP_ADDI (for immediate integer operand) (Experimental)

Roberto Ierusalimschy 8 lat temu
rodzic
commit
173e41b2eb
5 zmienionych plików z 65 dodań i 11 usunięć
  1. 28 4
      lcode.c
  2. 4 1
      ldebug.c
  3. 3 1
      lopcodes.c
  4. 6 2
      lopcodes.h
  5. 24 3
      lvm.c

+ 28 - 4
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);
 }

+ 4 - 1
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: {

+ 3 - 1
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 */

+ 6 - 2
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_OP)&MASK1(SIZE_OP,POS_OP))))
 
-#define getarg(i,pos,size)	(cast(int, ((i)>>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)<<pos)&MASK1(size,pos))))
 
@@ -100,6 +100,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 #define GETARG_B(i)	getarg(i, POS_B, SIZE_B)
 #define SETARG_B(i,v)	setarg(i, v, POS_B, SIZE_B)
 
+#define GETARG_Br(i)	getarg(i, POS_B, SIZE_B - 1)
+#define GETARG_Bk(i)	getarg(i, (POS_B + SIZE_B - 1), 1)
+
 #define GETARG_C(i)	getarg(i, POS_C, SIZE_C)
 #define SETARG_C(i,v)	setarg(i, v, POS_C, SIZE_C)
 
@@ -187,6 +190,7 @@ OP_NEWTABLE,/*	A B C	R(A) := {} (size = B,C)				*/
 
 OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
 
+OP_ADDI,/*	A B C	R(A) := R(B) + C				*/
 OP_ADD,/*	A B C	R(A) := RK(B) + RK(C)				*/
 OP_SUB,/*	A B C	R(A) := RK(B) - RK(C)				*/
 OP_MUL,/*	A B C	R(A) := RK(B) * RK(C)				*/

+ 24 - 3
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.271 2017/04/20 19:53:55 roberto Exp roberto $
+** $Id: lvm.c,v 2.272 2017/04/24 20:26:39 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -725,10 +725,10 @@ void luaV_finishOp (lua_State *L) {
 
 
 #define RA(i)	(base+GETARG_A(i))
-#define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
+#define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_Br(i))
 #define RC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
 #define RKB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
-	ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
+	(GETARG_Bk(i)) ? k+GETARG_Br(i) : base+GETARG_Br(i))
 #define RKC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
 	ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
 
@@ -898,6 +898,27 @@ void luaV_execute (lua_State *L) {
         else Protect(luaV_finishget(L, rb, rc, ra, slot));
         vmbreak;
       }
+      vmcase(OP_ADDI) {
+        TValue *rb = RB(i);
+        int ic = GETARG_C(i);
+        lua_Number nb;
+        if (ttisinteger(rb)) {
+          setivalue(ra, intop(+, ivalue(rb), ic));
+        }
+        else if (tonumber(rb, &nb)) {
+          setfltvalue(ra, luai_numadd(L, nb, cast_num(ic)));
+        }
+        else {
+          TValue aux; TValue *rc;
+          setivalue(&aux, ic);
+          if (GETARG_Bk(i)) {  /* arguments were exchanged? */
+            rc = rb; rb = &aux;  /* correct them */
+          }
+          else rc = &aux;
+          Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD));
+        }
+        vmbreak;
+      }
       vmcase(OP_ADD) {
         TValue *rb = RKB(i);
         TValue *rc = RKC(i);