diff options
-rw-r--r-- | lvm.c | 57 |
1 files changed, 37 insertions, 20 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.252 2015/09/09 13:44:07 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.253 2015/09/17 15:51:05 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 | */ |
@@ -710,21 +710,14 @@ void luaV_finishOp (lua_State *L) { | |||
710 | ** some macros for common tasks in 'luaV_execute' | 710 | ** some macros for common tasks in 'luaV_execute' |
711 | */ | 711 | */ |
712 | 712 | ||
713 | #if !defined(luai_runtimecheck) | ||
714 | #define luai_runtimecheck(L, c) /* void */ | ||
715 | #endif | ||
716 | |||
717 | 713 | ||
718 | #define RA(i) (base+GETARG_A(i)) | 714 | #define RA(i) (base+GETARG_A(i)) |
719 | /* to be used after possible stack reallocation */ | ||
720 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) | 715 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) |
721 | #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) | 716 | #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) |
722 | #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ | 717 | #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ |
723 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) | 718 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) |
724 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ | 719 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ |
725 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) | 720 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) |
726 | #define KBx(i) \ | ||
727 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) | ||
728 | 721 | ||
729 | 722 | ||
730 | /* execute a jump instruction */ | 723 | /* execute a jump instruction */ |
@@ -750,6 +743,23 @@ void luaV_finishOp (lua_State *L) { | |||
750 | #define vmcase(l) case l: | 743 | #define vmcase(l) case l: |
751 | #define vmbreak break | 744 | #define vmbreak break |
752 | 745 | ||
746 | |||
747 | /* | ||
748 | ** copy of 'luaV_gettable', but protecting call to potential metamethod | ||
749 | ** (which can reallocate the stack) | ||
750 | */ | ||
751 | #define gettableProtected(L,t,k,v) { const TValue *aux; \ | ||
752 | if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \ | ||
753 | else Protect(luaV_finishget(L,t,k,v,aux)); } | ||
754 | |||
755 | |||
756 | /* same for 'luaV_settable' */ | ||
757 | #define settableProtected(L,t,k,v) { const TValue *slot; \ | ||
758 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ | ||
759 | Protect(luaV_finishset(L,t,k,v,slot)); } | ||
760 | |||
761 | |||
762 | |||
753 | void luaV_execute (lua_State *L) { | 763 | void luaV_execute (lua_State *L) { |
754 | CallInfo *ci = L->ci; | 764 | CallInfo *ci = L->ci; |
755 | LClosure *cl; | 765 | LClosure *cl; |
@@ -757,9 +767,9 @@ void luaV_execute (lua_State *L) { | |||
757 | StkId base; | 767 | StkId base; |
758 | newframe: /* reentry point when frame changes (call/return) */ | 768 | newframe: /* reentry point when frame changes (call/return) */ |
759 | lua_assert(ci == L->ci); | 769 | lua_assert(ci == L->ci); |
760 | cl = clLvalue(ci->func); | 770 | cl = clLvalue(ci->func); /* local reference to function's closure */ |
761 | k = cl->p->k; | 771 | k = cl->p->k; /* local reference to function's constant table */ |
762 | base = ci->u.l.base; | 772 | base = ci->u.l.base; /* local copy of function's base */ |
763 | /* main loop of interpreter */ | 773 | /* main loop of interpreter */ |
764 | for (;;) { | 774 | for (;;) { |
765 | Instruction i = *(ci->u.l.savedpc++); | 775 | Instruction i = *(ci->u.l.savedpc++); |
@@ -807,17 +817,22 @@ void luaV_execute (lua_State *L) { | |||
807 | vmbreak; | 817 | vmbreak; |
808 | } | 818 | } |
809 | vmcase(OP_GETTABUP) { | 819 | vmcase(OP_GETTABUP) { |
810 | int b = GETARG_B(i); | 820 | TValue *upval = cl->upvals[GETARG_B(i)]->v; |
811 | Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); | 821 | TValue *rc = RKC(i); |
822 | gettableProtected(L, upval, rc, ra); | ||
812 | vmbreak; | 823 | vmbreak; |
813 | } | 824 | } |
814 | vmcase(OP_GETTABLE) { | 825 | vmcase(OP_GETTABLE) { |
815 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); | 826 | StkId rb = RB(i); |
827 | TValue *rc = RKC(i); | ||
828 | gettableProtected(L, rb, rc, ra); | ||
816 | vmbreak; | 829 | vmbreak; |
817 | } | 830 | } |
818 | vmcase(OP_SETTABUP) { | 831 | vmcase(OP_SETTABUP) { |
819 | int a = GETARG_A(i); | 832 | TValue *upval = cl->upvals[GETARG_A(i)]->v; |
820 | Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); | 833 | TValue *rb = RKB(i); |
834 | TValue *rc = RKC(i); | ||
835 | settableProtected(L, upval, rb, rc); | ||
821 | vmbreak; | 836 | vmbreak; |
822 | } | 837 | } |
823 | vmcase(OP_SETUPVAL) { | 838 | vmcase(OP_SETUPVAL) { |
@@ -827,7 +842,9 @@ void luaV_execute (lua_State *L) { | |||
827 | vmbreak; | 842 | vmbreak; |
828 | } | 843 | } |
829 | vmcase(OP_SETTABLE) { | 844 | vmcase(OP_SETTABLE) { |
830 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); | 845 | TValue *rb = RKB(i); |
846 | TValue *rc = RKC(i); | ||
847 | settableProtected(L, ra, rb, rc); | ||
831 | vmbreak; | 848 | vmbreak; |
832 | } | 849 | } |
833 | vmcase(OP_NEWTABLE) { | 850 | vmcase(OP_NEWTABLE) { |
@@ -842,8 +859,9 @@ void luaV_execute (lua_State *L) { | |||
842 | } | 859 | } |
843 | vmcase(OP_SELF) { | 860 | vmcase(OP_SELF) { |
844 | StkId rb = RB(i); | 861 | StkId rb = RB(i); |
845 | setobjs2s(L, ra+1, rb); | 862 | TValue *rc = RKC(i); |
846 | Protect(luaV_gettable(L, rb, RKC(i), ra)); | 863 | setobjs2s(L, ra + 1, rb); |
864 | gettableProtected(L, rb, rc, ra); | ||
847 | vmbreak; | 865 | vmbreak; |
848 | } | 866 | } |
849 | vmcase(OP_ADD) { | 867 | vmcase(OP_ADD) { |
@@ -1229,7 +1247,6 @@ void luaV_execute (lua_State *L) { | |||
1229 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); | 1247 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
1230 | c = GETARG_Ax(*ci->u.l.savedpc++); | 1248 | c = GETARG_Ax(*ci->u.l.savedpc++); |
1231 | } | 1249 | } |
1232 | luai_runtimecheck(L, ttistable(ra)); | ||
1233 | h = hvalue(ra); | 1250 | h = hvalue(ra); |
1234 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 1251 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
1235 | if (last > h->sizearray) /* needs more space? */ | 1252 | if (last > h->sizearray) /* needs more space? */ |