aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/ldo.c b/ldo.c
index 9e3d6955..57d4f7d5 100644
--- a/ldo.c
+++ b/ldo.c
@@ -341,7 +341,8 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) {
341} 341}
342 342
343 343
344static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { 344static void rethook (lua_State *L, CallInfo *ci, int nres) {
345 StkId firstres = L->top - nres; /* index of first result */
345 ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */ 346 ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */
346 int delta = 0; 347 int delta = 0;
347 if (isLuacode(ci)) { 348 if (isLuacode(ci)) {
@@ -360,7 +361,7 @@ static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
360 } 361 }
361 if (isLua(ci = ci->previous)) 362 if (isLua(ci = ci->previous))
362 L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* update 'oldpc' */ 363 L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* update 'oldpc' */
363 return restorestack(L, oldtop); 364 L->top = restorestack(L, oldtop);
364} 365}
365 366
366 367
@@ -397,7 +398,7 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
397 case 1: /* one value needed */ 398 case 1: /* one value needed */
398 if (nres == 0) /* no results? */ 399 if (nres == 0) /* no results? */
399 setnilvalue(s2v(res)); /* adjust with nil */ 400 setnilvalue(s2v(res)); /* adjust with nil */
400 else 401 else /* at least one result */
401 setobjs2s(L, res, L->top - nres); /* move it to proper place */ 402 setobjs2s(L, res, L->top - nres); /* move it to proper place */
402 L->top = res + 1; 403 L->top = res + 1;
403 return; 404 return;
@@ -412,6 +413,8 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
412 wanted = codeNresults(wanted); /* correct value */ 413 wanted = codeNresults(wanted); /* correct value */
413 if (wanted == LUA_MULTRET) 414 if (wanted == LUA_MULTRET)
414 wanted = nres; 415 wanted = nres;
416 if (L->hookmask) /* if needed, call hook after '__close's */
417 rethook(L, L->ci, nres);
415 } 418 }
416 break; 419 break;
417 } 420 }
@@ -426,15 +429,18 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
426 429
427 430
428/* 431/*
429** Finishes a function call: calls hook if necessary, removes CallInfo, 432** Finishes a function call: calls hook if necessary, moves current
430** moves current number of results to proper place. 433** number of results to proper place, and returns to previous call
434** info. If function has to close variables, hook must be called after
435** that.
431*/ 436*/
432void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { 437void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
433 if (L->hookmask) 438 int wanted = ci->nresults;
434 L->top = rethook(L, ci, L->top - nres, nres); 439 if (L->hookmask && !hastocloseCfunc(wanted))
435 L->ci = ci->previous; /* back to caller */ 440 rethook(L, ci, nres);
436 /* move results to proper place */ 441 /* move results to proper place */
437 moveresults(L, ci->func, nres, ci->nresults); 442 moveresults(L, ci->func, nres, wanted);
443 L->ci = ci->previous; /* back to caller (after closing variables) */
438} 444}
439 445
440 446