diff options
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | Cargo.lock | 20 | ||||
| -rw-r--r-- | crates/tinywasm/Cargo.toml | 10 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/num_helpers.rs | 29 |
4 files changed, 47 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index e63ff2b..8c47dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the custom memory page sizes proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14)) - Support for the `tail_call` proposal +- Support for the `memory64` proposal +- Groundwork for the `simd` proposal +- New `canonicalize_nans` feature flag to enable canonicalizing NaN values in the `f32`, `f64`, and `v128` types ### Breaking Changes @@ -114,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstyle", "clap_lex", @@ -353,15 +353,15 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libm" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" [[package]] name = "log" @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 3281476..10a3099 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -32,12 +32,20 @@ serde_json={version="1.0"} serde={version="1.0", features=["derive"]} [features] -default=["std", "parser", "logging", "archive"] +default=["std", "parser", "logging", "archive", "canonicalize_nans"] + logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] + +# support for parsing WebAssembly parser=["dep:tinywasm-parser"] + +# support for "archiving" tinywasm bytecode archive=["tinywasm-types/archive"] +# canonicalize all NaN values to a single representation +canonicalize_nans=[] + # enable simd support (unstable / unfinished) __simd=[] diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index 678c32e..7e8a461 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -72,9 +72,12 @@ macro_rules! impl_wasm_float_ops { ($($t:ty)*) => ($( impl TinywasmFloatExt for $t { // https://webassembly.github.io/spec/core/exec/numerics.html#op-fnearest + #[inline] fn tw_nearest(self) -> Self { match self { - // x if x.is_nan() => x, // preserve NaN + #[cfg(not(feature = "canonicalize_nans"))] + x if x.is_nan() => x, // preserve NaN + #[cfg(feature = "canonicalize_nans")] x if x.is_nan() => Self::NAN, // Do not preserve NaN x if x.is_infinite() || x == 0.0 => x, // preserve infinities and zeros x if (0.0..=0.5).contains(&x) => 0.0, @@ -100,7 +103,9 @@ macro_rules! impl_wasm_float_ops { Some(core::cmp::Ordering::Less) => self, Some(core::cmp::Ordering::Greater) => other, Some(core::cmp::Ordering::Equal) => if self.is_sign_negative() && other.is_sign_positive() { self } else { other }, - // None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(not(feature = "canonicalize_nans"))] + None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(feature = "canonicalize_nans")] None => Self::NAN, // Do not preserve NaN } } @@ -113,7 +118,9 @@ macro_rules! impl_wasm_float_ops { Some(core::cmp::Ordering::Greater) => self, Some(core::cmp::Ordering::Less) => other, Some(core::cmp::Ordering::Equal) => if self.is_sign_negative() && other.is_sign_positive() { other } else { self }, - // None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(not(feature = "canonicalize_nans"))] + None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(feature = "canonicalize_nans")] None => Self::NAN, // Do not preserve NaN } } @@ -184,8 +191,15 @@ macro_rules! impl_checked_wrapping_rem { impl_checked_wrapping_rem! { i32 i64 u32 u64 } -#[cfg(feature = "__simd")] +#[cfg(all(feature = "__simd", not(feature = "canonicalize_nans")))] +#[inline] +pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { + x // No need to do anything, as we are not replacing NaNs +} + +#[cfg(all(feature = "__simd", feature = "canonicalize_nans"))] /// replace all NaNs in a f32x4 with f32::NAN +#[inline] pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { use core::simd::{Simd, num::SimdFloat}; let nan = Simd::splat(f32::NAN); @@ -193,8 +207,15 @@ pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { mask.select(nan, x) } +#[cfg(all(feature = "__simd", not(feature = "canonicalize_nans")))] +#[inline] +pub(crate) fn canonicalize_f64x2(x: core::simd::f64x2) -> core::simd::f64x2 { + x // No need to do anything, as we are not replacing NaNs +} + #[cfg(feature = "__simd")] /// replace all NaNs in a f64x2 with f64::NAN +#[inline] pub(crate) fn canonicalize_f64x2(x: core::simd::f64x2) -> core::simd::f64x2 { use core::simd::{Simd, num::SimdFloat}; let nan = Simd::splat(f64::NAN); |
