aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/ldo.c b/ldo.c
index 72a1e306..cb7e5aef 100644
--- a/ldo.c
+++ b/ldo.c
@@ -464,21 +464,26 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
464 464
465/* 465/*
466** Check whether 'func' has a '__call' metafield. If so, put it in the 466** Check whether 'func' has a '__call' metafield. If so, put it in the
467** stack, below original 'func', so that 'luaD_precall' can call it. Raise 467** stack, below original 'func', so that 'luaD_precall' can call it.
468** an error if there is no '__call' metafield. 468** Raise an error if there is no '__call' metafield.
469** Bits CIST_CCMT in status count how many _call metamethods were
470** invoked and how many corresponding extra arguments were pushed.
471** (This count will be saved in the 'callstatus' of the call).
472** Raise an error if this counter overflows.
469*/ 473*/
470static StkId tryfuncTM (lua_State *L, StkId func) { 474static unsigned tryfuncTM (lua_State *L, StkId func, unsigned status) {
471 const TValue *tm; 475 const TValue *tm;
472 StkId p; 476 StkId p;
473 checkstackp(L, 1, func); /* space for metamethod */ 477 tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
474 tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */ 478 if (l_unlikely(ttisnil(tm))) /* no metamethod? */
475 if (l_unlikely(ttisnil(tm))) 479 luaG_callerror(L, s2v(func));
476 luaG_callerror(L, s2v(func)); /* nothing to call */
477 for (p = L->top.p; p > func; p--) /* open space for metamethod */ 480 for (p = L->top.p; p > func; p--) /* open space for metamethod */
478 setobjs2s(L, p, p-1); 481 setobjs2s(L, p, p-1);
479 L->top.p++; /* stack space pre-allocated by the caller */ 482 L->top.p++; /* stack space pre-allocated by the caller */
480 setobj2s(L, func, tm); /* metamethod is the new function to be called */ 483 setobj2s(L, func, tm); /* metamethod is the new function to be called */
481 return func; 484 if ((status & MAX_CCMT) == MAX_CCMT) /* is counter full? */
485 luaG_runerror(L, "'__call' chain too long");
486 return status + (1u << CIST_CCMT); /* increment counter */
482} 487}
483 488
484 489
@@ -564,11 +569,17 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
564#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) 569#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
565 570
566 571
572/*
573** Allocate and initialize CallInfo structure. At this point, the
574** only valid fields in the call status are number of results,
575** CIST_C (if it's a C function), and number of extra arguments.
576** (All these bit-fields fit in 16-bit values.)
577*/
567l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, unsigned status, 578l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, unsigned status,
568 StkId top) { 579 StkId top) {
569 CallInfo *ci = L->ci = next_ci(L); /* new frame */ 580 CallInfo *ci = L->ci = next_ci(L); /* new frame */
570 ci->func.p = func; 581 ci->func.p = func;
571 lua_assert((status & ~(CIST_NRESULTS | CIST_C)) == 0); 582 lua_assert((status & ~(CIST_NRESULTS | CIST_C | MAX_CCMT)) == 0);
572 ci->callstatus = status; 583 ci->callstatus = status;
573 ci->top.p = top; 584 ci->top.p = top;
574 return ci; 585 return ci;
@@ -607,12 +618,13 @@ l_sinline int precallC (lua_State *L, StkId func, unsigned status,
607*/ 618*/
608int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, 619int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
609 int narg1, int delta) { 620 int narg1, int delta) {
621 unsigned status = LUA_MULTRET + 1;
610 retry: 622 retry:
611 switch (ttypetag(s2v(func))) { 623 switch (ttypetag(s2v(func))) {
612 case LUA_VCCL: /* C closure */ 624 case LUA_VCCL: /* C closure */
613 return precallC(L, func, LUA_MULTRET + 1, clCvalue(s2v(func))->f); 625 return precallC(L, func, status, clCvalue(s2v(func))->f);
614 case LUA_VLCF: /* light C function */ 626 case LUA_VLCF: /* light C function */
615 return precallC(L, func, LUA_MULTRET + 1, fvalue(s2v(func))); 627 return precallC(L, func, status, fvalue(s2v(func)));
616 case LUA_VLCL: { /* Lua function */ 628 case LUA_VLCL: { /* Lua function */
617 Proto *p = clLvalue(s2v(func))->p; 629 Proto *p = clLvalue(s2v(func))->p;
618 int fsize = p->maxstacksize; /* frame size */ 630 int fsize = p->maxstacksize; /* frame size */
@@ -633,8 +645,8 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
633 return -1; 645 return -1;
634 } 646 }
635 default: { /* not a function */ 647 default: { /* not a function */
636 func = tryfuncTM(L, func); /* try to get '__call' metamethod */ 648 checkstackp(L, 1, func); /* space for metamethod */
637 /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ 649 status = tryfuncTM(L, func, status); /* try '__call' metamethod */
638 narg1++; 650 narg1++;
639 goto retry; /* try again */ 651 goto retry; /* try again */
640 } 652 }
@@ -676,7 +688,8 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
676 return ci; 688 return ci;
677 } 689 }
678 default: { /* not a function */ 690 default: { /* not a function */
679 func = tryfuncTM(L, func); /* try to get '__call' metamethod */ 691 checkstackp(L, 1, func); /* space for metamethod */
692 status = tryfuncTM(L, func, status); /* try '__call' metamethod */
680 goto retry; /* try again with metamethod */ 693 goto retry; /* try again with metamethod */
681 } 694 }
682 } 695 }