aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-28 13:42:57 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-28 13:42:57 -0200
commitcf7eff45f3abf2386d5392c0b431498bbb274ac7 (patch)
tree0eaafe3456bd03b241e447f1375296341fb648e8 /lvm.c
parent8691612f01ae4b32d861464032521d969766c1c5 (diff)
downloadlua-cf7eff45f3abf2386d5392c0b431498bbb274ac7.tar.gz
lua-cf7eff45f3abf2386d5392c0b431498bbb274ac7.tar.bz2
lua-cf7eff45f3abf2386d5392c0b431498bbb274ac7.zip
keep control of stack top in Lua functions concentrated in 'luaV_execute'
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/lvm.c b/lvm.c
index 89646d24..212d5f9d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.328 2017/12/20 14:58:05 roberto Exp roberto $ 2** $Id: lvm.c,v 2.329 2017/12/22 14:16:46 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*/
@@ -464,8 +464,6 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
464 } 464 }
465 if (tm == NULL) /* no TM? */ 465 if (tm == NULL) /* no TM? */
466 return 0; /* objects are different */ 466 return 0; /* objects are different */
467 if (isLuacode(L->ci))
468 L->top = L->ci->top; /* prepare top */
469 luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */ 467 luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */
470 return !l_isfalse(s2v(L->top)); 468 return !l_isfalse(s2v(L->top));
471} 469}
@@ -780,20 +778,29 @@ void luaV_finishOp (lua_State *L) {
780#define donextjump(ci) { i = *pc; dojump(ci, i, 1); } 778#define donextjump(ci) { i = *pc; dojump(ci, i, 1); }
781 779
782/* 780/*
783** Whenever code can raise errors (including memory errors), the global 781** Correct global 'pc'.
784** 'pc' must be correct to report occasional errors.
785*/ 782*/
786#define savepc(L) (ci->u.l.savedpc = pc) 783#define savepc(L) (ci->u.l.savedpc = pc)
787 784
788 785
789/* 786/*
787** Whenever code can raise errors, the global 'pc' and the global
788** 'top' must be correct to report occasional errors.
789*/
790#define savestate(L,ci) (savepc(L), L->top = ci->top)
791
792
793/*
790** Protect code that, in general, can raise errors, reallocate the 794** Protect code that, in general, can raise errors, reallocate the
791** stack, and change the hooks. 795** stack, and change the hooks.
792*/ 796*/
793#define Protect(exp) (savepc(L), (exp), updatetrap(ci)) 797#define Protect(exp) (savestate(L,ci), (exp), updatetrap(ci))
798
799/* special version that does not change the top */
800#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
794 801
795/* 802/*
796** Protect code that will return. 803** Protect code that will finish the loop (returns).
797*/ 804*/
798#define halfProtect(exp) (savepc(L), (exp)) 805#define halfProtect(exp) (savepc(L), (exp))
799 806
@@ -842,6 +849,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
842 vmfetch(); 849 vmfetch();
843 lua_assert(base == ci->func + 1); 850 lua_assert(base == ci->func + 1);
844 lua_assert(base <= L->top && L->top < L->stack + L->stacksize); 851 lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
852 lua_assert(ci->top < L->stack + L->stacksize);
845 vmdispatch (GET_OPCODE(i)) { 853 vmdispatch (GET_OPCODE(i)) {
846 vmcase(OP_MOVE) { 854 vmcase(OP_MOVE) {
847 setobjs2s(L, ra, RB(i)); 855 setobjs2s(L, ra, RB(i));
@@ -1000,10 +1008,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1000 int b = GETARG_B(i); 1008 int b = GETARG_B(i);
1001 int c = GETARG_C(i); 1009 int c = GETARG_C(i);
1002 Table *t; 1010 Table *t;
1003 t = luaH_new(L); 1011 L->top = ci->top; /* correct top in case of GC */
1012 t = luaH_new(L); /* memory allocation */
1004 sethvalue2s(L, ra, t); 1013 sethvalue2s(L, ra, t);
1005 if (b != 0 || c != 0) 1014 if (b != 0 || c != 0)
1006 luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); 1015 luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); /* idem */
1007 checkGC(L, ra + 1); 1016 checkGC(L, ra + 1);
1008 vmbreak; 1017 vmbreak;
1009 } 1018 }
@@ -1371,7 +1380,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1371 int c = GETARG_C(i); 1380 int c = GETARG_C(i);
1372 StkId rb; 1381 StkId rb;
1373 L->top = base + c + 1; /* mark the end of concat operands */ 1382 L->top = base + c + 1; /* mark the end of concat operands */
1374 Protect(luaV_concat(L, c - b + 1)); 1383 ProtectNT(luaV_concat(L, c - b + 1));
1375 if (trap) { /* 'luaV_concat' may move the stack */ 1384 if (trap) { /* 'luaV_concat' may move the stack */
1376 updatebase(ci); 1385 updatebase(ci);
1377 ra = RA(i); 1386 ra = RA(i);
@@ -1481,7 +1490,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1481 if (b != 0) /* fixed number of arguments? */ 1490 if (b != 0) /* fixed number of arguments? */
1482 L->top = ra + b; /* top signals number of arguments */ 1491 L->top = ra + b; /* top signals number of arguments */
1483 /* else previous instruction set top */ 1492 /* else previous instruction set top */
1484 Protect(luaD_call(L, ra, nresults)); 1493 ProtectNT(luaD_call(L, ra, nresults));
1485 vmbreak; 1494 vmbreak;
1486 } 1495 }
1487 vmcase(OP_TAILCALL) { 1496 vmcase(OP_TAILCALL) {
@@ -1493,12 +1502,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1493 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 1502 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
1494 if (!ttisfunction(vra)) { /* not a function? */ 1503 if (!ttisfunction(vra)) { /* not a function? */
1495 /* try to get '__call' metamethod */ 1504 /* try to get '__call' metamethod */
1496 Protect(ra = luaD_tryfuncTM(L, ra)); 1505 ProtectNT(ra = luaD_tryfuncTM(L, ra));
1497 vra = s2v(ra); 1506 vra = s2v(ra);
1498 b++; /* there is now one extra argument */ 1507 b++; /* there is now one extra argument */
1499 } 1508 }
1500 if (!ttisLclosure(vra)) { /* C function? */ 1509 if (!ttisLclosure(vra)) { /* C function? */
1501 Protect(luaD_call(L, ra, LUA_MULTRET)); /* call it */ 1510 ProtectNT(luaD_call(L, ra, LUA_MULTRET)); /* call it */
1502 /* next instruction will do the return */ 1511 /* next instruction will do the return */
1503 } 1512 }
1504 else { /* tail call */ 1513 else { /* tail call */
@@ -1568,7 +1577,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1568 lua_Integer ilimit, initv; 1577 lua_Integer ilimit, initv;
1569 int stopnow; 1578 int stopnow;
1570 if (!forlimit(plimit, &ilimit, 1, &stopnow)) { 1579 if (!forlimit(plimit, &ilimit, 1, &stopnow)) {
1571 savepc(L); /* for the error message */ 1580 savestate(L, ci); /* for the error message */
1572 luaG_runerror(L, "'for' limit must be a number"); 1581 luaG_runerror(L, "'for' limit must be a number");
1573 } 1582 }
1574 initv = (stopnow ? 0 : ivalue(init)); 1583 initv = (stopnow ? 0 : ivalue(init));
@@ -1618,7 +1627,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1618 } 1627 }
1619 else { /* try making all values floats */ 1628 else { /* try making all values floats */
1620 lua_Number ninit; lua_Number nlimit; lua_Number nstep; 1629 lua_Number ninit; lua_Number nlimit; lua_Number nstep;
1621 savepc(L); /* in case of errors */ 1630 savestate(L, ci); /* in case of errors */
1622 if (!tonumber(plimit, &nlimit)) 1631 if (!tonumber(plimit, &nlimit))
1623 luaG_runerror(L, "'for' limit must be a number"); 1632 luaG_runerror(L, "'for' limit must be a number");
1624 setfltvalue(plimit, nlimit); 1633 setfltvalue(plimit, nlimit);
@@ -1659,7 +1668,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1659 int c = GETARG_C(i); 1668 int c = GETARG_C(i);
1660 unsigned int last; 1669 unsigned int last;
1661 Table *h; 1670 Table *h;
1662 if (n == 0) n = cast_int(L->top - ra) - 1; 1671 if (n == 0)
1672 n = cast_int(L->top - ra) - 1;
1673 else
1674 L->top = ci->top; /* correct top in case of GC */
1663 if (c == 0) { 1675 if (c == 0) {
1664 c = GETARG_Ax(*pc); pc++; 1676 c = GETARG_Ax(*pc); pc++;
1665 } 1677 }
@@ -1679,7 +1691,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1679 Proto *p = cl->p->p[GETARG_Bx(i)]; 1691 Proto *p = cl->p->p[GETARG_Bx(i)];
1680 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ 1692 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
1681 if (ncl == NULL) { /* no match? */ 1693 if (ncl == NULL) { /* no match? */
1682 savepc(L); /* in case of allocation errors */ 1694 savestate(L, ci); /* in case of allocation errors */
1683 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ 1695 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
1684 } 1696 }
1685 else 1697 else