From c54580bdeb99f557b8d1960017ffd78a8aa1ae9f Mon Sep 17 00:00:00 2001 From: maelstrom Date: Thu, 10 Jul 2025 23:34:06 +0200 Subject: [PATCH] fix(lua): yet another rewrite of wrapper that supports yielding (via lua) --- core/src/objects/script.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/core/src/objects/script.cpp b/core/src/objects/script.cpp index f5bfb38..9988f1b 100644 --- a/core/src/objects/script.cpp +++ b/core/src/objects/script.cpp @@ -1,5 +1,6 @@ #include "script.h" #include "common.h" +#include "lauxlib.h" #include "logger.h" #include "objects/base/instance.h" #include "objects/base/member.h" @@ -13,9 +14,10 @@ int script_wait(lua_State*); int script_delay(lua_State*); -int script_wrapper(lua_State*); int script_errhandler(lua_State*); +const char* WRAPPER_SRC = "local func, errhandler = ... return function(...) local args = {...} xpcall(function() func(unpack(args)) end, errhandler) end"; + Script::Script(): Instance(&TYPE) { source = "print(\"Hello, world!\")"; } @@ -55,6 +57,9 @@ void Script::Run() { lua_pop(Lt, 1); // _G + // Push wrapper as thread function + luaL_loadbuffer(Lt, WRAPPER_SRC, strlen(WRAPPER_SRC), "=PCALL_WRAPPER"); + // Load source code and push onto thread as upvalue for wrapper int status = luaL_loadbuffer(Lt, source.c_str(), source.size(), this->GetFullName().c_str()); if (status != LUA_OK) { @@ -65,9 +70,11 @@ void Script::Run() { return; } - // Push wrapper as thread function - lua_pushcclosure(Lt, script_wrapper, 1); + // Push our error handler and then generate the wrapped function + lua_pushcfunction(Lt, script_errhandler); + lua_call(Lt, 2, 1); + // Resume the thread lua_resume(Lt, 0); lua_pop(L, 1); // Pop the thread @@ -107,13 +114,6 @@ int script_delay(lua_State* L) { return 0; } -int script_wrapper(lua_State* L) { - lua_pushcfunction(L, script_errhandler); - lua_pushvalue(L, lua_upvalueindex(1)); - lua_pcall(L, 0, 0, -2); - return 0; -} - int script_errhandler(lua_State* L) { std::string errorMessage = lua_tostring(L, -1); Logger::error(errorMessage); @@ -126,8 +126,9 @@ int script_errhandler(lua_State* L) { int stack = 1; while (lua_getstack(L, stack++, &dbg)) { lua_getinfo(L, "nlSu", &dbg); - if (strcmp(dbg.what, "C") == 0) - continue; // Ignore C frames + // Ignore C frames and internal wrappers + if (strcmp(dbg.what, "C") == 0 || strcmp(dbg.source, "=PCALL_WRAPPER") == 0) + continue; Logger::trace(dbg.source, dbg.currentline); }