浏览代码

some cleaning on signed opcode parameters

Roberto Ierusalimschy 7 年之前
父节点
当前提交
f8c1c1469a
共有 3 个文件被更改,包括 50 次插入27 次删除
  1. 32 12
      lcode.c
  2. 16 13
      lopcodes.h
  3. 2 2
      ltests.c

+ 32 - 12
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.143 2017/12/13 18:32:09 roberto Exp roberto $
+** $Id: lcode.c,v 2.144 2017/12/14 14:24:02 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -108,7 +108,7 @@ static void fixjump (FuncState *fs, int pc, int dest) {
   Instruction *jmp = &fs->f->code[pc];
   int offset = dest - (pc + 1);
   lua_assert(dest != NO_JUMP);
-  if (abs(offset) > MAXARG_sJ)
+  if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ))
     luaX_syntaxerror(fs->ls, "control structure too long");
   lua_assert(GET_OPCODE(*jmp) == OP_JMP);
   SETARG_sJ(*jmp, offset);
@@ -360,7 +360,7 @@ int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) {
 }
 
 
-#define codeABsC(fs,o,a,b,c,k)	luaK_codeABCk(fs,o,a,b,((c) + MAXARG_sC),k)
+#define codeABsC(fs,o,a,b,c,k)	luaK_codeABCk(fs,o,a,b,((c) + OFFSET_sC),k)
 
 
 
@@ -378,7 +378,7 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
 ** Format and emit an 'iAsBx' instruction.
 */
 int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
-  unsigned int b = bc + MAXARG_sBx;
+  unsigned int b = bc + OFFSET_sBx;
   lua_assert(getOpMode(o) == iAsBx);
   lua_assert(a <= MAXARG_A && b <= MAXARG_Bx);
   return luaK_code(fs, CREATE_ABx(o, a, b));
@@ -389,7 +389,7 @@ int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
 ** Format and emit an 'isJ' instruction.
 */
 static int codesJ (FuncState *fs, OpCode o, int sj, int k) {
-  unsigned int j = sj + MAXARG_sJ;
+  unsigned int j = sj + OFFSET_sJ;
   lua_assert(getOpMode(o) == isJ);
   lua_assert(j <= MAXARG_sJ && (k & ~1) == 0);
   return luaK_code(fs, CREATE_sJ(o, j, k));
@@ -582,8 +582,26 @@ static int nilK (FuncState *fs) {
 }
 
 
+/*
+** Check whether 'i' can be stored in an 'sC' operand.
+** Equivalent to (0 <= i + OFFSET_sC && i + OFFSET_sC <= MAXARG_C)
+** but without risk of overflows in the addition.
+*/
+static int fitsC (lua_Integer i) {
+  return (-OFFSET_sC <= i && i <= MAXARG_C - OFFSET_sC);
+}
+
+
+/*
+** Check whether 'i' can be stored in an 'sBx' operand.
+*/
+static int fitsBx (lua_Integer i) {
+  return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx);
+}
+
+
 void luaK_int (FuncState *fs, int reg, lua_Integer i) {
-  if (l_castS2U(i) + MAXARG_sBx <= l_castS2U(MAXARG_Bx))
+  if (fitsBx(i))
     luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i));
   else
     luaK_codek(fs, reg, luaK_intK(fs, i));
@@ -593,8 +611,7 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) {
 static int floatI (lua_Number f, lua_Integer *fi) {
   TValue v;
   setfltvalue(&v, f);
-  return (luaV_flttointeger(&v, fi, 0) &&
-      l_castS2U(*fi) + MAXARG_sBx <= l_castS2U(MAXARG_Bx));
+  return (luaV_flttointeger(&v, fi, 0) && fitsBx(*fi));
 }
 
 
@@ -1089,8 +1106,7 @@ static int isCint (expdesc *e) {
 ** proper range to fit in register sC
 */
 static int isSCint (expdesc *e) {
-  return (e->k == VKINT && !hasjumps(e) &&
-          l_castS2U(e->u.ival + MAXARG_sC) <= l_castS2U(MAXARG_C));
+  return (e->k == VKINT && !hasjumps(e) && fitsC(e->u.ival));
 }
 
 
@@ -1103,8 +1119,12 @@ static int isSCnumber (expdesc *e, lua_Integer *i) {
     *i = e->u.ival;
   else if (!(e->k == VKFLT && floatI(e->u.nval, i)))
     return 0;  /* not a number */
-  *i += MAXARG_sC;
-  return (!hasjumps(e) && l_castS2U(*i) <= l_castS2U(MAXARG_C));
+  if (!hasjumps(e) && fitsC(*i)) {
+    *i += OFFSET_sC;
+    return 1;
+  }
+  else
+    return 0;
 }
 
 

+ 16 - 13
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.177 2017/12/13 18:32:09 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.178 2017/12/15 18:35:22 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -62,13 +62,14 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ};  /* basic instruction formats */
 ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
 */
 #if SIZE_Bx < LUAI_BITSINT-1
-#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
-#define MAXARG_sBx        (MAXARG_Bx>>1)         /* 'sBx' is signed */
+#define MAXARG_Bx	((1<<SIZE_Bx)-1)
 #else
-#define MAXARG_Bx        MAX_INT
-#define MAXARG_sBx        MAX_INT
+#define MAXARG_Bx	MAX_INT
 #endif
 
+#define OFFSET_sBx	(MAXARG_Bx>>1)         /* 'sBx' is signed */
+
+
 #if SIZE_Ax < LUAI_BITSINT-1
 #define MAXARG_Ax	((1<<SIZE_Ax)-1)
 #else
@@ -76,16 +77,18 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ};  /* basic instruction formats */
 #endif
 
 #if SIZE_sJ < LUAI_BITSINT-1
