From ebaadef11d4cb55a5dde78ed392b7d7e4ad15030 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Sat, 3 Nov 2018 15:39:14 +0100 Subject: fix an internal error trying to call on_state_create in a lane without any libs loaded always duplicate the config structure in new lanes even when no libraries are initialized by the generator --- CHANGES | 4 ++++ src/lanes.c | 9 +++------ src/tools.c | 47 ++++++++++++++++------------------------------- src/tools.h | 1 - src/universe.h | 2 ++ 5 files changed, 25 insertions(+), 38 deletions(-) diff --git a/CHANGES b/CHANGES index 998a87a..440ade4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ CHANGES: +CHANGE 130: BGe 2-Nov-18 + * always duplicate the config structure in new lanes even when no libraries are initialized by the generator + (fixes an internal error trying to call on_state_create in a lane without any libs loaded) + CHANGE 129: BGe 2-Nov-18 * Bumped version to 3.13 * fix error when autodetecting protect_allocator when running under LuaJIT diff --git a/src/lanes.c b/src/lanes.c index f2e7927..7b1a707 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -2296,12 +2296,6 @@ LUAG_FUNC( lane_new) } else { - // if is it "lanes" or "lanes.core", make sure we have copied the initial settings over - // which might not be the case if the libs list didn't include lanes.core or "*" - if( strncmp( name, "lanes.core", len) == 0) // this works both both "lanes" and "lanes.core" because of len - { - luaG_copy_one_time_settings( U, L, L2); - } lua_pushlstring( L2, name, len); // require() name if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode { @@ -3116,6 +3110,9 @@ LUAG_FUNC( configure) lua_getfield( L, 1, "verbose_errors"); // settings verbose_errors U->verboseErrors = lua_toboolean( L, -1); lua_pop( L, 1); // settings + lua_getfield( L, 1, "demote_full_userdata"); // settings demote_full_userdata + U->demoteFullUserdata = lua_toboolean( L, -1); + lua_pop( L, 1); // settings #if HAVE_LANE_TRACKING MUTEX_INIT( &U->tracking_cs); lua_getfield( L, 1, "track_lanes"); // settings track_lanes diff --git a/src/tools.c b/src/tools.c index c13d80d..0ef779a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -140,7 +140,7 @@ void initialize_on_state_create( Universe* U, lua_State* L) // ################################################################################################ // just like lua_xmove, args are (from, to) -void luaG_copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) +static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) { STACK_GROW( L, 1); // copy settings from from source to destination registry @@ -213,11 +213,6 @@ static void open1lib( Universe* U, lua_State* L, char const* name_, size_t len_, bool_t const isLanesCore = (libfunc == require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core" DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); STACK_CHECK( L); - if( isLanesCore == TRUE) - { - // copy settings from from source to destination registry - luaG_copy_one_time_settings( U, from_, L); - } // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) luaL_requiref( L, name_, libfunc, !isLanesCore); // lanes.core doesn't declare a global, so scan it here and now @@ -666,10 +661,14 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END)); DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); + // copy settings (for example because it may contain a Lua on_state_create function) + copy_one_time_settings( U, from_, L); + // 'lua.c' stops GC during initialization so perhaps its a good idea. :) lua_gc( L, LUA_GCSTOP, 0); - // Anything causes 'base' to be taken in + + // Anything causes 'base' to be taken in // if( libs_ != NULL) { @@ -1657,8 +1656,7 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu ret = FALSE; break; } - /* Allow only deep userdata entities to be copied across - */ + // Allow only deep userdata entities to be copied across DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "USERDATA\n" INDENT_END)); if( !copydeep( U, L, L2, i, mode_)) { @@ -1694,29 +1692,16 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu } lua_pop( L, 2); // ... } + + // Not a deep or clonable full userdata + if( U->demoteFullUserdata) // attempt demotion to light userdata { - // Not a deep or clonable full userdata - bool_t demote = FALSE; - lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); - if( lua_istable( L, -1)) // should not happen, but who knows... - { - lua_getfield( L, -1, "demote_full_userdata"); - demote = lua_toboolean( L, -1); - lua_pop( L, 2); - } - else - { - lua_pop( L, 1); - } - if( demote) // attempt demotion to light userdata - { - void* lud = lua_touserdata( L, i); - lua_pushlightuserdata( L2, lud); - } - else // raise an error - { - (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); - } + void* lud = lua_touserdata( L, i); + lua_pushlightuserdata( L2, lud); + } + else // raise an error + { + (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); } } break; diff --git a/src/tools.h b/src/tools.h index 11a541c..09ae050 100644 --- a/src/tools.h +++ b/src/tools.h @@ -21,7 +21,6 @@ typedef struct s_Universe Universe; void luaG_dump( lua_State* L ); lua_State* luaG_newstate( Universe* U, lua_State* _from, char const* libs); -void luaG_copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2); // ################################################################################################ diff --git a/src/universe.h b/src/universe.h index a75cead..359dc90 100644 --- a/src/universe.h +++ b/src/universe.h @@ -32,6 +32,8 @@ struct s_Universe // for verbose errors bool_t verboseErrors; + bool_t demoteFullUserdata; + lua_CFunction on_state_create_func; Keepers* keepers; -- cgit v1.2.3-55-g6feb