From 42281aa8deb79b4a3bb4883247937499f3576b2f Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Mon, 5 May 2025 20:48:28 +0100 Subject: [PATCH] (regression) Fix `lua_requireinternal` to use variable number of stack args (#1804) Since 0.672 the `lua_proxyrequire` function is broken and attempt to use it fails with the error message `module must return a single value`. This function takes two stack arguments (`lua_require` takes one), but `lua_requireinternal` expects only one extra argument and pushes another one (`cacheKey`). As a result, the continuation function `lua_requirecont` (that has hardcoded number of stack args = 2) thinks that module returned more than one result and throw an exception. The fix instead of hardcoding number of arguments in the continuation function, pass this number in a first stack argument. This will allow both `lua_require` and `lua_proxyrequire` work at the same time. --- Require/Runtime/src/RequireImpl.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Require/Runtime/src/RequireImpl.cpp b/Require/Runtime/src/RequireImpl.cpp index e6fba3e8..b8f5c980 100644 --- a/Require/Runtime/src/RequireImpl.cpp +++ b/Require/Runtime/src/RequireImpl.cpp @@ -121,9 +121,9 @@ static int checkRegisteredModules(lua_State* L, const char* path) int lua_requirecont(lua_State* L, int status) { // Number of stack arguments present before this continuation is called. - const int numStackArgs = 2; + const int numStackArgs = lua_tointeger(L, 1); const int numResults = lua_gettop(L) - numStackArgs; - const char* cacheKey = luaL_checkstring(L, 2); + const char* cacheKey = luaL_checkstring(L, numStackArgs); if (numResults > 1) luaL_error(L, "module must return a single value"); @@ -152,6 +152,8 @@ int lua_requirecont(lua_State* L, int status) int lua_requireinternal(lua_State* L, const char* requirerChunkname) { + int stackTop = lua_gettop(L); + // If modifying the state of the stack, please update numStackArgs in the // lua_requirecont continuation function. @@ -171,10 +173,14 @@ int lua_requireinternal(lua_State* L, const char* requirerChunkname) if (resolvedRequire.status == ResolvedRequire::Status::Cached) return 1; - // (1) path, (2) cacheKey + // (1) path, ..., cacheKey lua_pushstring(L, resolvedRequire.cacheKey.c_str()); - int numArgsBeforeLoad = lua_gettop(L); + // Insert number of arguments before the continuation to check the results. + int numArgsBeforeLoad = stackTop + 2; + lua_pushinteger(L, numArgsBeforeLoad); + lua_insert(L, 1); + int numResults = lrc->load(L, ctx, path, resolvedRequire.chunkname.c_str(), resolvedRequire.contents.c_str()); if (numResults == -1) {