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 */ |