Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ pub use self::{
typed::{Typed, TypedVal},
units::Pages,
untyped::{DecodeUntypedSlice, EncodeUntypedSlice, UntypedError, UntypedVal},
value::ValType,
value::{CanonicalizeNan, ValType},
};
20 changes: 20 additions & 0 deletions crates/core/src/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,19 +299,23 @@ impl TypedVal {

fn f32_abs(f32) -> f32;
fn f32_neg(f32) -> f32;
fn f32_neg_canonicalize_nan(f32) -> f32;
fn f32_ceil(f32) -> f32;
fn f32_floor(f32) -> f32;
fn f32_trunc(f32) -> f32;
fn f32_nearest(f32) -> f32;
fn f32_sqrt(f32) -> f32;
fn f32_sqrt_canonicalize_nan(f32) -> f32;

fn f64_abs(f64) -> f64;
fn f64_neg(f64) -> f64;
fn f64_neg_canonicalize_nan(f64) -> f64;
fn f64_ceil(f64) -> f64;
fn f64_floor(f64) -> f64;
fn f64_trunc(f64) -> f64;
fn f64_nearest(f64) -> f64;
fn f64_sqrt(f64) -> f64;
fn f64_sqrt_canonicalize_nan(f64) -> f64;

fn f32_add(f32, f32) -> f32;
fn f32_sub(f32, f32) -> f32;
Expand All @@ -321,6 +325,14 @@ impl TypedVal {
fn f32_max(f32, f32) -> f32;
fn f32_copysign(f32, f32) -> f32;

fn f32_add_canonicalize_nan(f32, f32) -> f32;
fn f32_sub_canonicalize_nan(f32, f32) -> f32;
fn f32_mul_canonicalize_nan(f32, f32) -> f32;
fn f32_div_canonicalize_nan(f32, f32) -> f32;
fn f32_min_canonicalize_nan(f32, f32) -> f32;
fn f32_max_canonicalize_nan(f32, f32) -> f32;
fn f32_copysign_canonicalize_nan(f32, f32) -> f32;

fn f64_add(f64, f64) -> f64;
fn f64_sub(f64, f64) -> f64;
fn f64_mul(f64, f64) -> f64;
Expand All @@ -329,6 +341,14 @@ impl TypedVal {
fn f64_max(f64, f64) -> f64;
fn f64_copysign(f64, f64) -> f64;

fn f64_add_canonicalize_nan(f64, f64) -> f64;
fn f64_sub_canonicalize_nan(f64, f64) -> f64;
fn f64_mul_canonicalize_nan(f64, f64) -> f64;
fn f64_div_canonicalize_nan(f64, f64) -> f64;
fn f64_min_canonicalize_nan(f64, f64) -> f64;
fn f64_max_canonicalize_nan(f64, f64) -> f64;
fn f64_copysign_canonicalize_nan(f64, f64) -> f64;

// Conversions

fn i32_wrap_i64(i64) -> i32;
Expand Down
121 changes: 120 additions & 1 deletion crates/core/src/untyped.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
value::{LoadInto, StoreFrom},
ArithmeticOps,
CanonicalizeNan,
ExtendInto,
Float,
Integer,
Expand Down Expand Up @@ -931,6 +932,11 @@
self.execute_unary(<f32 as Neg>::neg)
}

/// Execute `f32.neg` Wasm operation.
pub fn f32_neg_canonicalize_nan(self) -> Self {
self.execute_unary(|value| <f32 as Neg>::neg(value).canonicalize_nan())

Check warning on line 937 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L936-L937

Added lines #L936 - L937 were not covered by tests
}

/// Execute `f32.ceil` Wasm operation.
pub fn f32_ceil(self) -> Self {
self.execute_unary(<f32 as Float>::ceil)
Expand All @@ -953,7 +959,12 @@

/// Execute `f32.sqrt` Wasm operation.
pub fn f32_sqrt(self) -> Self {
self.execute_unary(<f32 as Float>::sqrt)
self.execute_unary(<F32 as Float>::sqrt)
}

/// Execute `f32.sqrt` Wasm operation.
pub fn f32_sqrt_canonicalize_nan(self) -> Self {
self.execute_unary(|value| <f32 as Float>::sqrt(value).canonicalize_nan())

Check warning on line 967 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L966-L967

Added lines #L966 - L967 were not covered by tests
}

/// Execute `f64.abs` Wasm operation.
Expand All @@ -966,6 +977,11 @@
self.execute_unary(<f64 as Neg>::neg)
}

/// Execute `f64.neg` Wasm operation.
pub fn f64_neg_canonicalize_nan(self) -> Self {
self.execute_unary(|value| <f64 as Neg>::neg(value).canonicalize_nan())

Check warning on line 982 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L981-L982

Added lines #L981 - L982 were not covered by tests
}

/// Execute `f64.ceil` Wasm operation.
pub fn f64_ceil(self) -> Self {
self.execute_unary(<f64 as Float>::ceil)
Expand All @@ -991,76 +1007,179 @@
self.execute_unary(<f64 as Float>::sqrt)
}

/// Execute `f64.sqrt` Wasm operation.
pub fn f64_sqrt_canonicalize_nan(self) -> Self {
self.execute_unary(|value| <f64 as Float>::sqrt(value).canonicalize_nan())

Check warning on line 1012 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1011-L1012

Added lines #L1011 - L1012 were not covered by tests
}

/// Execute `f32.add` Wasm operation.
pub fn f32_add(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f32 as ArithmeticOps>::add)
}

/// Execute `f32.add` Wasm operation with NaN canonicalization.
pub fn f32_add_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as ArithmeticOps>::add(lhs, rhs).canonicalize_nan()

Check warning on line 1023 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1021-L1023

Added lines #L1021 - L1023 were not covered by tests
})
}

