diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-05-22 14:48:19 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-05-22 14:48:19 -0300 |
commit | d39bb51faaa0467ad6a0f5b4ee2ee8400d620727 (patch) | |
tree | 64d49afe6eb909412693c5e1c7498571aaa947ff /ldo.c | |
parent | 6142e663e4d3180d2afaea50bd0978a040f518a4 (diff) | |
download | lua-d39bb51faaa0467ad6a0f5b4ee2ee8400d620727.tar.gz lua-d39bb51faaa0467ad6a0f5b4ee2ee8400d620727.tar.bz2 lua-d39bb51faaa0467ad6a0f5b4ee2ee8400d620727.zip |
bug: interpreter cannot pop activation frame before calling return
hook (as it may want to access local variables active by the end
of the function)
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 18 |
1 files changed, 9 insertions, 9 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.136 2015/03/06 19:49:50 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.137 2015/03/30 16:05:23 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 | */ |
@@ -337,7 +337,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
337 | n = (*f)(L); /* do the actual call */ | 337 | n = (*f)(L); /* do the actual call */ |
338 | lua_lock(L); | 338 | lua_lock(L); |
339 | api_checknelems(L, n); | 339 | api_checknelems(L, n); |
340 | luaD_poscall(L, L->top - n); | 340 | luaD_poscall(L, L->top - n, n); |
341 | return 1; | 341 | return 1; |
342 | } | 342 | } |
343 | case LUA_TLCL: { /* Lua function: prepare its call */ | 343 | case LUA_TLCL: { /* Lua function: prepare its call */ |
@@ -379,7 +379,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
379 | } | 379 | } |
380 | 380 | ||
381 | 381 | ||
382 | int luaD_poscall (lua_State *L, StkId firstResult) { | 382 | int luaD_poscall (lua_State *L, StkId firstResult, int nres) { |
383 | StkId res; | 383 | StkId res; |
384 | int wanted, i; | 384 | int wanted, i; |
385 | CallInfo *ci = L->ci; | 385 | CallInfo *ci = L->ci; |
@@ -395,7 +395,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) { | |||
395 | wanted = ci->nresults; | 395 | wanted = ci->nresults; |
396 | L->ci = ci->previous; /* back to caller */ | 396 | L->ci = ci->previous; /* back to caller */ |
397 | /* move results to correct place */ | 397 | /* move results to correct place */ |
398 | for (i = wanted; i != 0 && firstResult < L->top; i--) | 398 | for (i = wanted; i != 0 && nres-- > 0; i--) |
399 | setobjs2s(L, res++, firstResult++); | 399 | setobjs2s(L, res++, firstResult++); |
400 | while (i-- > 0) | 400 | while (i-- > 0) |
401 | setnilvalue(res++); | 401 | setnilvalue(res++); |
@@ -449,7 +449,7 @@ static void finishCcall (lua_State *L, int status) { | |||
449 | lua_lock(L); | 449 | lua_lock(L); |
450 | api_checknelems(L, n); | 450 | api_checknelems(L, n); |
451 | /* finish 'luaD_precall' */ | 451 | /* finish 'luaD_precall' */ |
452 | luaD_poscall(L, L->top - n); | 452 | luaD_poscall(L, L->top - n, n); |
453 | } | 453 | } |
454 | 454 | ||
455 | 455 | ||
@@ -533,7 +533,8 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { | |||
533 | */ | 533 | */ |
534 | static void resume (lua_State *L, void *ud) { | 534 | static void resume (lua_State *L, void *ud) { |
535 | int nCcalls = L->nCcalls; | 535 | int nCcalls = L->nCcalls; |
536 | StkId firstArg = cast(StkId, ud); | 536 | int n = *(cast(int*, ud)); /* number of arguments */ |
537 | StkId firstArg = L->top - n; /* first argument */ | ||
537 | CallInfo *ci = L->ci; | 538 | CallInfo *ci = L->ci; |
538 | if (nCcalls >= LUAI_MAXCCALLS) | 539 | if (nCcalls >= LUAI_MAXCCALLS) |
539 | resume_error(L, "C stack overflow", firstArg); | 540 | resume_error(L, "C stack overflow", firstArg); |
@@ -553,14 +554,13 @@ static void resume (lua_State *L, void *ud) { | |||
553 | luaV_execute(L); /* just continue running Lua code */ | 554 | luaV_execute(L); /* just continue running Lua code */ |
554 | else { /* 'common' yield */ | 555 | else { /* 'common' yield */ |
555 | if (ci->u.c.k != NULL) { /* does it have a continuation function? */ | 556 | if (ci->u.c.k != NULL) { /* does it have a continuation function? */ |
556 | int n; | ||
557 | lua_unlock(L); | 557 | lua_unlock(L); |
558 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ | 558 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ |
559 | lua_lock(L); | 559 | lua_lock(L); |
560 | api_checknelems(L, n); | 560 | api_checknelems(L, n); |
561 | firstArg = L->top - n; /* yield results come from continuation */ | 561 | firstArg = L->top - n; /* yield results come from continuation */ |
562 | } | 562 | } |
563 | luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ | 563 | luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */ |
564 | } | 564 | } |
565 | unroll(L, NULL); /* run continuation */ | 565 | unroll(L, NULL); /* run continuation */ |
566 | } | 566 | } |
@@ -576,7 +576,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { | |||
576 | L->nCcalls = (from) ? from->nCcalls + 1 : 1; | 576 | L->nCcalls = (from) ? from->nCcalls + 1 : 1; |
577 | L->nny = 0; /* allow yields */ | 577 | L->nny = 0; /* allow yields */ |
578 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 578 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
579 | status = luaD_rawrunprotected(L, resume, L->top - nargs); | 579 | status = luaD_rawrunprotected(L, resume, &nargs); |
580 | if (status == -1) /* error calling 'lua_resume'? */ | 580 | if (status == -1) /* error calling 'lua_resume'? */ |
581 | status = LUA_ERRRUN; | 581 | status = LUA_ERRRUN; |
582 | else { /* continue running after recoverable errors */ | 582 | else { /* continue running after recoverable errors */ |