aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp81
1 files changed, 80 insertions, 1 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index d211b6a..ee40ffa 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -81,7 +81,8 @@ THE SOFTWARE.
81 81
82#include "lanes.h" 82#include "lanes.h"
83 83
84#include "compat.h" 84#include "deep.h"
85#include "intercopycontext.h"
85#include "keeper.h" 86#include "keeper.h"
86#include "lanes_private.h" 87#include "lanes_private.h"
87#include "state.h" 88#include "state.h"
@@ -1522,6 +1523,84 @@ LUAG_FUNC(wakeup_conv)
1522} 1523}
1523 1524
1524// ################################################################################################# 1525// #################################################################################################
1526// ################################### custom allocator support ####################################
1527// #################################################################################################
1528
1529// same as PUC-Lua l_alloc
1530extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_)
1531{
1532 if (nsize_ == 0) {
1533 free(ptr_);
1534 return nullptr;
1535 } else {
1536 return realloc(ptr_, nsize_);
1537 }
1538}
1539
1540// #################################################################################################
1541
1542[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_)
1543{
1544 Universe* const U{ universe_get(L_) };
1545 // push a new full userdata on the stack, giving access to the universe's protected allocator
1546 [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ U->protectedAllocator.makeDefinition() } };
1547 return 1;
1548}
1549
1550// #################################################################################################
1551
1552// called once at the creation of the universe (therefore L is the master Lua state everything originates from)
1553// Do I need to disable this when compiling for LuaJIT to prevent issues?
1554static void initialize_allocator_function(Universe* U_, lua_State* L_)
1555{
1556 STACK_CHECK_START_REL(L_, 1); // L_: settings
1557 lua_getfield(L_, -1, "allocator"); // L_: settings allocator|nil|"protected"
1558 if (!lua_isnil(L_, -1)) {
1559 // store C function pointer in an internal variable
1560 U_->provideAllocator = lua_tocfunction(L_, -1); // L_: settings allocator
1561 if (U_->provideAllocator != nullptr) {
1562 // make sure the function doesn't have upvalues
1563 char const* upname = lua_getupvalue(L_, -1, 1); // L_: settings allocator upval?
1564 if (upname != nullptr) { // should be "" for C functions with upvalues if any
1565 raise_luaL_error(L_, "config.allocator() shouldn't have upvalues");
1566 }
1567 // remove this C function from the config table so that it doesn't cause problems
1568 // when we transfer the config table in newly created Lua states
1569 lua_pushnil(L_); // L_: settings allocator nil
1570 lua_setfield(L_, -3, "allocator"); // L_: settings allocator
1571 } else if (lua_type(L_, -1) == LUA_TSTRING) { // should be "protected"
1572 LUA_ASSERT(L_, strcmp(lua_tostring(L_, -1), "protected") == 0);
1573 // set the original allocator to call from inside protection by the mutex
1574 U_->protectedAllocator.initFrom(L_);
1575 U_->protectedAllocator.installIn(L_);
1576 // before a state is created, this function will be called to obtain the allocator
1577 U_->provideAllocator = luaG_provide_protected_allocator;
1578 }
1579 } else {
1580 // just grab whatever allocator was provided to lua_newstate
1581 U_->protectedAllocator.initFrom(L_);
1582 }
1583 lua_pop(L_, 1); // L_: settings
1584 STACK_CHECK(L_, 1);
1585
1586 lua_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator"
1587 {
1588 char const* allocator = lua_tostring(L_, -1);
1589 if (strcmp(allocator, "libc") == 0) {
1590 U_->internalAllocator = AllocatorDefinition{ libc_lua_Alloc, nullptr };
1591 } else if (U_->provideAllocator == luaG_provide_protected_allocator) {
1592 // user wants mutex protection on the state's allocator. Use protection for our own allocations too, just in case.
1593 U_->internalAllocator = U_->protectedAllocator.makeDefinition();
1594 } else {
1595 // no protection required, just use whatever we have as-is.
1596 U_->internalAllocator = U_->protectedAllocator;
1597 }
1598 }
1599 lua_pop(L_, 1); // L_: settings
1600 STACK_CHECK(L_, 1);
1601}
1602
1603// #################################################################################################
1525// ######################################## Module linkage ######################################### 1604// ######################################## Module linkage #########################################
1526// ################################################################################################# 1605// #################################################################################################
1527 1606