瀏覽代碼

LibWasm: Make the Truncate operator trap on undefined results

Ali Mohammad Pur 3 年之前
父節點
當前提交
f492e98f19
共有 1 個文件被更改,包括 10 次插入4 次删除
  1. 10 4
      Userland/Libraries/LibWasm/AbstractMachine/Operators.h

+ 10 - 4
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();