Quellcode durchsuchen

new format for JUMP instructions (to allow larger offsets)

Roberto Ierusalimschy vor 7 Jahren
Ursprung
Commit
c3e5946fb2
6 geänderte Dateien mit 65 neuen und 24 gelöschten Zeilen
  1. 25 10
      lcode.c
  2. 2 2
      ldebug.c
  3. 2 2
      lopcodes.c
  4. 25 5
      lopcodes.h
  5. 9 3
      ltests.c
  6. 2 2
      lvm.c

+ 25 - 10
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.129 2017/10/04 15:49:24 roberto Exp roberto $
+** $Id: lcode.c,v 2.130 2017/10/04 21:56:32 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -37,6 +37,9 @@
 #define hasjumps(e)	((e)->t != (e)->f)
 
 
+static int codesJ (FuncState *fs, OpCode o, int sj, int k);
+
+
 /*
 ** If expression is a numeric constant, fills 'v' with its value
 ** and returns 1. Otherwise, returns 0.
@@ -89,7 +92,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
 ** a list of jumps.
 */
 static int getjump (FuncState *fs, int pc) {
-  int offset = GETARG_sBx(fs->f->code[pc]);
+  int offset = GETARG_sJ(fs->f->code[pc]);
   if (offset == NO_JUMP)  /* point to itself represents end of list */
     return NO_JUMP;  /* end of list */
   else
@@ -105,9 +108,10 @@ 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_sBx)
+  if (abs(offset) > MAXARG_sJ)
     luaX_syntaxerror(fs->ls, "control structure too long");
-  SETARG_sBx(*jmp, offset);
+  lua_assert(GET_OPCODE(*jmp) == OP_JMP);
+  SETARG_sJ(*jmp, offset);
 }
 
 
@@ -138,7 +142,7 @@ int luaK_jump (FuncState *fs) {
   int jpc = fs->jpc;  /* save list of jumps to here */
   int j;
   fs->jpc = NO_JUMP;  /* no more jumps to here */
-  j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
+  j = codesJ(fs, OP_JMP, NO_JUMP, 0);
   luaK_concat(fs, &j, jpc);  /* keep them on hold */
   return j;
 }
