aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-11-13 11:24:26 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-11-13 11:24:26 -0200
commit9a5d6aedb773a61153b07a0939d651efe8ee1753 (patch)
treed57498c48a8b68b3843c6f89e9ce963589cb8114 /ldo.c
parent89e3a843442679252773a29114c8552e3f59777d (diff)
downloadlua-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.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/ldo.c b/ldo.c
index e4f09076..aabc803c 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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*/
406static 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*/
405int luaD_poscall (lua_State *L, StkId firstResult, int nres) { 448int 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 }