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 | |
| parent | 89e3a843442679252773a29114c8552e3f59777d (diff) | |
| download | lua-9a5d6aedb773a61153b07a0939d651efe8ee1753.tar.gz lua-9a5d6aedb773a61153b07a0939d651efe8ee1753.tar.bz2 lua-9a5d6aedb773a61153b07a0939d651efe8ee1753.zip | |
trying to optimize a little 'luaD_poscall'
| -rw-r--r-- | ldo.c | 72 | ||||
| -rw-r--r-- | ldo.h | 5 | ||||
| -rw-r--r-- | lvm.c | 4 |
3 files changed, 56 insertions, 25 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 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 2.24 2015/11/02 16:09:30 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.25 2015/11/02 18:48:07 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 | */ |
| @@ -44,7 +44,8 @@ LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | |||
| 44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
| 45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | 45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 46 | ptrdiff_t oldtop, ptrdiff_t ef); | 46 | ptrdiff_t oldtop, ptrdiff_t ef); |
| 47 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres); | 47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, |
| 48 | int nres); | ||
| 48 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); | 49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); |
| 49 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); | 50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); |
| 50 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); | 51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.260 2015/11/02 18:48:07 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.261 2015/11/12 18:08:58 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -1157,7 +1157,7 @@ void luaV_execute (lua_State *L) { | |||
| 1157 | vmcase(OP_RETURN) { | 1157 | vmcase(OP_RETURN) { |
| 1158 | int b = GETARG_B(i); | 1158 | int b = GETARG_B(i); |
| 1159 | if (cl->p->sizep > 0) luaF_close(L, base); | 1159 | if (cl->p->sizep > 0) luaF_close(L, base); |
| 1160 | b = luaD_poscall(L, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); | 1160 | b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); |
| 1161 | if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ | 1161 | if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ |
| 1162 | return; /* external invocation: return */ | 1162 | return; /* external invocation: return */ |
| 1163 | else { /* invocation via reentry: continue execution */ | 1163 | else { /* invocation via reentry: continue execution */ |
