diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-14 12:13:48 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-14 12:13:48 -0300 |
commit | 7dfa4cd655118faf164427356609fec31906dac2 (patch) | |
tree | d39fac9afba1dc0ab01dd5d174824120650c9eab /ldo.c | |
parent | fc6203ee4308173283f9ad9de6694d47f0908c4d (diff) | |
download | lua-7dfa4cd655118faf164427356609fec31906dac2.tar.gz lua-7dfa4cd655118faf164427356609fec31906dac2.tar.bz2 lua-7dfa4cd655118faf164427356609fec31906dac2.zip |
first implementation of light C functions
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 54 |
1 files changed, 31 insertions, 23 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.82 2010/03/26 20:58:11 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.83 2010/04/08 17:16:46 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -293,18 +293,43 @@ static StkId tryfuncTM (lua_State *L, StkId func) { | |||
293 | ** returns true if function has been executed (C function) | 293 | ** returns true if function has been executed (C function) |
294 | */ | 294 | */ |
295 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 295 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
296 | LClosure *cl; | 296 | Closure *cl; |
297 | lua_CFunction f; | ||
297 | ptrdiff_t funcr; | 298 | ptrdiff_t funcr; |
298 | if (!ttisfunction(func)) /* `func' is not a function? */ | 299 | if (!ttisfunction(func)) /* `func' is not a function? */ |
299 | func = tryfuncTM(L, func); /* check the `function' tag method */ | 300 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
300 | funcr = savestack(L, func); | 301 | funcr = savestack(L, func); |
301 | cl = &clvalue(func)->l; | ||
302 | L->ci->nresults = nresults; | 302 | L->ci->nresults = nresults; |
303 | if (!cl->isC) { /* Lua function? prepare its call */ | 303 | if (ttiscfp(func)) { /* C function pointer? */ |
304 | f = fvalue(func); /* get it */ | ||
305 | goto isCfunc; /* go to call it */ | ||
306 | } | ||
307 | cl = clvalue(func); | ||
308 | if (cl->c.isC) { /* C closure? */ | ||
309 | CallInfo *ci; | ||
310 | int n; | ||
311 | f = cl->c.f; | ||
312 | isCfunc: /* call C function 'f' */ | ||
313 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
314 | ci = next_ci(L); /* now 'enter' new function */ | ||
315 | ci->func = restorestack(L, funcr); | ||
316 | ci->top = L->top + LUA_MINSTACK; | ||
317 | lua_assert(ci->top <= L->stack_last); | ||
318 | ci->callstatus = 0; | ||
319 | if (L->hookmask & LUA_MASKCALL) | ||
320 | luaD_hook(L, LUA_HOOKCALL, -1); | ||
321 | lua_unlock(L); | ||
322 | n = (*f)(L); /* do the actual call */ | ||
323 | lua_lock(L); | ||
324 | api_checknelems(L, n); | ||
325 | luaD_poscall(L, L->top - n); | ||
326 | return 1; | ||
327 | } | ||
328 | else { /* Lua function: prepare its call */ | ||
304 | CallInfo *ci; | 329 | CallInfo *ci; |
305 | int nparams, nargs; | 330 | int nparams, nargs; |
306 | StkId base; | 331 | StkId base; |
307 | Proto *p = cl->p; | 332 | Proto *p = cl->l.p; |
308 | luaD_checkstack(L, p->maxstacksize); | 333 | luaD_checkstack(L, p->maxstacksize); |
309 | func = restorestack(L, funcr); | 334 | func = restorestack(L, funcr); |
310 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ | 335 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ |
@@ -327,24 +352,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
327 | callhook(L, ci); | 352 | callhook(L, ci); |
328 | return 0; | 353 | return 0; |
329 | } | 354 | } |
330 | else { /* if is a C function, call it */ | ||
331 | CallInfo *ci; | ||
332 | int n; | ||
333 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
334 | ci = next_ci(L); /* now 'enter' new function */ | ||
335 | ci->func = restorestack(L, funcr); | ||
336 | ci->top = L->top + LUA_MINSTACK; | ||
337 | lua_assert(ci->top <= L->stack_last); | ||
338 | ci->callstatus = 0; | ||
339 | if (L->hookmask & LUA_MASKCALL) | ||
340 | luaD_hook(L, LUA_HOOKCALL, -1); | ||
341 | lua_unlock(L); | ||
342 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ | ||
343 | lua_lock(L); | ||
344 | api_checknelems(L, n); | ||
345 | luaD_poscall(L, L->top - n); | ||
346 | return 1; | ||
347 | } | ||
348 | } | 355 | } |
349 | 356 | ||
350 | 357 | ||
@@ -526,6 +533,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
526 | luai_userstateresume(L, nargs); | 533 | luai_userstateresume(L, nargs); |
527 | ++G(L)->nCcalls; /* count resume */ | 534 | ++G(L)->nCcalls; /* count resume */ |
528 | L->nny = 0; /* allow yields */ | 535 | L->nny = 0; /* allow yields */ |
536 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | ||
529 | status = luaD_rawrunprotected(L, resume, L->top - nargs); | 537 | status = luaD_rawrunprotected(L, resume, L->top - nargs); |
530 | if (status == -1) /* error calling 'lua_resume'? */ | 538 | if (status == -1) /* error calling 'lua_resume'? */ |
531 | status = LUA_ERRRUN; | 539 | status = LUA_ERRRUN; |