lua_continuation, lua_thread functions

21 views Asked by At

Trying to make the following code in lua 5.4

static int foreach(lua_State *L){
  luaL_checktype(L, 1, LUA_TTABLE);
  luaL_checktype(L, 2, LUA_TFUNCTION);

  lua_getglobal(L, "print");
  if (!lua_rawequal(L, -1, 2)) {
    lua_pop(L, 1);
    return luaL_error(L, "Second argument must be the 'print' function");
}
lua_pop(L, 1); 

lua_yield(L, 0);

lua_pushnil(L);
while (lua_next(L, 1) != 0) {
    lua_pushvalue(L, 2); // push print
    lua_pushvalue(L, -3); // push key
    lua_pushvalue(L, -3); // push value
    lua_call(L, 2, 0);
    lua_pop(L, 1);
}

return 0;
}

 static int resume_func_continuation(lua_State * L, int status, lua_KContext ctx) {
int res;
(void) ctx;
if (status != LUA_YIELD) {
    luaL_error(L, "Thread was not yielding. %s", lua_tostring(L, -1));
    exit(1);
 }

 lua_getglobal(L, "foreach");

 char *lua_Code = "foreach({x = 10, y = 20}; print)";

 res = luaL_dostring(L, lua_Code);
 if (res != LUA_OK) {
    luaL_error(L, "Error running lua_Code. %s\n", lua_tostring(L, -1));
 }

 lua_close(L);
 exit(0);
}

int main(void) {
  int res;
  lua_State *L = luaL_newstate();
  if (L == NULL) luaL_error(L, "Error creating new state. %s\n",   lua_tostring(L, -1));

  luaL_openlibs(L);

  lua_State *L1 = lua_newthread(L);
  if (L1 == NULL) {
    luaL_error(L, "Error, cannot create new thread. %s", lua_tostring(L, -1));
    exit(1);
  }

  lua_pushcfunction(L1, foreach);
  lua_setglobal(L1, "foreach");
  res = lua_pcallk(L1, 0, 0, 0, 0, resume_func_continuation);
  if (res != LUA_OK) {
    luaL_error(L, "Error calling foreach function. %s", lua_tostring(L, -1));
    exit(1);
  }

 //lua_closethread(L1, L);

 return 0;
 }

I need to make a new thread, pcallk the lua cfunction, the cfunction will yield, finally close the thread, i get segmentation fault on pcallk(), also closethread is not recognised from lua 5.4. Any suggestion? I need the to follow these steps not something else...

1

There are 1 answers

2
shingo On

lua_setglobal will pop the c function from the stack, causing lua_pcallk to call an invalid location, you need to duplicate the c function before setting global.

lua_pushcfunction(L1, foreach);
lua_pushvalue(L1, -1);
lua_setglobal(L1, "foreach");
res = lua_pcallk(L1, 0, 0, 0, 0, resume_func_continuation);