inline void init_caches(lua_State * L) { PRIMER_ASSERT_STACK_NEUTRAL(L); // Initialize some cached objects. If these can't be created later in a low // memory situation it will cause problems, so, try to preempt this. lua_state_ref::obtain_weak_ref_to_state(L); primer::push_singleton<primer::detail::fetch_traceback_function>(L); lua_pop(L, 1); }
// Based on impl of luaL_testudata static T * test_udata(lua_State * L, int idx) { PRIMER_ASSERT_STACK_NEUTRAL(L); if (void * p = lua_touserdata(L, idx)) { /* value is a userdata? */ if (lua_getmetatable(L, idx)) { /* does it have a metatable? */ primer::push_metatable<T>(L); /* get correct metatable */ if (!lua_rawequal(L, -1, -2)) { /* not the same? */ p = nullptr; /* value is a userdata with wrong metatable */ } lua_pop(L, 2); /* remove both metatables */ return static_cast<T *>(p); } } return nullptr; /* value is not a userdata with a metatable */ }
// Based on impl of luaL_setmetatable // Sets the top of the stack entry to this metatable static void set_metatable(lua_State * L) { PRIMER_ASSERT_STACK_NEUTRAL(L); primer::push_metatable<T>(L); lua_setmetatable(L, -2); }
// Obtain a weak ref to the given lua state. // This works by installing a strong ref at a special registry key. // If the strong ref is not found, it is lazily created. // The strong ref is destroyed in its __gc metamethod, or, it can be // explicitly destroyed by calling "close_weak_refs". static lua_state_ref obtain_weak_ref_to_state(lua_State * L) { PRIMER_ASSERT_STACK_NEUTRAL(L); weak_ptr_type result{get_strong_ptr(L)}; lua_pop(L, 1); return lua_state_ref{result}; }
// Close the strong ref which is found in the registry. // Post condition: Any weak refs to this lua state will return nullptr when // locked. // Any attempts to obtain_weak_ref from this lua_State will result in a dead // weak_ref. // Even if no strong ref currently exists, a dead one will be created to // prevent future obtain_weak_ref calls from installing one. // // [note You do not need to call this explicitly, unless you are paranoid // about // bad things happening *during* the lua garbage collection process. Closing // the state closes all objects which are marked with finalizers, so the weak // refs will be closed by that, during the course of lua_close execution.] static void close_weak_refs_to_state(lua_State * L) { PRIMER_ASSERT_STACK_NEUTRAL(L); get_strong_ptr(L).reset(); lua_pop(L, 1); }