From 8c8310f0bddc874a9f7f07c4158f0abc799357d4 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Tue, 16 Jul 2024 14:02:21 +0200 Subject: [PATCH] LibWasm: Make Absolute/Negate explicitly work mod 2^N Previously we relied on signed overflow, this commit makes the same behaviour explicit (avoiding UB in the process). --- .../LibWasm/AbstractMachine/Operators.h | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Operators.h b/Userland/Libraries/LibWasm/AbstractMachine/Operators.h index 5698b39386e..aa2d71ea5bf 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Operators.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/Operators.h @@ -505,14 +505,36 @@ struct PopCount { struct Absolute { template - auto operator()(Lhs lhs) const { return AK::abs(lhs); } + Lhs operator()(Lhs lhs) const + { + if constexpr (IsFloatingPoint) + return AK::abs(lhs); + + if constexpr (IsSigned) { + if (lhs == NumericLimits::min()) + return NumericLimits::min(); // Return the negation of _i_ modulo 2^N: https://www.w3.org/TR/wasm-core-2/#-hrefop-iabsmathrmiabs_n-i step 3 + } + + return AK::abs(lhs); + } static StringView name() { return "abs"sv; } }; struct Negate { template - auto operator()(Lhs lhs) const { return -lhs; } + Lhs operator()(Lhs lhs) const + { + if constexpr (IsFloatingPoint) + return -lhs; + + if constexpr (IsSigned) { + if (lhs == NumericLimits::min()) + return NumericLimits::min(); // Return the negation of _i_ modulo 2^N: https://www.w3.org/TR/wasm-core-2/#-hrefop-iabsmathrmiabs_n-i step 3 + } + + return -lhs; + } static StringView name() { return "== 0"sv; } };