summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-08-30 18:57:00 +0430
committerAndreas Kling <kling@serenityos.org>2021-08-30 22:47:02 +0200
commitf492e98f19c3a70b9204702181d20c46ed90896b (patch)
treeac770101f4d4e5a7a8e52d75929538a543bc573c /Userland
parent1465b11b58b1dc2125510ca722d9af87ba992d41 (diff)
downloadserenity-f492e98f19c3a70b9204702181d20c46ed90896b.zip
LibWasm: Make the Truncate operator trap on undefined results
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/Operators.h14
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();