From c2f88350772c01631ea3b7d60e56cea335c458b7 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 17 Feb 2022 16:30:36 +0100 Subject: NEVER use allocator obtained from lua_getallocf to allocate stuff manually when compiling for LuaJIT --- CHANGES | 3 +++ src/lanes.c | 22 ++++++++++++++++++---- src/linda.c | 27 ++++++++++++++++++++++----- src/macros_and_utils.h | 10 ++++++++++ src/state.c | 35 ++++++++++++++++++++--------------- src/uniquekey.h | 8 ++++---- 6 files changed, 77 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index 490d651..568f6db 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ CHANGES: +CHANGE 153: BGe 17-Feb-22 + * NEVER use allocator obtained from lua_getallocf to allocate stuff manually when compiling for LuaJIT + CHANGE 152: BGe 7-Feb-22 * bumped version to 3.16.0 * __lanesclone is now called only once with 3 parameters dest, source, size -> BREAKS CUSTOM DEEP USERDATA API diff --git a/src/lanes.c b/src/lanes.c index 8817071..bf0f0a3 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -238,7 +238,6 @@ static bool_t tracking_remove( Lane* s) static void lane_cleanup( Lane* s) { - AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; // Clean up after a (finished) thread // #if THREADWAIT_METHOD == THREADWAIT_CONDVAR @@ -254,7 +253,15 @@ static void lane_cleanup( Lane* s) } #endif // HAVE_LANE_TRACKING - allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); + // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly +#if LUAJIT_FLAVOR == 0 + { + AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; + allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); + } +#else // LUAJIT_FLAVOR + free(s); +#endif // LUAJIT_FLAVOR } /* @@ -1054,7 +1061,6 @@ LUAG_FUNC( lane_new) #define FIXED_ARGS 7 int const nargs = lua_gettop(L) - FIXED_ARGS; Universe* U = universe_get( L); - AllocatorDefinition* const allocD = &U->protected_allocator.definition; ASSERT_L( nargs >= 0); // public Lanes API accepts a generic range -3/+3 @@ -1224,7 +1230,15 @@ LUAG_FUNC( lane_new) // // a Lane full userdata needs a single uservalue ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane - s = *ud = (Lane*) allocD->allocF( allocD->allocUD, NULL, 0, sizeof(Lane)); + // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly +#if LUAJIT_FLAVOR == 0 + { + AllocatorDefinition* const allocD = &U->protected_allocator.definition; + s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); + } +#else // LUAJIT_FLAVOR + s = *ud = (Lane*) malloc(sizeof(Lane)); +#endif // LUAJIT_FLAVOR if( s == NULL) { return luaL_error( L, "could not create lane: out of memory"); diff --git a/src/linda.c b/src/linda.c index 21b38fe..4149e71 100644 --- a/src/linda.c +++ b/src/linda.c @@ -758,9 +758,6 @@ LUAG_FUNC( linda_towatch) */ static void* linda_id( lua_State* L, DeepOp op_) { - Universe* const U = universe_get(L); - AllocatorDefinition* const allocD = &U->protected_allocator.definition; - switch( op_) { case eDO_new: @@ -797,7 +794,17 @@ static void* linda_id( lua_State* L, DeepOp op_) * One can use any memory allocation scheme. * just don't use L's allocF because we don't know which state will get the honor of GCing the linda */ - s = (struct s_Linda*) allocD->allocF( allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included + // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly +#if LUAJIT_FLAVOR == 0 + { + Universe* const U = universe_get(L); + AllocatorDefinition* const allocD = &U->protected_allocator.definition; + + s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included + } +#else // LUAJIT_FLAVOR + s = (struct s_Linda*)malloc(sizeof(struct s_Linda) + name_len); // terminating 0 is already included +#endif // LUAJIT_FLAVOR if( s) { s->prelude.magic.value = DEEP_VERSION.value; @@ -830,7 +837,17 @@ static void* linda_id( lua_State* L, DeepOp op_) // There aren't any lanes waiting on these lindas, since all proxies have been gc'ed. Right? SIGNAL_FREE( &linda->read_happened); SIGNAL_FREE( &linda->write_happened); - allocD->allocF( allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); + // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly +#if LUAJIT_FLAVOR == 0 + { + Universe* const U = universe_get(L); + AllocatorDefinition* const allocD = &U->protected_allocator.definition; + + allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); + } +#else // LUAJIT_FLAVOR + free(linda); +#endif // LUAJIT_FLAVOR return NULL; } diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index b67a7c4..dac89d1 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -99,4 +99,14 @@ extern char const* debugspew_indent; #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) +#if defined(LUA_JITLIBNAME) +#if (defined(__x86_64__) || defined(_M_X64) || defined(__LP64__)) +#define LUAJIT_FLAVOR 64 +#else // 64 bits +#define LUAJIT_FLAVOR 32 +#endif // 64 bits +#else // LUA_JITLIBNAME +#define LUAJIT_FLAVOR 0 +#endif // LUA_JITLIBNAME + #endif // MACROS_AND_UTILS_H diff --git a/src/state.c b/src/state.c index c6c04d7..a2de5cb 100644 --- a/src/state.c +++ b/src/state.c @@ -129,31 +129,31 @@ static int require_lanes_core( lua_State* L) static const luaL_Reg libs[] = { { LUA_LOADLIBNAME, luaopen_package}, -{ LUA_TABLIBNAME, luaopen_table}, -{ LUA_STRLIBNAME, luaopen_string}, -{ LUA_MATHLIBNAME, luaopen_math}, + { LUA_TABLIBNAME, luaopen_table}, + { LUA_STRLIBNAME, luaopen_string}, + { LUA_MATHLIBNAME, luaopen_math}, #ifndef PLATFORM_XBOX // no os/io libs on xbox -{ LUA_OSLIBNAME, luaopen_os}, -{ LUA_IOLIBNAME, luaopen_io}, + { LUA_OSLIBNAME, luaopen_os}, + { LUA_IOLIBNAME, luaopen_io}, #endif // PLATFORM_XBOX #if LUA_VERSION_NUM >= 503 -{ LUA_UTF8LIBNAME, luaopen_utf8}, + { LUA_UTF8LIBNAME, luaopen_utf8}, #endif #if LUA_VERSION_NUM >= 502 #ifdef luaopen_bit32 -{ LUA_BITLIBNAME, luaopen_bit32}, + { LUA_BITLIBNAME, luaopen_bit32}, #endif -{ LUA_COLIBNAME, luaopen_coroutine}, // Lua 5.2: coroutine is no longer a part of base! + { LUA_COLIBNAME, luaopen_coroutine}, // Lua 5.2: coroutine is no longer a part of base! #else // LUA_VERSION_NUM -{ LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package + { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package #endif // LUA_VERSION_NUM -{ LUA_DBLIBNAME, luaopen_debug}, -#if defined LUA_JITLIBNAME // building against LuaJIT headers, add some LuaJIT-specific libs + { LUA_DBLIBNAME, luaopen_debug}, +#if LUAJIT_FLAVOR != 0 // building against LuaJIT headers, add some LuaJIT-specific libs //#pragma message( "supporting JIT base libs") -{ LUA_BITLIBNAME, luaopen_bit}, -{ LUA_JITLIBNAME, luaopen_jit}, -{ LUA_FFILIBNAME, luaopen_ffi}, -#endif // LUA_JITLIBNAME + { LUA_BITLIBNAME, luaopen_bit}, + { LUA_JITLIBNAME, luaopen_jit}, + { LUA_FFILIBNAME, luaopen_ffi}, +#endif // LUAJIT_FLAVOR { LUA_DBLIBNAME, luaopen_debug}, { "lanes.core", require_lanes_core}, // So that we can open it like any base library (possible since we have access to the init function) @@ -249,6 +249,10 @@ void initialize_on_state_create( Universe* U, lua_State* L) lua_State* create_state( Universe* U, lua_State* from_) { lua_State* L; +#if LUAJIT_FLAVOR == 64 + // for some reason, LuaJIT 64 bits does not support creating a state with lua_newstate... + L = luaL_newstate(); +#else // LUAJIT_FLAVOR == 64 if( U->provide_allocator != NULL) // we have a function we can call to obtain an allocator { lua_pushcclosure( from_, U->provide_allocator, 0); @@ -264,6 +268,7 @@ lua_State* create_state( Universe* U, lua_State* from_) // reuse the allocator provided when the master state was created L = lua_newstate( U->protected_allocator.definition.allocF, U->protected_allocator.definition.allocUD); } +#endif // LUAJIT_FLAVOR == 64 if( L == NULL) { diff --git a/src/uniquekey.h b/src/uniquekey.h index ff3d45d..a72426c 100644 --- a/src/uniquekey.h +++ b/src/uniquekey.h @@ -1,7 +1,7 @@ #if !defined __LANES_UNIQUEKEY_H__ #define __LANES_UNIQUEKEY_H__ 1 -#include "lualib.h" +#include "macros_and_utils.h" // Lua light userdata can hold a pointer. struct s_UniqueKey @@ -10,11 +10,11 @@ struct s_UniqueKey }; typedef struct s_UniqueKey UniqueKey; -#if defined(LUA_JITLIBNAME) && (defined(__x86_64__) || defined(_M_X64) || defined(__LP64__)) // building against LuaJIT headers, light userdata is restricted to 47 significant bits. +#if LUAJIT_FLAVOR == 64 // building against LuaJIT headers for 64 bits, light userdata is restricted to 47 significant bits, because LuaJIT uses the other bits for internal optimizations #define MAKE_UNIQUE_KEY( p_) ((void*)((ptrdiff_t)(p_) & 0x7fffffffffffull)) -#else // LUA_JITLIBNAME +#else // LUAJIT_FLAVOR #define MAKE_UNIQUE_KEY( p_) ((void*)(ptrdiff_t)(p_)) -#endif // LUA_JITLIBNAME +#endif // LUAJIT_FLAVOR #define DECLARE_UNIQUE_KEY( name_) UniqueKey name_ #define DECLARE_CONST_UNIQUE_KEY( name_, p_) UniqueKey const name_ = { MAKE_UNIQUE_KEY( p_)} -- cgit v1.2.3-55-g6feb