diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Operators.h b/Userland/Libraries/LibWasm/AbstractMachine/Operators.h index aac34ce7c6..44692d9d23 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Operators.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/Operators.h @@ -259,7 +259,7 @@ struct Floor { }; struct Truncate { template - auto operator()(Lhs lhs) const + Result operator()(Lhs lhs) const { if constexpr (IsSame) return truncf(lhs); @@ -327,10 +327,13 @@ struct CheckedTruncate { else VERIFY_NOT_REACHED(); - if (NumericLimits::min() <= truncated && static_cast(NumericLimits::max()) >= static_cast(truncated)) - return static_cast(truncated); + // FIXME: This function assumes that all values of ResultT are representable in Lhs + // the assumption comes from the fact that this was used exclusively by LibJS, + // which only considers values that are all representable in 'double'. + if (!AK::is_within_range(truncated)) + return "Truncation out of range"sv; - return "Truncation out of range"sv; + return static_cast(truncated); } static StringView name() { return "truncate.checked"; } @@ -424,6 +427,9 @@ struct SaturatingTruncate { return NumericLimits::max(); } + // FIXME: This assumes that all values in ResultT are representable in 'double'. + // that assumption is not correct, which makes this function yield incorrect values + // for 'edge' values of type i64. constexpr auto convert = [](auto truncated_value) { if (truncated_value < NumericLimits::min()) return NumericLimits::min();