aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/lcode.c b/lcode.c
index f94afb0b..5ca597eb 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.129 2017/10/04 15:49:24 roberto Exp roberto $ 2** $Id: lcode.c,v 2.130 2017/10/04 21:56:32 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -37,6 +37,9 @@
37#define hasjumps(e) ((e)->t != (e)->f) 37#define hasjumps(e) ((e)->t != (e)->f)
38 38
39 39
40static int codesJ (FuncState *fs, OpCode o, int sj, int k);
41
42
40/* 43/*
41** If expression is a numeric constant, fills 'v' with its value 44** If expression is a numeric constant, fills 'v' with its value
42** and returns 1. Otherwise, returns 0. 45** and returns 1. Otherwise, returns 0.
@@ -89,7 +92,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
89** a list of jumps. 92** a list of jumps.
90*/ 93*/
91static int getjump (FuncState *fs, int pc) { 94static int getjump (FuncState *fs, int pc) {
92 int offset = GETARG_sBx(fs->f->code[pc]); 95 int offset = GETARG_sJ(fs->f->code[pc]);
93 if (offset == NO_JUMP) /* point to itself represents end of list */ 96 if (offset == NO_JUMP) /* point to itself represents end of list */
94 return NO_JUMP; /* end of list */ 97 return NO_JUMP; /* end of list */
95 else 98 else
@@ -105,9 +108,10 @@ static void fixjump (FuncState *fs, int pc, int dest) {
105 Instruction *jmp = &fs->f->code[pc]; 108 Instruction *jmp = &fs->f->code[pc];
106 int offset = dest - (pc + 1); 109 int offset = dest - (pc + 1);
107 lua_assert(dest != NO_JUMP); 110 lua_assert(dest != NO_JUMP);
108 if (abs(offset) > MAXARG_sBx) 111 if (abs(offset) > MAXARG_sJ)
109 luaX_syntaxerror(fs->ls, "control structure too long"); 112 luaX_syntaxerror(fs->ls, "control structure too long");
110 SETARG_sBx(*jmp, offset); 113 lua_assert(GET_OPCODE(*jmp) == OP_JMP);
114 SETARG_sJ(*jmp, offset);
111} 115}
112 116
113 117
@@ -138,7 +142,7 @@ int luaK_jump (FuncState *fs) {
138 int jpc = fs->jpc; /* save list of jumps to here */ 142 int jpc = fs->jpc; /* save list of jumps to here */
139 int j; 143 int j;
140 fs->jpc = NO_JUMP; /* no more jumps to here */ 144 fs->jpc = NO_JUMP; /* no more jumps to here */
141 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); 145 j = codesJ(fs, OP_JMP, NO_JUMP, 0);
142 luaK_concat(fs, &j, jpc); /* keep them on hold */ 146 luaK_concat(fs, &j, jpc); /* keep them on hold */
143 return j; 147 return j;
144} 148}
@@ -286,16 +290,16 @@ int luaK_needclose (FuncState *fs, int list) {
286/* 290/*
287** Correct a jump list to jump to 'target'. If 'hasclose' is true, 291** Correct a jump list to jump to 'target'. If 'hasclose' is true,
288** 'target' contains an OP_CLOSE instruction (see first assert). 292** 'target' contains an OP_CLOSE instruction (see first assert).
289** Only jumps with the A arg true need that close; other jumps 293** Only jumps with the 'k' arg true need that close; other jumps
290** avoid it jumping to the next instruction. 294** avoid it jumping to the next instruction.
291*/ 295*/
292void luaK_patchgoto (FuncState *fs, int list, int target, int hasclose) { 296void luaK_patchgoto (FuncState *fs, int list, int target, int hasclose) {
293 lua_assert(!hasclose || GET_OPCODE(fs->f->code[target]) == OP_CLOSE); 297 lua_assert(!hasclose || GET_OPCODE(fs->f->code[target]) == OP_CLOSE);
294 while (list != NO_JUMP) { 298 while (list != NO_JUMP) {
295 int next = getjump(fs, list); 299 int next = getjump(fs, list);
296 lua_assert(!GETARG_A(fs->f->code[list]) || hasclose); 300 lua_assert(!GETARG_k(fs->f->code[list]) || hasclose);
297 patchtestreg(fs, list, NO_REG); /* do not generate values */ 301 patchtestreg(fs, list, NO_REG); /* do not generate values */
298 if (!hasclose || GETARG_A(fs->f->code[list])) 302 if (!hasclose || GETARG_k(fs->f->code[list]))
299 fixjump(fs, list, target); 303 fixjump(fs, list, target);
300 else /* there is a CLOSE instruction but jump does not need it */ 304 else /* there is a CLOSE instruction but jump does not need it */
301 fixjump(fs, list, target + 1); /* avoid CLOSE instruction */ 305 fixjump(fs, list, target + 1); /* avoid CLOSE instruction */
@@ -305,14 +309,14 @@ void luaK_patchgoto (FuncState *fs, int list, int target, int hasclose) {
305 309
306 310
307/* 311/*
308** Mark (using the A arg) all jumps in 'list' to close upvalues. Mark 312** Mark (using the 'k' arg) all jumps in 'list' to close upvalues. Mark
309** will instruct 'luaK_patchgoto' to make these jumps go to OP_CLOSE 313** will instruct 'luaK_patchgoto' to make these jumps go to OP_CLOSE
310** instructions. 314** instructions.
311*/ 315*/
312void luaK_patchclose (FuncState *fs, int list) { 316void luaK_patchclose (FuncState *fs, int list) {
313 for (; list != NO_JUMP; list = getjump(fs, list)) { 317 for (; list != NO_JUMP; list = getjump(fs, list)) {
314 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP); 318 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP);
315 SETARG_A(fs->f->code[list], 1); 319 SETARG_k(fs->f->code[list], 1);
316 } 320 }
317} 321}
318 322
@@ -399,6 +403,17 @@ int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
399 403
400 404
401/* 405/*
406** Format and emit an 'isJ' instruction.
407*/
408static int codesJ (FuncState *fs, OpCode o, int sj, int k) {
409 unsigned int j = sj + MAXARG_sJ;
410 lua_assert(getOpMode(o) == isJ);
411 lua_assert(j <= MAXARG_sJ && (k & ~1) == 0);
412 return luaK_code(fs, CREATE_sJ(o, j, k));
413}
414
415
416/*
402** Emit an "extra argument" instruction (format 'iAx') 417** Emit an "extra argument" instruction (format 'iAx')
403*/ 418*/
404static int codeextraarg (FuncState *fs, int a) { 419static int codeextraarg (FuncState *fs, int a) {