-#define MAXARG_sJ	((1 << (SIZE_sJ - 1)) - 1)
+#define MAXARG_sJ	((1 << SIZE_sJ) - 1)
 #else
 #define MAXARG_sJ	MAX_INT
 #endif
 
+#define OFFSET_sJ	(MAXARG_sJ >> 1)
+
 
 #define MAXARG_A	((1<<SIZE_A)-1)
 #define MAXARG_B	((1<<SIZE_B)-1)
 #define MAXARG_C	((1<<SIZE_C)-1)
-#define MAXARG_sC	(MAXARG_C >> 1)
+#define OFFSET_sC	(MAXARG_C >> 1)
 #define MAXARG_Cx	((1<<(SIZE_C + 1))-1)
 
 
@@ -114,11 +117,11 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ};  /* basic instruction formats */
 #define SETARG_A(i,v)	setarg(i, v, POS_A, SIZE_A)
 
 #define GETARG_B(i)	check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B))
-#define GETARG_sB(i)	(GETARG_B(i) - MAXARG_sC)
+#define GETARG_sB(i)	(GETARG_B(i) - OFFSET_sC)
 #define SETARG_B(i,v)	setarg(i, v, POS_B, SIZE_B)
 
 #define GETARG_C(i)	check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C))
-#define GETARG_sC(i)	(GETARG_C(i) - MAXARG_sC)
+#define GETARG_sC(i)	(GETARG_C(i) - OFFSET_sC)
 #define SETARG_C(i,v)	setarg(i, v, POS_C, SIZE_C)
 
 #define TESTARG_k(i)	(cast(int, ((i) & (1u << POS_k))))
@@ -132,13 +135,13 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ};  /* basic instruction formats */
 #define SETARG_Ax(i,v)	setarg(i, v, POS_Ax, SIZE_Ax)
 
 #define GETARG_sBx(i)  \
-	check_exp(checkopm(i, iAsBx), getarg(i, POS_Bx, SIZE_Bx) - MAXARG_sBx)
-#define SETARG_sBx(i,b)	SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
+	check_exp(checkopm(i, iAsBx), getarg(i, POS_Bx, SIZE_Bx) - OFFSET_sBx)
+#define SETARG_sBx(i,b)	SETARG_Bx((i),cast(unsigned int, (b)+OFFSET_sBx))
 
 #define GETARG_sJ(i)  \
-	check_exp(checkopm(i, isJ), getarg(i, POS_sJ, SIZE_sJ) - MAXARG_sJ)
+	check_exp(checkopm(i, isJ), getarg(i, POS_sJ, SIZE_sJ) - OFFSET_sJ)
 #define SETARG_sJ(i,j) \
-	setarg(i, cast(unsigned int, (j)+MAXARG_sJ), POS_sJ, SIZE_sJ)
+	setarg(i, cast(unsigned int, (j)+OFFSET_sJ), POS_sJ, SIZE_sJ)
 
 
 #define CREATE_ABCk(o,a,b,c,k)	((cast(Instruction, o)<<POS_OP) \

+ 2 - 2
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.235 2017/12/08 15:19:13 roberto Exp roberto $
+** $Id: ltests.c,v 2.236 2017/12/11 18:55:31 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -665,7 +665,7 @@ static int get_limits (lua_State *L) {
   setnameval(L, "BITS_INT", LUAI_BITSINT);
   setnameval(L, "MAXARG_Ax", MAXARG_Ax);
   setnameval(L, "MAXARG_Bx", MAXARG_Bx);
-  setnameval(L, "MAXARG_sBx", MAXARG_sBx);
+  setnameval(L, "OFFSET_sBx", OFFSET_sBx);
   setnameval(L, "BITS_INT", LUAI_BITSINT);
   setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
   setnameval(L, "NUM_OPCODES", NUM_OPCODES);