From 9a53a224283fb1d41bae229ad34d61fe6dbc1b76 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Wed, 22 Sep 2021 15:39:13 +0200 Subject: fix require() wrapper to return all values returned by original require() --- CHANGES | 3 +++ lanes-3.14.0-0.rockspec | 66 ------------------------------------------------- lanes-3.15.0-0.rockspec | 66 ------------------------------------------------- src/macros_and_utils.h | 2 +- src/state.c | 28 +++++++++------------ tests/basic.lua | 8 ++++-- 6 files changed, 22 insertions(+), 151 deletions(-) delete mode 100644 lanes-3.14.0-0.rockspec delete mode 100644 lanes-3.15.0-0.rockspec diff --git a/CHANGES b/CHANGES index c21a3ed..0aca28a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ CHANGES: +CHANGE 150: BGe 22-Sep-21 + * fix require() wrapper to return all values returned by original require() + CHANGE 149: BGe 8-Jul-21 * bumped version to 3.15.1 * fix function transfer with lua_dump for Lua 5.4 failing for functions big enough to necessitate a buffer reallocation diff --git a/lanes-3.14.0-0.rockspec b/lanes-3.14.0-0.rockspec deleted file mode 100644 index 8d56b80..0000000 --- a/lanes-3.14.0-0.rockspec +++ /dev/null @@ -1,66 +0,0 @@ --- --- Lanes rockspec --- --- Ref: --- --- - -package = "Lanes" - -version = "3.14.0-0" - -source= { - url= "git://github.com/LuaLanes/lanes.git", - branch= "v3.14.0" -} - -description = { - summary= "Multithreading support for Lua", - detailed= [[ - Lua Lanes is a portable, message passing multithreading library - providing the possibility to run multiple Lua states in parallel. - ]], - license= "MIT/X11", - homepage="https://github.com/LuaLanes/lanes", - maintainer="Benoit Germain " -} - --- Q: What is the difference of "windows" and "win32"? Seems there is none; --- so should we list either one or both? --- -supported_platforms= { "win32", - "macosx", - "linux", - "freebsd", -- TBD: not tested - "msys", -- TBD: not supported by LuaRocks 1.0 (or is it?) -} - -dependencies= { - "lua >= 5.1", -- builds with either 5.1, 5.2, 5.3 and 5.4 -} - -build = { - type = "builtin", - platforms = - { - linux = - { - modules = - { - ["lanes.core"] = - { - libraries = "pthread" - }, - } - } - }, - modules = - { - ["lanes.core"] = - { - sources = { "src/cancel.c", "src/compat.c", "src/deep.c", "src/lanes.c", "src/linda.c", "src/keeper.c", "src/tools.c", "src/threading.c", "src/universe.c"}, - incdirs = { "src"}, - }, - lanes = "src/lanes.lua" - } -} diff --git a/lanes-3.15.0-0.rockspec b/lanes-3.15.0-0.rockspec deleted file mode 100644 index bb23a7f..0000000 --- a/lanes-3.15.0-0.rockspec +++ /dev/null @@ -1,66 +0,0 @@ --- --- Lanes rockspec --- --- Ref: --- --- - -package = "Lanes" - -version = "3.15.0-0" - -source= { - url= "git://github.com/LuaLanes/lanes.git", - branch= "v3.15.0" -} - -description = { - summary= "Multithreading support for Lua", - detailed= [[ - Lua Lanes is a portable, message passing multithreading library - providing the possibility to run multiple Lua states in parallel. - ]], - license= "MIT/X11", - homepage="https://github.com/LuaLanes/lanes", - maintainer="Benoit Germain " -} - --- Q: What is the difference of "windows" and "win32"? Seems there is none; --- so should we list either one or both? --- -supported_platforms= { "win32", - "macosx", - "linux", - "freebsd", -- TBD: not tested - "msys", -- TBD: not supported by LuaRocks 1.0 (or is it?) -} - -dependencies= { - "lua >= 5.1", -- builds with either 5.1, 5.2, 5.3 and 5.4 -} - -build = { - type = "builtin", - platforms = - { - linux = - { - modules = - { - ["lanes.core"] = - { - libraries = "pthread" - }, - } - } - }, - modules = - { - ["lanes.core"] = - { - sources = { "src/compat.c", "src/deep.c", "src/lanes.c", "src/linda.c", "src/keeper.c", "src/tools.c", "src/state.c", "src/threading.c", "src/universe.c"}, - incdirs = { "src"}, - }, - lanes = "src/lanes.lua" - } -} diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index ae3a6c9..dba0010 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -60,7 +60,7 @@ extern char const* debugspew_indent; int const L##_oldtop = 0 #define STACK_MID( L, change) \ - do \ + do if( change != LUA_MULTRET) \ { \ int stack_check_a = lua_gettop( L) - L##_oldtop; \ int stack_check_b = (change); \ diff --git a/src/state.c b/src/state.c index cbbc0d8..81371b7 100644 --- a/src/state.c +++ b/src/state.c @@ -51,7 +51,7 @@ THE SOFTWARE. */ //--- -// [val]= new_require( ... ) +// [val,...]= new_require( ... ) // // Call 'old_require' but only one lane at a time. // @@ -59,36 +59,32 @@ THE SOFTWARE. // static int luaG_new_require( lua_State* L) { - int rc, i; - int args = lua_gettop( L); + int rc; + int const args = lua_gettop( L); // args Universe* U = universe_get( L); //char const* modname = luaL_checkstring( L, 1); - STACK_GROW( L, args + 1); - STACK_CHECK( L, 0); + STACK_GROW( L, 1); - lua_pushvalue( L, lua_upvalueindex( 1)); - for( i = 1; i <= args; ++ i) - { - lua_pushvalue( L, i); - } + lua_pushvalue( L, lua_upvalueindex( 1)); // args require + lua_insert( L, 1); // require args // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would // leave us locked, blocking any future 'require' calls from other lanes. - // + MUTEX_LOCK( &U->require_cs); - rc = lua_pcall( L, args, 1 /*retvals*/, 0 /*errfunc*/ ); + // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET + rc = lua_pcall( L, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s) MUTEX_UNLOCK( &U->require_cs); // the required module (or an error message) is left on the stack as returned value by original require function - STACK_END( L, 1); if( rc != LUA_OK) // LUA_ERRRUN / LUA_ERRMEM ? { - return lua_error( L); // error message already at [-1] + return lua_error( L); } - - return 1; + // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4 + return lua_gettop(L); // result(s) } /* diff --git a/tests/basic.lua b/tests/basic.lua index 6fcfd53..7bbcbb3 100644 --- a/tests/basic.lua +++ b/tests/basic.lua @@ -7,8 +7,12 @@ -- - ... -- -local lanes = require "lanes".configure{ with_timers = false} -require "assert" -- assert.fails() +local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{ with_timers = false} +print( "require_lanes_result:", require_lanes_result_1, require_lanes_result_2) +local lanes = require_lanes_result_1 + +local require_assert_result_1, require_assert_result_2 = require "assert" -- assert.fails() +print( "require_assert_result:", require_assert_result_1, require_assert_result_2) local lanes_gen= assert( lanes.gen ) local lanes_linda= assert( lanes.linda ) -- cgit v1.2.3-55-g6feb