diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 20 |
1 files changed, 12 insertions, 8 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.93 2009/06/17 17:50:09 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.94 2009/07/01 20:31:25 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 | */ |
@@ -461,7 +461,7 @@ void luaV_execute (lua_State *L) { | |||
461 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | 461 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
462 | ra = RA(i); | 462 | ra = RA(i); |
463 | lua_assert(base == ci->u.l.base); | 463 | lua_assert(base == ci->u.l.base); |
464 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | 464 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
465 | switch (GET_OPCODE(i)) { | 465 | switch (GET_OPCODE(i)) { |
466 | case OP_MOVE: { | 466 | case OP_MOVE: { |
467 | setobjs2s(L, ra, RB(i)); | 467 | setobjs2s(L, ra, RB(i)); |
@@ -658,18 +658,22 @@ void luaV_execute (lua_State *L) { | |||
658 | /* tail call: put called frame (n) in place of caller one (o) */ | 658 | /* tail call: put called frame (n) in place of caller one (o) */ |
659 | CallInfo *nci = L->ci; /* called frame */ | 659 | CallInfo *nci = L->ci; /* called frame */ |
660 | CallInfo *oci = nci->previous; /* caller frame */ | 660 | CallInfo *oci = nci->previous; /* caller frame */ |
661 | StkId nfunc = nci->func; /* called function index */ | 661 | StkId nfunc = nci->func; /* called function */ |
662 | StkId ofunc = oci->func; | 662 | StkId ofunc = oci->func; /* caller function */ |
663 | /* last stack slot filled by 'precall' */ | ||
664 | StkId lim = nci->u.l.base + getproto(nfunc)->numparams; | ||
663 | int aux; | 665 | int aux; |
666 | /* close all upvalues from previous call */ | ||
664 | if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); | 667 | if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); |
665 | oci->u.l.base = ofunc + (nci->u.l.base - nfunc); | 668 | /* move new frame into old one */ |
666 | for (aux = 0; nfunc+aux < L->top; aux++) /* move frame down */ | 669 | for (aux = 0; nfunc + aux < lim; aux++) |
667 | setobjs2s(L, ofunc + aux, nfunc + aux); | 670 | setobjs2s(L, ofunc + aux, nfunc + aux); |
668 | oci->top = L->top = ofunc + aux; /* correct top */ | 671 | oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ |
669 | lua_assert(L->top == oci->u.l.base + clvalue(ofunc)->l.p->maxstacksize); | 672 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ |
670 | oci->u.l.savedpc = nci->u.l.savedpc; | 673 | oci->u.l.savedpc = nci->u.l.savedpc; |
671 | oci->u.l.tailcalls++; /* one more call lost */ | 674 | oci->u.l.tailcalls++; /* one more call lost */ |
672 | ci = L->ci = oci; /* remove new frame */ | 675 | ci = L->ci = oci; /* remove new frame */ |
676 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); | ||
673 | break; /* restart luaV_execute over new Lua function */ | 677 | break; /* restart luaV_execute over new Lua function */ |
674 | } | 678 | } |
675 | } | 679 | } |