2
0
Эх сурвалжийг харах

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)

Roberto Ierusalimschy 10 жил өмнө
parent
commit
d39bb51faa
3 өөрчлөгдсөн 13 нэмэгдсэн , 14 устгасан
  1. 9 9
      ldo.c
  2. 2 2
      ldo.h
  3. 2 3
      lvm.c

+ 9 - 9
ldo.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.c,v 2.136 2015/03/06 19:49:50 roberto Exp roberto $
+** $Id: ldo.c,v 2.137 2015/03/30 16:05:23 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -337,7 +337,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
       n = (*f)(L);  /* do the actual call */
       n = (*f)(L);  /* do the actual call */
       lua_lock(L);
       lua_lock(L);
       api_checknelems(L, n);
       api_checknelems(L, n);
-      luaD_poscall(L, L->top - n);
+      luaD_poscall(L, L->top - n, n);
       return 1;
       return 1;
     }
     }
     case LUA_TLCL: {  /* Lua function: prepare its call */
     case LUA_TLCL: {  /* Lua function: prepare its call */
@@ -379,7 +379,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
 }
 }
 
 
 
 
-int luaD_poscall (lua_State *L, StkId firstResult) {
+int luaD_poscall (lua_State *L, StkId firstResult, int nres) {
   StkId res;
   StkId res;
   int wanted, i;
   int wanted, i;
   CallInfo *ci = L->ci;
   CallInfo *ci = L->ci;
@@ -395,7 +395,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
   wanted = ci->nresults;
   wanted = ci->nresults;
   L->ci = ci->previous;  /* back to caller */
   L->ci = ci->previous;  /* back to caller */
   /* move results to correct place */
   /* move results to correct place */
-  for (i = wanted; i != 0 && firstResult < L->top; i--)
+  for (i = wanted; i != 0 && nres-- > 0; i--)
     setobjs2s(L, res++, firstResult++);
     setobjs2s(L, res++, firstResult++);
   while (i-- > 0)
   while (i-- > 0)
     setnilvalue(res++);
     setnilvalue(res++);
@@ -449,7 +449,7 @@ static void finishCcall (lua_State *L, int status) {
   lua_lock(L);
   lua_lock(L);
   api_checknelems(L, n);
   api_checknelems(L, n);
   /* finish 'luaD_precall' */
   /* finish 'luaD_precall' */
-  luaD_poscall(L, L->top - n);
+  luaD_poscall(L, L->top - n, n);
 }
 }
 
 
 
 
@@ -533,7 +533,8 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
 */
 */
 static void resume (lua_State *L, void *ud) {
 static void resume (lua_State *L, void *ud) {
   int nCcalls = L->nCcalls;
   int nCcalls = L->nCcalls;
-  StkId firstArg = cast(StkId, ud);
+  int n = *(cast(int*, ud));  /* number of arguments */
+  StkId firstArg = L->top - n;  /* first argument */
   CallInfo *ci = L->ci;
   CallInfo *ci = L->ci;
   if (nCcalls >= LUAI_MAXCCALLS)
   if (nCcalls >= LUAI_MAXCCALLS)
     resume_error(L, "C stack overflow", firstArg);
     resume_error(L, "C stack overflow", firstArg);
@@ -553,14 +554,13 @@ static void resume (lua_State *L, void *ud) {
       luaV_execute(L);  /* just continue running Lua code */
       luaV_execute(L);  /* just continue running Lua code */
     else {  /* 'common' yield */
     else {  /* 'common' yield */
       if (ci->u.c.k != NULL) {  /* does it have a continuation function? */
       if (ci->u.c.k != NULL) {  /* does it have a continuation function? */
-        int n;
         lua_unlock(L);
         lua_unlock(L);
         n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
         n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
         lua_lock(L);
         lua_lock(L);
         api_checknelems(L, n);
         api_checknelems(L, n);
         firstArg = L->top - n;  /* yield results come from continuation */
         firstArg = L->top - n;  /* yield results come from continuation */
       }
       }
-      luaD_poscall(L, firstArg);  /* finish 'luaD_precall' */
+      luaD_poscall(L, firstArg, n);  /* finish 'luaD_precall' */
     }
     }
     unroll(L, NULL);  /* run continuation */
     unroll(L, NULL);  /* run continuation */
   }
   }
@@ -576,7 +576,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
   L->nCcalls = (from) ? from->nCcalls + 1 : 1;
   L->nCcalls = (from) ? from->nCcalls + 1 : 1;
   L->nny = 0;  /* allow yields */
   L->nny = 0;  /* allow yields */
   api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
   api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
-  status = luaD_rawrunprotected(L, resume, L->top - nargs);
+  status = luaD_rawrunprotected(L, resume, &nargs);
   if (status == -1)  /* error calling 'lua_resume'? */
   if (status == -1)  /* error calling 'lua_resume'? */
     status = LUA_ERRRUN;
     status = LUA_ERRRUN;
   else {  /* continue running after recoverable errors */
   else {  /* continue running after recoverable errors */

+ 2 - 2
ldo.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.h,v 2.20 2011/11/29 15:55:08 roberto Exp roberto $
+** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -34,7 +34,7 @@ LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
                                         int allowyield);
                                         int allowyield);
 LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
 LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
                                         ptrdiff_t oldtop, ptrdiff_t ef);
                                         ptrdiff_t oldtop, ptrdiff_t ef);
-LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
+LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres);
 LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
 LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
 LUAI_FUNC void luaD_growstack (lua_State *L, int n);
 LUAI_FUNC void luaD_growstack (lua_State *L, int n);
 LUAI_FUNC void luaD_shrinkstack (lua_State *L);
 LUAI_FUNC void luaD_shrinkstack (lua_State *L);

+ 2 - 3
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 2.241 2015/05/20 16:22:55 roberto Exp roberto $
+** $Id: lvm.c,v 2.242 2015/05/20 18:19:11 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -1106,9 +1106,8 @@ void luaV_execute (lua_State *L) {
       }
       }
       vmcase(OP_RETURN) {
       vmcase(OP_RETURN) {
         int b = GETARG_B(i);
         int b = GETARG_B(i);
-        if (b != 0) L->top = ra+b-1;
         if (cl->p->sizep > 0) luaF_close(L, base);
         if (cl->p->sizep > 0) luaF_close(L, base);
-        b = luaD_poscall(L, ra);
+        b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra));
         if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
         if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
           return;  /* external invocation: return */
           return;  /* external invocation: return */
         else {  /* invocation via reentry: continue execution */
         else {  /* invocation via reentry: continue execution */