I have the follwing code, trying to understand C-Api , lua_resume, continuations and different cases, just for expirements as doc mentions. I am currently in lua 5.4 on an ubuntu desktop. I have the following code:
// Attempt to yield C-Function, into protected mode. - Continuation Function -
static int finishpcall (lua_State *L, int status, intptr_t ctx) {
(void)ctx; // unused parameter
status = (status != LUA_OK && status != LUA_YIELD);
lua_pushboolean(L, (status == 0)); // status
lua_insert(L, 1); // status is first result
printf("%s, %d\n", "From lua", lua_gettop(L)); // it is lua's stack frame = 1
lua_getglobal(L, "co");
lua_resume(lua_tothread(L, 2), NULL, 0, 0);
lua_resume(lua_tothread(L, lua_gettop(L)), NULL, 0, 0);
return lua_gettop(L); // return status + all results
}
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, finishpcall);
return finishpcall(L, status, 0);
}
int main(void) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// Register luaB_pcall as a Lua function
lua_register(L, "pcall", luaB_pcall);
const char *str = "function test() \
local co = coroutine.create(function() print('me') \
coroutine.yield() \
print('me me') \
end) \
return co \
end \
pcall(test)";
int res = luaL_dostring(L, str);
if (res != LUA_OK) {
printf("Error running Lua code: %s\n", lua_tostring(L, -1));
lua_close(L);
return 1;
}
printf("%s, %d\n", "From C-Function", lua_gettop(L)); //it is C's stack frame = 0
lua_close(L);
return 0;
}
Can anyone suggest me why i get segmentaition fault on lua_resume in finishpcall() , although firstly i get From lua, 2 me as results.
Read the manual carefully, then you'll notice the type of lua_resume
's last argument is int*
, it's an output argument.
int lua_resume (lua_State *L, lua_State *from, int nargs, int *nresults);
Although in your example, it is 0, in general, you need to handle them.
lua_State* co = lua_tothread(L, 2);
int nresults;
status = lua_resume(co, NULL, 0, &nresults);
lua_pop(co, nresults); //handle the results by removing them
You'd better use the co
variable above for your 2nd lua_resume
call too, because you put the global co (which doesn't exist) on the top of the stack.