aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-20 12:58:05 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-20 12:58:05 -0200
commit1d5b885437286a307a77b5d12756d73d374efd54 (patch)
treeb2daefb8d44be37af3b61816eb1f966c94d44393
parent4dc0be950ad67e4385400aacd25e10325a2a6e59 (diff)
downloadlua-1d5b885437286a307a77b5d12756d73d374efd54.tar.gz
lua-1d5b885437286a307a77b5d12756d73d374efd54.tar.bz2
lua-1d5b885437286a307a77b5d12756d73d374efd54.zip
when running Lua code, there is no need to keep 'L->top' "correct";
set it only when needed.
-rw-r--r--ldebug.c19
-rw-r--r--ldo.c9
-rw-r--r--lgc.c14
-rw-r--r--ltm.c26
-rw-r--r--lvm.c26
5 files changed, 53 insertions, 41 deletions
diff --git a/ldebug.c b/ldebug.c
index 11d2b6a7..80c19d31 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.148 2017/12/13 18:32:09 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.149 2017/12/15 13:07:10 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -189,14 +189,10 @@ static const char *upvalname (Proto *p, int uv) {
189 189
190static const char *findlocal (lua_State *L, CallInfo *ci, int n, 190static const char *findlocal (lua_State *L, CallInfo *ci, int n,
191 StkId *pos) { 191 StkId *pos) {
192 const char *name = NULL; 192 StkId base = ci->func + 1;
193 StkId base; 193 const char *name = (isLua(ci))
194 if (isLua(ci)) { 194 ? luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci))
195 base = ci->func + 1; 195 : NULL;
196 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
197 }
198 else
199 base = ci->func + 1;
200 if (name == NULL) { /* no 'standard' name? */ 196 if (name == NULL) { /* no 'standard' name? */
201 StkId limit = (ci == L->ci) ? L->top : ci->next->func; 197 StkId limit = (ci == L->ci) ? L->top : ci->next->func;
202 if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 198 if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
@@ -741,6 +737,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
741 const char *msg; 737 const char *msg;
742 va_list argp; 738 va_list argp;
743 luaC_checkGC(L); /* error message uses memory */ 739 luaC_checkGC(L); /* error message uses memory */
740 if (isLuacode(ci))
741 L->top = ci->top; /* prepare top */
744 va_start(argp, fmt); 742 va_start(argp, fmt);
745 msg = luaO_pushvfstring(L, fmt, argp); /* format message */ 743 msg = luaO_pushvfstring(L, fmt, argp); /* format message */
746 va_end(argp); 744 va_end(argp);
@@ -764,6 +762,7 @@ static int changedline (Proto *p, int oldpc, int newpc) {
764 762
765 763
766void luaG_traceexec (lua_State *L) { 764void luaG_traceexec (lua_State *L) {
765 ptrdiff_t oldtop = savestack(L, L->top);
767 CallInfo *ci = L->ci; 766 CallInfo *ci = L->ci;
768 lu_byte mask = L->hookmask; 767 lu_byte mask = L->hookmask;
769 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); 768 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
@@ -775,6 +774,7 @@ void luaG_traceexec (lua_State *L) {
775 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ 774 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
776 return; /* do not call hook again (VM yielded, so it did not move) */ 775 return; /* do not call hook again (VM yielded, so it did not move) */
777 } 776 }
777 L->top = ci->top; /* prepare top */
778 if (counthook) 778 if (counthook)
779 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ 779 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
780 if (mask & LUA_MASKLINE) { 780 if (mask & LUA_MASKLINE) {
@@ -789,6 +789,7 @@ void luaG_traceexec (lua_State *L) {
789 } 789 }
790 L->oldpc = npc; 790 L->oldpc = npc;
791 } 791 }
792 L->top = restorestack(L, oldtop);
792 if (L->status == LUA_YIELD) { /* did hook yield? */ 793 if (L->status == LUA_YIELD) { /* did hook yield? */
793 if (counthook) 794 if (counthook)
794 L->hookcount = 1; /* undo decrement to zero */ 795 L->hookcount = 1; /* undo decrement to zero */
diff --git a/ldo.c b/ldo.c
index fa8a382b..77c408ba 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.181 2017/12/15 13:07:10 roberto Exp roberto $ 2** $Id: ldo.c,v 2.182 2017/12/19 16:40:17 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -299,6 +299,7 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) {
299 ci->u.l.trap = 1; 299 ci->u.l.trap = 1;
300 if (!(L->hookmask & LUA_MASKCALL)) 300 if (!(L->hookmask & LUA_MASKCALL))
301 return; /* some other hook */ 301 return; /* some other hook */
302 L->top = ci->top; /* prepare top */
302 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ 303 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
303 if (istail) { 304 if (istail) {
304 ci->callstatus |= CIST_TAIL; 305 ci->callstatus |= CIST_TAIL;
@@ -312,6 +313,8 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) {
312 313
313 314
314static void rethook (lua_State *L, CallInfo *ci) { 315static void rethook (lua_State *L, CallInfo *ci) {
316 if (isLuacode(ci))
317 L->top = ci->top; /* prepare top */
315 if (L->hookmask & LUA_MASKRET) /* is return hook on? */ 318 if (L->hookmask & LUA_MASKRET) /* is return hook on? */
316 luaD_hook(L, LUA_HOOKRET, -1); /* call it */ 319 luaD_hook(L, LUA_HOOKRET, -1); /* call it */
317 if (isLua(ci->previous)) 320 if (isLua(ci->previous))
@@ -421,7 +424,7 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n) {
421 L->top -= (func - ci->func); /* move down top */ 424 L->top -= (func - ci->func); /* move down top */
422 luaT_adjustvarargs(L, p, n - 1); 425 luaT_adjustvarargs(L, p, n - 1);
423 } 426 }
424 L->top = ci->top = ci->func + 1 + fsize; /* top for new function */ 427 ci->top = ci->func + 1 + fsize; /* top for new function */
425 lua_assert(ci->top <= L->stack_last); 428 lua_assert(ci->top <= L->stack_last);
426 ci->u.l.savedpc = p->code; /* starting point */ 429 ci->u.l.savedpc = p->code; /* starting point */
427 ci->callstatus |= CIST_TAIL; 430 ci->callstatus |= CIST_TAIL;
@@ -476,7 +479,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
476 ci = next_ci(L); /* now 'enter' new function */ 479 ci = next_ci(L); /* now 'enter' new function */
477 ci->nresults = nresults; 480 ci->nresults = nresults;
478 ci->func = func; 481 ci->func = func;
479 L->top = ci->top = func + 1 + fsize; 482 ci->top = func + 1 + fsize;
480 lua_assert(ci->top <= L->stack_last); 483 lua_assert(ci->top <= L->stack_last);
481 ci->u.l.savedpc = p->code; /* starting point */ 484 ci->u.l.savedpc = p->code; /* starting point */
482 ci->callstatus = 0; 485 ci->callstatus = 0;
diff --git a/lgc.c b/lgc.c
index 8d28d3bf..37bcdb8d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.241 2017/12/01 17:38:49 roberto Exp roberto $ 2** $Id: lgc.c,v 2.242 2017/12/08 17:28:25 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -569,13 +569,23 @@ static int traverseLclosure (global_State *g, LClosure *cl) {
569} 569}
570 570
571 571
572/*
573** Traverse a thread, marking the elements in the stack up to its top
574** and cleaning the rest of the stack in the last traversal.
575** That ensures that the entire stack have valid (non-dead) objects.
576** In an emergency collection running Lua code, 'L->top' may not be
577** update. In that case, traverse at least up to 'ci->top'.
578*/
572static int traversethread (global_State *g, lua_State *th) { 579static int traversethread (global_State *g, lua_State *th) {
573 StkId o = th->stack; 580 StkId o = th->stack;
581 StkId top = th->top;
574 if (o == NULL) 582 if (o == NULL)
575 return 1; /* stack not completely built yet */ 583 return 1; /* stack not completely built yet */
576 lua_assert(g->gcstate == GCSatomic || 584 lua_assert(g->gcstate == GCSatomic ||
577 th->openupval == NULL || isintwups(th)); 585 th->openupval == NULL || isintwups(th));
578 for (; o < th->top; o++) /* mark live elements in the stack */ 586 if (g->gcemergency && isLuacode(th->ci) && top < th->ci->top)
587 top = th->ci->top;
588 for (; o < top; o++) /* mark live elements in the stack */
579 markvalue(g, s2v(o)); 589 markvalue(g, s2v(o));
580 if (g->gcstate == GCSatomic) { /* final traversal? */ 590 if (g->gcstate == GCSatomic) { /* final traversal? */
581 StkId lim = th->stack + th->stacksize; /* real end of stack */ 591 StkId lim = th->stack + th->stacksize; /* real end of stack */
diff --git a/ltm.c b/ltm.c
index 5906a2fd..d41ab98d 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.53 2017/12/15 13:07:10 roberto Exp roberto $ 2** $Id: ltm.c,v 2.54 2017/12/19 16:40:17 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -101,12 +101,12 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
101 101
102void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 102void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
103 const TValue *p2, const TValue *p3) { 103 const TValue *p2, const TValue *p3) {
104 StkId func = L->top; 104 StkId func = (isLuacode(L->ci)) ? L->ci->top : L->top;
105 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 105 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
106 setobj2s(L, func + 1, p1); /* 1st argument */ 106 setobj2s(L, func + 1, p1); /* 1st argument */
107 setobj2s(L, func + 2, p2); /* 2nd argument */ 107 setobj2s(L, func + 2, p2); /* 2nd argument */
108 setobj2s(L, func + 3, p3); /* 3rd argument */ 108 setobj2s(L, func + 3, p3); /* 3rd argument */
109 L->top += 4; 109 L->top = func + 4;
110 /* metamethod may yield only when called from Lua code */ 110 /* metamethod may yield only when called from Lua code */
111 if (isLuacode(L->ci)) 111 if (isLuacode(L->ci))
112 luaD_call(L, func, 0); 112 luaD_call(L, func, 0);
@@ -115,8 +115,8 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
115} 115}
116 116
117 117
118void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, 118static void reallycallTMres (lua_State *L, const TValue *f, const TValue *p1,
119 const TValue *p2, StkId res) { 119 const TValue *p2, StkId res) {
120 ptrdiff_t result = savestack(L, res); 120 ptrdiff_t result = savestack(L, res);
121 StkId func = L->top; 121 StkId func = L->top;
122 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 122 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
@@ -129,7 +129,15 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
129 else 129 else
130 luaD_callnoyield(L, func, 1); 130 luaD_callnoyield(L, func, 1);
131 res = restorestack(L, result); 131 res = restorestack(L, result);
132 setobjs2s(L, res, --L->top); /* more result to its place */ 132 setobjs2s(L, res, --L->top); /* move result to its place */
133}
134
135
136void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
137 const TValue *p2, StkId res) {
138 if (isLuacode(L->ci))
139 L->top = L->ci->top; /* prepare top */
140 reallycallTMres(L, f, p1, p2, res);
133} 141}
134 142
135 143
@@ -139,13 +147,15 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
139 if (ttisnil(tm)) 147 if (ttisnil(tm))
140 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 148 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
141 if (ttisnil(tm)) return 0; 149 if (ttisnil(tm)) return 0;
142 luaT_callTMres(L, tm, p1, p2, res); 150 reallycallTMres(L, tm, p1, p2, res);
143 return 1; 151 return 1;
144} 152}
145 153
146 154
147void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 155void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
148 StkId res, TMS event) { 156 StkId res, TMS event) {
157 if (event != TM_CONCAT && isLuacode(L->ci))
158 L->top = L->ci->top; /* prepare top */
149 if (!callbinTM(L, p1, p2, res, event)) { 159 if (!callbinTM(L, p1, p2, res, event)) {
150 switch (event) { 160 switch (event) {
151 case TM_CONCAT: 161 case TM_CONCAT:
@@ -185,6 +195,8 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, int i2,
185 195
186int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 196int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
187 TMS event) { 197 TMS event) {
198 if (isLuacode(L->ci))
199 L->top = L->ci->top; /* prepare top */
188 if (callbinTM(L, p1, p2, L->top, event)) /* try original event */ 200 if (callbinTM(L, p1, p2, L->top, event)) /* try original event */
189 return !l_isfalse(s2v(L->top)); 201 return !l_isfalse(s2v(L->top));
190 else if (event == TM_LE) { 202 else if (event == TM_LE) {
diff --git a/lvm.c b/lvm.c
index 29c6e373..8039770e 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.326 2017/12/18 17:53:50 roberto Exp roberto $ 2** $Id: lvm.c,v 2.327 2017/12/19 16:18:04 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,6 +464,8 @@ 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 */
467 luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */ 469 luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */
468 return !l_isfalse(s2v(L->top)); 470 return !l_isfalse(s2v(L->top));
469} 471}
@@ -726,20 +728,10 @@ void luaV_finishOp (lua_State *L) {
726 } 728 }
727 /* move final result to final position */ 729 /* move final result to final position */
728 setobjs2s(L, ci->func + 1 + GETARG_A(inst), L->top - 1); 730 setobjs2s(L, ci->func + 1 + GETARG_A(inst), L->top - 1);
729 L->top = ci->top; /* restore top */
730 break; 731 break;
731 } 732 }
732 case OP_TFORCALL: { 733 case OP_TFORCALL: case OP_CALL: case OP_TAILCALL:
733 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); 734 case OP_SETTABUP: case OP_SETTABLE:
734 L->top = ci->top; /* correct top */
735 break;
736 }
737 case OP_CALL: {
738 if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
739 L->top = ci->top; /* adjust results */
740 break;
741 }
742 case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
743 case OP_SETI: case OP_SETFIELD: 735 case OP_SETI: case OP_SETFIELD:
744 break; 736 break;
745 default: lua_assert(0); 737 default: lua_assert(0);
@@ -808,7 +800,7 @@ void luaV_finishOp (lua_State *L) {
808 800
809#define checkGC(L,c) \ 801#define checkGC(L,c) \
810 { luaC_condGC(L, L->top = (c), /* limit of live values */ \ 802 { luaC_condGC(L, L->top = (c), /* limit of live values */ \
811 (L->top = ci->top, updatetrap(ci))); /* restore top */ \ 803 updatetrap(ci)); \
812 luai_threadyield(L); } 804 luai_threadyield(L); }
813 805
814 806
@@ -1387,7 +1379,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1387 rb = base + b; 1379 rb = base + b;
1388 setobjs2s(L, ra, rb); 1380 setobjs2s(L, ra, rb);
1389 checkGC(L, (ra >= rb ? ra + 1 : rb)); 1381 checkGC(L, (ra >= rb ? ra + 1 : rb));
1390 L->top = ci->top; /* restore top */
1391 vmbreak; 1382 vmbreak;
1392 } 1383 }
1393 vmcase(OP_CLOSE) { 1384 vmcase(OP_CLOSE) {
@@ -1491,9 +1482,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1491 L->top = ra + b; /* top signals number of arguments */ 1482 L->top = ra + b; /* top signals number of arguments */
1492 /* else previous instruction set top */ 1483 /* else previous instruction set top */
1493 Protect(luaD_call(L, ra, nresults)); 1484 Protect(luaD_call(L, ra, nresults));
1494 if (nresults >= 0) /* fixed number of results? */
1495 L->top = ci->top; /* correct top */
1496 /* else leave top for next instruction */
1497 vmbreak; 1485 vmbreak;
1498 } 1486 }
1499 vmcase(OP_TAILCALL) { 1487 vmcase(OP_TAILCALL) {
@@ -1651,7 +1639,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1651 setobjs2s(L, cb, ra); 1639 setobjs2s(L, cb, ra);
1652 L->top = cb + 3; /* func. + 2 args (state and index) */ 1640 L->top = cb + 3; /* func. + 2 args (state and index) */
1653 Protect(luaD_call(L, cb, GETARG_C(i))); 1641 Protect(luaD_call(L, cb, GETARG_C(i)));
1654 L->top = ci->top;
1655 if (trap) /* keep 'base' correct for next instruction */ 1642 if (trap) /* keep 'base' correct for next instruction */
1656 updatebase(ci); 1643 updatebase(ci);
1657 i = *(pc++); /* go to next instruction */ 1644 i = *(pc++); /* go to next instruction */
@@ -1686,7 +1673,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1686 last--; 1673 last--;
1687 luaC_barrierback(L, h, val); 1674 luaC_barrierback(L, h, val);
1688 } 1675 }
1689 L->top = ci->top; /* correct top (in case of previous open call) */
1690 vmbreak; 1676 vmbreak;
1691 } 1677 }
1692 vmcase(OP_CLOSURE) { 1678 vmcase(OP_CLOSURE) {