lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I finally had some time to make a minimal example how to provoke this problem.
This is the entire c file that uses the Lua 5.2.0 

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

int calldepth;

static void lyieldhook (lua_State *L, lua_Debug *ar) {
  if(ar->event == LUA_HOOKCALL) {
      calldepth++;
      printf("Hookcall: %i\n", calldepth);
  }
  else {
      calldepth--;
      printf("Hookret: %i\n", calldepth);
      if(calldepth == 0) {
        lua_sethook(L, NULL,0,0);
        lua_yield(L, 0);
      }
   }
}


int main (int argc, char **argv) {
  int status;
  lua_State *GL = luaL_newstate();  /* create state */
  lua_State *L = lua_newthread(GL);
  luaL_openlibs(L);

  status = luaL_loadstring(L,
          "print \"1\"\n"
          "print \"2\"\n"
          "print \"3\"\n"
          "print \"4\"\n"
          );

  printf("loadstatus=%i\n", status);
  lua_sethook(L, lyieldhook, LUA_MASKRET | LUA_MASKCALL, 0);
  calldepth = -1;
  status = lua_resume(L, 0, 0);
  while(status == LUA_YIELD) {
      printf("Yielded\n");
      calldepth = -1;
      lua_sethook(L, lyieldhook, LUA_MASKRET | LUA_MASKCALL, 0);
      status = lua_resume(L, 0, 0);
  }
  printf("Returned: Status=%i\n", status);
  if(status == LUA_ERRRUN) {
      printf(lua_tostring(L, -1));
  }

  lua_close(L);
  return 0;
}

The output of this programm is:
loadstatus=0
Hookcall: 0
Hookcall: 1
Hookcall: 2
Hookret: 1
1
Hookret: 0
Yielded
2
3
4
Returned: Status=0

As you can see from the output, after the first yield the program sets the hook again but the hook is never called anymore.
(The reason for this is that L->allowhook is not set to 1 after the yield).
I still believe the best solution is to just throw an error in this case, from looking at the code I think there is actually no easy solution to implement a proper yield inside a return-hook, on the other hand there is a simple workaround.

-- 
Thomas