diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-25 15:28:25 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-25 15:28:25 -0300 |
commit | 6dbae1b5d961a76d1e2ffd5d50d20b86290f483c (patch) | |
tree | 2b42581e278198859aea95ca2fccffd5eaeac586 | |
parent | cb3d5dce30089512085f78a0bef79e30ef732e30 (diff) | |
download | lua-6dbae1b5d961a76d1e2ffd5d50d20b86290f483c.tar.gz lua-6dbae1b5d961a76d1e2ffd5d50d20b86290f483c.tar.bz2 lua-6dbae1b5d961a76d1e2ffd5d50d20b86290f483c.zip |
registers in a VINDEXED expression must be freed in order
-rw-r--r-- | lcode.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -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 | */ | ||
397 | static 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 | */ |
397 | static void freeexp (FuncState *fs, expdesc *e) { | 412 | static void freeexp (FuncState *fs, expdesc *e) { |
@@ -407,14 +422,7 @@ static void freeexp (FuncState *fs, expdesc *e) { | |||
407 | static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { | 422 | static 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); |