diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-11-13 11:24:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-11-13 11:24:26 -0200 |
commit | 9a5d6aedb773a61153b07a0939d651efe8ee1753 (patch) | |
tree | d57498c48a8b68b3843c6f89e9ce963589cb8114 /ldo.c | |
parent | 89e3a843442679252773a29114c8552e3f59777d (diff) | |
download | lua-9a5d6aedb773a61153b07a0939d651efe8ee1753.tar.gz lua-9a5d6aedb773a61153b07a0939d651efe8ee1753.tar.bz2 lua-9a5d6aedb773a61153b07a0939d651efe8ee1753.zip |
trying to optimize a little 'luaD_poscall'
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 72 |
1 files changed, 51 insertions, 21 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.147 2015/11/02 16:09:30 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.148 2015/11/02 18:48:49 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 | */ |
@@ -360,7 +360,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
360 | n = (*f)(L); /* do the actual call */ | 360 | n = (*f)(L); /* do the actual call */ |
361 | lua_lock(L); | 361 | lua_lock(L); |
362 | api_checknelems(L, n); | 362 | api_checknelems(L, n); |
363 | luaD_poscall(L, L->top - n, n); | 363 | luaD_poscall(L, ci, L->top - n, n); |
364 | return 1; | 364 | return 1; |
365 | } | 365 | } |
366 | case LUA_TLCL: { /* Lua function: prepare its call */ | 366 | case LUA_TLCL: { /* Lua function: prepare its call */ |
@@ -398,14 +398,56 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
398 | 398 | ||
399 | 399 | ||
400 | /* | 400 | /* |
401 | ** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. | ||
402 | ** Handle most typical cases (zero results for commands, one result for | ||
403 | ** expressions, multiple results for tail calls/single parameters) | ||
404 | ** separated. | ||
405 | */ | ||
406 | static int moveresults (lua_State *L, const TValue *firstResult, StkId res, | ||
407 | int nres, int wanted) { | ||
408 | switch (wanted) { /* handle typical cases separately */ | ||
409 | case 0: break; /* nothing to move */ | ||
410 | case 1: { /* one result needed */ | ||
411 | if (nres == 0) /* no results? */ | ||
412 | firstResult = luaO_nilobject; /* ajdust with nil */ | ||
413 | setobjs2s(L, res, firstResult); /* move it to proper place */ | ||
414 | break; | ||
415 | } | ||
416 | case LUA_MULTRET: { | ||
417 | int i; | ||
418 | for (i = 0; i < nres; i++) /* move all results to correct place */ | ||
419 | setobjs2s(L, res + i, firstResult + i); | ||
420 | L->top = res + nres; | ||
421 | return 0; /* wanted == LUA_MULTRET */ | ||
422 | } | ||
423 | default: { | ||
424 | int i; | ||
425 | if (wanted <= nres) { /* enough results? */ | ||
426 | for (i = 0; i < wanted; i++) /* move wanted results to correct place */ | ||
427 | setobjs2s(L, res + i, firstResult + i); | ||
428 | } | ||
429 | else { /* not enough results; use all of them plus nils */ | ||
430 | for (i = 0; i < nres; i++) /* move all results to correct place */ | ||
431 | setobjs2s(L, res + i, firstResult + i); | ||
432 | for (; i < wanted; i++) /* complete wanted number of results */ | ||
433 | setnilvalue(res + i); | ||
434 | } | ||
435 | break; | ||
436 | } | ||
437 | } | ||
438 | L->top = res + wanted; /* top points after the last result */ | ||
439 | return 1; | ||
440 | } | ||
441 | |||
442 | |||
443 | /* | ||
401 | ** Finishes a function call: calls hook if necessary, removes CallInfo, | 444 | ** Finishes a function call: calls hook if necessary, removes CallInfo, |
402 | ** moves corrent number of results to proper place; returns 0 iff call | 445 | ** moves corrent number of results to proper place; returns 0 iff call |
403 | ** wanted multiple (variable number of) results. | 446 | ** wanted multiple (variable number of) results. |
404 | */ | 447 | */ |
405 | int luaD_poscall (lua_State *L, StkId firstResult, int nres) { | 448 | int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { |
406 | StkId res; | 449 | StkId res; |
407 | int wanted, i; | 450 | int wanted = ci->nresults; |
408 | CallInfo *ci = L->ci; | ||
409 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | 451 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { |
410 | if (L->hookmask & LUA_MASKRET) { | 452 | if (L->hookmask & LUA_MASKRET) { |
411 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 453 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ |
@@ -415,21 +457,9 @@ int luaD_poscall (lua_State *L, StkId firstResult, int nres) { | |||
415 | L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ | 457 | L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ |
416 | } | 458 | } |
417 | res = ci->func; /* res == final position of 1st result */ | 459 | res = ci->func; /* res == final position of 1st result */ |
418 | wanted = ci->nresults; | ||
419 | L->ci = ci->previous; /* back to caller */ | 460 | L->ci = ci->previous; /* back to caller */ |
420 | /* comparison is 'unsigned' to make 'LUA_MULTRET' fails test */ | 461 | /* move results to proper place */ |
421 | if ((unsigned int)wanted <= (unsigned int)nres) { /* enough results? */ | 462 | return moveresults(L, firstResult, res, nres, wanted); |
422 | for (i = 0; i < wanted; i++) /* move wanted results to correct place */ | ||
423 | setobjs2s(L, res + i, firstResult + i); | ||
424 | } | ||
425 | else { /* not enough results (or multret); use all of them plus nils */ | ||
426 | for (i = 0; i < nres; i++) /* move all results to correct place */ | ||
427 | setobjs2s(L, res + i, firstResult + i); | ||
428 | for (; i < wanted; i++) /* complete wanted number of results */ | ||
429 | setnilvalue(res + i); | ||
430 | } | ||
431 | L->top = res + i; /* top points after the last result */ | ||
432 | return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ | ||
433 | } | 463 | } |
434 | 464 | ||
435 | 465 | ||
@@ -497,7 +527,7 @@ static void finishCcall (lua_State *L, int status) { | |||
497 | lua_lock(L); | 527 | lua_lock(L); |
498 | api_checknelems(L, n); | 528 | api_checknelems(L, n); |
499 | /* finish 'luaD_precall' */ | 529 | /* finish 'luaD_precall' */ |
500 | luaD_poscall(L, L->top - n, n); | 530 | luaD_poscall(L, ci, L->top - n, n); |
501 | } | 531 | } |
502 | 532 | ||
503 | 533 | ||
@@ -608,7 +638,7 @@ static void resume (lua_State *L, void *ud) { | |||
608 | api_checknelems(L, n); | 638 | api_checknelems(L, n); |
609 | firstArg = L->top - n; /* yield results come from continuation */ | 639 | firstArg = L->top - n; /* yield results come from continuation */ |
610 | } | 640 | } |
611 | luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */ | 641 | luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ |
612 | } | 642 | } |
613 | unroll(L, NULL); /* run continuation */ | 643 | unroll(L, NULL); /* run continuation */ |
614 | } | 644 | } |