diff --git a/Distribution/LuaBridge/LuaBridge.h b/Distribution/LuaBridge/LuaBridge.h index d5d846b8..f5af00f2 100644 --- a/Distribution/LuaBridge/LuaBridge.h +++ b/Distribution/LuaBridge/LuaBridge.h @@ -91,6 +91,10 @@ #define LUABRIDGE_SAFE_STACK_CHECKS 1 #endif +#if !defined(LUABRIDGE_SAFE_LUA_C_EXCEPTION_HANDLING) +#define LUABRIDGE_SAFE_LUA_C_EXCEPTION_HANDLING 0 +#endif + #if !defined(LUABRIDGE_RAISE_UNREGISTERED_CLASS_USAGE) #if LUABRIDGE_HAS_EXCEPTIONS #define LUABRIDGE_RAISE_UNREGISTERED_CLASS_USAGE 1 @@ -164,6 +168,11 @@ inline int lua_error_x(lua_State* L) return 0; } +inline int lua_getstack_x(lua_State* L, int level, lua_Debug* ar) +{ + return lua_getinfo(L, level, "nlS", ar); +} + inline int lua_getstack_info_x(lua_State* L, int level, const char* what, lua_Debug* ar) { return lua_getinfo(L, level, what, ar); @@ -194,6 +203,11 @@ inline int lua_error_x(lua_State* L) return lua_error(L); } +inline int lua_getstack_x(lua_State* L, int level, lua_Debug* ar) +{ + return lua_getstack(L, level, ar); +} + inline int lua_getstack_info_x(lua_State* L, int level, const char* what, lua_Debug* ar) { lua_getstack(L, level, ar); @@ -6694,7 +6708,21 @@ int invoke_member_cfunction(lua_State* L) const F& func = *static_cast(lua_touserdata(L, lua_upvalueindex(1))); LUABRIDGE_ASSERT(func != nullptr); - return (t->*func)(L); +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + return (t->*func)(L); + +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } + + return 0; +#endif } template @@ -6709,7 +6737,21 @@ int invoke_const_member_cfunction(lua_State* L) const F& func = *static_cast(lua_touserdata(L, lua_upvalueindex(1))); LUABRIDGE_ASSERT(func != nullptr); - return (t->*func)(L); +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + return (t->*func)(L); + +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } + + return 0; +#endif } template @@ -6737,6 +6779,26 @@ int invoke_proxy_functor(lua_State* L) return function::call(L, func); } +#if LUABRIDGE_SAFE_LUA_C_EXCEPTION_HANDLING && LUABRIDGE_HAS_EXCEPTIONS +inline int invoke_safe_cfunction(lua_State* L) +{ + LUABRIDGE_ASSERT(lua_iscfunction(L, lua_upvalueindex(1))); + + auto func = lua_tocfunction(L, lua_upvalueindex(1)); + + try + { + return func(L); + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } + + return 0; +} +#endif + template int invoke_proxy_constructor(lua_State* L) { @@ -6829,7 +6891,12 @@ inline int try_overload_functions(lua_State* L) inline void push_function(lua_State* L, lua_CFunction fp) { +#if LUABRIDGE_SAFE_LUA_C_EXCEPTION_HANDLING && LUABRIDGE_HAS_EXCEPTIONS lua_pushcfunction_x(L, fp); + lua_pushcclosure_x(L, invoke_safe_cfunction, 1); +#else + lua_pushcfunction_x(L, fp); +#endif } template @@ -6860,7 +6927,12 @@ inline void push_function(lua_State* L, F&& f) template void push_member_function(lua_State* L, lua_CFunction fp) { +#if LUABRIDGE_SAFE_LUA_C_EXCEPTION_HANDLING && LUABRIDGE_HAS_EXCEPTIONS lua_pushcfunction_x(L, fp); + lua_pushcclosure_x(L, invoke_safe_cfunction, 1); +#else + lua_pushcfunction_x(L, fp); +#endif } template @@ -6981,14 +7053,14 @@ void push_member_function(lua_State* L, int (U::*mfp)(lua_State*) const) template struct constructor { - static T* call(const Args& args) + static T* construct(const Args& args) { auto alloc = [](auto&&... args) { return new T(std::forward(args)...); }; return std::apply(alloc, args); } - static T* call(void* ptr, const Args& args) + static T* construct(void* ptr, const Args& args) { auto alloc = [ptr](auto&&... args) { return new (ptr) T(std::forward(args)...); }; @@ -7037,7 +7109,21 @@ int constructor_container_proxy(lua_State* L) { using T = typename ContainerTraits::Type; - T* object = constructor::call(detail::make_arguments_list(L)); + T* object = nullptr; + +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + object = constructor::construct(detail::make_arguments_list(L)); + +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } +#endif auto result = UserdataSharedHelper::push(L, object); if (! result) @@ -7056,8 +7142,21 @@ int constructor_placement_proxy(lua_State* L) if (! value) raise_lua_error(L, "%s", ec.message().c_str()); - constructor::call(value->getObject(), std::move(args)); +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + + constructor::construct(value->getObject(), std::move(args)); +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } +#endif + value->commit(); return 1; @@ -7083,12 +7182,25 @@ struct constructor_forwarder if (! value) raise_lua_error(L, "%s", ec.message().c_str()); - T* obj = placement_constructor::construct( - value->getObject(), m_func, std::move(args)); + T* object = nullptr; + +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + object = placement_constructor::construct(value->getObject(), m_func, std::move(args)); + +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } +#endif value->commit(); - return obj; + return object; } private: @@ -7109,14 +7221,28 @@ struct factory_forwarder using FnTraits = function_traits; using FnArgs = typename FnTraits::argument_types; - T* obj = external_constructor::construct(m_alloc, make_arguments_list(L)); + T* object = nullptr; + +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + object = external_constructor::construct(m_alloc, make_arguments_list(L)); + +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } +#endif std::error_code ec; - auto* value = UserdataValueExternal::place(L, obj, m_dealloc, ec); + auto* value = UserdataValueExternal::place(L, object, m_dealloc, ec); if (! value) raise_lua_error(L, "%s", ec.message().c_str()); - return obj; + return object; } private: @@ -7137,13 +7263,27 @@ struct container_forwarder using FnTraits = function_traits; using FnArgs = typename FnTraits::argument_types; - auto obj = container_constructor::construct(m_func, make_arguments_list(L)); + C object; + +#if LUABRIDGE_HAS_EXCEPTIONS + try + { +#endif + object = container_constructor::construct(m_func, make_arguments_list(L)); + +#if LUABRIDGE_HAS_EXCEPTIONS + } + catch (const std::exception& e) + { + raise_lua_error(L, "%s", e.what()); + } +#endif - auto result = UserdataSharedHelper::push(L, obj); + auto result = UserdataSharedHelper::push(L, object); if (! result) raise_lua_error(L, "%s", result.message().c_str()); - return obj; + return object; } private: