Skip to content

Commit f492e98

Browse files
alimpfardawesomekling
authored andcommitted
LibWasm: Make the Truncate operator trap on undefined results
1 parent 1465b11 commit f492e98

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

Userland/Libraries/LibWasm/AbstractMachine/Operators.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ struct Floor {
259259
};
260260
struct Truncate {
261261
template<typename Lhs>
262-
auto operator()(Lhs lhs) const
262+
Result<Lhs, StringView> operator()(Lhs lhs) const
263263
{
264264
if constexpr (IsSame<Lhs, float>)
265265
return truncf(lhs);
@@ -327,10 +327,13 @@ struct CheckedTruncate {
327327
else
328328
VERIFY_NOT_REACHED();
329329

330-
if (NumericLimits<ResultT>::min() <= truncated && static_cast<double>(NumericLimits<ResultT>::max()) >= static_cast<double>(truncated))
331-
return static_cast<ResultT>(truncated);
330+
// FIXME: This function assumes that all values of ResultT are representable in Lhs
331+
// the assumption comes from the fact that this was used exclusively by LibJS,
332+
// which only considers values that are all representable in 'double'.
333+
if (!AK::is_within_range<ResultT>(truncated))
334+
return "Truncation out of range"sv;
332335

333-
return "Truncation out of range"sv;
336+
return static_cast<ResultT>(truncated);
334337
}
335338

336339
static StringView name() { return "truncate.checked"; }
@@ -424,6 +427,9 @@ struct SaturatingTruncate {
424427
return NumericLimits<ResultT>::max();
425428
}
426429

430+
// FIXME: This assumes that all values in ResultT are representable in 'double'.
431+
// that assumption is not correct, which makes this function yield incorrect values
432+
// for 'edge' values of type i64.
427433
constexpr auto convert = [](auto truncated_value) {
428434
if (truncated_value < NumericLimits<ResultT>::min())
429435
return NumericLimits<ResultT>::min();

0 commit comments

Comments
 (0)