diff options
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r-- | src/lanes.cpp | 84 |
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 | ||
583 | extern "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? | ||
607 | static 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 |