diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-02-01 16:03:10 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-02-01 16:03:10 -0200 |
commit | dd547c55c85ba48f481836ba76ecdfe69960bcd0 (patch) | |
tree | d75d864ae35fc5bafacf3c206eaa20885b03a3d1 /lvm.c | |
parent | f6bd8b1147d58c35e73225b4adc5499c11d2bf0f (diff) | |
download | lua-dd547c55c85ba48f481836ba76ecdfe69960bcd0.tar.gz lua-dd547c55c85ba48f481836ba76ecdfe69960bcd0.tar.bz2 lua-dd547c55c85ba48f481836ba76ecdfe69960bcd0.zip |
new scheme to close upvalues in 'break'; jump instructions may
do the close, avoiding the need for a OP_CLOSE instruction
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 29 |
1 files changed, 18 insertions, 11 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.126 2010/12/06 21:08:36 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.127 2010/12/17 12:05:37 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 | */ |
@@ -466,7 +466,14 @@ void luaV_finishOp (lua_State *L) { | |||
466 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) | 466 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) |
467 | 467 | ||
468 | 468 | ||
469 | #define dojump(i) (ci->u.l.savedpc += (i)) | 469 | /* execute a jump instruction */ |
470 | #define dojump(ci,i) \ | ||
471 | { int a = GETARG_A(i); \ | ||
472 | if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ | ||
473 | ci->u.l.savedpc += GETARG_sBx(i); } | ||
474 | |||
475 | /* for test instructions, execute the jump instruction that follows it */ | ||
476 | #define donextjump(ci) dojump(ci, *ci->u.l.savedpc) | ||
470 | 477 | ||
471 | 478 | ||
472 | #define Protect(x) { {x;}; base = ci->u.l.base; } | 479 | #define Protect(x) { {x;}; base = ci->u.l.base; } |
@@ -620,41 +627,41 @@ void luaV_execute (lua_State *L) { | |||
620 | L->top = ci->top; /* restore top */ | 627 | L->top = ci->top; /* restore top */ |
621 | ) | 628 | ) |
622 | vmcase(OP_JMP, | 629 | vmcase(OP_JMP, |
623 | dojump(GETARG_sBx(i)); | 630 | dojump(ci, i); |
624 | ) | 631 | ) |
625 | vmcase(OP_EQ, | 632 | vmcase(OP_EQ, |
626 | TValue *rb = RKB(i); | 633 | TValue *rb = RKB(i); |
627 | TValue *rc = RKC(i); | 634 | TValue *rc = RKC(i); |
628 | Protect( | 635 | Protect( |
629 | if (equalobj(L, rb, rc) == GETARG_A(i)) | 636 | if (equalobj(L, rb, rc) == GETARG_A(i)) |
630 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 637 | donextjump(ci); |
631 | ) | 638 | ) |
632 | ci->u.l.savedpc++; | 639 | ci->u.l.savedpc++; |
633 | ) | 640 | ) |
634 | vmcase(OP_LT, | 641 | vmcase(OP_LT, |
635 | Protect( | 642 | Protect( |
636 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | 643 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) |
637 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 644 | donextjump(ci); |
638 | ) | 645 | ) |
639 | ci->u.l.savedpc++; | 646 | ci->u.l.savedpc++; |
640 | ) | 647 | ) |
641 | vmcase(OP_LE, | 648 | vmcase(OP_LE, |
642 | Protect( | 649 | Protect( |
643 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | 650 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) |
644 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 651 | donextjump(ci); |
645 | ) | 652 | ) |
646 | ci->u.l.savedpc++; | 653 | ci->u.l.savedpc++; |
647 | ) | 654 | ) |
648 | vmcase(OP_TEST, | 655 | vmcase(OP_TEST, |
649 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) | 656 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) |
650 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 657 | donextjump(ci); |
651 | ci->u.l.savedpc++; | 658 | ci->u.l.savedpc++; |
652 | ) | 659 | ) |
653 | vmcase(OP_TESTSET, | 660 | vmcase(OP_TESTSET, |
654 | TValue *rb = RB(i); | 661 | TValue *rb = RB(i); |
655 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { | 662 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { |
656 | setobjs2s(L, ra, rb); | 663 | setobjs2s(L, ra, rb); |
657 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 664 | donextjump(ci); |
658 | } | 665 | } |
659 | ci->u.l.savedpc++; | 666 | ci->u.l.savedpc++; |
660 | ) | 667 | ) |
@@ -722,7 +729,7 @@ void luaV_execute (lua_State *L) { | |||
722 | lua_Number limit = nvalue(ra+1); | 729 | lua_Number limit = nvalue(ra+1); |
723 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) | 730 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) |
724 | : luai_numle(L, limit, idx)) { | 731 | : luai_numle(L, limit, idx)) { |
725 | dojump(GETARG_sBx(i)); /* jump back */ | 732 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
726 | setnvalue(ra, idx); /* update internal index... */ | 733 | setnvalue(ra, idx); /* update internal index... */ |
727 | setnvalue(ra+3, idx); /* ...and external index */ | 734 | setnvalue(ra+3, idx); /* ...and external index */ |
728 | } | 735 | } |
@@ -738,7 +745,7 @@ void luaV_execute (lua_State *L) { | |||
738 | else if (!tonumber(pstep, ra+2)) | 745 | else if (!tonumber(pstep, ra+2)) |
739 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | 746 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
740 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); | 747 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
741 | dojump(GETARG_sBx(i)); | 748 | ci->u.l.savedpc += GETARG_sBx(i); |
742 | ) | 749 | ) |
743 | vmcase(OP_TFORCALL, | 750 | vmcase(OP_TFORCALL, |
744 | StkId cb = ra + 3; /* call base */ | 751 | StkId cb = ra + 3; /* call base */ |
@@ -757,7 +764,7 @@ void luaV_execute (lua_State *L) { | |||
757 | l_tforloop: | 764 | l_tforloop: |
758 | if (!ttisnil(ra + 1)) { /* continue loop? */ | 765 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
759 | setobjs2s(L, ra, ra + 1); /* save control variable */ | 766 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
760 | dojump(GETARG_sBx(i)); /* jump back */ | 767 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
761 | } | 768 | } |
762 | ) | 769 | ) |
763 | vmcase(OP_SETLIST, | 770 | vmcase(OP_SETLIST, |