diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-07 16:22:39 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-07 16:22:39 -0300 |
commit | 5016f43aa439662ca35a5d78e820c617c517f60a (patch) | |
tree | 167aabeccb5a2307c3de7d20542ecf7d99769d3c /lvm.c | |
parent | c1c100a0c04bc77623b32269f37df49e7a2457d2 (diff) | |
download | lua-5016f43aa439662ca35a5d78e820c617c517f60a.tar.gz lua-5016f43aa439662ca35a5d78e820c617c517f60a.tar.bz2 lua-5016f43aa439662ca35a5d78e820c617c517f60a.zip |
(much) cleaner way to control function states
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 37 |
1 files changed, 21 insertions, 16 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.249 2002/08/05 17:36:24 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.250 2002/08/07 14:24:24 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 | */ |
@@ -24,8 +24,6 @@ | |||
24 | #include "lvm.h" | 24 | #include "lvm.h" |
25 | 25 | ||
26 | 26 | ||
27 | Instruction const *luaV_callingmark = NULL; | ||
28 | |||
29 | 27 | ||
30 | /* function to convert a lua_Number to a string */ | 28 | /* function to convert a lua_Number to a string */ |
31 | #ifndef lua_number2str | 29 | #ifndef lua_number2str |
@@ -83,16 +81,18 @@ static void traceexec (lua_State *L) { | |||
83 | if (mask & LUA_MASKLINE) { | 81 | if (mask & LUA_MASKLINE) { |
84 | CallInfo *ci = L->ci; | 82 | CallInfo *ci = L->ci; |
85 | Proto *p = ci_func(ci)->l.p; | 83 | Proto *p = ci_func(ci)->l.p; |
86 | int newline = getline(p, pcRel(*ci->pc, p)); | 84 | int newline = getline(p, pcRel(*ci->u.l.pc, p)); |
87 | if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ | 85 | lua_assert(ci->state & CI_HASFRAME); |
88 | ci->u.l.savedpc = *ci->pc; /* initialize `savedpc' */ | 86 | if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ |
87 | ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */ | ||
89 | /* calls linehook when enters a new line or jumps back (loop) */ | 88 | /* calls linehook when enters a new line or jumps back (loop) */ |
90 | if (*ci->pc <= ci->u.l.savedpc || | 89 | if (*ci->u.l.pc <= ci->u.l.savedpc || |
91 | newline != getline(p, pcRel(ci->u.l.savedpc, p))) { | 90 | newline != getline(p, pcRel(ci->u.l.savedpc, p))) { |
92 | luaD_callhook(L, LUA_HOOKLINE, newline); | 91 | luaD_callhook(L, LUA_HOOKLINE, newline); |
93 | ci = L->ci; /* previous call may reallocate `ci' */ | 92 | ci = L->ci; /* previous call may reallocate `ci' */ |
94 | } | 93 | } |
95 | ci->u.l.savedpc = *ci->pc; | 94 | ci->u.l.savedpc = *ci->u.l.pc; |
95 | ci->state |= CI_SAVEDPC; /* `savedpc' is updated */ | ||
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
@@ -374,11 +374,13 @@ StkId luaV_execute (lua_State *L) { | |||
374 | const Instruction *pc; | 374 | const Instruction *pc; |
375 | callentry: /* entry point when calling new functions */ | 375 | callentry: /* entry point when calling new functions */ |
376 | L->ci->u.l.pb = &base; | 376 | L->ci->u.l.pb = &base; |
377 | L->ci->pc = &pc; | 377 | L->ci->u.l.pc = &pc; |
378 | pc = L->ci->u.l.savedpc; | ||
379 | if (L->hookmask & LUA_MASKCALL) | 378 | if (L->hookmask & LUA_MASKCALL) |
380 | luaD_callhook(L, LUA_HOOKCALL, -1); | 379 | luaD_callhook(L, LUA_HOOKCALL, -1); |
381 | retentry: /* entry point when returning to old functions */ | 380 | retentry: /* entry point when returning to old functions */ |
381 | lua_assert(L->ci->state & CI_SAVEDPC); | ||
382 | L->ci->state = CI_HASFRAME; /* activate frame */ | ||
383 | pc = L->ci->u.l.savedpc; | ||
382 | base = L->ci->base; | 384 | base = L->ci->base; |
383 | cl = &clvalue(base - 1)->l; | 385 | cl = &clvalue(base - 1)->l; |
384 | k = cl->p->k; | 386 | k = cl->p->k; |
@@ -599,7 +601,7 @@ StkId luaV_execute (lua_State *L) { | |||
599 | if (firstResult) { | 601 | if (firstResult) { |
600 | if (firstResult > L->top) { /* yield? */ | 602 | if (firstResult > L->top) { /* yield? */ |
601 | (L->ci - 1)->u.l.savedpc = pc; | 603 | (L->ci - 1)->u.l.savedpc = pc; |
602 | (L->ci - 1)->pc = &luaV_callingmark; | 604 | (L->ci - 1)->state = CI_SAVEDPC; |
603 | return NULL; | 605 | return NULL; |
604 | } | 606 | } |
605 | /* it was a C function (`precall' called it); adjust results */ | 607 | /* it was a C function (`precall' called it); adjust results */ |
@@ -609,7 +611,7 @@ StkId luaV_execute (lua_State *L) { | |||
609 | else { /* it is a Lua function */ | 611 | else { /* it is a Lua function */ |
610 | if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ | 612 | if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ |
611 | (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ | 613 | (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ |
612 | (L->ci-1)->pc = &luaV_callingmark; /* function is calling */ | 614 | (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING); |
613 | } | 615 | } |
614 | else { /* tail call: put new frame in place of previous one */ | 616 | else { /* tail call: put new frame in place of previous one */ |
615 | int aux; | 617 | int aux; |
@@ -618,7 +620,9 @@ StkId luaV_execute (lua_State *L) { | |||
618 | for (aux = 0; ra1+aux < L->top; aux++) /* move frame down */ | 620 | for (aux = 0; ra1+aux < L->top; aux++) /* move frame down */ |
619 | setobj(base+aux-1, ra1+aux); | 621 | setobj(base+aux-1, ra1+aux); |
620 | (L->ci - 1)->top = L->top = base+aux; /* correct top */ | 622 | (L->ci - 1)->top = L->top = base+aux; /* correct top */ |
623 | lua_assert(L->ci->state & CI_SAVEDPC); | ||
621 | (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; | 624 | (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; |
625 | (L->ci - 1)->state = CI_SAVEDPC; | ||
622 | L->ci--; /* remove previous frame */ | 626 | L->ci--; /* remove previous frame */ |
623 | } | 627 | } |
624 | goto callentry; | 628 | goto callentry; |
@@ -629,20 +633,21 @@ StkId luaV_execute (lua_State *L) { | |||
629 | CallInfo *ci = L->ci - 1; | 633 | CallInfo *ci = L->ci - 1; |
630 | int b = GETARG_B(i); | 634 | int b = GETARG_B(i); |
631 | if (b != 0) L->top = ra+b-1; | 635 | if (b != 0) L->top = ra+b-1; |
632 | lua_assert(L->ci->pc == &pc); | 636 | lua_assert(L->ci->state & CI_HASFRAME); |
633 | if (L->openupval) luaF_close(L, base); | 637 | if (L->openupval) luaF_close(L, base); |
638 | L->ci->state = CI_SAVEDPC; /* deactivate current function */ | ||
639 | L->ci->u.l.savedpc = pc; | ||
634 | /* previous function was running `here'? */ | 640 | /* previous function was running `here'? */ |
635 | if (ci->pc != &luaV_callingmark) | 641 | if (!(ci->state & CI_CALLING)) |
636 | return ra; /* no: return */ | 642 | return ra; /* no: return */ |
637 | else { /* yes: continue its execution (go through) */ | 643 | else { /* yes: continue its execution (go through) */ |
638 | int nresults; | 644 | int nresults; |
639 | lua_assert(ttisfunction(ci->base - 1)); | 645 | lua_assert(ttisfunction(ci->base - 1)); |
646 | lua_assert(ci->state & CI_SAVEDPC); | ||
640 | lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); | 647 | lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); |
641 | nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; | 648 | nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; |
642 | luaD_poscall(L, nresults, ra); | 649 | luaD_poscall(L, nresults, ra); |
643 | if (nresults >= 0) L->top = L->ci->top; | 650 | if (nresults >= 0) L->top = L->ci->top; |
644 | L->ci->pc = &pc; /* function is active again */ | ||
645 | pc = L->ci->u.l.savedpc; | ||
646 | goto retentry; | 651 | goto retentry; |
647 | } | 652 | } |
648 | } | 653 | } |