diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-12-20 12:58:05 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-12-20 12:58:05 -0200 |
commit | 1d5b885437286a307a77b5d12756d73d374efd54 (patch) | |
tree | b2daefb8d44be37af3b61816eb1f966c94d44393 | |
parent | 4dc0be950ad67e4385400aacd25e10325a2a6e59 (diff) | |
download | lua-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.c | 19 | ||||
-rw-r--r-- | ldo.c | 9 | ||||
-rw-r--r-- | lgc.c | 14 | ||||
-rw-r--r-- | ltm.c | 26 | ||||
-rw-r--r-- | lvm.c | 26 |
5 files changed, 53 insertions, 41 deletions
@@ -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 | ||
190 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, | 190 | static 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 | ||
766 | void luaG_traceexec (lua_State *L) { | 764 | void 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 */ |
@@ -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 | ||
314 | static void rethook (lua_State *L, CallInfo *ci) { | 315 | static 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; |
@@ -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 | */ | ||
572 | static int traversethread (global_State *g, lua_State *th) { | 579 | static 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 */ |
@@ -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 | ||
102 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | 102 | void 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 | ||
118 | void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, | 118 | static 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 | |||
136 | void 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 | ||
147 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | 155 | void 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 | ||
186 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | 196 | int 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) { |
@@ -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) { |