From 305c1ced67db1a110986be0f9432f376a4cd8741 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 17:35:38 +0000 Subject: [PATCH 1/4] Initial plan From 3b41b04d6ab5f7ab4a5a5572de669b1e717aba60 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 17:41:33 +0000 Subject: [PATCH 2/4] Initial plan: allow NaN and Inf to pass through Stack push/get/isInstance Agent-Logs-Url: https://github.com/kunitoki/LuaBridge3/sessions/35478d43-613d-42fb-8556-4fffe1634e91 Co-authored-by: kunitoki <707032+kunitoki@users.noreply.github.com> --- tmpunwind.o | Bin 0 -> 1352 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tmpunwind.o diff --git a/tmpunwind.o b/tmpunwind.o new file mode 100644 index 0000000000000000000000000000000000000000..7ea5edf82eff5647e3aaedaf7d27979b251092ba GIT binary patch literal 1352 zcmbtT%}OId5Uz<|Hm?lNb>Z34!1bDjpUCdkM=-9F1ruVWtDogNg^y zo5y{GeS|$O_#$2eugl&<(5jg(?QQ3z1=Uscb$wkuRXrz58_Oxn0u~EO@Dec!kV(Dx z<;X2V76#zo(D;3I_44+Pu-~-Qu3@E8S+FOoZpW7$yHFHGk)NLHMB&Ww%&f@Iio#d5 zK@^l;)EsIb>dIynu-qTQdQeG5V*}RFH?X=nYiuB$xx$NnL7bE%%2^uBou?|<{&h@< z;l!1`u^0Y6CT;d4bl?Lfj%YaF=M&;|?^m)I%I!VB1P-{gM|=|cCenw;SZwr3sJ&W? z0YrG%l#Yv52C;3h7kCGbkX~1U*mk4?!VN$6?ZFg^854>X^746UJ)M*Z&% zVSJ$yY-QPS|2THhp)*bXFO@LQiOQP%8sbUwJ5?9uInn%x%Y4R@YE!8jT2Q*N0s7x) jMkb&BFLQQ8`L60`DbPg0&&V)(N&KHG@!&Z#c1->ga(P%a literal 0 HcmV?d00001 From 82c916b7ba8da366415c983320c0bde5646efe3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 17:48:16 +0000 Subject: [PATCH 3/4] Allow NaN and Inf values to pass through Stack push/get/isInstance Agent-Logs-Url: https://github.com/kunitoki/LuaBridge3/sessions/35478d43-613d-42fb-8556-4fffe1634e91 Co-authored-by: kunitoki <707032+kunitoki@users.noreply.github.com> --- .gitignore | 1 + Distribution/LuaBridge/LuaBridge.h | 6 +- Source/LuaBridge/detail/LuaHelpers.h | 6 +- Tests/Source/StackTests.cpp | 102 +++++++++++++++++++++++++++ tmpunwind.o | Bin 1352 -> 0 bytes 5 files changed, 113 insertions(+), 2 deletions(-) delete mode 100644 tmpunwind.o diff --git a/.gitignore b/.gitignore index 59b4e3e2..948f96c2 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ build/ .DS_store .idea/ cmake-build-*/ +tmpunwind.o diff --git a/Distribution/LuaBridge/LuaBridge.h b/Distribution/LuaBridge/LuaBridge.h index a773d348..315fbe1e 100644 --- a/Distribution/LuaBridge/LuaBridge.h +++ b/Distribution/LuaBridge/LuaBridge.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -689,8 +690,11 @@ bool is_integral_representable_by(lua_State* L, int index) } template -constexpr bool is_floating_point_representable_by(T value) +bool is_floating_point_representable_by(T value) { + if (std::isnan(value) || std::isinf(value)) + return true; + if constexpr (sizeof(T) == sizeof(U)) return true; diff --git a/Source/LuaBridge/detail/LuaHelpers.h b/Source/LuaBridge/detail/LuaHelpers.h index 62e83ffb..6bd2d0ea 100644 --- a/Source/LuaBridge/detail/LuaHelpers.h +++ b/Source/LuaBridge/detail/LuaHelpers.h @@ -8,6 +8,7 @@ #include "Config.h" +#include #include #include #include @@ -662,8 +663,11 @@ bool is_integral_representable_by(lua_State* L, int index) * @brief Checks if the value on the stack is a number type and can fit into the corresponding c++ numerical type.. */ template -constexpr bool is_floating_point_representable_by(T value) +bool is_floating_point_representable_by(T value) { + if (std::isnan(value) || std::isinf(value)) + return true; + if constexpr (sizeof(T) == sizeof(U)) return true; diff --git a/Tests/Source/StackTests.cpp b/Tests/Source/StackTests.cpp index 4793c4a2..daedd22f 100644 --- a/Tests/Source/StackTests.cpp +++ b/Tests/Source/StackTests.cpp @@ -1404,6 +1404,108 @@ TEST_F(StackTests, FloatTypeNotFittingIsInstance) EXPECT_TRUE(luabridge::isInstance(L, 1)); } +TEST_F(StackTests, FloatNaNAndInfPush) +{ + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, std::numeric_limits::quiet_NaN())); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isnan(*result)); + } + + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, std::numeric_limits::infinity())); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isinf(*result)); + } + + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, -std::numeric_limits::infinity())); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isinf(*result)); + EXPECT_LT(*result, 0.0f); + } +} + +TEST_F(StackTests, DoubleNaNAndInfPush) +{ + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, std::numeric_limits::quiet_NaN())); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isnan(*result)); + } + + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, std::numeric_limits::infinity())); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isinf(*result)); + } + + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, -std::numeric_limits::infinity())); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isinf(*result)); + EXPECT_LT(*result, 0.0); + } +} + +TEST_F(StackTests, LongDoubleNaNAndInfPush) +{ + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, std::numeric_limits::quiet_NaN())); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isnan(*result)); + } + + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, std::numeric_limits::infinity())); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + EXPECT_TRUE(luabridge::isInstance(L, -1)); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isinf(*result)); + } + + { + const luabridge::StackRestore sr(L); + EXPECT_TRUE(luabridge::push(L, -std::numeric_limits::infinity())); + auto result = luabridge::get(L, -1); + ASSERT_TRUE(result); + EXPECT_TRUE(std::isinf(*result)); + EXPECT_LT(*result, 0.0l); + } +} + TEST_F(StackTests, CharArrayType) { char value[] = "xyz"; diff --git a/tmpunwind.o b/tmpunwind.o deleted file mode 100644 index 7ea5edf82eff5647e3aaedaf7d27979b251092ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1352 zcmbtT%}OId5Uz<|Hm?lNb>Z34!1bDjpUCdkM=-9F1ruVWtDogNg^y zo5y{GeS|$O_#$2eugl&<(5jg(?QQ3z1=Uscb$wkuRXrz58_Oxn0u~EO@Dec!kV(Dx z<;X2V76#zo(D;3I_44+Pu-~-Qu3@E8S+FOoZpW7$yHFHGk)NLHMB&Ww%&f@Iio#d5 zK@^l;)EsIb>dIynu-qTQdQeG5V*}RFH?X=nYiuB$xx$NnL7bE%%2^uBou?|<{&h@< z;l!1`u^0Y6CT;d4bl?Lfj%YaF=M&;|?^m)I%I!VB1P-{gM|=|cCenw;SZwr3sJ&W? z0YrG%l#Yv52C;3h7kCGbkX~1U*mk4?!VN$6?ZFg^854>X^746UJ)M*Z&% zVSJ$yY-QPS|2THhp)*bXFO@LQiOQP%8sbUwJ5?9uInn%x%Y4R@YE!8jT2Q*N0s7x) jMkb&BFLQQ8`L60`DbPg0&&V)(N&KHG@!&Z#c1->ga(P%a From dd5accaba1c030c493583b06d4c6d5e4a3e9bf0d Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 27 Mar 2026 20:56:56 +0100 Subject: [PATCH 4/4] Fix speed for frequent cases --- Source/LuaBridge/detail/LuaHelpers.h | 51 ++++++++++++++++++---------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/Source/LuaBridge/detail/LuaHelpers.h b/Source/LuaBridge/detail/LuaHelpers.h index 6bd2d0ea..a8f6aae4 100644 --- a/Source/LuaBridge/detail/LuaHelpers.h +++ b/Source/LuaBridge/detail/LuaHelpers.h @@ -627,26 +627,33 @@ constexpr bool is_integral_representable_by(T value) if constexpr (sizeof(T) == sizeof(U)) { if constexpr (same_signedness) + { return true; - - if constexpr (std::is_unsigned_v) + } + else if constexpr (std::is_unsigned_v) + { return value <= static_cast((std::numeric_limits::max)()); - - return value >= static_cast((std::numeric_limits::min)()) - && static_cast(value) <= (std::numeric_limits::max)(); + } + else + { + return value >= static_cast((std::numeric_limits::min)()) + && static_cast(value) <= (std::numeric_limits::max)(); + } } - - if constexpr (sizeof(T) < sizeof(U)) + else if constexpr (sizeof(T) < sizeof(U)) { return static_cast(value) >= (std::numeric_limits::min)() && static_cast(value) <= (std::numeric_limits::max)(); } - - if constexpr (std::is_unsigned_v) + else if constexpr (std::is_unsigned_v) + { return value <= static_cast((std::numeric_limits::max)()); - - return value >= static_cast((std::numeric_limits::min)()) - && value <= static_cast((std::numeric_limits::max)()); + } + else + { + return value >= static_cast((std::numeric_limits::min)()) + && value <= static_cast((std::numeric_limits::max)()); + } } template @@ -665,18 +672,26 @@ bool is_integral_representable_by(lua_State* L, int index) template bool is_floating_point_representable_by(T value) { - if (std::isnan(value) || std::isinf(value)) - return true; - if constexpr (sizeof(T) == sizeof(U)) + { return true; + } + else if constexpr (sizeof(T) < sizeof(U)) + { + if (std::isnan(value) || std::isinf(value)) + return true; - if constexpr (sizeof(T) < sizeof(U)) return static_cast(value) >= -(std::numeric_limits::max)() && static_cast(value) <= (std::numeric_limits::max)(); + } + else + { + if (std::isnan(value) || std::isinf(value)) + return true; - return value >= static_cast(-(std::numeric_limits::max)()) - && value <= static_cast((std::numeric_limits::max)()); + return value >= static_cast(-(std::numeric_limits::max)()) + && value <= static_cast((std::numeric_limits::max)()); + } } template