From d72ace0a7e8b5fa9a3ea14a56bceffb80467884e Mon Sep 17 00:00:00 2001 From: Robert Patterson Date: Mon, 11 Mar 2024 19:59:27 -0500 Subject: [PATCH 1/4] refine callWithHandler --- Source/LuaBridge/detail/Invoke.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/LuaBridge/detail/Invoke.h b/Source/LuaBridge/detail/Invoke.h index 41c98c50..415feeb9 100644 --- a/Source/LuaBridge/detail/Invoke.h +++ b/Source/LuaBridge/detail/Invoke.h @@ -180,7 +180,10 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args const int stackTop = lua_gettop(L); if constexpr (isValidHandler) - detail::push_function(L, std::forward(errorHandler), ""); // Stack: error handler (eh) + { + if (errorHandler) + detail::push_function(L, std::forward(errorHandler), ""); // Stack: error handler (eh) + } object.push(); // Stack: eh, ref @@ -199,11 +202,8 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args auto ec = makeErrorCode(ErrorCode::LuaFunctionCallFailed); #if LUABRIDGE_HAS_EXCEPTIONS - if constexpr (! isValidHandler) - { - if (LuaException::areExceptionsEnabled(L)) - LuaException::raise(L, ec); - } + if (LuaException::areExceptionsEnabled(L)) + LuaException::raise(L, ec); #endif return LuaResult::errorFromStack(L, ec); From 07e28a5762c69d0405f5563dbf2c8399d0f1679f Mon Sep 17 00:00:00 2001 From: Robert Patterson Date: Tue, 12 Mar 2024 07:57:43 -0500 Subject: [PATCH 2/4] I figured out what was wrong when errorHandler was null. --- Source/LuaBridge/detail/Invoke.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/LuaBridge/detail/Invoke.h b/Source/LuaBridge/detail/Invoke.h index 415feeb9..7103d28a 100644 --- a/Source/LuaBridge/detail/Invoke.h +++ b/Source/LuaBridge/detail/Invoke.h @@ -181,8 +181,8 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args if constexpr (isValidHandler) { - if (errorHandler) - detail::push_function(L, std::forward(errorHandler), ""); // Stack: error handler (eh) + if (errorHandler) + detail::push_function(L, std::forward(errorHandler), ""); // Stack: error handler (eh) } object.push(); // Stack: eh, ref @@ -196,7 +196,11 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args } } - const int code = lua_pcall(L, sizeof...(Args), LUA_MULTRET, isValidHandler ? (-static_cast(sizeof...(Args)) - 2) : 0); + int errorFunction = 0; + if constexpr (isValidHandler) + errorFunction = errorHandler ? (-static_cast(sizeof...(Args)) - 2) : 0; + + const int code = lua_pcall(L, sizeof...(Args), LUA_MULTRET, errorFunction); if (code != LUABRIDGE_LUA_OK) { auto ec = makeErrorCode(ErrorCode::LuaFunctionCallFailed); From 6c26d4619c794d5455f313d13fdf7d1f88c5659c Mon Sep 17 00:00:00 2001 From: Robert Patterson Date: Sat, 16 Mar 2024 22:33:00 -0500 Subject: [PATCH 3/4] updated with tests. --- Source/LuaBridge/detail/Invoke.h | 10 ++++-- Tests/Source/LuaRefTests.cpp | 61 ++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/Source/LuaBridge/detail/Invoke.h b/Source/LuaBridge/detail/Invoke.h index 7103d28a..5fca56fa 100644 --- a/Source/LuaBridge/detail/Invoke.h +++ b/Source/LuaBridge/detail/Invoke.h @@ -179,9 +179,12 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args lua_State* L = object.state(); const int stackTop = lua_gettop(L); + bool isNonNullHandler = isValidHandler; if constexpr (isValidHandler) { - if (errorHandler) + if constexpr (std::is_pointer_v> || std::is_same_v, std::function>) + isNonNullHandler = errorHandler != nullptr; + if (isNonNullHandler) detail::push_function(L, std::forward(errorHandler), ""); // Stack: error handler (eh) } @@ -198,7 +201,10 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args int errorFunction = 0; if constexpr (isValidHandler) - errorFunction = errorHandler ? (-static_cast(sizeof...(Args)) - 2) : 0; + { + if (isNonNullHandler) + errorFunction = (-static_cast(sizeof...(Args)) - 2); + } const int code = lua_pcall(L, sizeof...(Args), LUA_MULTRET, errorFunction); if (code != LUABRIDGE_LUA_OK) diff --git a/Tests/Source/LuaRefTests.cpp b/Tests/Source/LuaRefTests.cpp index 62d4cbf4..18b72f74 100644 --- a/Tests/Source/LuaRefTests.cpp +++ b/Tests/Source/LuaRefTests.cpp @@ -8,6 +8,7 @@ #include "TestBase.h" #include +#include struct LuaRefTests : TestBase { @@ -534,12 +535,68 @@ TEST_F(LuaRefTests, CallableWithHandler) return 0; }; - auto result = f.callWithHandler(handler, "badly"); - EXPECT_FALSE(result); +#if LUABRIDGE_HAS_EXCEPTIONS + EXPECT_ANY_THROW(f.callWithHandler(handler, "badly")); +#else + EXPECT_FALSE(f.callWithHandler(handler, "badly")); +#endif EXPECT_TRUE(calledHandler); EXPECT_TRUE(errorMessage.find("we failed badly") != std::string::npos); } +TEST_F(LuaRefTests, CallableWithStdFunction) +{ + runLua("function f(x) error('we failed ' .. x) end"); + auto f = luabridge::getGlobal(L, "f"); + EXPECT_TRUE(f.isCallable()); + + bool calledHandler = false; + std::string errorMessage; + auto handler = [&](lua_State*) -> int + { + calledHandler = true; + + if (auto msg = lua_tostring(L, 1)) + errorMessage = msg; + + return 0; + }; + std::function pHandler = handler; + +#if LUABRIDGE_HAS_EXCEPTIONS + EXPECT_ANY_THROW(f.callWithHandler(pHandler, "badly")); +#else + EXPECT_FALSE(f.callWithHandler(pHandler, "badly")); +#endif + EXPECT_TRUE(calledHandler); + EXPECT_TRUE(errorMessage.find("we failed badly") != std::string::npos); + + calledHandler = false; + errorMessage = ""; + pHandler = nullptr; +#if LUABRIDGE_HAS_EXCEPTIONS + EXPECT_ANY_THROW(f.callWithHandler(pHandler, "badly")); +#else + EXPECT_FALSE(f.callWithHandler(pHandler, "badly")); +#endif + EXPECT_FALSE(calledHandler); + EXPECT_FALSE(errorMessage.find("we failed badly") != std::string::npos); +} + +TEST_F(LuaRefTests, CallableWithNullCFunction) +{ + runLua("function f(x) error('we failed ' .. x) end"); + auto f = luabridge::getGlobal(L, "f"); + EXPECT_TRUE(f.isCallable()); + + lua_CFunction pHandler = nullptr; +#if LUABRIDGE_HAS_EXCEPTIONS + EXPECT_ANY_THROW(f.callWithHandler(pHandler, "badly")); +#else + EXPECT_FALSE(f.callWithHandler(pHandler, "badly")); +#endif +} + TEST_F(LuaRefTests, Pop) { lua_pushstring(L, "hello"); From 5f9325056b3a64220ef308cf6c2d5638d3d00040 Mon Sep 17 00:00:00 2001 From: Robert Patterson Date: Sun, 17 Mar 2024 04:35:03 -0500 Subject: [PATCH 4/4] cleaner code --- Source/LuaBridge/detail/Invoke.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Source/LuaBridge/detail/Invoke.h b/Source/LuaBridge/detail/Invoke.h index 5fca56fa..25b11226 100644 --- a/Source/LuaBridge/detail/Invoke.h +++ b/Source/LuaBridge/detail/Invoke.h @@ -199,14 +199,7 @@ LuaResult callWithHandler(const LuaRef& object, F&& errorHandler, Args&&... args } } - int errorFunction = 0; - if constexpr (isValidHandler) - { - if (isNonNullHandler) - errorFunction = (-static_cast(sizeof...(Args)) - 2); - } - - const int code = lua_pcall(L, sizeof...(Args), LUA_MULTRET, errorFunction); + const int code = lua_pcall(L, sizeof...(Args), LUA_MULTRET, isNonNullHandler ? (-static_cast(sizeof...(Args)) - 2) : 0); if (code != LUABRIDGE_LUA_OK) { auto ec = makeErrorCode(ErrorCode::LuaFunctionCallFailed);