diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 24 |
1 files changed, 15 insertions, 9 deletions
@@ -341,7 +341,8 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) { | |||
341 | } | 341 | } |
342 | 342 | ||
343 | 343 | ||
344 | static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { | 344 | static 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 | */ |
432 | void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { | 437 | void 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 | ||