/// Execute `f64.add` Wasm operation.
pub fn f64_add(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f64 as ArithmeticOps>::add)
}

/// Execute `f64.add` Wasm operation with NaN canonicalization.
pub fn f64_add_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as ArithmeticOps>::add(lhs, rhs).canonicalize_nan()

Check warning on line 1035 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1033-L1035

Added lines #L1033 - L1035 were not covered by tests
})
}

/// Execute `f32.sub` Wasm operation.
pub fn f32_sub(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f32 as ArithmeticOps>::sub)
}

/// Execute `f32.sub` Wasm operation with NaN canonicalization.
pub fn f32_sub_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as ArithmeticOps>::sub(lhs, rhs).canonicalize_nan()

Check warning on line 1047 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1045-L1047

Added lines #L1045 - L1047 were not covered by tests
})
}

/// Execute `f64.sub` Wasm operation.
pub fn f64_sub(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f64 as ArithmeticOps>::sub)
}

/// Execute `f64.sub` Wasm operation with NaN canonicalization.
pub fn f64_sub_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as ArithmeticOps>::sub(lhs, rhs).canonicalize_nan()

Check warning on line 1059 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1057-L1059

Added lines #L1057 - L1059 were not covered by tests
})
}

/// Execute `f32.mul` Wasm operation.
pub fn f32_mul(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f32 as ArithmeticOps>::mul)
}

/// Execute `f32.mul` Wasm operation with NaN canonicalization.
pub fn f32_mul_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as ArithmeticOps>::mul(lhs, rhs).canonicalize_nan()

Check warning on line 1071 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1069-L1071

Added lines #L1069 - L1071 were not covered by tests
})
}

/// Execute `f64.mul` Wasm operation.
pub fn f64_mul(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f64 as ArithmeticOps>::mul)
}

/// Execute `f64.mul` Wasm operation with NaN canonicalization.
pub fn f64_mul_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as ArithmeticOps>::mul(lhs, rhs).canonicalize_nan()

Check warning on line 1083 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1081-L1083

Added lines #L1081 - L1083 were not covered by tests
})
}

/// Execute `f32.div` Wasm operation.
pub fn f32_div(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f32 as Float>::div)
}

/// Execute `f32.div` Wasm operation with NaN canonicalization.
pub fn f32_div_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as Float>::div(lhs, rhs).canonicalize_nan()

Check warning on line 1095 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1093-L1095

Added lines #L1093 - L1095 were not covered by tests
})
}

/// Execute `f64.div` Wasm operation.
pub fn f64_div(self, rhs: Self) -> Self {
self.execute_binary(rhs, <f64 as Float>::div)
}

/// Execute `f64.div` Wasm operation with NaN canonicalization.
pub fn f64_div_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as Float>::div(lhs, rhs).canonicalize_nan()

Check warning on line 1107 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1105-L1107

Added lines #L1105 - L1107 were not covered by tests
})
}

/// Execute `f32.min` Wasm operation.
pub fn f32_min(self, other: Self) -> Self {
self.execute_binary(other, <f32 as Float>::min)
}

