summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-04-25 15:28:25 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-04-25 15:28:25 -0300
commit6dbae1b5d961a76d1e2ffd5d50d20b86290f483c (patch)
tree2b42581e278198859aea95ca2fccffd5eaeac586
parentcb3d5dce30089512085f78a0bef79e30ef732e30 (diff)
downloadlua-6dbae1b5d961a76d1e2ffd5d50d20b86290f483c.tar.gz
lua-6dbae1b5d961a76d1e2ffd5d50d20b86290f483c.tar.bz2
lua-6dbae1b5d961a76d1e2ffd5d50d20b86290f483c.zip
registers in a VINDEXED expression must be freed in order
-rw-r--r--lcode.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/lcode.c b/lcode.c
index a8f196b6..4271a5a7 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.113 2017/04/20 19:53:55 roberto Exp roberto $ 2** $Id: lcode.c,v 2.114 2017/04/24 20:26:39 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*/
@@ -392,6 +392,21 @@ static void freereg (FuncState *fs, int reg) {
392 392
393 393
394/* 394/*
395** Free two registers in proper order
396*/
397static void freeregs (FuncState *fs, int r1, int r2) {
398 if (r1 > r2) {
399 freereg(fs, r1);
400 freereg(fs, r2);
401 }
402 else {
403 freereg(fs, r2);
404 freereg(fs, r1);
405 }
406}
407
408
409/*
395** Free register used by expression 'e' (if any) 410** Free register used by expression 'e' (if any)
396*/ 411*/
397static void freeexp (FuncState *fs, expdesc *e) { 412static void freeexp (FuncState *fs, expdesc *e) {
@@ -407,14 +422,7 @@ static void freeexp (FuncState *fs, expdesc *e) {
407static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { 422static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
408 int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; 423 int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
409 int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; 424 int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
410 if (r1 > r2) { 425 freeregs(fs, r1, r2);
411 freereg(fs, r1);
412 freereg(fs, r2);
413 }
414 else {
415 freereg(fs, r2);
416 freereg(fs, r1);
417 }
418} 426}
419 427
420 428
@@ -574,13 +582,13 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
574 } 582 }
575 case VINDEXED: { 583 case VINDEXED: {
576 OpCode op; 584 OpCode op;
577 freereg(fs, e->u.ind.idx);
578 if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */ 585 if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */
579 freereg(fs, e->u.ind.t); 586 freeregs(fs, e->u.ind.t, e->u.ind.idx);
580 op = OP_GETTABLE; 587 op = OP_GETTABLE;
581 } 588 }
582 else { 589 else {
583 lua_assert(e->u.ind.vt == VUPVAL); 590 lua_assert(e->u.ind.vt == VUPVAL);
591 freereg(fs, e->u.ind.idx);
584 op = OP_GETTABUP; /* 't' is in an upvalue */ 592 op = OP_GETTABUP; /* 't' is in an upvalue */
585 } 593 }
586 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); 594 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);