aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp84
1 files changed, 3 insertions, 81 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 6a84422..b3f7be7 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -576,84 +576,6 @@ LUAG_FUNC(wakeup_conv)
576} 576}
577 577
578// ################################################################################################# 578// #################################################################################################
579// ################################### custom allocator support ####################################
580// #################################################################################################
581
582// same as PUC-Lua l_alloc
583extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_)
584{
585 if (nsize_ == 0) {
586 free(ptr_);
587 return nullptr;
588 } else {
589 return realloc(ptr_, nsize_);
590 }
591}
592
593// #################################################################################################
594
595[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_)
596{
597 Universe* const _U{ universe_get(L_) };
598 // push a new full userdata on the stack, giving access to the universe's protected allocator
599 [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } };
600 return 1;
601}
602
603// #################################################################################################
604
605// called once at the creation of the universe (therefore L is the master Lua state everything originates from)
606// Do I need to disable this when compiling for LuaJIT to prevent issues?
607static void initialize_allocator_function(Universe* U_, lua_State* L_)
608{
609 STACK_CHECK_START_REL(L_, 1); // L_: settings
610 lua_getfield(L_, -1, "allocator"); // L_: settings allocator|nil|"protected"
611 if (!lua_isnil(L_, -1)) {
612 // store C function pointer in an internal variable
613 U_->provideAllocator = lua_tocfunction(L_, -1); // L_: settings allocator
614 if (U_->provideAllocator != nullptr) {
615 // make sure the function doesn't have upvalues
616 char const* upname = lua_getupvalue(L_, -1, 1); // L_: settings allocator upval?
617 if (upname != nullptr) { // should be "" for C functions with upvalues if any
618 raise_luaL_error(L_, "config.allocator() shouldn't have upvalues");
619 }
620 // remove this C function from the config table so that it doesn't cause problems
621 // when we transfer the config table in newly created Lua states
622 lua_pushnil(L_); // L_: settings allocator nil
623 lua_setfield(L_, -3, "allocator"); // L_: settings allocator
624 } else if (lua_type(L_, -1) == LUA_TSTRING) { // should be "protected"
625 LUA_ASSERT(L_, strcmp(lua_tostring(L_, -1), "protected") == 0);
626 // set the original allocator to call from inside protection by the mutex
627 U_->protectedAllocator.initFrom(L_);
628 U_->protectedAllocator.installIn(L_);
629 // before a state is created, this function will be called to obtain the allocator
630 U_->provideAllocator = luaG_provide_protected_allocator;
631 }
632 } else {
633 // just grab whatever allocator was provided to lua_newstate
634 U_->protectedAllocator.initFrom(L_);
635 }
636 lua_pop(L_, 1); // L_: settings
637 STACK_CHECK(L_, 1);
638
639 lua_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator"
640 {
641 char const* const _allocator{ lua_tostring(L_, -1) };
642 if (strcmp(_allocator, "libc") == 0) {
643 U_->internalAllocator = AllocatorDefinition{ libc_lua_Alloc, nullptr };
644 } else if (U_->provideAllocator == luaG_provide_protected_allocator) {
645 // user wants mutex protection on the state's allocator. Use protection for our own allocations too, just in case.
646 U_->internalAllocator = U_->protectedAllocator.makeDefinition();
647 } else {
648 // no protection required, just use whatever we have as-is.
649 U_->internalAllocator = U_->protectedAllocator;
650 }
651 }
652 lua_pop(L_, 1); // L_: settings
653 STACK_CHECK(L_, 1);
654}
655
656// #################################################################################################
657// ######################################## Module linkage ######################################### 579// ######################################## Module linkage #########################################
658// ################################################################################################# 580// #################################################################################################
659 581
@@ -728,9 +650,9 @@ LUAG_FUNC(configure)
728#endif // HAVE_LANE_TRACKING() 650#endif // HAVE_LANE_TRACKING()
729 // Linked chains handling 651 // Linked chains handling
730 _U->selfdestructFirst = SELFDESTRUCT_END; 652 _U->selfdestructFirst = SELFDESTRUCT_END;
731 initialize_allocator_function(_U, L_); 653 _U->initializeAllocatorFunction(L_);
732 initializeOnStateCreate(_U, L_); 654 InitializeOnStateCreate(_U, L_);
733 init_keepers(_U, L_); 655 _U->initializeKeepers(L_);
734 STACK_CHECK(L_, 1); 656 STACK_CHECK(L_, 1);
735 657
736 // Initialize 'timerLinda'; a common Linda object shared by all states 658 // Initialize 'timerLinda'; a common Linda object shared by all states