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? */ |
