From 3b44821334a1aa387c13eaf3cd23a2344091cbc7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 2 Jun 2011 16:31:40 -0300 Subject: stricter control (using tag variants) over closure kinds (Lua x C) --- ldo.c | 108 +++++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) (limited to 'ldo.c') diff --git a/ldo.c b/ldo.c index 63f5fb89..88722dda 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.93 2011/02/23 13:13:10 roberto Exp roberto $ +** $Id: ldo.c,v 2.94 2011/05/30 16:36:38 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -293,59 +293,59 @@ static StkId tryfuncTM (lua_State *L, StkId func) { ** returns true if function has been executed (C function) */ int luaD_precall (lua_State *L, StkId func, int nresults) { - Closure *cl; lua_CFunction f; - ptrdiff_t funcr; - if (!ttisfunction(func)) /* `func' is not a function? */ - func = tryfuncTM(L, func); /* check the `function' tag method */ - funcr = savestack(L, func); - if (ttislcf(func) || (cl = clvalue(func), cl->c.isC)) { /* C function? */ - CallInfo *ci; - int n; - f = (ttislcf(func) ? fvalue(func) : cl->c.f); - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci = next_ci(L); /* now 'enter' new function */ - ci->nresults = nresults; - ci->func = restorestack(L, funcr); - ci->top = L->top + LUA_MINSTACK; - lua_assert(ci->top <= L->stack_last); - ci->callstatus = 0; - if (L->hookmask & LUA_MASKCALL) - luaD_hook(L, LUA_HOOKCALL, -1); - lua_unlock(L); - n = (*f)(L); /* do the actual call */ - lua_lock(L); - api_checknelems(L, n); - luaD_poscall(L, L->top - n); - return 1; - } - else { /* Lua function: prepare its call */ - CallInfo *ci; - int nparams, nargs; - StkId base; - Proto *p = cl->l.p; - luaD_checkstack(L, p->maxstacksize); - func = restorestack(L, funcr); - nargs = cast_int(L->top - func) - 1; /* number of real arguments */ - nparams = p->numparams; /* number of expected parameters */ - for (; nargs < nparams; nargs++) - setnilvalue(L->top++); /* complete missing arguments */ - if (!p->is_vararg) /* no varargs? */ - base = func + 1; - else /* vararg function */ - base = adjust_varargs(L, p, nargs); - ci = next_ci(L); /* now 'enter' new function */ - ci->nresults = nresults; - ci->func = func; - ci->u.l.base = base; - ci->top = base + p->maxstacksize; - lua_assert(ci->top <= L->stack_last); - ci->u.l.savedpc = p->code; /* starting point */ - ci->callstatus = CIST_LUA; - L->top = ci->top; - if (L->hookmask & LUA_MASKCALL) - callhook(L, ci); - return 0; + CallInfo *ci; + int n; /* number of arguments (Lua) or returns (C) */ + ptrdiff_t funcr = savestack(L, func); + switch (ttype(func)) { + case LUA_TLCF: /* light C function */ + f = fvalue(func); + goto Cfunc; + case LUA_TCCL: { /* C closure */ + f = clCvalue(func)->f; + Cfunc: + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = restorestack(L, funcr); + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, L->top - n); + return 1; + } + case LUA_TLCL: { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + n = cast_int(L->top - func) - 1; /* number of real arguments */ + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n); + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + ci->top = base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* retry with 'function' tag method */ + return luaD_precall(L, func, nresults); + } } } @@ -626,7 +626,7 @@ static void f_parser (lua_State *L, void *ud) { setptvalue2s(L, L->top, tf); incr_top(L); cl = luaF_newLclosure(L, tf); - setclvalue(L, L->top - 1, cl); + setclLvalue(L, L->top - 1, cl); for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ cl->l.upvals[i] = luaF_newupval(L); } -- cgit v1.2.3-55-g6feb