diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-09 13:16:06 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-09 13:16:06 -0200 |
commit | b1379936cf35787d3ef3aab82d1607a3e1562eef (patch) | |
tree | fe47cb5c35fddab945faf731f0bc175bf5431352 /ldo.c | |
parent | 4e0de3a43cc30a83334c272cb7575bf8412bfeae (diff) | |
download | lua-b1379936cf35787d3ef3aab82d1607a3e1562eef.tar.gz lua-b1379936cf35787d3ef3aab82d1607a3e1562eef.tar.bz2 lua-b1379936cf35787d3ef3aab82d1607a3e1562eef.zip |
vararg back to '...' (but with another implementation)
new implementation should have zero overhead for non-vararg functions
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 37 |
1 files changed, 17 insertions, 20 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.191 2018/02/07 15:18:04 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.192 2018/02/07 15:55:18 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 | */ |
@@ -310,7 +310,7 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) { | |||
310 | } | 310 | } |
311 | 311 | ||
312 | 312 | ||
313 | static void rethook (lua_State *L, CallInfo *ci) { | 313 | void luaD_rethook (lua_State *L, CallInfo *ci) { |
314 | if (isLuacode(ci)) | 314 | if (isLuacode(ci)) |
315 | L->top = ci->top; /* prepare top */ | 315 | L->top = ci->top; /* prepare top */ |
316 | if (L->hookmask & LUA_MASKRET) /* is return hook on? */ | 316 | if (L->hookmask & LUA_MASKRET) /* is return hook on? */ |
@@ -343,8 +343,8 @@ void luaD_tryfuncTM (lua_State *L, StkId func) { | |||
343 | ** expressions, multiple results for tail calls/single parameters) | 343 | ** expressions, multiple results for tail calls/single parameters) |
344 | ** separated. | 344 | ** separated. |
345 | */ | 345 | */ |
346 | static void moveresults (lua_State *L, StkId firstResult, StkId res, | 346 | void luaD_moveresults (lua_State *L, StkId firstResult, StkId res, |
347 | int nres, int wanted) { | 347 | int nres, int wanted) { |
348 | switch (wanted) { /* handle typical cases separately */ | 348 | switch (wanted) { /* handle typical cases separately */ |
349 | case 0: break; /* nothing to move */ | 349 | case 0: break; /* nothing to move */ |
350 | case 1: { /* one result needed */ | 350 | case 1: { /* one result needed */ |
@@ -382,27 +382,22 @@ static void moveresults (lua_State *L, StkId firstResult, StkId res, | |||
382 | 382 | ||
383 | /* | 383 | /* |
384 | ** Finishes a function call: calls hook if necessary, removes CallInfo, | 384 | ** Finishes a function call: calls hook if necessary, removes CallInfo, |
385 | ** moves current number of results to proper place; returns 0 iff call | 385 | ** moves current number of results to proper place. |
386 | ** wanted multiple (variable number of) results. | ||
387 | */ | 386 | */ |
388 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { | 387 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { |
389 | if (L->hookmask) { | 388 | if (L->hookmask) { |
390 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 389 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ |
391 | rethook(L, ci); | 390 | luaD_rethook(L, ci); |
392 | firstResult = restorestack(L, fr); | 391 | firstResult = restorestack(L, fr); |
393 | } | 392 | } |
394 | L->ci = ci->previous; /* back to caller */ | 393 | L->ci = ci->previous; /* back to caller */ |
395 | /* move results to proper place */ | 394 | /* move results to proper place */ |
396 | moveresults(L, firstResult, ci->func, nres, ci->nresults); | 395 | luaD_moveresults(L, firstResult, ci->func, nres, ci->nresults); |
397 | } | 396 | } |
398 | 397 | ||
399 | 398 | ||
400 | 399 | ||
401 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) | 400 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) |
402 | |||
403 | |||
404 | #define checkstackGC(L,fsize) \ | ||
405 | luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L)) | ||
406 | 401 | ||
407 | 402 | ||
408 | /* | 403 | /* |
@@ -438,8 +433,6 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { | |||
438 | void luaD_call (lua_State *L, StkId func, int nresults) { | 433 | void luaD_call (lua_State *L, StkId func, int nresults) { |
439 | lua_CFunction f; | 434 | lua_CFunction f; |
440 | TValue *funcv = s2v(func); | 435 | TValue *funcv = s2v(func); |
441 | CallInfo *ci = next_ci(L); | ||
442 | ci->nresults = nresults; | ||
443 | switch (ttype(funcv)) { | 436 | switch (ttype(funcv)) { |
444 | case LUA_TCCL: /* C closure */ | 437 | case LUA_TCCL: /* C closure */ |
445 | f = clCvalue(funcv)->f; | 438 | f = clCvalue(funcv)->f; |
@@ -448,12 +441,14 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
448 | f = fvalue(funcv); | 441 | f = fvalue(funcv); |
449 | Cfunc: { | 442 | Cfunc: { |
450 | int n; /* number of returns */ | 443 | int n; /* number of returns */ |
444 | CallInfo *ci; | ||
451 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 445 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
446 | ci = next_ci(L); | ||
447 | ci->nresults = nresults; | ||
452 | ci->callstatus = CIST_C; | 448 | ci->callstatus = CIST_C; |
453 | ci->top = L->top + LUA_MINSTACK; | 449 | ci->top = L->top + LUA_MINSTACK; |
454 | ci->func = func; | 450 | ci->func = func; |
455 | lua_assert(ci->top <= L->stack_last); | 451 | lua_assert(ci->top <= L->stack_last); |
456 | L->ci = ci; /* now 'enter' new function */ | ||
457 | if (L->hookmask & LUA_MASKCALL) | 452 | if (L->hookmask & LUA_MASKCALL) |
458 | luaD_hook(L, LUA_HOOKCALL, -1); | 453 | luaD_hook(L, LUA_HOOKCALL, -1); |
459 | lua_unlock(L); | 454 | lua_unlock(L); |
@@ -464,18 +459,20 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
464 | break; | 459 | break; |
465 | } | 460 | } |
466 | case LUA_TLCL: { /* Lua function */ | 461 | case LUA_TLCL: { /* Lua function */ |
462 | CallInfo *ci; | ||
467 | Proto *p = clLvalue(funcv)->p; | 463 | Proto *p = clLvalue(funcv)->p; |
468 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ | 464 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ |
469 | int nfixparams = p->numparams; | 465 | int nfixparams = p->numparams; |
470 | int fsize = p->maxstacksize; /* frame size */ | 466 | int fsize = p->maxstacksize; /* frame size */ |
471 | ci->u.l.savedpc = p->code; /* starting point */ | ||
472 | checkstackp(L, fsize, func); | 467 | checkstackp(L, fsize, func); |
473 | for (; narg < nfixparams; narg++) | 468 | ci = next_ci(L); |
474 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | 469 | ci->nresults = nresults; |
470 | ci->u.l.savedpc = p->code; /* starting point */ | ||
475 | ci->callstatus = 0; | 471 | ci->callstatus = 0; |
476 | ci->top = func + 1 + fsize; | 472 | ci->top = func + 1 + fsize; |
477 | ci->func = func; | 473 | ci->func = func; |
478 | L->ci = ci; /* now 'enter' new function */ | 474 | for (; narg < nfixparams; narg++) |
475 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | ||
479 | lua_assert(ci->top <= L->stack_last); | 476 | lua_assert(ci->top <= L->stack_last); |
480 | luaV_execute(L, ci); /* run the function */ | 477 | luaV_execute(L, ci); /* run the function */ |
481 | break; | 478 | break; |