@@ -286,16 +290,16 @@ int luaK_needclose (FuncState *fs, int list) {
 /*
 ** Correct a jump list to jump to 'target'. If 'hasclose' is true,
 ** 'target' contains an OP_CLOSE instruction (see first assert).
-** Only jumps with the A arg true need that close; other jumps
+** Only jumps with the 'k' arg true need that close; other jumps
 ** avoid it jumping to the next instruction.
 */
 void luaK_patchgoto (FuncState *fs, int list, int target, int hasclose) {
   lua_assert(!hasclose || GET_OPCODE(fs->f->code[target]) == OP_CLOSE);
   while (list != NO_JUMP) {
     int next = getjump(fs, list);
-    lua_assert(!GETARG_A(fs->f->code[list]) || hasclose);
+    lua_assert(!GETARG_k(fs->f->code[list]) || hasclose);
     patchtestreg(fs, list, NO_REG);  /* do not generate values */
-    if (!hasclose || GETARG_A(fs->f->code[list]))
+    if (!hasclose || GETARG_k(fs->f->code[list]))
       fixjump(fs, list, target);
     else  /* there is a CLOSE instruction but jump does not need it */
       fixjump(fs, list, target + 1);  /* avoid CLOSE instruction */
@@ -305,14 +309,14 @@ void luaK_patchgoto (FuncState *fs, int list, int target, int hasclose) {
 
 
 /*
-** Mark (using the A arg) all jumps in 'list' to close upvalues. Mark
+** Mark (using the 'k' arg) all jumps in 'list' to close upvalues. Mark
 ** will instruct 'luaK_patchgoto' to make these jumps go to OP_CLOSE
 ** instructions.
 */
 void luaK_patchclose (FuncState *fs, int list) {
   for (; list != NO_JUMP; list = getjump(fs, list)) {
     lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP);
-    SETARG_A(fs->f->code[list], 1);
+    SETARG_k(fs->f->code[list], 1);
   }
 }
 
@@ -398,6 +402,17 @@ 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;
+  lua_assert(getOpMode(o) == isJ);
+  lua_assert(j <= MAXARG_sJ && (k & ~1) == 0);
+  return luaK_code(fs, CREATE_sJ(o, j, k));
+}
+
+
 /*
 ** Emit an "extra argument" instruction (format 'iAx')
 */

+ 2 - 2
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp $
+** $Id: ldebug.c,v 2.140 2017/11/07 13:25:26 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -442,7 +442,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) {
         break;
       }
       case OP_JMP: {  /* doesn't change registers, but changes 'jmptarget' */
-        int b = GETARG_sBx(i);
+        int b = GETARG_sJ(i);
         int dest = pc + 1 + b;
         /* jump does not skip 'lastpc' and is larger than current one? */
         if (dest <= lastpc && dest > jmptarget)

+ 2 - 2
lopcodes.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.c,v 1.65 2017/09/28 16:53:29 roberto Exp roberto $
+** $Id: lopcodes.c,v 1.66 2017/10/04 15:49:24 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -129,7 +129,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
  ,opmode(0, 1, iABC)		/* OP_LEN */
  ,opmode(0, 1, iABC)		/* OP_CONCAT */
  ,opmode(0, 0, iABC)		/* OP_CLOSE */
- ,opmode(0, 0, iAsBx)		/* OP_JMP */
+ ,opmode(0, 0, isJ)		/* OP_JMP */
  ,opmode(1, 0, iABC)		/* OP_EQ */
  ,opmode(1, 0, iABC)		/* OP_LT */
  ,opmode(1, 0, iABC)		/* OP_LE */

+ 25 - 5
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.165 2017/10/04 15:49:24 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.166 2017/10/04 21:56:32 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -21,6 +21,7 @@ iABC    |k|     C(8)    | |     B(8)    | |     A(8)    | |   Op(7)   |
 iABx    |            Bx(17)             | |     A(8)    | |   Op(7)   |
 iAsBx   |           sBx (signed)(17)    | |     A(8)    | |   Op(7)   |
 iAx     |                       Ax(25)                  | |   Op(7)   |
+iksJ    |k|                     sJ(24)                  | |   Op(7)   |
 
   A signed argument is represented in excess K: the represented value is
   the written unsigned value minus K, where K is half the maximum for the
@@ -28,7 +29,7 @@ iAx     |                       Ax(25)                  | |   Op(7)   |
 ===========================================================================*/
 
 
-enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
+enum OpMode {iABC, iABx, iAsBx, iAx, isJ};  /* basic instruction formats */
 
 
 /*
@@ -40,6 +41,8 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 #define SIZE_Bx		(SIZE_Cx + SIZE_B)
 #define SIZE_A		8
 #define SIZE_Ax		(SIZE_Cx + SIZE_B + SIZE_A)
+#define SIZE_sJ		(SIZE_C + SIZE_B + SIZE_A)
+
 
 #define SIZE_OP		7
 
@@ -50,6 +53,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 #define POS_k		(POS_C + SIZE_C)
 #define POS_Bx		POS_B
 #define POS_Ax		POS_A
+#define POS_sJ		POS_A
 
 
 /*
@@ -71,6 +75,12 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 #define MAXARG_Ax	MAX_INT
 #endif
 
+#if SIZE_sJ < LUAI_BITSINT-1
+#define MAXARG_sJ	((1 << (SIZE_sJ - 1)) - 1)
+#else
+#define MAXARG_sJ	MAX_INT
+#endif
+
 
 #define MAXARG_A	((1<<SIZE_A)-1)
 #define MAXARG_B	((1<<SIZE_B)-1)
@@ -111,6 +121,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 #define SETARG_C(i,v)	setarg(i, v, POS_C, SIZE_C)
 
 #define GETARG_k(i)	(cast(int, ((i) & (1 << POS_k))))
+#define SETARG_k(i,v)	setarg(i, v, POS_k, 1)
 
 #define GETARG_Bx(i)	check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx))
 #define SETARG_Bx(i,v)	setarg(i, v, POS_Bx, SIZE_Bx)
@@ -122,12 +133,17 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 	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))
 
+#define GETARG_sJ(i)  \
+	check_exp(checkopm(i, isJ), getarg(i, POS_sJ, SIZE_sJ) - MAXARG_sJ)
+#define SETARG_sJ(i,j) \
+	setarg(i, cast(unsigned int, (j)+MAXARG_sJ), POS_sJ, SIZE_sJ)
+
 
 #define CREATE_ABCk(o,a,b,c,k)	((cast(Instruction, o)<<POS_OP) \
 			| (cast(Instruction, a)<<POS_A) \
 			| (cast(Instruction, b)<<POS_B) \
-			| (cast(Instruction, c)<<POS_C)) \
-			| (cast(Instruction, k)<<POS_k)
+			| (cast(Instruction, c)<<POS_C) \
+			| (cast(Instruction, k)<<POS_k))
 
 #define CREATE_ABx(o,a,bc)	((cast(Instruction, o)<<POS_OP) \
 			| (cast(Instruction, a)<<POS_A) \
@@ -136,6 +152,10 @@ enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
 #define CREATE_Ax(o,a)		((cast(Instruction, o)<<POS_OP) \
 			| (cast(Instruction, a)<<POS_Ax))
 
+#define CREATE_sJ(o,j,k)	((cast(Instruction, o) << POS_OP) \
+			| (cast(Instruction, j) << POS_sJ) \
+			| (cast(Instruction, k) << POS_k))
+
 
 #if !defined(MAXINDEXRK)  /* (for debugging only) */
 #define MAXINDEXRK	MAXARG_B
@@ -215,7 +235,7 @@ OP_LEN,/*	A B	R(A) := length of R(B)				*/
 OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
 
 OP_CLOSE,/*	A	close all upvalues >= R(A)			*/
-OP_JMP,/*	sBx	pc+=sBx						*/
+OP_JMP,/*	k sJ	pc += sJ  (k is used in code generation)	*/
 OP_EQ,/*	A B C	if ((R(B) == R(C)) ~= A) then pc++		*/
 OP_LT,/*	A B C	if ((R(B) <  R(C)) ~= A) then pc++		*/
 OP_LE,/*	A B C	if ((R(B) <= R(C)) ~= A) then pc++		*/

+ 9 - 3
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp $
+** $Id: ltests.c,v 2.230 2017/11/07 13:25:26 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -543,14 +543,20 @@ static char *buildop (Proto *p, int pc, char *buff) {
               GETARG_k(i) ? " (k)" : "");
       break;
     case iABx:
-      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
+      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i),
+                                                       GETARG_Bx(i));
       break;
     case iAsBx:
-      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
+      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i),
+                                                       GETARG_sBx(i));
       break;
     case iAx:
       sprintf(buff+strlen(buff), "%-12s%4d", name, GETARG_Ax(i));
       break;
+    case isJ:
+      sprintf(buff+strlen(buff), "%-12s%4d (%1d)", name, GETARG_sJ(i),
+                                                         !!GETARG_k(i));
+      break;
   }
   return buff;
 }

+ 2 - 2
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp $
+** $Id: lvm.c,v 2.306 2017/11/07 13:25:26 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -753,7 +753,7 @@ void luaV_finishOp (lua_State *L) {
 ** Execute a jump instruction. The 'updatemask' allows signals to stop
 ** tight loops. (Without it, the local copy of 'mask' could never change.)
 */
-#define dojump(ci,i,e)	{ pc += GETARG_sBx(i) + e; updatemask(L); }
+#define dojump(ci,i,e)	{ pc += GETARG_sJ(i) + e; updatemask(L); }
 
 
 /* for test instructions, execute the jump instruction that follows it */