From f7f77cd3026e39a2c29faf539575ef57165c81db Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 27 Nov 2025 22:11:43 +0100 Subject: chore: remove unstable-simd feature, rename logging feature to log Signed-off-by: Henry Gressmann --- Cargo.lock | 216 +++-- Cargo.toml | 10 +- README.md | 2 +- crates/parser/Cargo.toml | 4 +- crates/parser/README.md | 2 +- crates/parser/src/lib.rs | 5 +- crates/parser/src/visit.rs | 2 +- crates/tinywasm/Cargo.toml | 7 +- crates/tinywasm/src/instance.rs | 4 +- crates/tinywasm/src/interpreter/executor.rs | 915 ++++++++++----------- crates/tinywasm/src/interpreter/mod.rs | 4 +- crates/tinywasm/src/interpreter/no_std_floats.rs | 1 + crates/tinywasm/src/interpreter/num_helpers.rs | 32 - .../tinywasm/src/interpreter/stack/call_stack.rs | 2 +- .../tinywasm/src/interpreter/stack/value_stack.rs | 7 +- crates/tinywasm/src/interpreter/value128.rs | 76 ++ crates/tinywasm/src/interpreter/values.rs | 46 +- crates/tinywasm/src/lib.rs | 7 +- crates/tinywasm/src/store/memory.rs | 25 - crates/tinywasm/src/store/mod.rs | 14 +- crates/types/Cargo.toml | 4 +- crates/types/src/archive.rs | 1 - crates/types/src/lib.rs | 4 +- 23 files changed, 674 insertions(+), 716 deletions(-) create mode 100644 crates/tinywasm/src/interpreter/value128.rs diff --git a/Cargo.lock b/Cargo.lock index 39e9f07..2547a99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -63,9 +63,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bumpalo" @@ -81,9 +81,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "ciborium" @@ -114,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstyle", "clap_lex", @@ -133,9 +133,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cobs" @@ -258,19 +258,20 @@ dependencies = [ [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hermit-abi" @@ -311,9 +312,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.11.4" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown", @@ -321,13 +322,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -353,9 +354,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.176" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libm" @@ -426,18 +427,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -464,9 +465,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -476,9 +477,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -487,9 +488,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rust-fuzzy-search" @@ -563,9 +564,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.106" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -627,7 +628,7 @@ dependencies = [ "tinywasm-parser", "tinywasm-types", "wasm-testsuite", - "wast", + "wast 242.0.0", "wat", ] @@ -640,7 +641,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", - "wast", + "wast 242.0.0", ] [[package]] @@ -649,7 +650,7 @@ version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", - "wasmparser", + "wasmparser 0.242.0", ] [[package]] @@ -673,15 +674,15 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "walkdir" @@ -700,7 +701,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be00faa2b4950c76fe618c409d2c3ea5a3c9422013e079482d78544bb2d184c" dependencies = [ "leb128fmt", - "wasmparser", + "wasmparser 0.239.0", +] + +[[package]] +name = "wasm-encoder" +version = "0.242.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67f90e55bc9c6ee6954a757cc6eb3424d96b442e5252ed10fea627e518878d36" +dependencies = [ + "leb128fmt", + "wasmparser 0.242.0", ] [[package]] @@ -710,7 +721,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bc4691cd6c251229ed1580c7547800f4ffb4ec9586d7ed5f2a6e1f130d65aa5" dependencies = [ "include_dir", - "wast", + "wast 239.0.0", ] [[package]] @@ -724,6 +735,17 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.242.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3c6e611f4cd748d85c767815823b777dc56afca793fcda27beae4e85028849" +dependencies = [ + "bitflags", + "indexmap", + "semver", +] + [[package]] name = "wast" version = "239.0.0" @@ -734,16 +756,29 @@ dependencies = [ "leb128fmt", "memchr", "unicode-width", - "wasm-encoder", + "wasm-encoder 0.239.0", +] + +[[package]] +name = "wast" +version = "242.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50a61ae2997784a4ae2a47b3a99f7cf0ad2a54db09624a28a0c2e9d7a24408ce" +dependencies = [ + "bumpalo", + "leb128fmt", + "memchr", + "unicode-width", + "wasm-encoder 0.242.0", ] [[package]] name = "wat" -version = "1.239.0" +version = "1.242.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1c941927d34709f255558166f8901a2005f8ab4a9650432e9281b7cc6f3b75" +checksum = "5ae8cf6adfb79b5d89cb3fe68bd56aaab9409d9cf23b588097eae7d75585dae2" dependencies = [ - "wast", + "wast 242.0.0", ] [[package]] @@ -752,93 +787,40 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.1", + "windows-sys", ] [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets", + "windows-link", ] [[package]] -name = "windows-sys" -version = "0.61.1" +name = "zerocopy" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" dependencies = [ - "windows-link", + "zerocopy-derive", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "zerocopy-derive" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "proc-macro2", + "quote", + "syn", ] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 7770272..443c8d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,22 +4,22 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="239" -wat="1.239" -wasmparser={version="0.239", default-features=false} +wast="242" +wat="1.242" +wasmparser={version="0.242", default-features=false} eyre="0.6" log="0.4" pretty_env_logger="0.5" criterion={version="0.7", default-features=false, features=["cargo_bench_support", "rayon"]} wasm-testsuite={version="0.5"} -indexmap="2.11" +indexmap="2.12" owo-colors={version="4.2"} serde_json={version="1.0"} serde={version="1.0", features=["derive"]} [workspace.package] version="0.9.0-alpha.0" -rust-version="1.90" +rust-version="1.91" edition="2024" license="MIT OR Apache-2.0" authors=["Henry Gressmann "] diff --git a/README.md b/README.md index ee1028f..29b019f 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ $ tinywasm-cli --help - **`std`**\ Enables the use of `std` and `std::io` for parsing from files and streams. This is enabled by default. -- **`logging`**\ +- **`log`**\ Enables logging using the `log` crate. This is enabled by default. - **`parser`**\ Enables the `tinywasm-parser` crate. This is enabled by default. diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 3cbeee1..598a5b7 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -16,6 +16,6 @@ log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} [features] -default=["std", "logging"] -logging=["log"] +default=["std", "log"] +log=["dep:log"] std=["tinywasm-types/std", "wasmparser/std"] diff --git a/crates/parser/README.md b/crates/parser/README.md index 563cd6b..104cd50 100644 --- a/crates/parser/README.md +++ b/crates/parser/README.md @@ -6,7 +6,7 @@ It uses [my fork](https://crates.io/crates/tinywasm-wasmparser) of the [`wasmpar ## Features - `std`: Enables the use of `std` and `std::io` for parsing from files and streams. -- `logging`: Enables logging of the parsing process using the `log` crate. +- `log`: Enables logging of the parsing process using the `log` crate. ## Usage diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 3f45db8..3f543b6 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -13,12 +13,12 @@ extern crate alloc; extern crate std; // log for logging (optional). -#[cfg(feature = "logging")] +#[cfg(feature = "log")] #[allow(clippy::single_component_path_imports, unused_imports)] use log; // noop fallback if logging is disabled. -#[cfg(not(feature = "logging"))] +#[cfg(not(feature = "log"))] #[allow(unused_imports, unused_macros)] pub(crate) mod log { macro_rules! debug ( ($($tt:tt)*) => {{}} ); @@ -67,6 +67,7 @@ impl Parser { bulk_memory_opt: true, call_indirect_overlong: true, + custom_descriptors: false, cm_threading: false, extended_const: false, wide_arithmetic: false, diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 4ae2cc1..9b9ab75 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -158,7 +158,7 @@ macro_rules! impl_visit_operator { (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { #[cold] - fn $visit(&mut self $($(,$arg: $argty)*)?) { + fn $visit(&mut self $($(,_: $argty)*)?) { self.unsupported(stringify!($visit)) } }; diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 2315b9b..d1a0839 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -34,9 +34,9 @@ serde_json.workspace=true serde.workspace=true [features] -default=["std", "parser", "logging", "archive", "canonicalize_nans"] +default=["std", "parser", "log", "archive", "canonicalize_nans"] -logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] +log=["dep:log", "tinywasm-parser?/log", "tinywasm-types/log"] std=["tinywasm-parser?/std", "tinywasm-types/std"] # support for parsing WebAssembly @@ -48,9 +48,6 @@ archive=["tinywasm-types/archive"] # canonicalize all NaN values to a single representation canonicalize_nans=[] -# enable simd support (unstable / unfinished) -unstable-simd=[] - [[test]] name="test-wasm-1" harness=false diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index aaa3407..0ca8f6f 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -4,7 +4,7 @@ use tinywasm_types::*; use crate::func::{FromWasmValueTuple, IntoWasmValueTuple}; use crate::{Error, FuncHandle, FuncHandleTyped, Imports, MemoryRef, MemoryRefMut, Module, Result, Store}; -/// An instanciated WebAssembly module +/// An instantiated WebAssembly module /// /// Backed by an Rc, so cloning is cheap /// @@ -72,7 +72,7 @@ impl ModuleInstance { let global_addrs = store.init_globals(addrs.globals, module.0.globals.into(), &addrs.funcs, idx)?; let (elem_addrs, elem_trapped) = store.init_elements(&addrs.tables, &addrs.funcs, &global_addrs, &module.0.elements, idx)?; - let (data_addrs, data_trapped) = store.init_datas(&addrs.memories, module.0.data.into(), idx)?; + let (data_addrs, data_trapped) = store.init_data(&addrs.memories, module.0.data.into(), idx)?; let instance = ModuleInstanceInner { failed_to_instantiate: elem_trapped.is_some() || data_trapped.is_some(), diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 2e979bc..8033a4e 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -8,17 +8,10 @@ use core::ops::ControlFlow; use interpreter::stack::CallFrame; use tinywasm_types::*; -#[cfg(all(feature = "std", feature = "unstable-simd"))] -use crate::std::simd::StdFloat; -#[cfg(feature = "unstable-simd")] -use core::simd::{cmp::*, num::*, *}; - -#[cfg(feature = "unstable-simd")] -use core::ops::{Index, IndexMut, Shl, Shr}; - use super::num_helpers::*; use super::stack::{BlockFrame, BlockType, Stack}; use super::values::*; +use crate::interpreter::Value128; use crate::*; pub(crate) struct Executor<'store, 'stack> { @@ -316,410 +309,410 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), - #[cfg(feature = "unstable-simd")] V128Not => self.stack.values.replace_top_same::(|v| Ok(!v)).to_cf()?, - #[cfg(feature = "unstable-simd")] V128And => self.stack.values.calculate_same::(|a, b| Ok(a & b)).to_cf()?, - #[cfg(feature = "unstable-simd")] V128AndNot => self.stack.values.calculate_same::(|a, b| Ok(a & (!b))).to_cf()?, - #[cfg(feature = "unstable-simd")] V128Or => self.stack.values.calculate_same::(|a, b| Ok(a | b)).to_cf()?, - #[cfg(feature = "unstable-simd")] V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, - #[cfg(feature = "unstable-simd")] V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, - #[cfg(feature = "unstable-simd")] V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_or() != 0) as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, - - #[cfg(feature = "unstable-simd")] V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, - #[cfg(feature = "unstable-simd")] V128Load8x8S(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load8x8U(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load16x4S(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load16x4U(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load32x2S(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load32x2U(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load8Splat(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load16Splat(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load32Splat(_arg) => unimplemented!(), - #[cfg(feature = "unstable-simd")] V128Load64Splat(_arg) => unimplemented!(), - - #[cfg(feature = "unstable-simd")] V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, - - #[cfg(feature = "unstable-simd")] V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - #[cfg(feature = "unstable-simd")] V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - #[cfg(feature = "unstable-simd")] V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - #[cfg(feature = "unstable-simd")] V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - - // Load a single 32-bit or 64-bit element into the lowest bits of a v128 vector, and initialize all other bits of the v128 vector to zero. - #[cfg(feature = "unstable-simd")] V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { - let bytes = v.to_le_bytes(); - u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) - })?, - #[cfg(feature = "unstable-simd")] V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { - let bytes = v.to_le_bytes(); - u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 0, 0, 0, 0, 0, 0, 0, 0]) - })?, - - #[cfg(feature = "unstable-simd")] V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), - - #[cfg(feature = "unstable-simd")] I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - - #[cfg(feature = "unstable-simd")] V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - #[cfg(feature = "unstable-simd")] V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - #[cfg(feature = "unstable-simd")] V128Load32Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - #[cfg(feature = "unstable-simd")] V128Load64Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - - #[cfg(feature = "unstable-simd")] I8x16ReplaceLane(_lane) => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ReplaceLane(_lane) => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ReplaceLane(_lane) => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ReplaceLane(_lane) => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4ReplaceLane(_lane) => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2ReplaceLane(_lane) => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] F32x4Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i8))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i16))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a))).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i64))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i8))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i16))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a))).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i64))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u8))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u16))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u32))).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u64))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16NarrowI16x8S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I8x16NarrowI16x8U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8NarrowI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8NarrowI32x4U => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I8x16AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - #[cfg(feature = "unstable-simd")] I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - - #[cfg(feature = "unstable-simd")] I8x16AvgrU => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8AvgrU => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I16x8ExtAddPairwiseI8x16S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtAddPairwiseI8x16U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtAddPairwiseI16x8S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtAddPairwiseI16x8U => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I16x8ExtMulLowI8x16S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtMulLowI8x16U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtMulHighI8x16S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtMulHighI8x16U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtMulLowI16x8S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtMulLowI16x8U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtMulHighI16x8S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtMulHighI16x8U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtMulLowI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtMulLowI32x4U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtMulHighI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtMulHighI32x4U => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I16x8ExtendLowI8x16S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtendLowI8x16U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtendHighI8x16S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8ExtendHighI8x16U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtendLowI16x8S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtendLowI16x8U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtendHighI16x8S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4ExtendHighI16x8U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtendLowI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtendLowI32x4U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtendHighI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2ExtendHighI32x4U => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I8x16Popcnt => self.stack.values.replace_top::(|v| Ok(v.count_ones())).to_cf()?, - #[cfg(feature = "unstable-simd")] I8x16Shuffle(_idx) => unimplemented!(), - - #[cfg(feature = "unstable-simd")] - I16x8Q15MulrSatS => self.stack.values.calculate_same::(|a, b| { - let subq15mulr = |a,b| { - let a = a as i32; - let b = b as i32; - let r = (a * b + 0x4000) >> 15; - if r > i16::MAX as i32 { - i16::MAX - } else if r < i16::MIN as i32 { - i16::MIN - } else { - r as i16 - } - }; - Ok(Simd::::from_array([ - subq15mulr(a[0], b[0]), - subq15mulr(a[1], b[1]), - subq15mulr(a[2], b[2]), - subq15mulr(a[3], b[3]), - subq15mulr(a[4], b[4]), - subq15mulr(a[5], b[5]), - subq15mulr(a[6], b[6]), - subq15mulr(a[7], b[7]), - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - I32x4DotI16x8S => self.stack.values.calculate::(|a, b| { - Ok(Simd::::from_array([ - i32::from(a[0] * b[0] + a[1] * b[1]), - i32::from(a[2] * b[2] + a[3] * b[3]), - i32::from(a[4] * b[4] + a[5] * b[5]), - i32::from(a[6] * b[6] + a[7] * b[7]), - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Nearest => self.stack.values.replace_top_same::(|v| Ok(v.round())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Nearest => self.stack.values.replace_top_same::(|v| Ok(v.round())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f32x4(v.sqrt()))).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f64x2(v.sqrt()))).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a + b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a + b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a - b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a - b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a * b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a * b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a / b))).to_cf()?, - #[cfg(feature = "unstable-simd")] F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a / b))).to_cf()?, - #[cfg(feature = "unstable-simd")] - F32x4Min => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - b[0].tw_minimum(a[0]), - b[1].tw_minimum(a[1]), - b[2].tw_minimum(a[2]), - b[3].tw_minimum(a[3]), - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F64x2Min => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - b[0].tw_minimum(a[0]), - b[1].tw_minimum(a[1]), - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F32x4Max => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - b[0].tw_maximum(a[0]), - b[1].tw_maximum(a[1]), - b[2].tw_maximum(a[2]), - b[3].tw_maximum(a[3]), - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F64x2Max => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - b[0].tw_maximum(a[0]), - b[1].tw_maximum(a[1]), - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F32x4PMin => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - if b[0] < a[0] { b[0] } else { a[0]}, - if b[1] < a[1] { b[1] } else { a[1]}, - if b[2] < a[2] { b[2] } else { a[2]}, - if b[3] < a[3] { b[3] } else { a[3]}, - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F32x4PMax => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - if b[0] > a[0] { b[0] } else { a[0]}, - if b[1] > a[1] { b[1] } else { a[1]}, - if b[2] > a[2] { b[2] } else { a[2]}, - if b[3] > a[3] { b[3] } else { a[3]}, - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F64x2PMin => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - if b[0] < a[0] { b[0] } else { a[0]}, - if b[1] < a[1] { b[1] } else { a[1]}, - ])) - }).to_cf()?, - - #[cfg(feature = "unstable-simd")] - F64x2PMax => self.stack.values.calculate_same::(|a, b| { - Ok(Simd::::from_array([ - if b[0] > a[0] { b[0] } else { a[0]}, - if b[1] > a[1] { b[1] } else { a[1]}, - ])) - }).to_cf()?, - - // not correct - #[cfg(feature = "unstable-simd")] I32x4TruncSatF32x4S => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, - #[cfg(feature = "unstable-simd")] I32x4TruncSatF32x4U => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, - #[cfg(feature = "unstable-simd")] F32x4ConvertI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4ConvertI32x4U => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2ConvertLowI32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2ConvertLowI32x4U => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4DemoteF64x2Zero => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2PromoteLowF32x4 => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4TruncSatF64x2SZero => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4TruncSatF64x2UZero => unimplemented!(), - - #[cfg(feature = "unstable-simd")] I8x16RelaxedSwizzle => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4RelaxedTruncF32x4S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4RelaxedTruncF32x4U => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4RelaxedTruncF64x2SZero => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4RelaxedTruncF64x2UZero => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4RelaxedMadd => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4RelaxedNmadd => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2RelaxedMadd => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2RelaxedNmadd => unimplemented!(), - #[cfg(feature = "unstable-simd")] I8x16RelaxedLaneselect => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8RelaxedLaneselect => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4RelaxedLaneselect => unimplemented!(), - #[cfg(feature = "unstable-simd")] I64x2RelaxedLaneselect => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4RelaxedMin => unimplemented!(), - #[cfg(feature = "unstable-simd")] F32x4RelaxedMax => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2RelaxedMin => unimplemented!(), - #[cfg(feature = "unstable-simd")] F64x2RelaxedMax => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8RelaxedQ15mulrS => unimplemented!(), - #[cfg(feature = "unstable-simd")] I16x8RelaxedDotI8x16I7x16S => unimplemented!(), - #[cfg(feature = "unstable-simd")] I32x4RelaxedDotI8x16I7x16AddS => unimplemented!(), + V128Not => self.stack.values.replace_top_same::(|v| Ok(!v)).to_cf()?, + V128And => self.stack.values.calculate_same::(|a, b| Ok(a & b)).to_cf()?, + V128AndNot => self.stack.values.calculate_same::(|a, b| Ok(a & (!b))).to_cf()?, + V128Or => self.stack.values.calculate_same::(|a, b| Ok(a | b)).to_cf()?, + V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, + V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, + V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_or() != 0) as i32)).to_cf()?, + I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle(s))).to_cf()?, + + // V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, + // V128Load8x8S(_arg) => unimplemented!(), + // V128Load8x8U(_arg) => unimplemented!(), + // V128Load16x4S(_arg) => unimplemented!(), + // V128Load16x4U(_arg) => unimplemented!(), + // V128Load32x2S(_arg) => unimplemented!(), + // V128Load32x2U(_arg) => unimplemented!(), + // V128Load8Splat(_arg) => unimplemented!(), + // V128Load16Splat(_arg) => unimplemented!(), + // V128Load32Splat(_arg) => unimplemented!(), + // V128Load64Splat(_arg) => unimplemented!(), + + // V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, + + // V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + // V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + // V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + // V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + + // // Load a single 32-bit or 64-bit element into the lowest bits of a v128 vector, and initialize all other bits of the v128 vector to zero. + // V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + // let bytes = v.to_le_bytes(); + // u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + // })?, + // V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + // let bytes = v.to_le_bytes(); + // u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 0, 0, 0, 0, 0, 0, 0, 0]) + // })?, + + // V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), + + // I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + // I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + // I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + // F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + // F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + + // V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + // V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + // V128Load32Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + // V128Load64Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + + // I8x16ReplaceLane(_lane) => unimplemented!(), + // I16x8ReplaceLane(_lane) => unimplemented!(), + // I32x4ReplaceLane(_lane) => unimplemented!(), + // I64x2ReplaceLane(_lane) => unimplemented!(), + // F32x4ReplaceLane(_lane) => unimplemented!(), + // F64x2ReplaceLane(_lane) => unimplemented!(), + + // I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8))).to_cf()?, + // I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16))).to_cf()?, + // I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + // I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + // F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + // F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + + // I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + // I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + // I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + // I64x2Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + // F32x4Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + // F64x2Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + + // I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + // I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + // I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + // I64x2Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + // F32x4Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + // F64x2Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + + // I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // F32x4Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + // F64x2Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + + // F32x4Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // F64x2Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + + // I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + // F32x4Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + // F64x2Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + // I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + // F32x4Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + // F64x2Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + // I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + // I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + // I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + // I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + // I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + // I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + // I8x16GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + // I16x8GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + // I32x4GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + // I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + // I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + // I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + // I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + // I8x16Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + // I16x8Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + // I32x4Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + // I64x2Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + + // I8x16Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + // I16x8Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + // I32x4Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + // I64x2Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + + // I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + // I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + // I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + // I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + + // I8x16Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + // I16x8Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + // I32x4Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + // I64x2Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + + // I8x16Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i8))).to_cf()?, + // I16x8Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i16))).to_cf()?, + // I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a))).to_cf()?, + // I64x2Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i64))).to_cf()?, + + // I8x16ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i8))).to_cf()?, + // I16x8ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i16))).to_cf()?, + // I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a))).to_cf()?, + // I64x2ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i64))).to_cf()?, + + // I8x16ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u8))).to_cf()?, + // I16x8ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u16))).to_cf()?, + // I32x4ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u32))).to_cf()?, + // I64x2ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u64))).to_cf()?, + + // I8x16Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + // I16x8Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + // I32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + // I64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + + // I8x16Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + // I16x8Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + // I32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + // I64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + + // I8x16MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + // I16x8MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + // I32x4MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + + // I8x16MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + // I16x8MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + // I32x4MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + + // I8x16MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + // I16x8MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + // I32x4MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + + // I8x16MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + // I16x8MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + // I32x4MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + + // I64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + // I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + // I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + + // I8x16NarrowI16x8S => unimplemented!(), + // I8x16NarrowI16x8U => unimplemented!(), + // I16x8NarrowI32x4S => unimplemented!(), + // I16x8NarrowI32x4U => unimplemented!(), + + // I8x16AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + // I16x8AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + // I8x16AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + // I16x8AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + // I8x16SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + // I16x8SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + // I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + // I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + + // I8x16AvgrU => unimplemented!(), + // I16x8AvgrU => unimplemented!(), + + // I16x8ExtAddPairwiseI8x16S => unimplemented!(), + // I16x8ExtAddPairwiseI8x16U => unimplemented!(), + // I32x4ExtAddPairwiseI16x8S => unimplemented!(), + // I32x4ExtAddPairwiseI16x8U => unimplemented!(), + + // I16x8ExtMulLowI8x16S => unimplemented!(), + // I16x8ExtMulLowI8x16U => unimplemented!(), + // I16x8ExtMulHighI8x16S => unimplemented!(), + // I16x8ExtMulHighI8x16U => unimplemented!(), + // I32x4ExtMulLowI16x8S => unimplemented!(), + // I32x4ExtMulLowI16x8U => unimplemented!(), + // I32x4ExtMulHighI16x8S => unimplemented!(), + // I32x4ExtMulHighI16x8U => unimplemented!(), + // I64x2ExtMulLowI32x4S => unimplemented!(), + // I64x2ExtMulLowI32x4U => unimplemented!(), + // I64x2ExtMulHighI32x4S => unimplemented!(), + // I64x2ExtMulHighI32x4U => unimplemented!(), + + // I16x8ExtendLowI8x16S => unimplemented!(), + // I16x8ExtendLowI8x16U => unimplemented!(), + // I16x8ExtendHighI8x16S => unimplemented!(), + // I16x8ExtendHighI8x16U => unimplemented!(), + // I32x4ExtendLowI16x8S => unimplemented!(), + // I32x4ExtendLowI16x8U => unimplemented!(), + // I32x4ExtendHighI16x8S => unimplemented!(), + // I32x4ExtendHighI16x8U => unimplemented!(), + // I64x2ExtendLowI32x4S => unimplemented!(), + // I64x2ExtendLowI32x4U => unimplemented!(), + // I64x2ExtendHighI32x4S => unimplemented!(), + // I64x2ExtendHighI32x4U => unimplemented!(), + + // I8x16Popcnt => self.stack.values.replace_top::(|v| Ok(v.count_ones())).to_cf()?, + // I8x16Shuffle(_idx) => unimplemented!(), + + + // I16x8Q15MulrSatS => self.stack.values.calculate_same::(|a, b| { + // let subq15mulr = |a,b| { + // let a = a as i32; + // let b = b as i32; + // let r = (a * b + 0x4000) >> 15; + // if r > i16::MAX as i32 { + // i16::MAX + // } else if r < i16::MIN as i32 { + // i16::MIN + // } else { + // r as i16 + // } + // }; + // Ok(Simd::::from_array([ + // subq15mulr(a[0], b[0]), + // subq15mulr(a[1], b[1]), + // subq15mulr(a[2], b[2]), + // subq15mulr(a[3], b[3]), + // subq15mulr(a[4], b[4]), + // subq15mulr(a[5], b[5]), + // subq15mulr(a[6], b[6]), + // subq15mulr(a[7], b[7]), + // ])) + // }).to_cf()?, + + + // I32x4DotI16x8S => self.stack.values.calculate::(|a, b| { + // Ok(Simd::::from_array([ + // i32::from(a[0] * b[0] + a[1] * b[1]), + // i32::from(a[2] * b[2] + a[3] * b[3]), + // i32::from(a[4] * b[4] + a[5] * b[5]), + // i32::from(a[6] * b[6] + a[7] * b[7]), + // ])) + // }).to_cf()?, + + // F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, + // F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, + // F32x4Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, + // F64x2Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, + // F32x4Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, + // F64x2Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, + // F32x4Nearest => self.stack.values.replace_top_same::(|v| Ok(v.round())).to_cf()?, + // F64x2Nearest => self.stack.values.replace_top_same::(|v| Ok(v.round())).to_cf()?, + // F32x4Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, + // F64x2Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, + // F32x4Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, + // F64x2Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, + // F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f32x4(v.sqrt()))).to_cf()?, + // F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f64x2(v.sqrt()))).to_cf()?, + // F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a + b))).to_cf()?, + // F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a + b))).to_cf()?, + // F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a - b))).to_cf()?, + // F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a - b))).to_cf()?, + // F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a * b))).to_cf()?, + // F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a * b))).to_cf()?, + // F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a / b))).to_cf()?, + // F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a / b))).to_cf()?, + + // F32x4Min => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // b[0].tw_minimum(a[0]), + // b[1].tw_minimum(a[1]), + // b[2].tw_minimum(a[2]), + // b[3].tw_minimum(a[3]), + // ])) + // }).to_cf()?, + + + // F64x2Min => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // b[0].tw_minimum(a[0]), + // b[1].tw_minimum(a[1]), + // ])) + // }).to_cf()?, + + + // F32x4Max => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // b[0].tw_maximum(a[0]), + // b[1].tw_maximum(a[1]), + // b[2].tw_maximum(a[2]), + // b[3].tw_maximum(a[3]), + // ])) + // }).to_cf()?, + + + // F64x2Max => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // b[0].tw_maximum(a[0]), + // b[1].tw_maximum(a[1]), + // ])) + // }).to_cf()?, + + + // F32x4PMin => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // if b[0] < a[0] { b[0] } else { a[0]}, + // if b[1] < a[1] { b[1] } else { a[1]}, + // if b[2] < a[2] { b[2] } else { a[2]}, + // if b[3] < a[3] { b[3] } else { a[3]}, + // ])) + // }).to_cf()?, + + + // F32x4PMax => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // if b[0] > a[0] { b[0] } else { a[0]}, + // if b[1] > a[1] { b[1] } else { a[1]}, + // if b[2] > a[2] { b[2] } else { a[2]}, + // if b[3] > a[3] { b[3] } else { a[3]}, + // ])) + // }).to_cf()?, + + + // F64x2PMin => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // if b[0] < a[0] { b[0] } else { a[0]}, + // if b[1] < a[1] { b[1] } else { a[1]}, + // ])) + // }).to_cf()?, + + + // F64x2PMax => self.stack.values.calculate_same::(|a, b| { + // Ok(Simd::::from_array([ + // if b[0] > a[0] { b[0] } else { a[0]}, + // if b[1] > a[1] { b[1] } else { a[1]}, + // ])) + // }).to_cf()?, + + // // not correct + // I32x4TruncSatF32x4S => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, + // I32x4TruncSatF32x4U => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, + // F32x4ConvertI32x4S => unimplemented!(), + // F32x4ConvertI32x4U => unimplemented!(), + // F64x2ConvertLowI32x4S => unimplemented!(), + // F64x2ConvertLowI32x4U => unimplemented!(), + // F32x4DemoteF64x2Zero => unimplemented!(), + // F64x2PromoteLowF32x4 => unimplemented!(), + // I32x4TruncSatF64x2SZero => unimplemented!(), + // I32x4TruncSatF64x2UZero => unimplemented!(), + + // I8x16RelaxedSwizzle => unimplemented!(), + // I32x4RelaxedTruncF32x4S => unimplemented!(), + // I32x4RelaxedTruncF32x4U => unimplemented!(), + // I32x4RelaxedTruncF64x2SZero => unimplemented!(), + // I32x4RelaxedTruncF64x2UZero => unimplemented!(), + // F32x4RelaxedMadd => unimplemented!(), + // F32x4RelaxedNmadd => unimplemented!(), + // F64x2RelaxedMadd => unimplemented!(), + // F64x2RelaxedNmadd => unimplemented!(), + // I8x16RelaxedLaneselect => unimplemented!(), + // I16x8RelaxedLaneselect => unimplemented!(), + // I32x4RelaxedLaneselect => unimplemented!(), + // I64x2RelaxedLaneselect => unimplemented!(), + // F32x4RelaxedMin => unimplemented!(), + // F32x4RelaxedMax => unimplemented!(), + // F64x2RelaxedMin => unimplemented!(), + // F64x2RelaxedMax => unimplemented!(), + // I16x8RelaxedQ15mulrS => unimplemented!(), + // I16x8RelaxedDotI8x16I7x16S => unimplemented!(), + // I32x4RelaxedDotI8x16I7x16AddS => unimplemented!(), #[allow(unreachable_patterns)] i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), @@ -995,7 +988,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { let data = self .store .data - .datas + .data .get(self.module.resolve_data_addr(data_index) as usize) .ok_or_else(|| Error::Other("data not found".to_string()))?; @@ -1045,33 +1038,32 @@ impl<'store, 'stack> Executor<'store, 'stack> { } } - #[cfg(feature = "unstable-simd")] - fn exec_mem_load_lane< - LOAD: MemLoadable, - INTO: InternalValue + IndexMut, - const LOAD_SIZE: usize, - >( - &mut self, - mem_addr: tinywasm_types::MemAddr, - offset: u64, - lane: u8, - ) -> ControlFlow> { - let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); - let mut imm = self.stack.values.pop::(); - let val = self.stack.values.pop::() as u64; - let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { - cold(); - return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds { - offset: val as usize, - len: LOAD_SIZE, - max: 0, - }))); - }; - let val = mem.load_as::(addr).to_cf()?; - imm[lane as usize] = val; - self.stack.values.push(imm); - ControlFlow::Continue(()) - } + // fn exec_mem_load_lane< + // LOAD: MemLoadable, + // INTO: InternalValue + IndexMut, + // const LOAD_SIZE: usize, + // >( + // &mut self, + // mem_addr: tinywasm_types::MemAddr, + // offset: u64, + // lane: u8, + // ) -> ControlFlow> { + // let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); + // let mut imm = self.stack.values.pop::(); + // let val = self.stack.values.pop::() as u64; + // let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { + // cold(); + // return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds { + // offset: val as usize, + // len: LOAD_SIZE, + // max: 0, + // }))); + // }; + // let val = mem.load_as::(addr).to_cf()?; + // imm[lane as usize] = val; + // self.stack.values.push(imm); + // ControlFlow::Continue(()) + // } fn exec_mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( &mut self, @@ -1099,28 +1091,27 @@ impl<'store, 'stack> Executor<'store, 'stack> { ControlFlow::Continue(()) } - #[cfg(feature = "unstable-simd")] - fn exec_mem_store_lane, U: MemStorable + Copy, const N: usize>( - &mut self, - mem_addr: tinywasm_types::MemAddr, - offset: u64, - lane: u8, - ) -> ControlFlow> { - let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr)); - let val = self.stack.values.pop::(); - let val = val[lane as usize].to_mem_bytes(); - - let addr = match mem.is_64bit() { - true => self.stack.values.pop::() as u64, - false => self.stack.values.pop::() as u32 as u64, - }; - - if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) { - return ControlFlow::Break(Some(e)); - } - - ControlFlow::Continue(()) - } + // fn exec_mem_store_lane, U: MemStorable + Copy, const N: usize>( + // &mut self, + // mem_addr: tinywasm_types::MemAddr, + // offset: u64, + // lane: u8, + // ) -> ControlFlow> { + // let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr)); + // let val = self.stack.values.pop::(); + // let val = val[lane as usize].to_mem_bytes(); + + // let addr = match mem.is_64bit() { + // true => self.stack.values.pop::() as u64, + // false => self.stack.values.pop::() as u32 as u64, + // }; + + // if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) { + // return ControlFlow::Break(Some(e)); + // } + + // ControlFlow::Continue(()) + // } fn exec_mem_store, const N: usize>( &mut self, diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index 0b7df2f..6d94ce1 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -1,12 +1,14 @@ pub(crate) mod executor; pub(crate) mod num_helpers; pub(crate) mod stack; -mod values; +pub(crate) mod value128; +pub(crate) mod values; #[cfg(not(feature = "std"))] mod no_std_floats; use crate::{Result, Store}; +pub(crate) use value128::*; pub use values::*; /// The main `TinyWasm` runtime. diff --git a/crates/tinywasm/src/interpreter/no_std_floats.rs b/crates/tinywasm/src/interpreter/no_std_floats.rs index e273184..b6ce998 100644 --- a/crates/tinywasm/src/interpreter/no_std_floats.rs +++ b/crates/tinywasm/src/interpreter/no_std_floats.rs @@ -1,3 +1,4 @@ +// see https://github.com/rust-lang/rust/issues/137578 :( pub(super) trait NoStdFloatExt { fn round(self) -> Self; fn ceil(self) -> Self; diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index da27f3d..0356403 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -190,35 +190,3 @@ macro_rules! impl_checked_wrapping_rem { } impl_checked_wrapping_rem! { i32 i64 u32 u64 } - -#[cfg(all(feature = "unstable-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 = "unstable-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); - let mask = x.is_nan(); - mask.select(nan, x) -} - -#[cfg(all(feature = "unstable-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 = "unstable-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); - let mask = x.is_nan(); - mask.select(nan, x) -} diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index c7f02b6..e0a4d6a 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -2,7 +2,7 @@ use core::ops::ControlFlow; use super::BlockType; use crate::Trap; -use crate::interpreter::values::*; +use crate::interpreter::{Value128, values::*}; use crate::{Error, unlikely}; use alloc::boxed::Box; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 054ffe3..6e02b0f 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -188,12 +188,7 @@ impl ValueStack { ValType::F64 => WasmValue::F64(self.pop()), ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.pop())), ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.pop())), - - #[cfg(not(feature = "unstable-simd"))] - ValType::V128 => WasmValue::V128(self.pop()), - - #[cfg(feature = "unstable-simd")] - ValType::V128 => WasmValue::V128(i128::from_le_bytes(self.pop::().to_array())), + ValType::V128 => WasmValue::V128(self.pop::().into()), } } diff --git a/crates/tinywasm/src/interpreter/value128.rs b/crates/tinywasm/src/interpreter/value128.rs new file mode 100644 index 0000000..12d70e5 --- /dev/null +++ b/crates/tinywasm/src/interpreter/value128.rs @@ -0,0 +1,76 @@ +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub struct Value128(i128); + +impl Value128 { + pub const fn from_le_bytes(bytes: [u8; 16]) -> Self { + Self(i128::from_le_bytes(bytes)) + } + + pub const fn to_le_bytes(self) -> [u8; 16] { + self.0.to_le_bytes() + } + + pub const fn reduce_or(self) -> u8 { + let mut result = 0u8; + let bytes = self.to_le_bytes(); + let mut i = 0; + while i < 16 { + result |= bytes[i]; + i += 1; + } + result + } + + pub const fn swizzle(self, s: Self) -> Self { + let a_bytes = self.to_le_bytes(); + let s_bytes = s.to_le_bytes(); + let mut result_bytes = [0u8; 16]; + let mut i = 0; + while i < 16 { + let index = s_bytes[i] as usize; + result_bytes[i] = if index < 16 { a_bytes[index] } else { 0 }; + i += 1; + } + Self::from_le_bytes(result_bytes) + } +} + +impl From for i128 { + fn from(val: Value128) -> Self { + val.0 + } +} + +impl From for Value128 { + fn from(value: i128) -> Self { + Self(value) + } +} + +impl core::ops::Not for Value128 { + type Output = Self; + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl core::ops::BitAnd for Value128 { + type Output = Self; + fn bitand(self, rhs: Self) -> Self::Output { + Self(self.0 & rhs.0) + } +} + +impl core::ops::BitOr for Value128 { + type Output = Self; + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0) + } +} + +impl core::ops::BitXor for Value128 { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self::Output { + Self(self.0 ^ rhs.0) + } +} diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 9cf90ca..0940c97 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -1,4 +1,4 @@ -use crate::Result; +use crate::{Result, interpreter::value128::Value128}; use super::stack::{Locals, ValueStack}; use tinywasm_types::{ExternRef, FuncRef, LocalAddr, ValType, WasmValue}; @@ -7,11 +7,6 @@ pub(crate) type Value32 = u32; pub(crate) type Value64 = u64; pub(crate) type ValueRef = Option; -#[cfg(feature = "unstable-simd")] -pub(crate) type Value128 = core::simd::u8x16; -#[cfg(not(feature = "unstable-simd"))] -pub(crate) type Value128 = i128; - #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// A untyped WebAssembly value pub enum TinyWasmValue { @@ -112,12 +107,7 @@ impl TinyWasmValue { ValType::F64 => WasmValue::F64(f64::from_bits(self.unwrap_64())), ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.unwrap_ref())), ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.unwrap_ref())), - - #[cfg(feature = "unstable-simd")] - ValType::V128 => WasmValue::V128(i128::from_le_bytes(self.unwrap_128().to_array())), - - #[cfg(not(feature = "unstable-simd"))] - ValType::V128 => WasmValue::V128(self.unwrap_128()), + ValType::V128 => WasmValue::V128(self.unwrap_128().into()), } } } @@ -131,12 +121,7 @@ impl From<&WasmValue> for TinyWasmValue { WasmValue::F64(v) => Self::Value64(v.to_bits()), WasmValue::RefExtern(v) => Self::ValueRef(v.addr()), WasmValue::RefFunc(v) => Self::ValueRef(v.addr()), - - #[cfg(not(feature = "unstable-simd"))] - WasmValue::V128(v) => Self::Value128(*v), - - #[cfg(feature = "unstable-simd")] - WasmValue::V128(v) => TinyWasmValue::Value128(v.to_le_bytes().into()), + WasmValue::V128(v) => Self::Value128((*v).into()), } } } @@ -147,6 +132,12 @@ impl From for TinyWasmValue { } } +impl From for TinyWasmValue { + fn from(value: i128) -> Self { + Self::Value128(Value128::from(value)) + } +} + mod sealed { #[expect(unreachable_pub)] pub trait Sealed {} @@ -272,22 +263,3 @@ impl_internalvalue! { ValueRef, stack_ref, locals_ref, ValueRef, ValueRef, |v| v, |v| v Value128, stack_128, locals_128, Value128, Value128, |v| v, |v| v } - -#[cfg(feature = "unstable-simd")] -use core::simd::{num::SimdUint, *}; - -#[cfg(feature = "unstable-simd")] -impl_internalvalue! { - Value128, stack_128, locals_128, u8x16, i128, |v: i128| v.to_le_bytes().into(), |v: u8x16| i128::from_le_bytes(v.into()) - Value128, stack_128, locals_128, u8x16, u128, |v: u128| v.to_le_bytes().into(), |v: u8x16| u128::from_le_bytes(v.into()) - Value128, stack_128, locals_128, u8x16, i8x16, |v: i8x16| v.to_le_bytes(), |v: u8x16| v.cast() - Value128, stack_128, locals_128, u8x16, i16x8, |v: i16x8| v.to_le_bytes(), |v: u8x16| i16x8::from_le_bytes(v) - Value128, stack_128, locals_128, u8x16, i32x4, |v: i32x4| v.to_le_bytes(), |v: u8x16| i32x4::from_le_bytes(v) - Value128, stack_128, locals_128, u8x16, i64x2, |v: i64x2| v.to_le_bytes(), |v: u8x16| i64x2::from_le_bytes(v) - Value128, stack_128, locals_128, u8x16, f32x4, |v: f32x4| v.to_le_bytes(), |v: u8x16| f32x4::from_le_bytes(v) - Value128, stack_128, locals_128, u8x16, f64x2, |v: f64x2| v.to_le_bytes(), |v: u8x16| f64x2::from_le_bytes(v) - - Value128, stack_128, locals_128, u8x16, u16x8, |v: u16x8| v.to_le_bytes(), |v: u8x16| u16x8::from_le_bytes(v) - Value128, stack_128, locals_128, u8x16, u32x4, |v: u32x4| v.to_le_bytes(), |v: u8x16| u32x4::from_le_bytes(v) - Value128, stack_128, locals_128, u8x16, u64x2, |v: u64x2| v.to_le_bytes(), |v: u8x16| u64x2::from_le_bytes(v) -} diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 0037829..a176670 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -5,7 +5,6 @@ ))] #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] #![forbid(unsafe_code)] -#![cfg_attr(feature = "unstable-simd", feature(portable_simd))] //! A tiny WebAssembly Runtime written in Rust //! @@ -16,7 +15,7 @@ //! ## Features //!- **`std`**\ //! Enables the use of `std` and `std::io` for parsing from files and streams. This is enabled by default. -//!- **`logging`**\ +//!- **`log`**\ //! Enables logging using the `log` crate. This is enabled by default. //!- **`parser`**\ //! Enables the `tinywasm-parser` crate. This is enabled by default. @@ -97,12 +96,12 @@ mod std; extern crate alloc; // log for logging (optional). -#[cfg(feature = "logging")] +#[cfg(feature = "log")] #[expect(clippy::single_component_path_imports)] use log; // noop fallback if logging is disabled. -#[cfg(not(feature = "logging"))] +#[cfg(not(feature = "log"))] #[allow(unused_imports, unused_macros)] pub(crate) mod log { macro_rules! debug ( ($($tt:tt)*) => {{}} ); diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index b8ca1e8..267ca9a 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -4,9 +4,6 @@ use tinywasm_types::{MemoryArch, MemoryType, ModuleInstanceAddr}; use crate::{Error, Result, cold, interpreter::Value128, log}; -#[cfg(feature = "unstable-simd")] -use core::simd::ToBytes; - /// A WebAssembly Memory Instance /// /// See @@ -189,28 +186,6 @@ macro_rules! impl_mem_traits { impl_mem_traits!(u8, 1, i8, 1, u16, 2, i16, 2, u32, 4, i32, 4, f32, 4, u64, 8, i64, 8, f64, 8, Value128, 16); -#[cfg(feature = "unstable-simd")] -impl_mem_traits!( - core::simd::i8x16, - 16, - core::simd::i16x8, - 16, - core::simd::i32x4, - 16, - core::simd::i64x2, - 16, - core::simd::u16x8, - 16, - core::simd::u32x4, - 16, - core::simd::u64x2, - 16, - core::simd::f32x4, - 16, - core::simd::f64x2, - 16 -); - #[cfg(test)] mod memory_instance_tests { use super::*; diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index 8446297..9cafa7e 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -111,7 +111,7 @@ pub(crate) struct StoreData { pub(crate) memories: Vec, pub(crate) globals: Vec, pub(crate) elements: Vec, - pub(crate) datas: Vec, + pub(crate) data: Vec, } impl Store { @@ -199,7 +199,7 @@ impl Store { /// Get the data at the actual index in the store #[inline] pub(crate) fn get_data_mut(&mut self, addr: DataAddr) -> &mut DataInstance { - &mut self.data.datas[addr as usize] + &mut self.data.data[addr as usize] } /// Get the element at the actual index in the store @@ -370,15 +370,15 @@ impl Store { } /// Add data to the store, returning their addresses in the store - pub(crate) fn init_datas( + pub(crate) fn init_data( &mut self, mem_addrs: &[MemAddr], - datas: Vec, + data: Vec, idx: ModuleInstanceAddr, ) -> Result<(Box<[Addr]>, Option)> { - let data_count = self.data.datas.len(); + let data_count = self.data.data.len(); let mut data_addrs = Vec::with_capacity(data_count); - for (i, data) in datas.into_iter().enumerate() { + for (i, data) in data.into_iter().enumerate() { let data_val = match data.kind { tinywasm_types::DataKind::Active { mem: mem_addr, offset } => { let Some(mem_addr) = mem_addrs.get(mem_addr as usize) else { @@ -399,7 +399,7 @@ impl Store { tinywasm_types::DataKind::Passive => Some(data.data.to_vec()), }; - self.data.datas.push(DataInstance::new(data_val, idx)); + self.data.data.push(DataInstance::new(data_val, idx)); data_addrs.push((i + data_count) as Addr); } diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index b986c2a..5efcb8b 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -16,8 +16,8 @@ postcard={version="1.1", optional=true, default-features=false, features=["alloc serde={version="1.0", optional=true, default-features=false, features=["alloc"]} [features] -default=["std", "logging", "archive"] +default=["std", "log", "archive"] std=["serde?/std"] archive=["dep:postcard", "dep:serde"] -logging=["dep:log"] +log=["dep:log"] diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index 7d52049..069addf 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -51,7 +51,6 @@ impl TinyWasmModule { /// Creates a `TinyWasmModule` from a slice of bytes. pub fn from_twasm(wasm: &[u8]) -> Result { let len = validate_magic(wasm)?; - postcard::from_bytes(&wasm[len..]).map_err(TwasmError::InvalidArchive) } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index c34b705..beaa828 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -21,12 +21,12 @@ const fn max_page_count(page_size: u64) -> u64 { } // log for logging (optional). -#[cfg(feature = "logging")] +#[cfg(feature = "log")] #[allow(clippy::single_component_path_imports, unused_imports)] use log; // noop fallback if logging is disabled. -#[cfg(not(feature = "logging"))] +#[cfg(not(feature = "log"))] #[allow(unused_imports, unused_macros)] pub(crate) mod log { macro_rules! debug ( ($($tt:tt)*) => {{}} ); -- cgit v1.3.1