فهرست منبع

BUG: debug hooks may get wrong when mixed with coroutines

Roberto Ierusalimschy 19 سال پیش
والد
کامیت
a62fca1ebb
2فایلهای تغییر یافته به همراه43 افزوده شده و 3 حذف شده
  1. 39 0
      bugs
  2. 4 3
      ldo.c

+ 39 - 0
bugs

@@ -974,3 +974,42 @@ lgc.c:
 +          g->estimate -= GCFINALIZECOST;
 ]]
 }
+
+
+But{
+
+what = [[debug hooks may get wrong when mixed with coroutines]],
+
+report = [[by Ivko Stanilov, 03/06/2006]],
+
+example = [[
+co = coroutine.create(function (a,b)
+   coroutine.yield(a, b)
+   return b, "end"
+end)
+
+debug.sethook(co, function() end, "lcr")
+coroutine.resume(co, 100, 2000)
+coroutine.resume(co, 100, 2000)
+]],
+
+patch = [[
+* ldo.c:
+@@ -389,6 +389,7 @@
+       return;
+   }
+   else {  /* resuming from previous yield */
++    L->status = 0;
+     if (!f_isLua(ci)) {  /* `common' yield? */
+       /* finish interrupted execution of `OP_CALL' */
+       lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
+@@ -399,7 +400,6 @@
+     else  /* yielded inside a hook: just continue its execution */
+       L->base = L->ci->base;
+   }
+-  L->status = 0;
+   luaV_execute(L, cast_int(L->ci - L->base_ci));
+ }
+]],
+
+}

+ 4 - 3
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.36 2005/10/23 17:52:42 roberto Exp roberto $
+** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -383,12 +383,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
 static void resume (lua_State *L, void *ud) {
   StkId firstArg = cast(StkId, ud);
   CallInfo *ci = L->ci;
-  if (L->status != LUA_YIELD) {  /* start coroutine */
+  if (L->status == 0) {  /* start coroutine? */
     lua_assert(ci == L->base_ci && firstArg > L->base);
     if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
       return;
   }
   else {  /* resuming from previous yield */
+    lua_assert(L->status == LUA_YIELD);
+    L->status = 0;
     if (!f_isLua(ci)) {  /* `common' yield? */
       /* finish interrupted execution of `OP_CALL' */
       lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -399,7 +401,6 @@ static void resume (lua_State *L, void *ud) {
     else  /* yielded inside a hook: just continue its execution */
       L->base = L->ci->base;
   }
-  L->status = 0;
   luaV_execute(L, cast_int(L->ci - L->base_ci));
 }