@@ -1067,8 +1067,6 @@ inline void lua_pushcclosure_x(lua_State* L, lua_CFunction fn, const char* debug
10671067[[noreturn]] inline void lua_error_x (lua_State* L)
10681068{
10691069 lua_error (L);
1070-
1071- detail::unreachable ();
10721070}
10731071
10741072inline int lua_getstack_x (lua_State* L, int level, lua_Debug* ar)
@@ -3707,6 +3705,7 @@ class LuaException : public std::exception
37073705 LuaException (lua_State* L, std::error_code code)
37083706 : m_L(L)
37093707 , m_code(code)
3708+ , m_what(code.message())
37103709 {
37113710 }
37123711
@@ -4732,7 +4731,7 @@ struct UserdataGetter
47324731};
47334732
47344733template <class T >
4735- struct UserdataGetter <T, std::void_t <T (*)()>>
4734+ struct UserdataGetter <T, std::enable_if_t <!is_move_only_function_v<T>, std:: void_t <T (*)()> >>
47364735{
47374736 using ReturnType = TypeResult<T>;
47384737
@@ -4746,6 +4745,26 @@ struct UserdataGetter<T, std::void_t<T (*)()>>
47464745 }
47474746};
47484747
4748+ #if LUABRIDGE_HAS_CXX23_MOVE_ONLY_FUNCTION
4749+ template <class T >
4750+ struct UserdataGetter <T, std::enable_if_t <is_move_only_function_v<T>>>
4751+ {
4752+ using ReturnType = TypeResult<T>;
4753+
4754+ static ReturnType get (lua_State* L, int index)
4755+ {
4756+ auto result = Userdata::get<T>(L, index, true );
4757+ if (! result)
4758+ return result.error ();
4759+
4760+ if (*result == nullptr )
4761+ return getNilBadArgError<T>(L, index);
4762+
4763+ return std::move (**result);
4764+ }
4765+ };
4766+ #endif
4767+
47494768}
47504769
47514770template <class T , class = void >
@@ -7566,6 +7585,76 @@ inline void push_class_or_const_table(lua_State* L, int index)
75667585 }
75677586}
75687587
7588+ inline std::optional<int > try_call_instance_static_index (lua_State* L, int classMetatableIndex)
7589+ {
7590+ lua_rawgetp_x (L, classMetatableIndex, getStaticKey ());
7591+ if (! lua_istable (L, -1 ))
7592+ {
7593+ lua_pop (L, 1 );
7594+ return std::nullopt ;
7595+ }
7596+
7597+ lua_pushvalue (L, 2 );
7598+ lua_rawget (L, -2 );
7599+ if (! lua_isnil (L, -1 ))
7600+ {
7601+ lua_remove (L, -2 );
7602+ return 1 ;
7603+ }
7604+
7605+ lua_pop (L, 1 );
7606+ lua_rawgetp_x (L, -1 , getPropgetKey ());
7607+ if (! lua_istable (L, -1 ))
7608+ {
7609+ lua_pop (L, 2 );
7610+ return std::nullopt ;
7611+ }
7612+
7613+ lua_pushvalue (L, 2 );
7614+ lua_rawget (L, -2 );
7615+ if (! lua_iscfunction (L, -1 ))
7616+ {
7617+ lua_pop (L, 3 );
7618+ return std::nullopt ;
7619+ }
7620+
7621+ lua_remove (L, -2 );
7622+ lua_remove (L, -2 );
7623+ lua_call (L, 0 , 1 );
7624+ return 1 ;
7625+ }
7626+
7627+ inline std::optional<int > try_call_instance_static_newindex (lua_State* L, int classMetatableIndex)
7628+ {
7629+ lua_rawgetp_x (L, classMetatableIndex, getStaticKey ());
7630+ if (! lua_istable (L, -1 ))
7631+ {
7632+ lua_pop (L, 1 );
7633+ return std::nullopt ;
7634+ }
7635+
7636+ lua_rawgetp_x (L, -1 , getPropsetKey ());
7637+ if (! lua_istable (L, -1 ))
7638+ {
7639+ lua_pop (L, 2 );
7640+ return std::nullopt ;
7641+ }
7642+
7643+ lua_pushvalue (L, 2 );
7644+ lua_rawget (L, -2 );
7645+ if (! lua_iscfunction (L, -1 ))
7646+ {
7647+ lua_pop (L, 3 );
7648+ return std::nullopt ;
7649+ }
7650+
7651+ lua_remove (L, -2 );
7652+ lua_remove (L, -2 );
7653+ lua_pushvalue (L, 3 );
7654+ lua_call (L, 1 , 0 );
7655+ return 0 ;
7656+ }
7657+
75697658inline std::optional<int > try_call_index_fallback (lua_State* L)
75707659{
75717660 LUABRIDGE_ASSERT (lua_istable (L, -1 ));
@@ -7763,12 +7852,6 @@ inline int index_metamethod(lua_State* L)
77637852 {
77647853 const Options options = get_class_options (L, -1 );
77657854
7766- // For static __index: the static fallback takes priority over registered static
7767- // property getters so that a user-defined static __index fallback can shadow
7768- // static properties.
7769- // For instance __index with allowOverridingMethods: the instance fallback takes
7770- // priority over class-table Lua methods, enabling Lua-side method overrides via
7771- // __newindex.
77727855 if constexpr (IsObject)
77737856 {
77747857 if (options.test (extensibleClass | allowOverridingMethods))
@@ -7840,6 +7923,12 @@ inline int index_metamethod(lua_State* L)
78407923 LUABRIDGE_ASSERT (lua_isnil (L, -1 ));
78417924 lua_pop (L, 1 );
78427925
7926+ if constexpr (IsObject)
7927+ {
7928+ if (auto result = try_call_instance_static_index (L, -1 ))
7929+ return *result;
7930+ }
7931+
78437932 lua_rawgetp_x (L, -1 , getParentKey ());
78447933
78457934 if (lua_istable (L, -1 ))
@@ -7973,6 +8062,10 @@ inline int index_metamethod_simple(lua_State* L)
79738062 return 1 ;
79748063
79758064 lua_pop (L, 1 );
8065+
8066+ if (auto result = try_call_instance_static_index (L, lua_upvalueindex (2 )))
8067+ return *result;
8068+
79768069 lua_pushnil (L);
79778070 return 1 ;
79788071 }
@@ -8165,7 +8258,7 @@ inline std::optional<int> try_call_newindex_extensible(lua_State* L, const char*
81658258
81668259 const int mtIndex = lua_absindex (L, -2 );
81678260 const int origClassTableIndex = lua_absindex (L, -1 );
8168- const auto process_metatable = [L, key, origClassTableIndex ](int candidateMtIndex)
8261+ const auto process_metatable = [= ](int candidateMtIndex)
81698262 {
81708263 push_class_or_const_table (L, candidateMtIndex);
81718264 if (! lua_istable (L, -1 ))
@@ -8235,7 +8328,7 @@ inline std::optional<int> try_call_newindex_extensible(lua_State* L, const char*
82358328 lua_pushvalue (L, rootMetatableIndex);
82368329 const int targetMetatableIndex = lua_absindex (L, -1 );
82378330
8238- const auto process_metatable = [L, key, targetMetatableIndex ](int candidateMtIndex)
8331+ const auto process_metatable = [= ](int candidateMtIndex)
82398332 {
82408333 push_class_or_const_table (L, candidateMtIndex);
82418334 if (! lua_istable (L, -1 ))
@@ -8454,6 +8547,12 @@ inline int newindex_metamethod(lua_State* L)
84548547
84558548 lua_pop (L, 1 );
84568549
8550+ if constexpr (IsObject)
8551+ {
8552+ if (auto result = try_call_instance_static_newindex (L, -1 ))
8553+ return *result;
8554+ }
8555+
84578556 if (auto result = try_call_parent_newindex_setters<IsObject>(L))
84588557 return *result;
84598558
@@ -8529,6 +8628,13 @@ inline int newindex_metamethod_simple(lua_State* L)
85298628 return 0 ;
85308629 }
85318630
8631+ lua_pop (L, 1 );
8632+ lua_getmetatable (L, 1 );
8633+ LUABRIDGE_ASSERT (lua_istable (L, -1 ));
8634+ if (auto result = try_call_instance_static_newindex (L, -1 ))
8635+ return *result;
8636+ lua_pop (L, 1 );
8637+
85328638 luaL_error (L, " no writable member '%s'" , key);
85338639 }
85348640 }
@@ -12488,7 +12594,7 @@ class Namespace : public detail::Registrar
1248812594 LUABRIDGE_ASSERT (lua_istable (L, visitedIndex));
1248912595 LUABRIDGE_ASSERT (lua_istable (L, baseMetatableIndex));
1249012596
12491- const auto appendUnique = [L, parentsIndex, visitedIndex ](int metatableIndex)
12597+ const auto appendUnique = [= ](int metatableIndex)
1249212598 {
1249312599 metatableIndex = lua_absindex (L, metatableIndex);
1249412600
0 commit comments