diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWasm/AbstractMachine/Operators.h | 14 |
1 files changed, 10 insertions, 4 deletions
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<typename Lhs> - auto operator()(Lhs lhs) const + Result<Lhs, StringView> operator()(Lhs lhs) const { if constexpr (IsSame<Lhs, float>) return truncf(lhs); @@ -327,10 +327,13 @@ struct CheckedTruncate { else VERIFY_NOT_REACHED(); - if (NumericLimits<ResultT>::min() <= truncated && static_cast<double>(NumericLimits<ResultT>::max()) >= static_cast<double>(truncated)) - return static_cast<ResultT>(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<ResultT>(truncated)) + return "Truncation out of range"sv; - return "Truncation out of range"sv; + return static_cast<ResultT>(truncated); } static StringView name() { return "truncate.checked"; } @@ -424,6 +427,9 @@ struct SaturatingTruncate { return NumericLimits<ResultT>::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<ResultT>::min()) return NumericLimits<ResultT>::min(); |