From 2baf7a6e001951d08098149d80d7ce79e7035a16 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 3 Jun 2024 17:48:07 +0200 Subject: New global setting "strip_functions" --- docs/index.html | 11 +++++++++++ src/intercopycontext.cpp | 2 +- src/lanes.lua | 48 +++++++++++++++++++++++++----------------------- src/universe.cpp | 6 ++++++ src/universe.h | 2 ++ tests/basic.lua | 24 +++++++++++++----------- 6 files changed, 58 insertions(+), 35 deletions(-) diff --git a/docs/index.html b/docs/index.html index c3e8285..0cad4a0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -436,6 +436,17 @@ Select the cancellation mode used at Lanes shutdown to request free running lane termination. See lane cancellation. Default is "hard". + + + .strip_functions + + + nil/false/true + + + Controls function bytecode stripping when dumping them for lane transfer. Choose between faster copies or more debug info. Default is true. + +

diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index 3557c7b..07eea24 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp @@ -196,7 +196,7 @@ void InterCopyContext::copy_func() const // not sure this could ever fail but for memory shortage reasons // last parameter is Lua 5.4-specific (no stripping) luaL_Buffer B{}; - if (lua504_dump(L1, buf_writer, &B, 0) != 0) { + if (lua504_dump(L1, buf_writer, &B, U->stripFunctions) != 0) { raise_luaL_error(getErrL(), "internal error: function dump failed."); } diff --git a/src/lanes.lua b/src/lanes.lua index 4f11033..95c4eff 100644 --- a/src/lanes.lua +++ b/src/lanes.lua @@ -90,19 +90,20 @@ local isLuaJIT = (package and package.loaded.jit and jit.version) and true or fa local default_params = { - nb_user_keepers = 0, + -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes + allocator = isLuaJIT and "protected" or nil, + demote_full_userdata = nil, + -- it looks also like LuaJIT allocator may not appreciate direct use of its allocator for other purposes than the VM operation + internal_allocator = isLuaJIT and "libc" or "allocator", keepers_gc_threshold = -1, + nb_user_keepers = 0, on_state_create = nil, - shutdown_timeout = 0.25, shutdown_mode = "hard", - with_timers = false, + shutdown_timeout = 0.25, + strip_functions = true, track_lanes = false, - demote_full_userdata = nil, verbose_errors = false, - -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes - allocator = isLuaJIT and "protected" or nil, - -- it looks also like LuaJIT allocator may not appreciate direct use of its allocator for other purposes than the VM operation - internal_allocator = isLuaJIT and "libc" or "allocator" + with_timers = false, } -- ################################################################################################# @@ -114,39 +115,40 @@ end local param_checkers = { - nb_user_keepers = function(val_) - -- nb_user_keepers should be a number in [0,100] (so that nobody tries to run OOM by specifying a huge amount) - return type(val_) == "number" and val_ >= 0 and val_ <= 100 - end, - keepers_gc_threshold = function(val_) - -- keepers_gc_threshold should be a number - return type(val_) == "number" - end, - with_timers = boolean_param_checker, allocator = function(val_) -- can be nil, "protected", or a function return val_ and (type(val_) == "function" or val_ == "protected") or true end, + demote_full_userdata = boolean_param_checker, internal_allocator = function(val_) -- can be "libc" or "allocator" return val_ == "libc" or val_ == "allocator" end, + keepers_gc_threshold = function(val_) + -- keepers_gc_threshold should be a number + return type(val_) == "number" + end, + nb_user_keepers = function(val_) + -- nb_user_keepers should be a number in [0,100] (so that nobody tries to run OOM by specifying a huge amount) + return type(val_) == "number" and val_ >= 0 and val_ <= 100 + end, on_state_create = function(val_) -- on_state_create may be nil or a function return val_ and type(val_) == "function" or true end, - shutdown_timeout = function(val_) - -- shutdown_timeout should be a number >= 0 - return type(val_) == "number" and val_ >= 0 - end, shutdown_mode = function(val_) local valid_hooks = { soft = true, hard = true, call = true, ret = true, line = true, count = true } -- shutdown_mode should be a known hook mask return valid_hooks[val_] end, + shutdown_timeout = function(val_) + -- shutdown_timeout should be a number >= 0 + return type(val_) == "number" and val_ >= 0 + end, + strip_functions = boolean_param_checker, track_lanes = boolean_param_checker, - demote_full_userdata = boolean_param_checker, - verbose_errors = boolean_param_checker + verbose_errors = boolean_param_checker, + with_timers = boolean_param_checker, } -- ################################################################################################# diff --git a/src/universe.cpp b/src/universe.cpp index 2e7fd55..5a52f7e 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -107,6 +107,12 @@ Universe::Universe() lua_setfield(L_, -2, "__gc"); // L_: settings universe {mt} lua_setmetatable(L_, -2); // L_: settings universe lua_pop(L_, 1); // L_: settings + + // TODO: write some tests to see what happens when we trigger errors in stripped mode + std::ignore = luaG_getfield(L_, 1, "strip_functions"); // L_: settings strip_functions + _U->stripFunctions = lua_toboolean(L_, -1) ? true : false; + lua_pop(L_, 1); // L_: settings + std::ignore = luaG_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors _U->verboseErrors = lua_toboolean(L_, -1) ? true : false; lua_pop(L_, 1); // L_: settings diff --git a/src/universe.h b/src/universe.h index 7b9f309..4239466 100644 --- a/src/universe.h +++ b/src/universe.h @@ -133,6 +133,8 @@ class Universe bool demoteFullUserdata{ false }; + bool stripFunctions{ true }; + // before a state is created, this function will be called to obtain the allocator lua_CFunction provideAllocator{ nullptr }; diff --git a/tests/basic.lua b/tests/basic.lua index da7d756..fff19ed 100644 --- a/tests/basic.lua +++ b/tests/basic.lua @@ -6,8 +6,8 @@ -- To do: -- - ... -- - -local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{ with_timers = false, internal_allocator = "libc"} +local config = { with_timers = false, strip_functions = false, internal_allocator = "libc"} +local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config) print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2) local lanes = require_lanes_result_1 @@ -403,26 +403,28 @@ local function chunk2(linda) -- local info= debug.getinfo(1) -- 1 = us -- + PRINT "debug.getinfo->" for k,v in pairs(info) do PRINT(k,v) end - assert(info.nups == (_VERSION == "Lua 5.1" and 2 or 3)) -- one upvalue + PRINT + _ENV (Lua 5.2 only) - assert(info.what == "Lua") + -- some assertions are adjusted depending on config.strip_functions, because it changes what we get out of debug.getinfo + assert(info.nups == (_VERSION == "Lua 5.1" and 3 or 4), "bad nups") -- upvalue + config + PRINT + _ENV (Lua > 5.2 only) + assert(info.what == "Lua", "bad what") --assert(info.name == "chunk2") -- name does not seem to come through - assert(string.match(info.source, "^@.*basic.lua$")) - assert(string.match(info.short_src, "^.*basic.lua$")) + assert(config.strip_functions and info.source=="=?" or string.match(info.source, "^@.*basic.lua$"), "bad info.source") + assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src") -- These vary so let's not be picky (they're there..) -- - assert(info.linedefined > 200) -- start of 'chunk2' - assert(info.currentline > info.linedefined) -- line of 'debug.getinfo' - assert(info.lastlinedefined > info.currentline) -- end of 'chunk2' + assert(info.linedefined == 400, "bad linedefined") -- start of 'chunk2' + assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo' + assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2' local k,func= linda:receive("down") - assert(type(func)=="function") + assert(type(func)=="function", "not a function") assert(k=="down") func(linda) local k,str= linda:receive("down") - assert(str=="ok") + assert(str=="ok", "bad receive result") linda:send("up", function() return ":)" end, "ok2") end -- cgit v1.2.3-55-g6feb