aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/lvm.c b/lvm.c
index 7acb387f..ce15d61b 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp roberto $ 2** $Id: lvm.c,v 2.302 2017/11/03 12:12:30 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*/
@@ -654,13 +654,14 @@ 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
657/* 659/*
658** finish execution of an opcode interrupted by an yield 660** finish execution of an opcode interrupted by an yield
659*/ 661*/
660void luaV_finishOp (lua_State *L) { 662void luaV_finishOp (lua_State *L) {
661 CallInfo *ci = L->ci;
662 StkId base = L->func + 1; 663 StkId base = L->func + 1;
663 Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ 664 Instruction inst = *(basepc(base) - 1); /* interrupted instruction */
664 OpCode op = GET_OPCODE(inst); 665 OpCode op = GET_OPCODE(inst);
665 switch (op) { /* finish its execution */ 666 switch (op) { /* finish its execution */
666 case OP_ADDI: case OP_SUBI: 667 case OP_ADDI: case OP_SUBI:
@@ -684,9 +685,9 @@ void luaV_finishOp (lua_State *L) {
684 callstatus(base - 1) ^= CIST_LEQ; /* clear mark */ 685 callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
685 res = !res; /* negate result */ 686 res = !res; /* negate result */
686 } 687 }
687 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); 688 lua_assert(GET_OPCODE(*basepc(base)) == OP_JMP);
688 if (res != GETARG_A(inst)) /* condition failed? */ 689 if (res != GETARG_A(inst)) /* condition failed? */
689 ci->u.l.savedpc++; /* skip jump instruction */ 690 basepc(base)++; /* skip jump instruction */
690 break; 691 break;
691 } 692 }
692 case OP_CONCAT: { 693 case OP_CONCAT: {
@@ -704,7 +705,7 @@ void luaV_finishOp (lua_State *L) {
704 break; 705 break;
705 } 706 }
706 case OP_TFORCALL: { 707 case OP_TFORCALL: {
707 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); 708 lua_assert(GET_OPCODE(*basepc(base)) == OP_TFORLOOP);
708 L->top = functop(base - 1); /* correct top */ 709 L->top = functop(base - 1); /* correct top */
709 break; 710 break;
710 } 711 }
@@ -763,20 +764,22 @@ void luaV_finishOp (lua_State *L) {
763** Whenever code can raise errors (including memory errors), the global 764** Whenever code can raise errors (including memory errors), the global
764** 'pc' must be correct to report occasional errors. 765** 'pc' must be correct to report occasional errors.
765*/ 766*/
766#define savepc(L) (ci->u.l.savedpc = pc) 767#define savepc(base) (basepc(base) = pc)
768
767 769
770/* update internal copies to its correct values */
771#define updatestate() (base = L->func + 1, updatemask(L))
768 772
769/* 773/*
770** Protect code that, in general, can raise errors, reallocate the 774** Protect code that, in general, can raise errors, reallocate the
771** stack, and change the hooks. 775** stack, and change the hooks.
772*/ 776*/
773#define Protect(code) \ 777#define Protect(code) { savepc(base); {code;}; updatestate(); }
774 { savepc(L); {code;}; base = L->func + 1; updatemask(L); }
775 778
776 779
777#define checkGC(L,c) \ 780#define checkGC(L,c) \
778 { luaC_condGC(L, L->top = (c), /* limit of live values */ \ 781 { luaC_condGC(L, L->top = (c), /* limit of live values */ \
779 {Protect((void)0); L->top = functop(base - 1);}); /* restore top */ \ 782 {updatestate(); L->top = functop(base - 1);}); /* restore top */ \
780 luai_threadyield(L); } 783 luai_threadyield(L); }
781 784
782 785
@@ -798,14 +801,14 @@ void luaV_execute (lua_State *L) {
798 TValue *k; 801 TValue *k;
799 StkId base = L->func + 1; /* local copy of 'L->func + 1' */ 802 StkId base = L->func + 1; /* local copy of 'L->func + 1' */
800 int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ 803 int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
801 const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */ 804 const Instruction *pc; /* local copy of 'basepc(base)' */
802 callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ 805 callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
803 newframe: /* reentry point when frame changes (call/return) */ 806 newframe: /* reentry point when frame changes (call/return) */
804 lua_assert(ci == L->ci); 807 lua_assert(ci == L->ci);
805 cl = clLvalue(s2v(L->func)); /* local reference to function's closure */ 808 cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
806 k = cl->p->k; /* local reference to function's constant table */ 809 k = cl->p->k; /* local reference to function's constant table */
807 updatemask(L); 810 updatemask(L);
808 pc = ci->u.l.savedpc; 811 pc = basepc(base);
809 /* main loop of interpreter */ 812 /* main loop of interpreter */
810 for (;;) { 813 for (;;) {
811 Instruction i; 814 Instruction i;
@@ -969,7 +972,7 @@ void luaV_execute (lua_State *L) {
969 int b = GETARG_B(i); 972 int b = GETARG_B(i);
970 int c = GETARG_C(i); 973 int c = GETARG_C(i);
971 Table *t; 974 Table *t;
972 savepc(L); /* in case of allocation errors */ 975 savepc(base); /* in case of allocation errors */
973 t = luaH_new(L); 976 t = luaH_new(L);
974 sethvalue2s(L, ra, t); 977 sethvalue2s(L, ra, t);
975 if (b != 0 || c != 0) 978 if (b != 0 || c != 0)
@@ -1368,9 +1371,9 @@ void luaV_execute (lua_State *L) {
1368 int b = GETARG_B(i); 1371 int b = GETARG_B(i);
1369 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 1372 if (b != 0) L->top = ra+b; /* else previous instruction set top */
1370 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 1373 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
1371 savepc(L); 1374 savepc(base);
1372 if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ 1375 if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
1373 Protect((void)0); /* update 'base' */ 1376 updatestate(); /* update 'base' */
1374 } 1377 }
1375 else { 1378 else {
1376 /* tail call: put called frame (n) in place of caller one (o) */ 1379 /* tail call: put called frame (n) in place of caller one (o) */
@@ -1388,7 +1391,7 @@ void luaV_execute (lua_State *L) {
1388 setobjs2s(L, ofunc + aux, nfunc + aux); 1391 setobjs2s(L, ofunc + aux, nfunc + aux);
1389 ofunc->stkci.framesize = L->top - nfunc; 1392 ofunc->stkci.framesize = L->top - nfunc;
1390 L->top = functop(ofunc); /* correct top */ 1393 L->top = functop(ofunc); /* correct top */
1391 oci->u.l.savedpc = nci->u.l.savedpc; 1394 ofunc->stkci.u.l.savedpc = nfunc->stkci.u.l.savedpc;
1392 callstatus(ofunc) |= CIST_TAIL; /* function was tail called */ 1395 callstatus(ofunc) |= CIST_TAIL; /* function was tail called */
1393 ci = L->ci = oci; /* remove new frame */ 1396 ci = L->ci = oci; /* remove new frame */
1394 base = ofunc + 1; 1397 base = ofunc + 1;
@@ -1401,7 +1404,7 @@ void luaV_execute (lua_State *L) {
1401 vmcase(OP_RETURN) { 1404 vmcase(OP_RETURN) {
1402 int b = GETARG_B(i); 1405 int b = GETARG_B(i);
1403 if (cl->p->sizep > 0) luaF_close(L, base); 1406 if (cl->p->sizep > 0) luaF_close(L, base);
1404 savepc(L); 1407 savepc(base);
1405 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); 1408 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
1406 if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */ 1409 if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
1407 return; /* external invocation: return */ 1410 return; /* external invocation: return */
@@ -1409,8 +1412,8 @@ void luaV_execute (lua_State *L) {
1409 ci = L->ci; 1412 ci = L->ci;
1410 base = L->func + 1; 1413 base = L->func + 1;
1411 if (b) L->top = functop(base - 1); 1414 if (b) L->top = functop(base - 1);
1412 lua_assert(isLua(L->func)); 1415 lua_assert(isLua(base - 1));
1413 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); 1416 lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL);
1414 goto newframe; /* restart luaV_execute over previous Lua function */ 1417 goto newframe; /* restart luaV_execute over previous Lua function */
1415 } 1418 }
1416 } 1419 }
@@ -1455,7 +1458,7 @@ void luaV_execute (lua_State *L) {
1455 } 1458 }
1456 else { /* try making all values floats */ 1459 else { /* try making all values floats */
1457 lua_Number ninit; lua_Number nlimit; lua_Number nstep; 1460 lua_Number ninit; lua_Number nlimit; lua_Number nstep;
1458 savepc(L); /* in case of errors */ 1461 savepc(base); /* in case of errors */
1459 if (!tonumber(plimit, &nlimit)) 1462 if (!tonumber(plimit, &nlimit))
1460 luaG_runerror(L, "'for' limit must be a number"); 1463 luaG_runerror(L, "'for' limit must be a number");
1461 setfltvalue(plimit, nlimit); 1464 setfltvalue(plimit, nlimit);
@@ -1501,7 +1504,7 @@ void luaV_execute (lua_State *L) {
1501 } 1504 }
1502 h = hvalue(s2v(ra)); 1505 h = hvalue(s2v(ra));
1503 last = ((c-1)*LFIELDS_PER_FLUSH) + n; 1506 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
1504 savepc(L); /* in case of allocation errors */ 1507 savepc(base); /* in case of allocation errors */
1505 if (last > h->sizearray) /* needs more space? */ 1508 if (last > h->sizearray) /* needs more space? */
1506 luaH_resizearray(L, h, last); /* preallocate it at once */ 1509 luaH_resizearray(L, h, last); /* preallocate it at once */
1507 for (; n > 0; n--) { 1510 for (; n > 0; n--) {
@@ -1518,7 +1521,7 @@ void luaV_execute (lua_State *L) {
1518 Proto *p = cl->p->p[GETARG_Bx(i)]; 1521 Proto *p = cl->p->p[GETARG_Bx(i)];
1519 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ 1522 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
1520 if (ncl == NULL) { /* no match? */ 1523 if (ncl == NULL) { /* no match? */
1521 savepc(L); /* in case of allocation errors */ 1524 savepc(base); /* in case of allocation errors */
1522 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ 1525 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
1523 } 1526 }
1524 else 1527 else