summaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-07-15 15:38:16 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-07-15 15:38:16 -0300
commit11d7ba79f2a84a4feda8013a7fb270e479b785f8 (patch)
tree6d5b4fcab65af6f5b24e10d7fc9b1bcda13664eb /lvm.c
parentbd5fa9cc8fdd966edc46c3de2cc420a72240ead3 (diff)
downloadlua-11d7ba79f2a84a4feda8013a7fb270e479b785f8.tar.gz
lua-11d7ba79f2a84a4feda8013a7fb270e479b785f8.tar.bz2
lua-11d7ba79f2a84a4feda8013a7fb270e479b785f8.zip
tail calls do not need to move whole new frame down, only its slice
up to last parameter (the rest has not been used yet)
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/lvm.c b/lvm.c
index 9ba3131e..056e09e6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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 }