1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:07:45 +00:00

LibWasm: Make the Truncate operator trap on undefined results

This commit is contained in:
Ali Mohammad Pur 2021-08-30 18:57:00 +04:30 committed by Andreas Kling
parent 1465b11b58
commit f492e98f19

View file

@ -259,7 +259,7 @@ struct Floor {
}; };
struct Truncate { struct Truncate {
template<typename Lhs> template<typename Lhs>
auto operator()(Lhs lhs) const Result<Lhs, StringView> operator()(Lhs lhs) const
{ {
if constexpr (IsSame<Lhs, float>) if constexpr (IsSame<Lhs, float>)
return truncf(lhs); return truncf(lhs);
@ -327,10 +327,13 @@ struct CheckedTruncate {
else else
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
if (NumericLimits<ResultT>::min() <= truncated && static_cast<double>(NumericLimits<ResultT>::max()) >= static_cast<double>(truncated)) // FIXME: This function assumes that all values of ResultT are representable in Lhs
return static_cast<ResultT>(truncated); // 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"; } static StringView name() { return "truncate.checked"; }
@ -424,6 +427,9 @@ struct SaturatingTruncate {
return NumericLimits<ResultT>::max(); 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) { constexpr auto convert = [](auto truncated_value) {
if (truncated_value < NumericLimits<ResultT>::min()) if (truncated_value < NumericLimits<ResultT>::min())
return NumericLimits<ResultT>::min(); return NumericLimits<ResultT>::min();