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; |
