diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
commit | ad0704e40cc7b3135fedc6d40a522addb039e090 (patch) | |
tree | 4bcd104de4941239e09316efcee5e5e3566b8b81 /lvm.c | |
parent | 5a3f26f85558bedfa439027919d928abfdd00b6d (diff) | |
download | lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.gz lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.bz2 lua-ad0704e40cc7b3135fedc6d40a522addb039e090.zip |
back to 'CallInfo' (no gains with its removal)
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 133 |
1 files changed, 66 insertions, 67 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.304 2017/11/03 19:33:22 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -390,9 +390,9 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | |||
390 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ | 390 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ |
391 | return res; | 391 | return res; |
392 | else { /* try 'lt': */ | 392 | else { /* try 'lt': */ |
393 | callstatus(L->func) |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ | 393 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ |
394 | res = luaT_callorderTM(L, r, l, TM_LT); | 394 | res = luaT_callorderTM(L, r, l, TM_LT); |
395 | callstatus(L->func) ^= CIST_LEQ; /* clear mark */ | 395 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ |
396 | if (res < 0) | 396 | if (res < 0) |
397 | luaG_ordererror(L, l, r); | 397 | luaG_ordererror(L, l, r); |
398 | return !res; /* result is negated */ | 398 | return !res; /* result is negated */ |
@@ -654,14 +654,13 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | |||
654 | } | 654 | } |
655 | 655 | ||
656 | 656 | ||
657 | #define basepc(base) ((base - 1)->stkci.u.l.savedpc) | ||
658 | |||
659 | /* | 657 | /* |
660 | ** finish execution of an opcode interrupted by an yield | 658 | ** finish execution of an opcode interrupted by an yield |
661 | */ | 659 | */ |
662 | void luaV_finishOp (lua_State *L) { | 660 | void luaV_finishOp (lua_State *L) { |
663 | StkId base = L->func + 1; | 661 | CallInfo *ci = L->ci; |
664 | Instruction inst = *(basepc(base) - 1); /* interrupted instruction */ | 662 | StkId base = ci->func + 1; |
663 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
665 | OpCode op = GET_OPCODE(inst); | 664 | OpCode op = GET_OPCODE(inst); |
666 | switch (op) { /* finish its execution */ | 665 | switch (op) { /* finish its execution */ |
667 | case OP_ADDI: case OP_SUBI: | 666 | case OP_ADDI: case OP_SUBI: |
@@ -680,14 +679,14 @@ void luaV_finishOp (lua_State *L) { | |||
680 | case OP_LE: case OP_LT: case OP_EQ: { | 679 | case OP_LE: case OP_LT: case OP_EQ: { |
681 | int res = !l_isfalse(s2v(L->top - 1)); | 680 | int res = !l_isfalse(s2v(L->top - 1)); |
682 | L->top--; | 681 | L->top--; |
683 | if (callstatus(base - 1) & CIST_LEQ) { /* "<=" using "<" ? */ | 682 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ |
684 | lua_assert(op == OP_LE); | 683 | lua_assert(op == OP_LE); |
685 | callstatus(base - 1) ^= CIST_LEQ; /* clear mark */ | 684 | ci->callstatus ^= CIST_LEQ; /* clear mark */ |
686 | res = !res; /* negate result */ | 685 | res = !res; /* negate result */ |
687 | } | 686 | } |
688 | lua_assert(GET_OPCODE(*basepc(base)) == OP_JMP); | 687 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
689 | if (res != GETARG_A(inst)) /* condition failed? */ | 688 | if (res != GETARG_A(inst)) /* condition failed? */ |
690 | basepc(base)++; /* skip jump instruction */ | 689 | ci->u.l.savedpc++; /* skip jump instruction */ |
691 | break; | 690 | break; |
692 | } | 691 | } |
693 | case OP_CONCAT: { | 692 | case OP_CONCAT: { |
@@ -700,18 +699,18 @@ void luaV_finishOp (lua_State *L) { | |||
700 | luaV_concat(L, total); /* concat them (may yield again) */ | 699 | luaV_concat(L, total); /* concat them (may yield again) */ |
701 | } | 700 | } |
702 | /* move final result to final position */ | 701 | /* move final result to final position */ |
703 | setobjs2s(L, L->func + 1 + GETARG_A(inst), L->top - 1); | 702 | setobjs2s(L, ci->func + 1 + GETARG_A(inst), L->top - 1); |
704 | L->top = functop(base - 1); /* restore top */ | 703 | L->top = ci->top; /* restore top */ |
705 | break; | 704 | break; |
706 | } | 705 | } |
707 | case OP_TFORCALL: { | 706 | case OP_TFORCALL: { |
708 | lua_assert(GET_OPCODE(*basepc(base)) == OP_TFORLOOP); | 707 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); |
709 | L->top = functop(base - 1); /* correct top */ | 708 | L->top = ci->top; /* correct top */ |
710 | break; | 709 | break; |
711 | } | 710 | } |
712 | case OP_CALL: { | 711 | case OP_CALL: { |
713 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ | 712 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ |
714 | L->top = functop(base - 1); /* adjust results */ | 713 | L->top = ci->top; /* adjust results */ |
715 | break; | 714 | break; |
716 | } | 715 | } |
717 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: | 716 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: |
@@ -754,33 +753,31 @@ void luaV_finishOp (lua_State *L) { | |||
754 | ** Execute a jump instruction. The 'updatemask' allows signals to stop | 753 | ** Execute a jump instruction. The 'updatemask' allows signals to stop |
755 | ** tight loops. (Without it, the local copy of 'mask' could never change.) | 754 | ** tight loops. (Without it, the local copy of 'mask' could never change.) |
756 | */ | 755 | */ |
757 | #define dojump(i,e) { pc += GETARG_sBx(i) + e; updatemask(L); } | 756 | #define dojump(ci,i,e) { pc += GETARG_sBx(i) + e; updatemask(L); } |
758 | 757 | ||
759 | 758 | ||
760 | /* for test instructions, execute the jump instruction that follows it */ | 759 | /* for test instructions, execute the jump instruction that follows it */ |
761 | #define donextjump() { i = *pc; dojump(i, 1); } | 760 | #define donextjump(ci) { i = *pc; dojump(ci, i, 1); } |
762 | 761 | ||
763 | /* | 762 | /* |
764 | ** Whenever code can raise errors (including memory errors), the global | 763 | ** Whenever code can raise errors (including memory errors), the global |
765 | ** 'pc' must be correct to report occasional errors. | 764 | ** 'pc' must be correct to report occasional errors. |
766 | */ | 765 | */ |
767 | #define savepc(base) (basepc(base) = pc) | 766 | #define savepc(L) (ci->u.l.savedpc = pc) |
768 | |||
769 | 767 | ||
770 | /* update internal copies to its correct values */ | ||
771 | #define updatestate() (base = L->func + 1, updatemask(L)) | ||
772 | 768 | ||
773 | /* | 769 | /* |
774 | ** Protect code that, in general, can raise errors, reallocate the | 770 | ** Protect code that, in general, can raise errors, reallocate the |
775 | ** stack, and change the hooks. | 771 | ** stack, and change the hooks. |
776 | */ | 772 | */ |
777 | #define Protect(code) { savepc(base); {code;}; updatestate(); } | 773 | #define Protect(code) \ |
774 | { savepc(L); {code;}; base = ci->func + 1; updatemask(L); } | ||
778 | 775 | ||
779 | 776 | ||
780 | #define checkGC(L,c) \ | 777 | #define checkGC(L,c) \ |
781 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ | 778 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ |
782 | {updatestate(); L->top = functop(base - 1);}); /* restore top */ \ | 779 | Protect(L->top = ci->top)); /* restore top */ \ |
783 | luai_threadyield(L); } | 780 | luai_threadyield(L); } |
784 | 781 | ||
785 | 782 | ||
786 | /* fetch an instruction and prepare its execution */ | 783 | /* fetch an instruction and prepare its execution */ |
@@ -796,23 +793,26 @@ void luaV_finishOp (lua_State *L) { | |||
796 | 793 | ||
797 | 794 | ||
798 | void luaV_execute (lua_State *L) { | 795 | void luaV_execute (lua_State *L) { |
796 | CallInfo *ci = L->ci; | ||
799 | LClosure *cl; | 797 | LClosure *cl; |
800 | TValue *k; | 798 | TValue *k; |
801 | StkId base = L->func + 1; /* local copy of 'L->func + 1' */ | 799 | StkId base; /* local copy of 'ci->func + 1' */ |
802 | int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ | 800 | int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ |
803 | const Instruction *pc; /* local copy of 'basepc(base)' */ | 801 | const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */ |
804 | callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ | 802 | ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ |
805 | newframe: /* reentry point when frame changes (call/return) */ | 803 | newframe: /* reentry point when frame changes (call/return) */ |
806 | cl = clLvalue(s2v(L->func)); /* local reference to function's closure */ | 804 | lua_assert(ci == L->ci); |
805 | cl = clLvalue(s2v(ci->func)); /* local reference to function's closure */ | ||
807 | k = cl->p->k; /* local reference to function's constant table */ | 806 | k = cl->p->k; /* local reference to function's constant table */ |
808 | updatemask(L); | 807 | updatemask(L); |
809 | pc = basepc(base); | 808 | base = ci->func + 1; |
809 | pc = ci->u.l.savedpc; | ||
810 | /* main loop of interpreter */ | 810 | /* main loop of interpreter */ |
811 | for (;;) { | 811 | for (;;) { |
812 | Instruction i; | 812 | Instruction i; |
813 | StkId ra; | 813 | StkId ra; |
814 | vmfetch(); | 814 | vmfetch(); |
815 | lua_assert(base == L->func + 1); | 815 | lua_assert(base == ci->func + 1); |
816 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); | 816 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
817 | vmdispatch (GET_OPCODE(i)) { | 817 | vmdispatch (GET_OPCODE(i)) { |
818 | vmcase(OP_MOVE) { | 818 | vmcase(OP_MOVE) { |
@@ -970,7 +970,7 @@ void luaV_execute (lua_State *L) { | |||
970 | int b = GETARG_B(i); | 970 | int b = GETARG_B(i); |
971 | int c = GETARG_C(i); | 971 | int c = GETARG_C(i); |
972 | Table *t; | 972 | Table *t; |
973 | savepc(base); /* in case of allocation errors */ | 973 | savepc(L); /* in case of allocation errors */ |
974 | t = luaH_new(L); | 974 | t = luaH_new(L); |
975 | sethvalue2s(L, ra, t); | 975 | sethvalue2s(L, ra, t); |
976 | if (b != 0 || c != 0) | 976 | if (b != 0 || c != 0) |
@@ -1276,7 +1276,7 @@ void luaV_execute (lua_State *L) { | |||
1276 | rb = base + b; | 1276 | rb = base + b; |
1277 | setobjs2s(L, ra, rb); | 1277 | setobjs2s(L, ra, rb); |
1278 | checkGC(L, (ra >= rb ? ra + 1 : rb)); | 1278 | checkGC(L, (ra >= rb ? ra + 1 : rb)); |
1279 | L->top = functop(base - 1); /* restore top */ | 1279 | L->top = ci->top; /* restore top */ |
1280 | vmbreak; | 1280 | vmbreak; |
1281 | } | 1281 | } |
1282 | vmcase(OP_CLOSE) { | 1282 | vmcase(OP_CLOSE) { |
@@ -1284,7 +1284,7 @@ void luaV_execute (lua_State *L) { | |||
1284 | vmbreak; | 1284 | vmbreak; |
1285 | } | 1285 | } |
1286 | vmcase(OP_JMP) { | 1286 | vmcase(OP_JMP) { |
1287 | dojump(i, 0); | 1287 | dojump(ci, i, 0); |
1288 | vmbreak; | 1288 | vmbreak; |
1289 | } | 1289 | } |
1290 | vmcase(OP_EQ) { | 1290 | vmcase(OP_EQ) { |
@@ -1294,7 +1294,7 @@ void luaV_execute (lua_State *L) { | |||
1294 | if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) | 1294 | if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) |
1295 | pc++; | 1295 | pc++; |
1296 | else | 1296 | else |
1297 | donextjump(); | 1297 | donextjump(ci); |
1298 | ) | 1298 | ) |
1299 | vmbreak; | 1299 | vmbreak; |
1300 | } | 1300 | } |
@@ -1310,7 +1310,7 @@ void luaV_execute (lua_State *L) { | |||
1310 | if (res != GETARG_A(i)) | 1310 | if (res != GETARG_A(i)) |
1311 | pc++; | 1311 | pc++; |
1312 | else | 1312 | else |
1313 | donextjump(); | 1313 | donextjump(ci); |
1314 | vmbreak; | 1314 | vmbreak; |
1315 | } | 1315 | } |
1316 | vmcase(OP_LE) { | 1316 | vmcase(OP_LE) { |
@@ -1325,14 +1325,14 @@ void luaV_execute (lua_State *L) { | |||
1325 | if (res != GETARG_A(i)) | 1325 | if (res != GETARG_A(i)) |
1326 | pc++; | 1326 | pc++; |
1327 | else | 1327 | else |
1328 | donextjump(); | 1328 | donextjump(ci); |
1329 | vmbreak; | 1329 | vmbreak; |
1330 | } | 1330 | } |
1331 | vmcase(OP_TEST) { | 1331 | vmcase(OP_TEST) { |
1332 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) | 1332 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) |
1333 | pc++; | 1333 | pc++; |
1334 | else | 1334 | else |
1335 | donextjump(); | 1335 | donextjump(ci); |
1336 | vmbreak; | 1336 | vmbreak; |
1337 | } | 1337 | } |
1338 | vmcase(OP_TESTSET) { | 1338 | vmcase(OP_TESTSET) { |
@@ -1341,7 +1341,7 @@ void luaV_execute (lua_State *L) { | |||
1341 | pc++; | 1341 | pc++; |
1342 | else { | 1342 | else { |
1343 | setobj2s(L, ra, rb); | 1343 | setobj2s(L, ra, rb); |
1344 | donextjump(); | 1344 | donextjump(ci); |
1345 | } | 1345 | } |
1346 | vmbreak; | 1346 | vmbreak; |
1347 | } | 1347 | } |
@@ -1355,11 +1355,11 @@ void luaV_execute (lua_State *L) { | |||
1355 | Protect(isC = luaD_precall(L, ra, nresults)); | 1355 | Protect(isC = luaD_precall(L, ra, nresults)); |
1356 | if (isC) { /* C function? */ | 1356 | if (isC) { /* C function? */ |
1357 | if (nresults >= 0) /* fixed number of results? */ | 1357 | if (nresults >= 0) /* fixed number of results? */ |
1358 | L->top = functop(base - 1); /* correct top */ | 1358 | L->top = ci->top; /* correct top */ |
1359 | /* else leave top for next instruction */ | 1359 | /* else leave top for next instruction */ |
1360 | } | 1360 | } |
1361 | else { /* Lua function */ | 1361 | else { /* Lua function */ |
1362 | base = L->func + 1; | 1362 | ci = L->ci; |
1363 | goto newframe; /* restart luaV_execute over new Lua function */ | 1363 | goto newframe; /* restart luaV_execute over new Lua function */ |
1364 | } | 1364 | } |
1365 | vmbreak; | 1365 | vmbreak; |
@@ -1368,14 +1368,16 @@ void luaV_execute (lua_State *L) { | |||
1368 | int b = GETARG_B(i); | 1368 | int b = GETARG_B(i); |
1369 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 1369 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
1370 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 1370 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
1371 | savepc(base); | 1371 | savepc(L); |
1372 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | 1372 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ |
1373 | updatestate(); /* update 'base' */ | 1373 | Protect((void)0); /* update 'base' */ |
1374 | } | 1374 | } |
1375 | else { | 1375 | else { |
1376 | /* tail call: put called frame (n) in place of caller one (o) */ | 1376 | /* tail call: put called frame (n) in place of caller one (o) */ |
1377 | StkId nfunc = L->func; /* called function */ | 1377 | CallInfo *nci = L->ci; /* called frame (new) */ |
1378 | StkId ofunc = nfunc - nfunc->stkci.previous; /* caller function */ | 1378 | CallInfo *oci = nci->previous; /* caller frame (old) */ |
1379 | StkId nfunc = nci->func; /* called function */ | ||
1380 | StkId ofunc = oci->func; /* caller function */ | ||
1379 | /* last stack slot filled by 'precall' */ | 1381 | /* last stack slot filled by 'precall' */ |
1380 | StkId lim = nfunc + 1 + getproto(s2v(nfunc))->numparams; | 1382 | StkId lim = nfunc + 1 + getproto(s2v(nfunc))->numparams; |
1381 | int aux; | 1383 | int aux; |
@@ -1384,13 +1386,11 @@ void luaV_execute (lua_State *L) { | |||
1384 | /* move new frame into old one */ | 1386 | /* move new frame into old one */ |
1385 | for (aux = 0; nfunc + aux < lim; aux++) | 1387 | for (aux = 0; nfunc + aux < lim; aux++) |
1386 | setobjs2s(L, ofunc + aux, nfunc + aux); | 1388 | setobjs2s(L, ofunc + aux, nfunc + aux); |
1387 | ofunc->stkci.framesize = L->top - nfunc; | 1389 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ |
1388 | L->top = functop(ofunc); /* correct top */ | 1390 | oci->u.l.savedpc = nci->u.l.savedpc; |
1389 | ofunc->stkci.u.l.savedpc = nfunc->stkci.u.l.savedpc; | 1391 | oci->callstatus |= CIST_TAIL; /* function was tail called */ |
1390 | callstatus(ofunc) |= CIST_TAIL; /* function was tail called */ | 1392 | ci = L->ci = oci; /* remove new frame */ |
1391 | base = ofunc + 1; | 1393 | lua_assert(L->top == ofunc + 1 + getproto(s2v(ofunc))->maxstacksize); |
1392 | L->func = ofunc; | ||
1393 | lua_assert(L->top == base + getproto(s2v(ofunc))->maxstacksize); | ||
1394 | goto newframe; /* restart luaV_execute over new Lua function */ | 1394 | goto newframe; /* restart luaV_execute over new Lua function */ |
1395 | } | 1395 | } |
1396 | vmbreak; | 1396 | vmbreak; |
@@ -1398,16 +1398,16 @@ void luaV_execute (lua_State *L) { | |||
1398 | vmcase(OP_RETURN) { | 1398 | vmcase(OP_RETURN) { |
1399 | int b = GETARG_B(i); | 1399 | int b = GETARG_B(i); |
1400 | if (cl->p->sizep > 0) luaF_close(L, base); | 1400 | if (cl->p->sizep > 0) luaF_close(L, base); |
1401 | savepc(base); | 1401 | savepc(L); |
1402 | b = luaD_poscall(L, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); | 1402 | b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); |
1403 | if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */ | 1403 | if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ |
1404 | return; /* external invocation: return */ | 1404 | return; /* external invocation: return */ |
1405 | else { /* invocation via reentry: continue execution */ | 1405 | else { /* invocation via reentry: continue execution */ |
1406 | base = L->func + 1; | 1406 | ci = L->ci; |
1407 | if (b) L->top = functop(base - 1); | 1407 | if (b) L->top = ci->top; |
1408 | lua_assert(isLua(base - 1)); | 1408 | lua_assert(isLua(ci)); |
1409 | lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL); | 1409 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
1410 | goto newframe; /* restart luaV_execute over previous Lua function */ | 1410 | goto newframe; /* restart luaV_execute over new Lua function */ |
1411 | } | 1411 | } |
1412 | } | 1412 | } |
1413 | vmcase(OP_FORLOOP) { | 1413 | vmcase(OP_FORLOOP) { |
@@ -1451,7 +1451,7 @@ void luaV_execute (lua_State *L) { | |||
1451 | } | 1451 | } |
1452 | else { /* try making all values floats */ | 1452 | else { /* try making all values floats */ |
1453 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | 1453 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; |
1454 | savepc(base); /* in case of errors */ | 1454 | savepc(L); /* in case of errors */ |
1455 | if (!tonumber(plimit, &nlimit)) | 1455 | if (!tonumber(plimit, &nlimit)) |
1456 | luaG_runerror(L, "'for' limit must be a number"); | 1456 | luaG_runerror(L, "'for' limit must be a number"); |
1457 | setfltvalue(plimit, nlimit); | 1457 | setfltvalue(plimit, nlimit); |
@@ -1472,7 +1472,7 @@ void luaV_execute (lua_State *L) { | |||
1472 | setobjs2s(L, cb, ra); | 1472 | setobjs2s(L, cb, ra); |
1473 | L->top = cb + 3; /* func. + 2 args (state and index) */ | 1473 | L->top = cb + 3; /* func. + 2 args (state and index) */ |
1474 | Protect(luaD_call(L, cb, GETARG_C(i))); | 1474 | Protect(luaD_call(L, cb, GETARG_C(i))); |
1475 | L->top = functop(base - 1); | 1475 | L->top = ci->top; |
1476 | i = *(pc++); /* go to next instruction */ | 1476 | i = *(pc++); /* go to next instruction */ |
1477 | ra = RA(i); | 1477 | ra = RA(i); |
1478 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); | 1478 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
@@ -1497,7 +1497,7 @@ void luaV_execute (lua_State *L) { | |||
1497 | } | 1497 | } |
1498 | h = hvalue(s2v(ra)); | 1498 | h = hvalue(s2v(ra)); |
1499 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 1499 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
1500 | savepc(base); /* in case of allocation errors */ | 1500 | savepc(L); /* in case of allocation errors */ |
1501 | if (last > h->sizearray) /* needs more space? */ | 1501 | if (last > h->sizearray) /* needs more space? */ |
1502 | luaH_resizearray(L, h, last); /* preallocate it at once */ | 1502 | luaH_resizearray(L, h, last); /* preallocate it at once */ |
1503 | for (; n > 0; n--) { | 1503 | for (; n > 0; n--) { |
@@ -1506,15 +1506,14 @@ void luaV_execute (lua_State *L) { | |||
1506 | last--; | 1506 | last--; |
1507 | luaC_barrierback(L, h, val); | 1507 | luaC_barrierback(L, h, val); |
1508 | } | 1508 | } |
1509 | /* correct top (in case of previous open call) */ | 1509 | L->top = ci->top; /* correct top (in case of previous open call) */ |
1510 | L->top = functop(base - 1); | ||
1511 | vmbreak; | 1510 | vmbreak; |
1512 | } | 1511 | } |
1513 | vmcase(OP_CLOSURE) { | 1512 | vmcase(OP_CLOSURE) { |
1514 | Proto *p = cl->p->p[GETARG_Bx(i)]; | 1513 | Proto *p = cl->p->p[GETARG_Bx(i)]; |
1515 | LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ | 1514 | LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ |
1516 | if (ncl == NULL) { /* no match? */ | 1515 | if (ncl == NULL) { /* no match? */ |
1517 | savepc(base); /* in case of allocation errors */ | 1516 | savepc(L); /* in case of allocation errors */ |
1518 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ | 1517 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ |
1519 | } | 1518 | } |
1520 | else | 1519 | else |