mirror of https://github.com/rusefi/lua.git
new format for JUMP instructions (to allow larger offsets)
This commit is contained in:
parent
ad0704e40c
commit
c3e5946fb2
35
lcode.c
35
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')
|
||||
*/
|
||||
|
|
4
ldebug.c
4
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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
30
lopcodes.h
30
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++ */
|
||||
|
|
12
ltests.c
12
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;
|
||||
}
|
||||
|
|
4
lvm.c
4
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 */
|
||||
|
|
Loading…
Reference in New Issue