aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c91
-rw-r--r--lcode.h3
-rw-r--r--lparser.c4
-rw-r--r--lparser.h3
-rw-r--r--lvm.c10
5 files changed, 63 insertions, 48 deletions
diff --git a/lcode.c b/lcode.c
index 8f9fa408..d1585193 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.138 2017/11/28 15:26:15 roberto Exp roberto $ 2** $Id: lcode.c,v 2.140 2017/11/30 13:17:06 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*/
@@ -134,17 +134,10 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
134 134
135/* 135/*
136** Create a jump instruction and return its position, so its destination 136** Create a jump instruction and return its position, so its destination
137** can be fixed later (with 'fixjump'). If there are jumps to 137** can be fixed later (with 'fixjump').
138** this position (kept in 'jpc'), link them all together so that
139** 'patchlistaux' will fix all them directly to the final destination.
140*/ 138*/
141int luaK_jump (FuncState *fs) { 139int luaK_jump (FuncState *fs) {
142 int jpc = fs->jpc; /* save list of jumps to here */ 140 return codesJ(fs, OP_JMP, NO_JUMP, 0);
143 int j;
144 fs->jpc = NO_JUMP; /* no more jumps to here */
145 j = codesJ(fs, OP_JMP, NO_JUMP, 0);
146 luaK_concat(fs, &j, jpc); /* keep them on hold */
147 return j;
148} 141}
149 142
150 143
@@ -250,38 +243,19 @@ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
250 243
251 244
252/* 245/*
253** Ensure all pending jumps to current position are fixed (jumping
254** to current position with no values) and reset list of pending
255** jumps
256*/
257static void dischargejpc (FuncState *fs) {
258 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
259 fs->jpc = NO_JUMP;
260}
261
262
263/*
264** Add elements in 'list' to list of pending jumps to "here"
265** (current position)
266*/
267void luaK_patchtohere (FuncState *fs, int list) {
268 luaK_getlabel(fs); /* mark "here" as a jump target */
269 luaK_concat(fs, &fs->jpc, list);
270}
271
272
273/*
274** Path all jumps in 'list' to jump to 'target'. 246** Path all jumps in 'list' to jump to 'target'.
275** (The assert means that we cannot fix a jump to a forward address 247** (The assert means that we cannot fix a jump to a forward address
276** because we only know addresses once code is generated.) 248** because we only know addresses once code is generated.)
277*/ 249*/
278void luaK_patchlist (FuncState *fs, int list, int target) { 250void luaK_patchlist (FuncState *fs, int list, int target) {
279 if (target == fs->pc) /* 'target' is current position? */ 251 lua_assert(target <= fs->pc);
280 luaK_patchtohere(fs, list); /* add list to pending jumps */ 252 patchlistaux(fs, list, target, NO_REG, target);
281 else { 253}
282 lua_assert(target < fs->pc); 254
283 patchlistaux(fs, list, target, NO_REG, target); 255
284 } 256void luaK_patchtohere (FuncState *fs, int list) {
257 int hr = luaK_getlabel(fs); /* mark "here" as a jump target */
258 luaK_patchlist(fs, list, hr);
285} 259}
286 260
287 261
@@ -365,7 +339,6 @@ static void savelineinfo (FuncState *fs, Proto *f, int pc, int line) {
365*/ 339*/
366static int luaK_code (FuncState *fs, Instruction i) { 340static int luaK_code (FuncState *fs, Instruction i) {
367 Proto *f = fs->f; 341 Proto *f = fs->f;
368 dischargejpc(fs); /* 'pc' will change */
369 /* put new instruction in code array */ 342 /* put new instruction in code array */
370 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, 343 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
371 MAX_INT, "opcodes"); 344 MAX_INT, "opcodes");
@@ -1537,3 +1510,45 @@ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
1537 fs->freereg = base + 1; /* free registers with list values */ 1510 fs->freereg = base + 1; /* free registers with list values */
1538} 1511}
1539 1512
1513
1514/*
1515** return the final target of a jump (skipping jumps to jumps)
1516*/
1517static int finaltarget (Instruction *code, int i) {
1518 int count;
1519 for (count = 0; count < 100; count++) { /* avoid infinite loops */
1520 Instruction pc = code[i];
1521 if (GET_OPCODE(pc) != OP_JMP)
1522 break;
1523 else
1524 i += GETARG_sJ(pc) + 1;
1525 }
1526 return i;
1527}
1528
1529
1530/*
1531** Do a final pass over the code of a function, doing small peephole
1532** optimizations and adjustments.
1533*/
1534void luaK_finish (FuncState *fs) {
1535 int i;
1536 Proto *p = fs->f;
1537 for (i = 0; i < fs->pc; i++) {
1538 Instruction *pc = &p->code[i];
1539 switch (GET_OPCODE(*pc)) {
1540 case OP_RETURN: case OP_RETURN0: case OP_RETURN1:
1541 case OP_TAILCALL: {
1542 if (p->sizep > 0)
1543 SETARG_k(*pc, 1); /* signal that they must close upvalues */
1544 break;
1545 }
1546 case OP_JMP: {
1547 int target = finaltarget(p->code, i);
1548 fixjump(fs, i, target);
1549 break;
1550 }
1551 default: break;
1552 }
1553 }
1554}
diff --git a/lcode.h b/lcode.h
index 1c3229d9..a1fd735d 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.67 2017/09/28 16:53:29 roberto Exp roberto $ 2** $Id: lcode.h,v 1.68 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*/
@@ -88,6 +88,7 @@ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
88LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 88LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
89 expdesc *v2, int line); 89 expdesc *v2, int line);
90LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 90LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
91LUAI_FUNC void luaK_finish (FuncState *fs);
91 92
92 93
93#endif 94#endif
diff --git a/lparser.c b/lparser.c
index 3eb83fba..1d46c6f2 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.167 2017/10/04 21:53:03 roberto Exp roberto $ 2** $Id: lparser.c,v 2.168 2017/11/23 16:35:54 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -547,7 +547,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
547 fs->previousline = f->linedefined; 547 fs->previousline = f->linedefined;
548 fs->iwthabs = 0; 548 fs->iwthabs = 0;
549 fs->lasttarget = 0; 549 fs->lasttarget = 0;
550 fs->jpc = NO_JUMP;
551 fs->freereg = 0; 550 fs->freereg = 0;
552 fs->nk = 0; 551 fs->nk = 0;
553 fs->nabslineinfo = 0; 552 fs->nabslineinfo = 0;
@@ -569,6 +568,7 @@ static void close_func (LexState *ls) {
569 Proto *f = fs->f; 568 Proto *f = fs->f;
570 luaK_ret(fs, 0, 0); /* final return */ 569 luaK_ret(fs, 0, 0); /* final return */
571 leaveblock(fs); 570 leaveblock(fs);
571 luaK_finish(fs);
572 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); 572 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
573 f->sizecode = fs->pc; 573 f->sizecode = fs->pc;
574 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); 574 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
diff --git a/lparser.h b/lparser.h
index 3ab6065d..4d342d32 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.77 2017/04/28 20:57:45 roberto Exp roberto $ 2** $Id: lparser.h,v 1.78 2017/06/27 11:35:31 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -124,7 +124,6 @@ typedef struct FuncState {
124 int pc; /* next position to code (equivalent to 'ncode') */ 124 int pc; /* next position to code (equivalent to 'ncode') */
125 int lasttarget; /* 'label' of last 'jump label' */ 125 int lasttarget; /* 'label' of last 'jump label' */
126 int previousline; /* last line that was saved in 'lineinfo' */ 126 int previousline; /* last line that was saved in 'lineinfo' */
127 int jpc; /* list of pending jumps to 'pc' */
128 int nk; /* number of elements in 'k' */ 127 int nk; /* number of elements in 'k' */
129 int np; /* number of elements in 'p' */ 128 int np; /* number of elements in 'p' */
130 int nabslineinfo; /* number of elements in 'abslineinfo' */ 129 int nabslineinfo; /* number of elements in 'abslineinfo' */
diff --git a/lvm.c b/lvm.c
index 16e4fde0..0ba78b3d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.321 2017/11/29 13:02:17 roberto Exp roberto $ 2** $Id: lvm.c,v 2.322 2017/11/29 16:57:36 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1453,7 +1453,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1453 /* next instruction will do the return */ 1453 /* next instruction will do the return */
1454 } 1454 }
1455 else { /* tail call */ 1455 else { /* tail call */
1456 if (cl->p->sizep > 0) /* close upvalues from previous call */ 1456 if (TESTARG_k(i)) /* close upvalues from previous call */
1457 luaF_close(L, ci->func + 1); 1457 luaF_close(L, ci->func + 1);
1458 luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ 1458 luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
1459 goto tailcall; 1459 goto tailcall;
@@ -1462,7 +1462,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1462 } 1462 }
1463 vmcase(OP_RETURN) { 1463 vmcase(OP_RETURN) {
1464 int b = GETARG_B(i); 1464 int b = GETARG_B(i);
1465 if (cl->p->sizep > 0) 1465 if (TESTARG_k(i))
1466 luaF_close(L, base); 1466 luaF_close(L, base);
1467 halfProtect( 1467 halfProtect(
1468 luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))) 1468 luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)))
@@ -1470,7 +1470,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1470 return; 1470 return;
1471 } 1471 }
1472 vmcase(OP_RETURN0) { 1472 vmcase(OP_RETURN0) {
1473 if (cl->p->sizep > 0) 1473 if (TESTARG_k(i))
1474 luaF_close(L, base); 1474 luaF_close(L, base);
1475 if (L->hookmask) 1475 if (L->hookmask)
1476 halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */ 1476 halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */
@@ -1484,7 +1484,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1484 return; 1484 return;
1485 } 1485 }
1486 vmcase(OP_RETURN1) { 1486 vmcase(OP_RETURN1) {
1487 if (cl->p->sizep > 0) 1487 if (TESTARG_k(i))
1488 luaF_close(L, base); 1488 luaF_close(L, base);
1489 if (L->hookmask) 1489 if (L->hookmask)
1490 halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */ 1490 halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */