diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2008-08-13 14:02:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2008-08-13 14:02:42 -0300 |
commit | fdbb243ff9980870c54676f3b2597b110ab82864 (patch) | |
tree | 37c1d31df7addd0638c8b26b28e6f4a0b6024a88 /lvm.c | |
parent | c1565c16edc487f32d87d1742a7c8e76d0b10236 (diff) | |
download | lua-fdbb243ff9980870c54676f3b2597b110ab82864.tar.gz lua-fdbb243ff9980870c54676f3b2597b110ab82864.tar.bz2 lua-fdbb243ff9980870c54676f3b2597b110ab82864.zip |
first steps towards yielding through longjump
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 71 |
1 files changed, 30 insertions, 41 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.73 2007/09/10 17:59:32 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.74 2008/04/02 16:16:06 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 | */ |
@@ -415,7 +415,7 @@ void luaV_execute (lua_State *L, int nexeccalls) { | |||
415 | traceexec(L); | 415 | traceexec(L); |
416 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 416 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
417 | L->savedpc--; /* undo increment */ | 417 | L->savedpc--; /* undo increment */ |
418 | return; | 418 | luaD_throw(L, LUA_YIELD); |
419 | } | 419 | } |
420 | base = L->base; | 420 | base = L->base; |
421 | } | 421 | } |
@@ -595,51 +595,40 @@ void luaV_execute (lua_State *L, int nexeccalls) { | |||
595 | int b = GETARG_B(i); | 595 | int b = GETARG_B(i); |
596 | int nresults = GETARG_C(i) - 1; | 596 | int nresults = GETARG_C(i) - 1; |
597 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 597 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
598 | switch (luaD_precall(L, ra, nresults)) { | 598 | if (luaD_precall(L, ra, nresults)) { /* C function? */ |
599 | case PCRLUA: { | 599 | if (nresults >= 0) L->top = L->ci->top; /* adjust results */ |
600 | nexeccalls++; | 600 | base = L->base; |
601 | goto reentry; /* restart luaV_execute over new Lua function */ | 601 | continue; |
602 | } | 602 | } |
603 | case PCRC: { | 603 | else { /* Lua function */ |
604 | /* it was a C function (`precall' called it); adjust results */ | 604 | nexeccalls++; |
605 | if (nresults >= 0) L->top = L->ci->top; | 605 | goto reentry; /* restart luaV_execute over new Lua function */ |
606 | base = L->base; | ||
607 | continue; | ||
608 | } | ||
609 | default: { | ||
610 | return; /* yield */ | ||
611 | } | ||
612 | } | 606 | } |
613 | } | 607 | } |
614 | case OP_TAILCALL: { | 608 | case OP_TAILCALL: { |
615 | int b = GETARG_B(i); | 609 | int b = GETARG_B(i); |
616 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 610 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
617 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 611 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
618 | switch (luaD_precall(L, ra, LUA_MULTRET)) { | 612 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ |
619 | case PCRLUA: { | 613 | base = L->base; |
620 | /* tail call: put new frame in place of previous one */ | 614 | continue; |
621 | CallInfo *ci = L->ci - 1; /* previous frame */ | 615 | } |
622 | int aux; | 616 | else { |
623 | StkId func = ci->func; | 617 | /* tail call: put new frame in place of previous one */ |
624 | StkId pfunc = (ci+1)->func; /* previous function index */ | 618 | CallInfo *ci = L->ci - 1; /* previous frame */ |
625 | if (L->openupval) luaF_close(L, ci->base); | 619 | int aux; |
626 | L->base = ci->base = ci->func + ((ci+1)->base - pfunc); | 620 | StkId func = ci->func; |
627 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ | 621 | StkId pfunc = (ci+1)->func; /* previous function index */ |
628 | setobjs2s(L, func+aux, pfunc+aux); | 622 | if (L->openupval) luaF_close(L, ci->base); |
629 | ci->top = L->top = func+aux; /* correct top */ | 623 | L->base = ci->base = ci->func + ((ci+1)->base - pfunc); |
630 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | 624 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ |
631 | ci->savedpc = L->savedpc; | 625 | setobjs2s(L, func+aux, pfunc+aux); |
632 | ci->tailcalls++; /* one more call lost */ | 626 | ci->top = L->top = func+aux; /* correct top */ |
633 | L->ci--; /* remove new frame */ | 627 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); |
634 | goto reentry; | 628 | ci->savedpc = L->savedpc; |
635 | } | 629 | ci->tailcalls++; /* one more call lost */ |
636 | case PCRC: { /* it was a C function (`precall' called it) */ | 630 | L->ci--; /* remove new frame */ |
637 | base = L->base; | 631 | goto reentry; |
638 | continue; | ||
639 | } | ||
640 | default: { | ||
641 | return; /* yield */ | ||
642 | } | ||
643 | } | 632 | } |
644 | } | 633 | } |
645 | case OP_RETURN: { | 634 | case OP_RETURN: { |