/// Execute `f32.min` Wasm operation with NaN canonicalization.
pub fn f32_min_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as Float>::min(lhs, rhs).canonicalize_nan()

Check warning on line 1119 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1117-L1119

Added lines #L1117 - L1119 were not covered by tests
})
}

/// Execute `f64.min` Wasm operation.
pub fn f64_min(self, other: Self) -> Self {
self.execute_binary(other, <f64 as Float>::min)
}

/// Execute `f64.min` Wasm operation with NaN canonicalization.
pub fn f64_min_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as Float>::min(lhs, rhs).canonicalize_nan()

Check warning on line 1131 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1129-L1131

Added lines #L1129 - L1131 were not covered by tests
})
}

/// Execute `f32.max` Wasm operation.
pub fn f32_max(self, other: Self) -> Self {
self.execute_binary(other, <f32 as Float>::max)
}

/// Execute `f32.max` Wasm operation with NaN canonicalization.
pub fn f32_max_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as Float>::max(lhs, rhs).canonicalize_nan()

Check warning on line 1143 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1141-L1143

Added lines #L1141 - L1143 were not covered by tests
})
}

/// Execute `f64.max` Wasm operation.
pub fn f64_max(self, other: Self) -> Self {
self.execute_binary(other, <f64 as Float>::max)
}

/// Execute `f64.max` Wasm operation with NaN canonicalization.
pub fn f64_max_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as Float>::max(lhs, rhs).canonicalize_nan()

Check warning on line 1155 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1153-L1155

Added lines #L1153 - L1155 were not covered by tests
})
}

/// Execute `f32.copysign` Wasm operation.
pub fn f32_copysign(self, other: Self) -> Self {
self.execute_binary(other, <f32 as Float>::copysign)
}

/// Execute `f32.copysign` Wasm operation with NaN canonicalization.
pub fn f32_copysign_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f32 as Float>::copysign(lhs, rhs).canonicalize_nan()

Check warning on line 1167 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1165-L1167

Added lines #L1165 - L1167 were not covered by tests
})
}

/// Execute `f64.copysign` Wasm operation.
pub fn f64_copysign(self, other: Self) -> Self {
self.execute_binary(other, <f64 as Float>::copysign)
}

/// Execute `f64.copysign` Wasm operation with NaN canonicalization.
pub fn f64_copysign_canonicalize_nan(self, rhs: Self) -> Self {
self.execute_binary(rhs, |lhs, rhs| {
<f64 as Float>::copysign(lhs, rhs).canonicalize_nan()

Check warning on line 1179 in crates/core/src/untyped.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/untyped.rs#L1177-L1179

Added lines #L1177 - L1179 were not covered by tests
})
}

/// Execute `i32.wrap_i64` Wasm operation.
pub fn i32_wrap_i64(self) -> Self {
self.execute_unary(<i64 as WrapInto<i32>>::wrap_into)
Expand Down
31 changes: 31 additions & 0 deletions crates/core/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,3 +791,34 @@
)
}
}

/// Trait implemented by floating point types for NaN canonicalization.
pub trait CanonicalizeNan {
/// Canonicalizes `self` if it is NaN.
fn canonicalize_nan(self) -> Self;
}

macro_rules! impl_caninocalize_nan {
( $( $ty:ty as $nan_val:literal),* $(,)? ) => {
$(
impl CanonicalizeNan for $ty {
fn canonicalize_nan(self) -> Self {
if self.is_nan() {
let canonicalized = Self::from_bits($nan_val);
debug_assert!(canonicalized.is_nan());
return canonicalized

Check warning on line 809 in crates/core/src/value.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/value.rs#L805-L809

Added lines #L805 - L809 were not covered by tests
}
self

Check warning on line 811 in crates/core/src/value.rs

View check run for this annotation

Codecov / codecov/patch

crates/core/src/value.rs#L811

Added line #L811 was not covered by tests
}
}
)*
};
}
impl_caninocalize_nan! {
// Note: These patterns ensures that the sign bit can be either 0 or 1,
// the exponent bits are all set to 1 (indicating an infinity or NaN),
// and the fraction (mantissa) bits are all zero, except the most significant bit
// of the fraction is set to 1 to indicate a quiet NaN.
f32 as 0x7FC00000_u32,
f64 as 0x7FF8000000000000_u64,
}
Loading
Loading