From 4d09764c66ab88a5a6cb8bc4060817e98c2e97ee Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Wed, 22 Mar 2023 19:27:18 +0000 Subject: [PATCH] Bug 1823476 - Update wast vendor dependency. r=supply-chain-reviewers Updated wast=55.0.0. And also wasm-smith to avoid duplicate copy of wasm-encoder. Differential Revision: https://phabricator.services.mozilla.com/D173217 --- Cargo.lock | 16 +- js/src/fuzz-tests/gluesmith/Cargo.toml | 2 +- js/src/rust/Cargo.toml | 2 +- supply-chain/imports.lock | 24 + .../rust/wasm-encoder/.cargo-checksum.json | 2 +- third_party/rust/wasm-encoder/Cargo.toml | 2 +- .../rust/wasm-encoder/src/component.rs | 20 +- .../wasm-encoder/src/component/instances.rs | 21 +- .../rust/wasm-encoder/src/component/types.rs | 4 +- third_party/rust/wasm-encoder/src/core.rs | 22 +- .../rust/wasm-encoder/src/core/code.rs | 76 ++- .../rust/wasm-encoder/src/core/elements.rs | 16 +- .../rust/wasm-encoder/src/core/tables.rs | 20 +- .../rust/wasm-encoder/src/core/types.rs | 123 +++- .../rust/wasm-smith/.cargo-checksum.json | 2 +- third_party/rust/wasm-smith/Cargo.toml | 6 +- third_party/rust/wasm-smith/src/component.rs | 2 +- third_party/rust/wasm-smith/src/core.rs | 49 +- .../rust/wasm-smith/src/core/code_builder.rs | 118 ++-- .../src/core/code_builder/no_traps.rs | 7 +- .../rust/wasm-smith/src/core/encode.rs | 4 +- third_party/rust/wasm-smith/tests/core.rs | 5 +- .../rust/wasmparser/.cargo-checksum.json | 2 +- third_party/rust/wasmparser/Cargo.lock | 18 +- third_party/rust/wasmparser/Cargo.toml | 5 +- .../rust/wasmparser/benches/benchmark.rs | 6 +- .../rust/wasmparser/src/binary_reader.rs | 46 +- third_party/rust/wasmparser/src/lib.rs | 30 +- third_party/rust/wasmparser/src/limits.rs | 8 +- .../rust/wasmparser/src/readers/core/code.rs | 2 +- .../wasmparser/src/readers/core/elements.rs | 10 +- .../wasmparser/src/readers/core/tables.rs | 49 +- .../rust/wasmparser/src/readers/core/types.rs | 175 +++++- third_party/rust/wasmparser/src/resources.rs | 76 ++- third_party/rust/wasmparser/src/validator.rs | 48 +- .../wasmparser/src/validator/component.rs | 116 +++- .../rust/wasmparser/src/validator/core.rs | 247 ++++++-- .../rust/wasmparser/src/validator/func.rs | 19 +- .../wasmparser/src/validator/operators.rs | 581 +++++++++++++----- .../rust/wasmparser/src/validator/types.rs | 54 +- .../rust/wasmparser/tests/big-module.rs | 32 + third_party/rust/wast/.cargo-checksum.json | 2 +- third_party/rust/wast/Cargo.toml | 4 +- third_party/rust/wast/src/component/binary.rs | 27 +- third_party/rust/wast/src/core/binary.rs | 17 +- third_party/rust/wast/src/core/expr.rs | 21 +- third_party/rust/wast/src/core/table.rs | 2 +- 47 files changed, 1540 insertions(+), 600 deletions(-) create mode 100644 third_party/rust/wasmparser/tests/big-module.rs diff --git a/Cargo.lock b/Cargo.lock index bfe9e3069e32..521da8cecaff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6159,18 +6159,18 @@ version = "0.2.100" [[package]] name = "wasm-encoder" -version = "0.23.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c3e4bc09095436c8e7584d86d33e6c3ee67045af8fb262cbb9cc321de553428" +checksum = "4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7" dependencies = [ "leb128", ] [[package]] name = "wasm-smith" -version = "0.12.2" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411278ee8e89067a252a3a6d6d578038251f9c0a1d4c088adf4162ad13e97b04" +checksum = "549cb78be46f43ad6746402871336cb6a989127fb847e93eb6ba0817647485a6" dependencies = [ "arbitrary", "flagset", @@ -6182,9 +6182,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.100.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b20236ab624147dfbb62cf12a19aaf66af0e41b8398838b66e997d07d269d4" +checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b" dependencies = [ "indexmap", "url", @@ -6192,9 +6192,9 @@ dependencies = [ [[package]] name = "wast" -version = "53.0.0" +version = "55.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8244fa24196b1d8fd3ca4a96a3a164c40f846498c5deab6caf414c67340ca4af" +checksum = "4984d3e1406571f4930ba5cf79bd70f75f41d0e87e17506e0bd19b0e5d085f05" dependencies = [ "leb128", "memchr", diff --git a/js/src/fuzz-tests/gluesmith/Cargo.toml b/js/src/fuzz-tests/gluesmith/Cargo.toml index bde7d7a35209..42c8cec4f2aa 100644 --- a/js/src/fuzz-tests/gluesmith/Cargo.toml +++ b/js/src/fuzz-tests/gluesmith/Cargo.toml @@ -5,6 +5,6 @@ authors = ["Christian Holler"] license = "MPL-2.0" [dependencies] -wasm-smith = "0.12.2" +wasm-smith = "0.12.5" arbitrary = { version = "1.0.0", features = ["derive"] } libc = "0.2" diff --git a/js/src/rust/Cargo.toml b/js/src/rust/Cargo.toml index 74eb35c8c45a..13c543f2e7bc 100644 --- a/js/src/rust/Cargo.toml +++ b/js/src/rust/Cargo.toml @@ -19,4 +19,4 @@ gluesmith = ['jsrust_shared/gluesmith'] jsrust_shared = { path = "./shared" } # Workaround for https://github.com/rust-lang/rust/issues/58393 mozglue-static = { path = "../../../mozglue/static/rust" } -wast = { version = "53.0.0" } +wast = { version = "55.0.0" } diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index e297f72cdb0d..55712feeaa49 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -197,24 +197,48 @@ criteria = "safe-to-deploy" version = "0.23.0" notes = "The Bytecode Alliance is the author of this crate." +[[audits.bytecode-alliance.audits.wasm-encoder]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.25.0" +notes = "The Bytecode Alliance is the author of this crate." + [[audits.bytecode-alliance.audits.wasm-smith]] who = "Alex Crichton " criteria = "safe-to-run" version = "0.12.2" notes = "The Bytecode Alliance is the author of this crate." +[[audits.bytecode-alliance.audits.wasm-smith]] +who = "Alex Crichton " +criteria = "safe-to-run" +version = "0.12.5" +notes = "The Bytecode Alliance is the author of this crate." + [[audits.bytecode-alliance.audits.wasmparser]] who = "Alex Crichton " criteria = "safe-to-deploy" version = "0.100.0" notes = "The Bytecode Alliance is the author of this crate." +[[audits.bytecode-alliance.audits.wasmparser]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.102.0" +notes = "The Bytecode Alliance is the author of this crate." + [[audits.bytecode-alliance.audits.wast]] who = "Alex Crichton " criteria = "safe-to-deploy" version = "53.0.0" notes = "The Bytecode Alliance is the author of this crate." +[[audits.bytecode-alliance.audits.wast]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "55.0.0" +notes = "The Bytecode Alliance is the author of this crate." + [[audits.chromeos.audits.fastrand]] who = "George Burgess IV " criteria = "safe-to-deploy" diff --git a/third_party/rust/wasm-encoder/.cargo-checksum.json b/third_party/rust/wasm-encoder/.cargo-checksum.json index 9249151940c9..3482054cb00d 100644 --- a/third_party/rust/wasm-encoder/.cargo-checksum.json +++ b/third_party/rust/wasm-encoder/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"fefb25e72fb204befadd0bedd4b998538a04bdbec2c28d4f70ef725a0de35a17","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"ac016c4843a7e1a5737255b39418732783592222dc518020730edf9dd46a1c13","src/component.rs":"c84b64b732fa84222452e13589ec187d62bee55098ca9e5b299810791b972906","src/component/aliases.rs":"be5215154b872ed5664f3bfe2aa1391f36a2575aa9d53971ab61868a1c446e9d","src/component/canonicals.rs":"8b270caef4e0f1e2b62af5b27560ac370399d11ce411aae6b811dddeaedb7750","src/component/components.rs":"07b8cae3a400e1955cc39d142569910b4fef2136021053d0ddbd6404d810aa52","src/component/exports.rs":"9a685fb44af0cfefbb2e92ddb0259955766cf6d1c0022830a865f92426ce0f7b","src/component/imports.rs":"41414a4cb71d79404e8721a985dd1d3a7df287f6417b4cab017d12e9aef31c43","src/component/instances.rs":"c86f24e466aeb6889413f32d95e039a90a1e20d2e5a0505339aa81fc086a8c24","src/component/modules.rs":"9e80907e72360fae4d8057b6b0e7a6b58edd7ba6aba6e63ba17346518e169617","src/component/names.rs":"7b651284ffdf147aabf1e01226f34ddc8bbe3d38a2dcd26ca0fc15ad24002b6f","src/component/start.rs":"4055553d5c99c99abbc01bb8abb928ecb8b909d148b647a9977fbd444bb464a3","src/component/types.rs":"885e26ce451a50ff48ab472161d8923c0195406180f36588c1d38c79181dee51","src/core.rs":"492e5ce8de8e0c0bfe55fdad62d0b8825ed88b4a01f4e1dcffae60020f27aea0","src/core/code.rs":"0dd762215e487f76d138dd6507679c24bfd747531d989baaa78d7e2382f099e4","src/core/custom.rs":"df2d6a8c5a64603822301522e9df4344022226301df846941d95930f1f4d99c4","src/core/data.rs":"c9d59eab2ab811bd950da52e6766c7df2367986c7a3a0d94d7aeb47d86f203ac","src/core/elements.rs":"361eba770b0bd6129e5b96f3081b022c5fa74640730d1d0501a33d93fea7d707","src/core/exports.rs":"f37351587cd0cfa7608f94e0fcbfa09d41c7df1d123c47825992c364d5d9ff11","src/core/functions.rs":"c18b9872ac0c21048a3ce32e5e44e8e702f97a57fa1b3a07bdd98c7f6c820f09","src/core/globals.rs":"560d8e8c818d968cd8a101ab3c639f723b1c754716aa1178d1c4570efd84d010","src/core/imports.rs":"782bbc2e70b379831f85716c0f50c0221d1487c8cba26e8845028b2ae1962c0c","src/core/linking.rs":"5c7d5bce822fad92dc096ceafde878c6d25869004ca26dde1378e78ae37071c9","src/core/memories.rs":"840d15fcd9bd4a668298491c6a91455b145c5c7ff1adf8c769aaf49d6c664d3a","src/core/names.rs":"1337a5ab769e1a1b83113041d6fc59652db34a01ef44f14a2641b3748c216dc1","src/core/producers.rs":"e96156e2b87a4e9162b918b8f9cae870c5abc9410835651d74ac54f0ff2665e7","src/core/start.rs":"a01d4a91bcd93048977ccafc6af160357297450395bf598351f5a3e6d322e0de","src/core/tables.rs":"f87a9761002e93c8e04e646cdf19fb5d012b190a4dbba542e8bfe1cfc606b545","src/core/tags.rs":"26d58904871d92f395eed67d4c25f0914b337d213bab2288011abe3ad31fa12b","src/core/types.rs":"42125c08577c418237982980fd13eb9a21e63b52674c0820c2df2e61b5f454fc","src/lib.rs":"aaec7fa68ae0764721d7b4b6d0d935ea60380c6268cbd512480fee2f7a61b755","src/raw.rs":"a6a72cfe8f88ea6476eccee4acf362030ba2d2e5710215bc4f13cde7de6d71ae"},"package":"1c3e4bc09095436c8e7584d86d33e6c3ee67045af8fb262cbb9cc321de553428"} \ No newline at end of file +{"files":{"Cargo.toml":"b96ee82a5f62db5b6f57000e3f1fdab6872b1bed6d36350e9af08d90984b47af","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"ac016c4843a7e1a5737255b39418732783592222dc518020730edf9dd46a1c13","src/component.rs":"b07b239571c54100a258da3fb00d9155c85d3750f93cc24d408ebc17301f3e66","src/component/aliases.rs":"be5215154b872ed5664f3bfe2aa1391f36a2575aa9d53971ab61868a1c446e9d","src/component/canonicals.rs":"8b270caef4e0f1e2b62af5b27560ac370399d11ce411aae6b811dddeaedb7750","src/component/components.rs":"07b8cae3a400e1955cc39d142569910b4fef2136021053d0ddbd6404d810aa52","src/component/exports.rs":"9a685fb44af0cfefbb2e92ddb0259955766cf6d1c0022830a865f92426ce0f7b","src/component/imports.rs":"41414a4cb71d79404e8721a985dd1d3a7df287f6417b4cab017d12e9aef31c43","src/component/instances.rs":"75e0ec12a578aa22d78053add818a960373171ff10c3619ca1e8058ded277a41","src/component/modules.rs":"9e80907e72360fae4d8057b6b0e7a6b58edd7ba6aba6e63ba17346518e169617","src/component/names.rs":"7b651284ffdf147aabf1e01226f34ddc8bbe3d38a2dcd26ca0fc15ad24002b6f","src/component/start.rs":"4055553d5c99c99abbc01bb8abb928ecb8b909d148b647a9977fbd444bb464a3","src/component/types.rs":"02982d0b7962462f0b083ade9a639216cc040775a0426ad431afbf9fbedf664b","src/core.rs":"7b02ef53a430693cfadcfd83f3aa9f556062eb9b9408e661ead5364e2150cd5e","src/core/code.rs":"b340cb948d1e28e8bd369353c729674146bcc28508bbb427a8d249af4fd491fe","src/core/custom.rs":"df2d6a8c5a64603822301522e9df4344022226301df846941d95930f1f4d99c4","src/core/data.rs":"c9d59eab2ab811bd950da52e6766c7df2367986c7a3a0d94d7aeb47d86f203ac","src/core/elements.rs":"76ab78bed1956fad030821b267a115511a99c61f33f2c6e588b5a8d4ee9b4204","src/core/exports.rs":"f37351587cd0cfa7608f94e0fcbfa09d41c7df1d123c47825992c364d5d9ff11","src/core/functions.rs":"c18b9872ac0c21048a3ce32e5e44e8e702f97a57fa1b3a07bdd98c7f6c820f09","src/core/globals.rs":"560d8e8c818d968cd8a101ab3c639f723b1c754716aa1178d1c4570efd84d010","src/core/imports.rs":"782bbc2e70b379831f85716c0f50c0221d1487c8cba26e8845028b2ae1962c0c","src/core/linking.rs":"5c7d5bce822fad92dc096ceafde878c6d25869004ca26dde1378e78ae37071c9","src/core/memories.rs":"840d15fcd9bd4a668298491c6a91455b145c5c7ff1adf8c769aaf49d6c664d3a","src/core/names.rs":"1337a5ab769e1a1b83113041d6fc59652db34a01ef44f14a2641b3748c216dc1","src/core/producers.rs":"e96156e2b87a4e9162b918b8f9cae870c5abc9410835651d74ac54f0ff2665e7","src/core/start.rs":"a01d4a91bcd93048977ccafc6af160357297450395bf598351f5a3e6d322e0de","src/core/tables.rs":"d5ae8c92c8707332eda6be6e5649f2f8042a1c6242494b0174cbee5e1971cace","src/core/tags.rs":"26d58904871d92f395eed67d4c25f0914b337d213bab2288011abe3ad31fa12b","src/core/types.rs":"988175ad3a47f4aca29c7fad9d594b54c5a5717fedf7ecd6296fbb45cb058999","src/lib.rs":"aaec7fa68ae0764721d7b4b6d0d935ea60380c6268cbd512480fee2f7a61b755","src/raw.rs":"a6a72cfe8f88ea6476eccee4acf362030ba2d2e5710215bc4f13cde7de6d71ae"},"package":"4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7"} \ No newline at end of file diff --git a/third_party/rust/wasm-encoder/Cargo.toml b/third_party/rust/wasm-encoder/Cargo.toml index ef83c8948312..efd41e73b2e6 100644 --- a/third_party/rust/wasm-encoder/Cargo.toml +++ b/third_party/rust/wasm-encoder/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "wasm-encoder" -version = "0.23.0" +version = "0.25.0" authors = ["Nick Fitzgerald "] description = """ A low-level WebAssembly encoder. diff --git a/third_party/rust/wasm-encoder/src/component.rs b/third_party/rust/wasm-encoder/src/component.rs index af05dcdc5572..5f92a91f77f7 100644 --- a/third_party/rust/wasm-encoder/src/component.rs +++ b/third_party/rust/wasm-encoder/src/component.rs @@ -42,6 +42,12 @@ const INSTANCE_SORT: u8 = 0x05; pub trait ComponentSection: Encode { /// Gets the section identifier for this section. fn id(&self) -> u8; + + /// Appends this section to the specified destination list of bytes. + fn append_to_component(&self, dst: &mut Vec) { + dst.push(self.id()); + self.encode(dst); + } } /// Known section identifiers of WebAssembly components. @@ -101,13 +107,19 @@ pub struct Component { } impl Component { + /// The 8-byte header at the beginning of all components. + #[rustfmt::skip] + pub const HEADER: [u8; 8] = [ + // Magic + 0x00, 0x61, 0x73, 0x6D, + // Version + 0x0c, 0x00, 0x01, 0x00, + ]; + /// Begin writing a new `Component`. pub fn new() -> Self { Self { - bytes: vec![ - 0x00, 0x61, 0x73, 0x6D, // magic (`\0asm`) - 0x0c, 0x00, 0x01, 0x00, // version - ], + bytes: Self::HEADER.to_vec(), } } diff --git a/third_party/rust/wasm-encoder/src/component/instances.rs b/third_party/rust/wasm-encoder/src/component/instances.rs index 000a872d6b8c..5f2c97dec3d0 100644 --- a/third_party/rust/wasm-encoder/src/component/instances.rs +++ b/third_party/rust/wasm-encoder/src/component/instances.rs @@ -59,17 +59,18 @@ impl InstanceSection { } /// Define an instance by instantiating a core module. - pub fn instantiate<'a, A>(&mut self, module_index: u32, args: A) -> &mut Self + pub fn instantiate(&mut self, module_index: u32, args: A) -> &mut Self where - A: IntoIterator, + A: IntoIterator, A::IntoIter: ExactSizeIterator, + S: AsRef, { let args = args.into_iter(); self.bytes.push(0x00); module_index.encode(&mut self.bytes); args.len().encode(&mut self.bytes); for (name, arg) in args { - name.encode(&mut self.bytes); + name.as_ref().encode(&mut self.bytes); arg.encode(&mut self.bytes); } self.num_added += 1; @@ -77,16 +78,17 @@ impl InstanceSection { } /// Define an instance by exporting core WebAssembly items. - pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self + pub fn export_items(&mut self, exports: E) -> &mut Self where - E: IntoIterator, + E: IntoIterator, E::IntoIter: ExactSizeIterator, + S: AsRef, { let exports = exports.into_iter(); self.bytes.push(0x01); exports.len().encode(&mut self.bytes); for (name, kind, index) in exports { - name.encode(&mut self.bytes); + name.as_ref().encode(&mut self.bytes); kind.encode(&mut self.bytes); index.encode(&mut self.bytes); } @@ -146,17 +148,18 @@ impl ComponentInstanceSection { } /// Define an instance by instantiating a component. - pub fn instantiate<'a, A>(&mut self, component_index: u32, args: A) -> &mut Self + pub fn instantiate(&mut self, component_index: u32, args: A) -> &mut Self where - A: IntoIterator, + A: IntoIterator, A::IntoIter: ExactSizeIterator, + S: AsRef, { let args = args.into_iter(); self.bytes.push(0x00); component_index.encode(&mut self.bytes); args.len().encode(&mut self.bytes); for (name, kind, index) in args { - name.encode(&mut self.bytes); + name.as_ref().encode(&mut self.bytes); kind.encode(&mut self.bytes); index.encode(&mut self.bytes); } diff --git a/third_party/rust/wasm-encoder/src/component/types.rs b/third_party/rust/wasm-encoder/src/component/types.rs index 9407940b32b2..930467d57aef 100644 --- a/third_party/rust/wasm-encoder/src/component/types.rs +++ b/third_party/rust/wasm-encoder/src/component/types.rs @@ -92,9 +92,9 @@ impl<'a> CoreTypeEncoder<'a> { self.0.push(0x60); params.len().encode(self.0); - self.0.extend(params.map(u8::from)); + params.for_each(|p| p.encode(self.0)); results.len().encode(self.0); - self.0.extend(results.map(u8::from)); + results.for_each(|p| p.encode(self.0)); } /// Define a module type. diff --git a/third_party/rust/wasm-encoder/src/core.rs b/third_party/rust/wasm-encoder/src/core.rs index 8bacae8221a0..dcf4d6fb7456 100644 --- a/third_party/rust/wasm-encoder/src/core.rs +++ b/third_party/rust/wasm-encoder/src/core.rs @@ -48,6 +48,12 @@ pub(crate) const CORE_TAG_SORT: u8 = 0x04; pub trait Section: Encode { /// Gets the section identifier for this section. fn id(&self) -> u8; + + /// Appends this section to the specified destination list of bytes. + fn append_to(&self, dst: &mut Vec) { + dst.push(self.id()); + self.encode(dst); + } } /// Known section identifiers of WebAssembly modules. @@ -110,16 +116,20 @@ pub struct Module { } impl Module { + /// The 8-byte header at the beginning of all core wasm modules. + #[rustfmt::skip] + pub const HEADER: [u8; 8] = [ + // Magic + 0x00, 0x61, 0x73, 0x6D, + // Version + 0x01, 0x00, 0x00, 0x00, + ]; + /// Begin writing a new `Module`. #[rustfmt::skip] pub fn new() -> Self { Module { - bytes: vec![ - // Magic - 0x00, 0x61, 0x73, 0x6D, - // Version - 0x01, 0x00, 0x00, 0x00, - ], + bytes: Self::HEADER.to_vec(), } } diff --git a/third_party/rust/wasm-encoder/src/core/code.rs b/third_party/rust/wasm-encoder/src/core/code.rs index 8f0f3c3b2856..641231d04f4f 100644 --- a/third_party/rust/wasm-encoder/src/core/code.rs +++ b/third_party/rust/wasm-encoder/src/core/code.rs @@ -1,4 +1,4 @@ -use crate::{encode_section, Encode, Section, SectionId, ValType}; +use crate::{encode_section, Encode, HeapType, Section, SectionId, ValType}; use std::borrow::Cow; /// An encoder for the code section. @@ -318,9 +318,13 @@ pub enum Instruction<'a> { Br(u32), BrIf(u32), BrTable(Cow<'a, [u32]>, u32), + BrOnNull(u32), + BrOnNonNull(u32), Return, Call(u32), + CallRef(HeapType), CallIndirect { ty: u32, table: u32 }, + ReturnCallRef(HeapType), ReturnCall(u32), ReturnCallIndirect { ty: u32, table: u32 }, Throw(u32), @@ -513,9 +517,10 @@ pub enum Instruction<'a> { // Reference types instructions. TypedSelect(ValType), - RefNull(ValType), + RefNull(HeapType), RefIsNull, RefFunc(u32), + RefAsNonNull, // Bulk memory instructions. TableInit { elem_index: u32, table: u32 }, @@ -764,15 +769,17 @@ pub enum Instruction<'a> { F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, + + // Relaxed simd proposal I8x16RelaxedSwizzle, - I32x4RelaxedTruncSatF32x4S, - I32x4RelaxedTruncSatF32x4U, - I32x4RelaxedTruncSatF64x2SZero, - I32x4RelaxedTruncSatF64x2UZero, - F32x4RelaxedFma, - F32x4RelaxedFnma, - F64x2RelaxedFma, - F64x2RelaxedFnma, + I32x4RelaxedTruncF32x4S, + I32x4RelaxedTruncF32x4U, + I32x4RelaxedTruncF64x2SZero, + I32x4RelaxedTruncF64x2UZero, + F32x4RelaxedMadd, + F32x4RelaxedNmadd, + F64x2RelaxedMadd, + F64x2RelaxedNmadd, I8x16RelaxedLaneselect, I16x8RelaxedLaneselect, I32x4RelaxedLaneselect, @@ -782,9 +789,8 @@ pub enum Instruction<'a> { F64x2RelaxedMin, F64x2RelaxedMax, I16x8RelaxedQ15mulrS, - I16x8DotI8x16I7x16S, - I32x4DotI8x16I7x16AddS, - F32x4RelaxedDotBf16x8AddF32x4, + I16x8RelaxedDotI8x16I7x16S, + I32x4RelaxedDotI8x16I7x16AddS, // Atomic instructions (the threads proposal) MemoryAtomicNotify(MemArg), @@ -905,16 +911,33 @@ impl Encode for Instruction<'_> { ls.encode(sink); l.encode(sink); } + Instruction::BrOnNull(l) => { + sink.push(0xD4); + l.encode(sink); + } + Instruction::BrOnNonNull(l) => { + sink.push(0xD6); + l.encode(sink); + } Instruction::Return => sink.push(0x0F), Instruction::Call(f) => { sink.push(0x10); f.encode(sink); } + Instruction::CallRef(ty) => { + sink.push(0x14); + ty.encode(sink); + } Instruction::CallIndirect { ty, table } => { sink.push(0x11); ty.encode(sink); table.encode(sink); } + Instruction::ReturnCallRef(ty) => { + sink.push(0x15); + ty.encode(sink); + } + Instruction::ReturnCall(f) => { sink.push(0x12); f.encode(sink); @@ -1290,6 +1313,7 @@ impl Encode for Instruction<'_> { sink.push(0xd2); f.encode(sink); } + Instruction::RefAsNonNull => sink.push(0xD3), // Bulk memory instructions. Instruction::TableInit { elem_index, table } => { @@ -2347,35 +2371,35 @@ impl Encode for Instruction<'_> { sink.push(0xFD); 0x100u32.encode(sink); } - Instruction::I32x4RelaxedTruncSatF32x4S => { + Instruction::I32x4RelaxedTruncF32x4S => { sink.push(0xFD); 0x101u32.encode(sink); } - Instruction::I32x4RelaxedTruncSatF32x4U => { + Instruction::I32x4RelaxedTruncF32x4U => { sink.push(0xFD); 0x102u32.encode(sink); } - Instruction::I32x4RelaxedTruncSatF64x2SZero => { + Instruction::I32x4RelaxedTruncF64x2SZero => { sink.push(0xFD); 0x103u32.encode(sink); } - Instruction::I32x4RelaxedTruncSatF64x2UZero => { + Instruction::I32x4RelaxedTruncF64x2UZero => { sink.push(0xFD); 0x104u32.encode(sink); } - Instruction::F32x4RelaxedFma => { + Instruction::F32x4RelaxedMadd => { sink.push(0xFD); 0x105u32.encode(sink); } - Instruction::F32x4RelaxedFnma => { + Instruction::F32x4RelaxedNmadd => { sink.push(0xFD); 0x106u32.encode(sink); } - Instruction::F64x2RelaxedFma => { + Instruction::F64x2RelaxedMadd => { sink.push(0xFD); 0x107u32.encode(sink); } - Instruction::F64x2RelaxedFnma => { + Instruction::F64x2RelaxedNmadd => { sink.push(0xFD); 0x108u32.encode(sink); } @@ -2415,18 +2439,14 @@ impl Encode for Instruction<'_> { sink.push(0xFD); 0x111u32.encode(sink); } - Instruction::I16x8DotI8x16I7x16S => { + Instruction::I16x8RelaxedDotI8x16I7x16S => { sink.push(0xFD); 0x112u32.encode(sink); } - Instruction::I32x4DotI8x16I7x16AddS => { + Instruction::I32x4RelaxedDotI8x16I7x16AddS => { sink.push(0xFD); 0x113u32.encode(sink); } - Instruction::F32x4RelaxedDotBf16x8AddF32x4 => { - sink.push(0xFD); - 0x114u32.encode(sink); - } // Atmoic instructions from the thread proposal Instruction::MemoryAtomicNotify(memarg) => { @@ -2801,7 +2821,7 @@ impl ConstExpr { } /// Create a constant expression containing a single `ref.null` instruction. - pub fn ref_null(ty: ValType) -> Self { + pub fn ref_null(ty: HeapType) -> Self { Self::new_insn(Instruction::RefNull(ty)) } diff --git a/third_party/rust/wasm-encoder/src/core/elements.rs b/third_party/rust/wasm-encoder/src/core/elements.rs index 5eb641247bb2..3325c3d429af 100644 --- a/third_party/rust/wasm-encoder/src/core/elements.rs +++ b/third_party/rust/wasm-encoder/src/core/elements.rs @@ -1,4 +1,4 @@ -use crate::{encode_section, ConstExpr, Encode, Section, SectionId, ValType}; +use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId}; /// An encoder for the element section. /// @@ -9,12 +9,12 @@ use crate::{encode_section, ConstExpr, Encode, Section, SectionId, ValType}; /// ``` /// use wasm_encoder::{ /// Elements, ElementSection, Module, TableSection, TableType, -/// ValType, ConstExpr +/// RefType, ConstExpr /// }; /// /// let mut tables = TableSection::new(); /// tables.table(TableType { -/// element_type: ValType::FuncRef, +/// element_type: RefType::FUNCREF, /// minimum: 128, /// maximum: None, /// }); @@ -22,7 +22,7 @@ use crate::{encode_section, ConstExpr, Encode, Section, SectionId, ValType}; /// let mut elements = ElementSection::new(); /// let table_index = 0; /// let offset = ConstExpr::i32_const(42); -/// let element_type = ValType::FuncRef; +/// let element_type = RefType::FUNCREF; /// let functions = Elements::Functions(&[ /// // Function indices... /// ]); @@ -80,7 +80,7 @@ pub struct ElementSegment<'a> { /// The element segment's mode. pub mode: ElementMode<'a>, /// The element segment's type. - pub element_type: ValType, + pub element_type: RefType, /// This segment's elements. pub elements: Elements<'a>, } @@ -171,7 +171,7 @@ impl ElementSection { &mut self, table_index: Option, offset: &ConstExpr, - element_type: ValType, + element_type: RefType, elements: Elements<'_>, ) -> &mut Self { self.segment(ElementSegment { @@ -187,7 +187,7 @@ impl ElementSection { /// Encode a passive element segment. /// /// Passive segments are part of the bulk memory proposal. - pub fn passive<'a>(&mut self, element_type: ValType, elements: Elements<'a>) -> &mut Self { + pub fn passive<'a>(&mut self, element_type: RefType, elements: Elements<'a>) -> &mut Self { self.segment(ElementSegment { mode: ElementMode::Passive, element_type, @@ -198,7 +198,7 @@ impl ElementSection { /// Encode a declared element segment. /// /// Declared segments are part of the bulk memory proposal. - pub fn declared<'a>(&mut self, element_type: ValType, elements: Elements<'a>) -> &mut Self { + pub fn declared<'a>(&mut self, element_type: RefType, elements: Elements<'a>) -> &mut Self { self.segment(ElementSegment { mode: ElementMode::Declared, element_type, diff --git a/third_party/rust/wasm-encoder/src/core/tables.rs b/third_party/rust/wasm-encoder/src/core/tables.rs index 57a7628a5ddf..cbb2048a6419 100644 --- a/third_party/rust/wasm-encoder/src/core/tables.rs +++ b/third_party/rust/wasm-encoder/src/core/tables.rs @@ -1,4 +1,4 @@ -use crate::{encode_section, Encode, Section, SectionId, ValType}; +use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId}; /// An encoder for the table section. /// @@ -7,11 +7,11 @@ use crate::{encode_section, Encode, Section, SectionId, ValType}; /// # Example /// /// ``` -/// use wasm_encoder::{Module, TableSection, TableType, ValType}; +/// use wasm_encoder::{Module, TableSection, TableType, RefType}; /// /// let mut tables = TableSection::new(); /// tables.table(TableType { -/// element_type: ValType::FuncRef, +/// element_type: RefType::FUNCREF, /// minimum: 128, /// maximum: None, /// }); @@ -49,6 +49,18 @@ impl TableSection { self.num_added += 1; self } + + /// Define a table with an explicit initialization expression. + /// + /// Note that this is part of the function-references proposal. + pub fn table_with_init(&mut self, table_type: TableType, init: &ConstExpr) -> &mut Self { + self.bytes.push(0x40); + self.bytes.push(0x00); + table_type.encode(&mut self.bytes); + init.encode(&mut self.bytes); + self.num_added += 1; + self + } } impl Encode for TableSection { @@ -67,7 +79,7 @@ impl Section for TableSection { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct TableType { /// The table's element type. - pub element_type: ValType, + pub element_type: RefType, /// Minimum size, in elements, of this table pub minimum: u32, /// Maximum size, in elements, of this table diff --git a/third_party/rust/wasm-encoder/src/core/types.rs b/third_party/rust/wasm-encoder/src/core/types.rs index d99e22ea94a1..d21dbbc9600f 100644 --- a/third_party/rust/wasm-encoder/src/core/types.rs +++ b/third_party/rust/wasm-encoder/src/core/types.rs @@ -2,41 +2,120 @@ use crate::{encode_section, Encode, Section, SectionId}; /// The type of a core WebAssembly value. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] -#[repr(u8)] pub enum ValType { /// The `i32` type. - I32 = 0x7F, + I32, /// The `i64` type. - I64 = 0x7E, + I64, /// The `f32` type. - F32 = 0x7D, + F32, /// The `f64` type. - F64 = 0x7C, + F64, /// The `v128` type. /// /// Part of the SIMD proposal. - V128 = 0x7B, - /// The `funcref` type. + V128, + /// A reference type. /// - /// Part of the reference types proposal when used anywhere other than a - /// table's element type. - FuncRef = 0x70, - /// The `externref` type. - /// - /// Part of the reference types proposal. - ExternRef = 0x6F, + /// The `funcref` and `externref` type fall into this category and the full + /// generalization here is due to the implementation of the + /// function-references proposal. + Ref(RefType), } -impl From for u8 { - #[inline] - fn from(t: ValType) -> u8 { - t as u8 - } +impl ValType { + /// Alias for the `funcref` type in WebAssembly + pub const FUNCREF: ValType = ValType::Ref(RefType::FUNCREF); + /// Alias for the `externref` type in WebAssembly + pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF); } impl Encode for ValType { fn encode(&self, sink: &mut Vec) { - sink.push(*self as u8); + match self { + ValType::I32 => sink.push(0x7F), + ValType::I64 => sink.push(0x7E), + ValType::F32 => sink.push(0x7D), + ValType::F64 => sink.push(0x7C), + ValType::V128 => sink.push(0x7B), + ValType::Ref(rt) => rt.encode(sink), + } + } +} + +/// A reference type. +/// +/// This is largely part of the function references proposal for WebAssembly but +/// additionally is used by the `funcref` and `externref` types. The full +/// generality of this type is only exercised with function-references. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] +#[allow(missing_docs)] +pub struct RefType { + pub nullable: bool, + pub heap_type: HeapType, +} + +impl RefType { + /// Alias for the `funcref` type in WebAssembly + pub const FUNCREF: RefType = RefType { + nullable: true, + heap_type: HeapType::Func, + }; + + /// Alias for the `externref` type in WebAssembly + pub const EXTERNREF: RefType = RefType { + nullable: true, + heap_type: HeapType::Extern, + }; +} + +impl Encode for RefType { + fn encode(&self, sink: &mut Vec) { + if self.nullable { + // Favor the original encodings of `funcref` and `externref` where + // possible + match self.heap_type { + HeapType::Func => return sink.push(0x70), + HeapType::Extern => return sink.push(0x6f), + _ => {} + } + } + + if self.nullable { + sink.push(0x6C); + } else { + sink.push(0x6B); + } + self.heap_type.encode(sink); + } +} + +impl From for ValType { + fn from(ty: RefType) -> ValType { + ValType::Ref(ty) + } +} + +/// Part of the function references proposal. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub enum HeapType { + /// A function reference. When nullable, equivalent to `funcref` + Func, + /// An extern reference. When nullable, equivalent to `externref` + Extern, + /// A reference to a particular index in a table. + TypedFunc(u32), +} + +impl Encode for HeapType { + fn encode(&self, sink: &mut Vec) { + match self { + HeapType::Func => sink.push(0x70), + HeapType::Extern => sink.push(0x6F), + // Note that this is encoded as a signed type rather than unsigned + // as it's decoded as an s33 + HeapType::TypedFunc(i) => i64::from(*i).encode(sink), + } } } @@ -91,9 +170,9 @@ impl TypeSection { self.bytes.push(0x60); params.len().encode(&mut self.bytes); - self.bytes.extend(params.map(u8::from)); + params.for_each(|p| p.encode(&mut self.bytes)); results.len().encode(&mut self.bytes); - self.bytes.extend(results.map(u8::from)); + results.for_each(|p| p.encode(&mut self.bytes)); self.num_added += 1; self } diff --git a/third_party/rust/wasm-smith/.cargo-checksum.json b/third_party/rust/wasm-smith/.cargo-checksum.json index ac5d8be7859c..d0d11b788196 100644 --- a/third_party/rust/wasm-smith/.cargo-checksum.json +++ b/third_party/rust/wasm-smith/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"b99b0bed493c2364e7dd63d34be429a7858d1066b19b59bc0fd9cb5d51d9b5f4","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9202d01e78acf04e38e23e162a91c20ece8968f6172c87bfa6f18bf0b3f27d74","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/component.rs":"8cb11020b03ef2f5b8a78bd71694334362df1777541ba5247c430f0dd7ac1673","src/component/encode.rs":"09eddb96b5b607a87673714208c6d43b247ec4870168661d27d2c3ce92c43afd","src/config.rs":"3d33dea22d53081504e13fea4b5c99898624f26ed03013a831bae0c9759823fc","src/core.rs":"1412d51c92f998054fd87381becd433641f0261407796cec28372c1ae3c3f873","src/core/code_builder.rs":"5c36773e5c5a43ceb1dcd5243a1e64a392021ed890c6953a4c789018fff3df11","src/core/code_builder/no_traps.rs":"e004030a038916e748b716e0b08f340fc8d4451cd7057416f6299c870cc01156","src/core/encode.rs":"b8599fc907573827ff5e85108421a9c74a031fc57de502c22e021bb9986af58c","src/core/terminate.rs":"d24af5206a13aee7d6a6ea900ccdf088c09d053c36026cf1607cc38c972b3ba9","src/lib.rs":"77ed926d64d325a73613f1c307db39c65c428a1eafae114033c73a60da586fd3","tests/component.rs":"54c69ebdda583207f9f0467a600ee0ca87fbee6b365e97ec3deff7b46bd6af06","tests/core.rs":"b3f51e9c81685f1ee23a01df3f1f48876f416d33db4aeb1e6609aaba9d7bb77a"},"package":"411278ee8e89067a252a3a6d6d578038251f9c0a1d4c088adf4162ad13e97b04"} \ No newline at end of file +{"files":{"Cargo.toml":"3fab85439f91b5b0dfc20abd90cabf4a9f29ab1c422ab1308851c344302d32b3","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9202d01e78acf04e38e23e162a91c20ece8968f6172c87bfa6f18bf0b3f27d74","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/component.rs":"32f93aac210f70fbc3f870c400993f4e7ff780ca6e111453a4dc4545906887e8","src/component/encode.rs":"09eddb96b5b607a87673714208c6d43b247ec4870168661d27d2c3ce92c43afd","src/config.rs":"3d33dea22d53081504e13fea4b5c99898624f26ed03013a831bae0c9759823fc","src/core.rs":"40949add77c2b90e9f3fc0ce6862a7c83ac03d5dd9babde5abee536d6fe074e6","src/core/code_builder.rs":"60e407a758ff58aafdcf4eb4e9141aca2ab7c7fe09d6644bc6e31043f88d0d69","src/core/code_builder/no_traps.rs":"e595dbde06551f5f8b23e03cfac0634beacab08e6243c66d6ffda95079212b24","src/core/encode.rs":"b4cc82895e3c3afe26e2e62bbdd63c44e7c1f091133e49f0eaf7e7ec22400e40","src/core/terminate.rs":"d24af5206a13aee7d6a6ea900ccdf088c09d053c36026cf1607cc38c972b3ba9","src/lib.rs":"77ed926d64d325a73613f1c307db39c65c428a1eafae114033c73a60da586fd3","tests/component.rs":"54c69ebdda583207f9f0467a600ee0ca87fbee6b365e97ec3deff7b46bd6af06","tests/core.rs":"da9e27e7057a7cd9435666d4bd4d57cec03b0d5d74bad289373db7beb8a2e1a6"},"package":"549cb78be46f43ad6746402871336cb6a989127fb847e93eb6ba0817647485a6"} \ No newline at end of file diff --git a/third_party/rust/wasm-smith/Cargo.toml b/third_party/rust/wasm-smith/Cargo.toml index 6ffcf0faa64f..06606c0147f9 100644 --- a/third_party/rust/wasm-smith/Cargo.toml +++ b/third_party/rust/wasm-smith/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "wasm-smith" -version = "0.12.2" +version = "0.12.5" authors = ["Nick Fitzgerald "] exclude = ["/benches/corpus"] description = "A WebAssembly test case generator" @@ -50,10 +50,10 @@ features = ["derive"] optional = true [dependencies.wasm-encoder] -version = "0.23.0" +version = "0.25.0" [dependencies.wasmparser] -version = "0.100.0" +version = "0.102.0" [dev-dependencies.criterion] version = "0.3.3" diff --git a/third_party/rust/wasm-smith/src/component.rs b/third_party/rust/wasm-smith/src/component.rs index 9d068e3a2b59..cb8acdc6bb25 100644 --- a/third_party/rust/wasm-smith/src/component.rs +++ b/third_party/rust/wasm-smith/src/component.rs @@ -1868,7 +1868,7 @@ fn inverse_scalar_canonical_abi_for( .cloned(), ValType::F32 => Ok(ComponentValType::Primitive(PrimitiveValType::Float32)), ValType::F64 => Ok(ComponentValType::Primitive(PrimitiveValType::Float64)), - ValType::V128 | ValType::FuncRef | ValType::ExternRef => { + ValType::V128 | ValType::Ref(_) => { unreachable!("not used in canonical ABI") } }; diff --git a/third_party/rust/wasm-smith/src/core.rs b/third_party/rust/wasm-smith/src/core.rs index 631f9ed42b50..1d3702179c71 100644 --- a/third_party/rust/wasm-smith/src/core.rs +++ b/third_party/rust/wasm-smith/src/core.rs @@ -14,7 +14,7 @@ use std::marker; use std::ops::Range; use std::rc::Rc; use std::str::{self, FromStr}; -use wasm_encoder::{BlockType, ConstExpr, ExportKind, ValType}; +use wasm_encoder::{BlockType, ConstExpr, ExportKind, HeapType, RefType, ValType}; pub(crate) use wasm_encoder::{GlobalType, MemoryType, TableType}; // NB: these constants are used to control the rate at which various events @@ -285,7 +285,7 @@ pub(crate) struct TagType { #[derive(Debug)] struct ElementSegment { kind: ElementKind, - ty: ValType, + ty: RefType, items: Elements, } @@ -655,7 +655,7 @@ impl Module { wasmparser::TypeRef::Table(table_ty) => { let table_ty = TableType { - element_type: convert_type(table_ty.element_type), + element_type: convert_reftype(table_ty.element_type), minimum: table_ty.initial, maximum: table_ty.maximum, }; @@ -879,14 +879,13 @@ impl Module { ValType::F32 => ConstExpr::f32_const(u.arbitrary()?), ValType::F64 => ConstExpr::f64_const(u.arbitrary()?), ValType::V128 => ConstExpr::v128_const(u.arbitrary()?), - ValType::ExternRef => ConstExpr::ref_null(ValType::ExternRef), - ValType::FuncRef => { - if num_funcs > 0 && u.arbitrary()? { + ValType::Ref(ty) => { + assert!(ty.nullable); + if ty.heap_type == HeapType::Func && num_funcs > 0 && u.arbitrary()? { let func = u.int_in_range(0..=num_funcs - 1)?; return Ok(GlobalInitExpr::FuncRef(func)); - } else { - ConstExpr::ref_null(ValType::FuncRef) } + ConstExpr::ref_null(ty.heap_type) } })) })); @@ -1073,7 +1072,7 @@ impl Module { continue; } - let dst = if ty.element_type == ValType::FuncRef { + let dst = if ty.element_type == RefType::FUNCREF { &mut funcrefs } else { &mut externrefs @@ -1081,7 +1080,7 @@ impl Module { let minimum = ty.minimum; // If the first table is a funcref table then it's a candidate for // the MVP encoding of element segments. - if i == 0 && ty.element_type == ValType::FuncRef { + if i == 0 && ty.element_type == RefType::FUNCREF { dst.push(Box::new(move |u| { arbitrary_active_elem(u, minimum, None, disallow_traps, ty) })); @@ -1105,10 +1104,10 @@ impl Module { let mut choices = Vec::new(); if !funcrefs.is_empty() { - choices.push((&funcrefs, ValType::FuncRef)); + choices.push((&funcrefs, RefType::FUNCREF)); } if !externrefs.is_empty() { - choices.push((&externrefs, ValType::ExternRef)); + choices.push((&externrefs, RefType::EXTERNREF)); } if choices.is_empty() { @@ -1133,13 +1132,13 @@ impl Module { // Pick whether we're going to use expression elements or // indices. Note that externrefs must use expressions, // and functions without reference types must use indices. - let items = if ty == ValType::ExternRef + let items = if ty == RefType::EXTERNREF || (self.config.reference_types_enabled() && u.arbitrary()?) { let mut init = vec![]; arbitrary_loop(u, self.config.min_elements(), max, |u| { init.push( - if ty == ValType::ExternRef || func_max == 0 || u.arbitrary()? { + if ty == RefType::EXTERNREF || func_max == 0 || u.arbitrary()? { None } else { Some(u.int_in_range(0..=func_max - 1)?) @@ -1381,8 +1380,8 @@ pub(crate) fn configured_valtypes(config: &dyn Config) -> Vec { valtypes.push(ValType::V128); } if config.reference_types_enabled() { - valtypes.push(ValType::ExternRef); - valtypes.push(ValType::FuncRef); + valtypes.push(ValType::EXTERNREF); + valtypes.push(ValType::FUNCREF); } valtypes } @@ -1431,9 +1430,9 @@ pub(crate) fn arbitrary_table_type(u: &mut Unstructured, config: &dyn Config) -> } Ok(TableType { element_type: if config.reference_types_enabled() { - *u.choose(&[ValType::FuncRef, ValType::ExternRef])? + *u.choose(&[RefType::FUNCREF, RefType::EXTERNREF])? } else { - ValType::FuncRef + RefType::FUNCREF }, minimum, maximum, @@ -1634,8 +1633,18 @@ fn convert_type(parsed_type: wasmparser::ValType) -> ValType { F32 => ValType::F32, F64 => ValType::F64, V128 => ValType::V128, - FuncRef => ValType::FuncRef, - ExternRef => ValType::ExternRef, + Ref(ty) => ValType::Ref(convert_reftype(ty)), + } +} + +fn convert_reftype(ty: wasmparser::RefType) -> RefType { + wasm_encoder::RefType { + nullable: ty.nullable, + heap_type: match ty.heap_type { + wasmparser::HeapType::Func => wasm_encoder::HeapType::Func, + wasmparser::HeapType::Extern => wasm_encoder::HeapType::Extern, + wasmparser::HeapType::TypedFunc(i) => wasm_encoder::HeapType::TypedFunc(i.into()), + }, } } diff --git a/third_party/rust/wasm-smith/src/core/code_builder.rs b/third_party/rust/wasm-smith/src/core/code_builder.rs index a76eca2d6b74..1ac01c1af7e6 100644 --- a/third_party/rust/wasm-smith/src/core/code_builder.rs +++ b/third_party/rust/wasm-smith/src/core/code_builder.rs @@ -6,7 +6,7 @@ use arbitrary::{Result, Unstructured}; use std::collections::{BTreeMap, BTreeSet}; use std::convert::TryFrom; use std::rc::Rc; -use wasm_encoder::{BlockType, MemArg}; +use wasm_encoder::{BlockType, MemArg, RefType}; mod no_traps; macro_rules! instructions { @@ -350,10 +350,10 @@ instructions! { (Some(simd_v128_v128_on_stack), i8x16_swizzle, Vector), (Some(simd_v128_v128_on_stack_relaxed), i8x16_relaxed_swizzle, Vector), (Some(simd_v128_v128_v128_on_stack), v128_bitselect, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), i8x16_laneselect, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), i16x8_laneselect, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_laneselect, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), i64x2_laneselect, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), i8x16_relaxed_laneselect, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), i16x8_relaxed_laneselect, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_laneselect, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), i64x2_relaxed_laneselect, Vector), (Some(simd_v128_v128_on_stack), i8x16_eq, Vector), (Some(simd_v128_v128_on_stack), i8x16_ne, Vector), (Some(simd_v128_v128_on_stack), i8x16_lt_s, Vector), @@ -544,22 +544,21 @@ instructions! { (Some(simd_v128_on_stack), f64x2_convert_low_i32x4u, Vector), (Some(simd_v128_on_stack), f32x4_demote_f64x2_zero, Vector), (Some(simd_v128_on_stack), f64x2_promote_low_f32x4, Vector), - (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_sat_f32x4s, Vector), - (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_sat_f32x4u, Vector), - (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_sat_f64x2s_zero, Vector), - (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_sat_f64x2u_zero, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_fma, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_fnma, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), f64x2_fma, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), f64x2_fnma, Vector), + (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f32x4s, Vector), + (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f32x4u, Vector), + (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f64x2s_zero, Vector), + (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f64x2u_zero, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_relaxed_madd, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_relaxed_nmadd, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), f64x2_relaxed_madd, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), f64x2_relaxed_nmadd, Vector), (Some(simd_v128_v128_on_stack_relaxed), f32x4_relaxed_min, Vector), (Some(simd_v128_v128_on_stack_relaxed), f32x4_relaxed_max, Vector), (Some(simd_v128_v128_on_stack_relaxed), f64x2_relaxed_min, Vector), (Some(simd_v128_v128_on_stack_relaxed), f64x2_relaxed_max, Vector), (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_q15mulr_s, Vector), - (Some(simd_v128_v128_on_stack_relaxed), i16x8_dot_i8x16_i7x16_s, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_dot_i8x16_i7x16_add_s, Vector), - (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_relaxed_dot_bf16x8_add_f32x4, Vector), + (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_dot_i8x16_i7x16_s, Vector), + (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_dot_i8x16_i7x16_add_s, Vector), } pub(crate) struct CodeBuilderAllocations { @@ -694,7 +693,7 @@ impl CodeBuilderAllocations { let mut table_tys = Vec::new(); for (i, table) in module.tables.iter().enumerate() { table_tys.push(table.element_type); - if table.element_type == ValType::FuncRef { + if table.element_type == RefType::FUNCREF { funcref_tables.push(i as u32); } } @@ -1107,8 +1106,10 @@ fn arbitrary_val(ty: ValType, u: &mut Unstructured<'_>) -> Instruction { ValType::F32 => Instruction::F32Const(u.arbitrary().unwrap_or(0.0)), ValType::F64 => Instruction::F64Const(u.arbitrary().unwrap_or(0.0)), ValType::V128 => Instruction::V128Const(u.arbitrary().unwrap_or(0)), - ValType::ExternRef => Instruction::RefNull(ValType::ExternRef), - ValType::FuncRef => Instruction::RefNull(ValType::FuncRef), + ValType::Ref(ty) => { + assert!(ty.nullable); + Instruction::RefNull(ty.heap_type) + } } } @@ -1789,9 +1790,7 @@ fn select( let ty = t.or(u); builder.allocs.operands.push(ty); match ty { - Some(ty @ ValType::ExternRef) | Some(ty @ ValType::FuncRef) => { - instructions.push(Instruction::TypedSelect(ty)) - } + Some(ty @ ValType::Ref(_)) => instructions.push(Instruction::TypedSelect(ty)), Some(ValType::I32) | Some(ValType::I64) | Some(ValType::F32) | Some(ValType::F64) | Some(ValType::V128) | None => instructions.push(Instruction::Select), } @@ -4510,9 +4509,9 @@ fn ref_null( builder: &mut CodeBuilder, instructions: &mut Vec, ) -> Result<()> { - let ty = *u.choose(&[ValType::ExternRef, ValType::FuncRef])?; - builder.push_operands(&[ty]); - instructions.push(Instruction::RefNull(ty)); + let ty = *u.choose(&[RefType::EXTERNREF, RefType::FUNCREF])?; + builder.push_operands(&[ty.into()]); + instructions.push(Instruction::RefNull(ty.heap_type)); Ok(()) } @@ -4528,7 +4527,7 @@ fn ref_func( instructions: &mut Vec, ) -> Result<()> { let i = *u.choose(&builder.allocs.referenced_functions)?; - builder.push_operands(&[ValType::FuncRef]); + builder.push_operands(&[ValType::FUNCREF]); instructions.push(Instruction::RefFunc(i)); Ok(()) } @@ -4536,7 +4535,7 @@ fn ref_func( #[inline] fn ref_is_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool { module.config.reference_types_enabled() - && (builder.type_on_stack(ValType::ExternRef) || builder.type_on_stack(ValType::FuncRef)) + && (builder.type_on_stack(ValType::EXTERNREF) || builder.type_on_stack(ValType::FUNCREF)) } fn ref_is_null( @@ -4556,9 +4555,9 @@ fn table_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool { module.config.reference_types_enabled() && module.config.bulk_memory_enabled() && !module.config.disallow_traps() // Non-trapping table fill generation not yet implemented - && [ValType::ExternRef, ValType::FuncRef].iter().any(|ty| { + && [ValType::EXTERNREF, ValType::FUNCREF].iter().any(|ty| { builder.types_on_stack(&[ValType::I32, *ty, ValType::I32]) - && module.tables.iter().any(|t| t.element_type == *ty) + && module.tables.iter().any(|t| *ty == t.element_type.into()) }) } @@ -4580,9 +4579,9 @@ fn table_fill( fn table_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool { module.config.reference_types_enabled() && !module.config.disallow_traps() // Non-trapping table.set generation not yet implemented - && [ValType::ExternRef, ValType::FuncRef].iter().any(|ty| { + && [ValType::EXTERNREF, ValType::FUNCREF].iter().any(|ty| { builder.types_on_stack(&[ValType::I32, *ty]) - && module.tables.iter().any(|t| t.element_type == *ty) + && module.tables.iter().any(|t| *ty == t.element_type.into()) }) } @@ -4616,7 +4615,7 @@ fn table_get( builder.pop_operands(&[ValType::I32]); let idx = u.int_in_range(0..=module.tables.len() - 1)?; let ty = module.tables[idx].element_type; - builder.push_operands(&[ty]); + builder.push_operands(&[ty.into()]); instructions.push(Instruction::TableGet(idx as u32)); Ok(()) } @@ -4641,9 +4640,9 @@ fn table_size( #[inline] fn table_grow_valid(module: &Module, builder: &mut CodeBuilder) -> bool { module.config.reference_types_enabled() - && [ValType::ExternRef, ValType::FuncRef].iter().any(|ty| { + && [ValType::EXTERNREF, ValType::FUNCREF].iter().any(|ty| { builder.types_on_stack(&[*ty, ValType::I32]) - && module.tables.iter().any(|t| t.element_type == *ty) + && module.tables.iter().any(|t| *ty == t.element_type.into()) }) } @@ -4732,17 +4731,17 @@ fn elem_drop( Ok(()) } -fn pop_reference_type(builder: &mut CodeBuilder) -> ValType { - if builder.type_on_stack(ValType::ExternRef) { - builder.pop_operands(&[ValType::ExternRef]); - ValType::ExternRef +fn pop_reference_type(builder: &mut CodeBuilder) -> RefType { + if builder.type_on_stack(ValType::EXTERNREF) { + builder.pop_operands(&[ValType::EXTERNREF]); + RefType::EXTERNREF } else { - builder.pop_operands(&[ValType::FuncRef]); - ValType::FuncRef + builder.pop_operands(&[ValType::FUNCREF]); + RefType::FUNCREF } } -fn table_index(ty: ValType, u: &mut Unstructured, module: &Module) -> Result { +fn table_index(ty: RefType, u: &mut Unstructured, module: &Module) -> Result { let tables = module .tables .iter() @@ -5332,32 +5331,25 @@ simd_unop!(F32x4DemoteF64x2Zero, f32x4_demote_f64x2_zero); simd_unop!(F64x2PromoteLowF32x4, f64x2_promote_low_f32x4); simd_ternop!(V128Bitselect, v128_bitselect); simd_binop!(I8x16RelaxedSwizzle, i8x16_relaxed_swizzle); -simd_unop!(I32x4RelaxedTruncSatF32x4S, i32x4_relaxed_trunc_sat_f32x4s); -simd_unop!(I32x4RelaxedTruncSatF32x4U, i32x4_relaxed_trunc_sat_f32x4u); -simd_unop!( - I32x4RelaxedTruncSatF64x2SZero, - i32x4_relaxed_trunc_sat_f64x2s_zero -); -simd_unop!( - I32x4RelaxedTruncSatF64x2UZero, - i32x4_relaxed_trunc_sat_f64x2u_zero -); -simd_ternop!(F32x4RelaxedFma, f32x4_fma); -simd_ternop!(F32x4RelaxedFnma, f32x4_fnma); -simd_ternop!(F64x2RelaxedFma, f64x2_fma); -simd_ternop!(F64x2RelaxedFnma, f64x2_fnma); -simd_ternop!(I8x16RelaxedLaneselect, i8x16_laneselect); -simd_ternop!(I16x8RelaxedLaneselect, i16x8_laneselect); -simd_ternop!(I32x4RelaxedLaneselect, i32x4_laneselect); -simd_ternop!(I64x2RelaxedLaneselect, i64x2_laneselect); +simd_unop!(I32x4RelaxedTruncF32x4S, i32x4_relaxed_trunc_f32x4s); +simd_unop!(I32x4RelaxedTruncF32x4U, i32x4_relaxed_trunc_f32x4u); +simd_unop!(I32x4RelaxedTruncF64x2SZero, i32x4_relaxed_trunc_f64x2s_zero); +simd_unop!(I32x4RelaxedTruncF64x2UZero, i32x4_relaxed_trunc_f64x2u_zero); +simd_ternop!(F32x4RelaxedMadd, f32x4_relaxed_madd); +simd_ternop!(F32x4RelaxedNmadd, f32x4_relaxed_nmadd); +simd_ternop!(F64x2RelaxedMadd, f64x2_relaxed_madd); +simd_ternop!(F64x2RelaxedNmadd, f64x2_relaxed_nmadd); +simd_ternop!(I8x16RelaxedLaneselect, i8x16_relaxed_laneselect); +simd_ternop!(I16x8RelaxedLaneselect, i16x8_relaxed_laneselect); +simd_ternop!(I32x4RelaxedLaneselect, i32x4_relaxed_laneselect); +simd_ternop!(I64x2RelaxedLaneselect, i64x2_relaxed_laneselect); simd_binop!(F32x4RelaxedMin, f32x4_relaxed_min); simd_binop!(F32x4RelaxedMax, f32x4_relaxed_max); simd_binop!(F64x2RelaxedMin, f64x2_relaxed_min); simd_binop!(F64x2RelaxedMax, f64x2_relaxed_max); simd_binop!(I16x8RelaxedQ15mulrS, i16x8_relaxed_q15mulr_s); -simd_binop!(I16x8DotI8x16I7x16S, i16x8_dot_i8x16_i7x16_s); -simd_ternop!(I32x4DotI8x16I7x16AddS, i32x4_dot_i8x16_i7x16_add_s); +simd_binop!(I16x8RelaxedDotI8x16I7x16S, i16x8_relaxed_dot_i8x16_i7x16_s); simd_ternop!( - F32x4RelaxedDotBf16x8AddF32x4, - f32x4_relaxed_dot_bf16x8_add_f32x4 + I32x4RelaxedDotI8x16I7x16AddS, + i32x4_relaxed_dot_i8x16_i7x16_add_s ); diff --git a/third_party/rust/wasm-smith/src/core/code_builder/no_traps.rs b/third_party/rust/wasm-smith/src/core/code_builder/no_traps.rs index 6b4bb126ee09..a1232b69222d 100644 --- a/third_party/rust/wasm-smith/src/core/code_builder/no_traps.rs +++ b/third_party/rust/wasm-smith/src/core/code_builder/no_traps.rs @@ -399,7 +399,10 @@ fn dummy_value_inst<'a>(ty: ValType) -> Instruction<'a> { ValType::F32 => Instruction::F32Const(0.0), ValType::F64 => Instruction::F64Const(0.0), ValType::V128 => Instruction::V128Const(0), - ValType::FuncRef | ValType::ExternRef => Instruction::RefNull(ty), + ValType::Ref(ty) => { + assert!(ty.nullable); + Instruction::RefNull(ty.heap_type) + } } } @@ -636,6 +639,6 @@ fn size_of_type_in_memory(ty: ValType) -> u64 { ValType::F32 => 4, ValType::F64 => 8, ValType::V128 => 16, - ValType::FuncRef | ValType::ExternRef => panic!("not a memory type"), + ValType::Ref(_) => panic!("not a memory type"), } } diff --git a/third_party/rust/wasm-smith/src/core/encode.rs b/third_party/rust/wasm-smith/src/core/encode.rs index 157277ae00ba..33cb7c2817e9 100644 --- a/third_party/rust/wasm-smith/src/core/encode.rs +++ b/third_party/rust/wasm-smith/src/core/encode.rs @@ -152,10 +152,10 @@ impl Module { // TODO(nagisa): generate global.get of imported ref globals too. match e { Some(i) => match el.ty { - ValType::FuncRef => wasm_encoder::ConstExpr::ref_func(*i), + RefType::FUNCREF => wasm_encoder::ConstExpr::ref_func(*i), _ => unreachable!(), }, - None => wasm_encoder::ConstExpr::ref_null(el.ty), + None => wasm_encoder::ConstExpr::ref_null(el.ty.heap_type), } })); wasm_encoder::Elements::Expressions(&exps) diff --git a/third_party/rust/wasm-smith/tests/core.rs b/third_party/rust/wasm-smith/tests/core.rs index 7360e69095ac..b177d8eea899 100644 --- a/third_party/rust/wasm-smith/tests/core.rs +++ b/third_party/rust/wasm-smith/tests/core.rs @@ -151,7 +151,7 @@ fn smoke_test_imports_config() { *seen = true } (Some((seen, I::Table(t))), TypeRef::Table(tt)) - if *t == tt.element_type => + if *t == ValType::Ref(tt.element_type) => { *seen = true } @@ -253,7 +253,7 @@ fn import_config( ("env", "pipo", Func(&[I32], &[I32])), ("env", "popo", Func(&[], &[I32, I32])), ("env", "mem", Memory), - ("env", "tbl", Table(FuncRef)), + ("env", "tbl", Table(ValType::FUNCREF)), ("vars", "g", Global(I64)), ("tags", "tag1", Tag(&[I32])), ] @@ -300,6 +300,7 @@ fn parser_features_from_config(config: &impl Config) -> WasmFeatures { floats: true, extended_const: false, component_model: false, + function_references: false, memory_control: false, } } diff --git a/third_party/rust/wasmparser/.cargo-checksum.json b/third_party/rust/wasmparser/.cargo-checksum.json index 79bd8e4124b4..7e081694a9a8 100644 --- a/third_party/rust/wasmparser/.cargo-checksum.json +++ b/third_party/rust/wasmparser/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"430baae8cea83da0463cc95ec996de0437beb083ac5173cf876f6d7d12103429","Cargo.toml":"9261b35e9cdb0ee22b78849c060aafef729e356884aa6186be48acf8ca9fe015","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"09254d9d4d19ec102e1e19ee025f0542b9b2b84e014adc49e51e9024274301ac","examples/simple.rs":"e9eb076367cc0932e2a32651372defa4a27ef800f47fad28c0ef840ba8ea7e08","src/binary_reader.rs":"84a18c2955ce3a76ebdc1eb1aa56087a97e9f0c24e2c2b0598078778ccae73b7","src/lib.rs":"2ebd0a6222060c7ae306b641ce1d11cbec389c3d1eda1b3219a53d80452e19e1","src/limits.rs":"f9590aba36c682a16b9036a151cd1140393624e54c7b4b190487639923b15a52","src/parser.rs":"b65b995296ed03a5b4d31c6459f2f3430ff685e50fec397c44f91b1364de5aaf","src/readers.rs":"406bf0cf694ed364c9c53cd25eb27a8e3fa97d099994f3e2a640747c49abf74b","src/readers/component.rs":"c259628ca3f09ff904f7e920aeec261b657f7a197c99b520a6a7d3e918b9fb3b","src/readers/component/aliases.rs":"72f3339cb452c1b055bd080281fe4923d132c280da112fcd1182594811b87494","src/readers/component/canonicals.rs":"c36e9bffc2e1ed752586189903eec77ea9897ae265e020096a9b92c467be26d9","src/readers/component/exports.rs":"f2c76e4be5045f1d099fd89dedf20e2f4817f046ea1e64bde7ca8f3ea9b2cdc6","src/readers/component/imports.rs":"725a688f2ab4306dbb421fe92ffff9373e3c88632557e352529f297bb2b96e0e","src/readers/component/instances.rs":"bca614178da3337e8c71a6ec431f12157a8cccc15411a0222bbc0106926a3ad5","src/readers/component/names.rs":"3f5dac9db8668b18cd6721cd780e6aba9b223b404c9d1173d09efe4e6b4d3a8a","src/readers/component/start.rs":"8e1e5d8aa5ece26d42251449cadcce0546c4d995f1641941b8a31ed4bc6ac761","src/readers/component/types.rs":"878fdf8f3d6a1c1387fd92b34838d8e79cee039710366bd5ea6739448d468a7a","src/readers/core.rs":"b1dbe0ffe61af1e6da4104de687009bcaa71fd3137300896159abbcfd903b800","src/readers/core/code.rs":"e14884ac83f5644c813c8196aabcb6a5539d3d2860f251c064481f61b0e0ffed","src/readers/core/custom.rs":"f80d3a994e8778a912319834228cbb772c65a4b6b1f25b41fe00d220d388831f","src/readers/core/data.rs":"c1fcda7b548b15be40b3dd1f667d97c30c543867f2dc4734b590846beefe3ae3","src/readers/core/elements.rs":"f3ed0c28b044f1fe51a576e3b5baf93f5aa896e7fefd8432eaf14b59073eb7f6","src/readers/core/exports.rs":"50dc1ee51b73f03f24077f7c290bca756966563cedbad9e49d735d60f60c91db","src/readers/core/functions.rs":"b5bbc7f7b7a429187376f63c695a9f1cbf92e515dba840ac876fa60f7290da34","src/readers/core/globals.rs":"d23f99a3adc9593652a5efd4dc81e8f014f57e776b49717dabbdcd0a811a96b1","src/readers/core/imports.rs":"4d247e8cac0b3cef7425d93f7a7f2412b2ae8979da944080d565415499e27e87","src/readers/core/init.rs":"ec6717063b0b7f2e9aa17ae52083019cee52594bf5a8b6858f2d77b10d7a0639","src/readers/core/memories.rs":"351f816d663b7d17546dc3b19ce0e43f406ce743289219a3758f7c837903fa6d","src/readers/core/names.rs":"408ebf052170bf0dc874b3158bb31089a891c3735cb35df2976e0b1e9791febb","src/readers/core/operators.rs":"46e927f6db9db9097217c5485da3a7b89e638730def809d177897f39356f5f52","src/readers/core/producers.rs":"4b42b7e1c9e22e7e2913d9da2291b491dc2d4fea417503d7ce99ad33c7beb439","src/readers/core/tables.rs":"87f11101c81c53ccbe5b112c1b49e008ebc651c6d18cd80a1bcd995051193cdf","src/readers/core/tags.rs":"c1dcfeb973195da9708549bcc2df4dd8ff282fe802c15a603bebc8a856f70949","src/readers/core/types.rs":"aa8cf5a56f5b2ad5155ab110ea1058a7f9d72729c0aac4bc87d870267949b9f8","src/resources.rs":"f87a31420b2e7f377e4ffe16d9d9eb23abbb377e35a75756425941aa707dc775","src/validator.rs":"e1e93bf6bfdfc5ec9d157c3cbb30ff704e4aa4e68911d0372e4bfe017b30d24b","src/validator/component.rs":"c91c15defdb84aeb73b356803df62cb8850776e6ecfbec858104fc67c12cd65a","src/validator/core.rs":"628bee96b2e3520f125ce0073f9ff9440320d96f9c5e6f4a13d667202270311b","src/validator/func.rs":"d98940cc1210bea6acbea514face78e23f8357ad3746c920fb32d17f169ba9dc","src/validator/operators.rs":"7b325c2e0e40dfc378cbfcf5f5c2f292de64a652ed7385f493a722e16dc8d392","src/validator/types.rs":"4f0edbe37c12e0c030069106437f38797f3f4e8af1312420b53de5f620b0a4f8"},"package":"64b20236ab624147dfbb62cf12a19aaf66af0e41b8398838b66e997d07d269d4"} \ No newline at end of file +{"files":{"Cargo.lock":"ef76d24da3e4c9b0e0034844c4d3fa21f84ddb56af9f3134222046aaf26a48d3","Cargo.toml":"f1f05638e3da3d7304ccb0a41ef0a9889224bc5dc92352c634a553c6fa27d4bd","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"b8417fbd86058b76f3ff15426075f9afee25b9f90155bbd9a2d774f4bad0af04","examples/simple.rs":"e9eb076367cc0932e2a32651372defa4a27ef800f47fad28c0ef840ba8ea7e08","src/binary_reader.rs":"1b1f0e1d831a716875ed578380f96b4b60245f0c6a4f43e2407c50fc94e50e6d","src/lib.rs":"d64774abb8d193f6a177130ffca94ce9fd199535fb6177dcb9910c4af7602082","src/limits.rs":"0c4dc6b96b35a320a8cff8269c0b55acd56f1f7b8a093c4885e04b9835441458","src/parser.rs":"b65b995296ed03a5b4d31c6459f2f3430ff685e50fec397c44f91b1364de5aaf","src/readers.rs":"406bf0cf694ed364c9c53cd25eb27a8e3fa97d099994f3e2a640747c49abf74b","src/readers/component.rs":"c259628ca3f09ff904f7e920aeec261b657f7a197c99b520a6a7d3e918b9fb3b","src/readers/component/aliases.rs":"72f3339cb452c1b055bd080281fe4923d132c280da112fcd1182594811b87494","src/readers/component/canonicals.rs":"c36e9bffc2e1ed752586189903eec77ea9897ae265e020096a9b92c467be26d9","src/readers/component/exports.rs":"f2c76e4be5045f1d099fd89dedf20e2f4817f046ea1e64bde7ca8f3ea9b2cdc6","src/readers/component/imports.rs":"725a688f2ab4306dbb421fe92ffff9373e3c88632557e352529f297bb2b96e0e","src/readers/component/instances.rs":"bca614178da3337e8c71a6ec431f12157a8cccc15411a0222bbc0106926a3ad5","src/readers/component/names.rs":"3f5dac9db8668b18cd6721cd780e6aba9b223b404c9d1173d09efe4e6b4d3a8a","src/readers/component/start.rs":"8e1e5d8aa5ece26d42251449cadcce0546c4d995f1641941b8a31ed4bc6ac761","src/readers/component/types.rs":"878fdf8f3d6a1c1387fd92b34838d8e79cee039710366bd5ea6739448d468a7a","src/readers/core.rs":"b1dbe0ffe61af1e6da4104de687009bcaa71fd3137300896159abbcfd903b800","src/readers/core/code.rs":"53f49986febb27f4cb67f4495e7b369fc80e2f70908e1e831750698dd15fe37f","src/readers/core/custom.rs":"f80d3a994e8778a912319834228cbb772c65a4b6b1f25b41fe00d220d388831f","src/readers/core/data.rs":"c1fcda7b548b15be40b3dd1f667d97c30c543867f2dc4734b590846beefe3ae3","src/readers/core/elements.rs":"197d3427fcf0fa8a3eb654e62dfa53159e6bc5cb160e75a06cf394f821bddef5","src/readers/core/exports.rs":"50dc1ee51b73f03f24077f7c290bca756966563cedbad9e49d735d60f60c91db","src/readers/core/functions.rs":"b5bbc7f7b7a429187376f63c695a9f1cbf92e515dba840ac876fa60f7290da34","src/readers/core/globals.rs":"d23f99a3adc9593652a5efd4dc81e8f014f57e776b49717dabbdcd0a811a96b1","src/readers/core/imports.rs":"4d247e8cac0b3cef7425d93f7a7f2412b2ae8979da944080d565415499e27e87","src/readers/core/init.rs":"ec6717063b0b7f2e9aa17ae52083019cee52594bf5a8b6858f2d77b10d7a0639","src/readers/core/memories.rs":"351f816d663b7d17546dc3b19ce0e43f406ce743289219a3758f7c837903fa6d","src/readers/core/names.rs":"408ebf052170bf0dc874b3158bb31089a891c3735cb35df2976e0b1e9791febb","src/readers/core/operators.rs":"46e927f6db9db9097217c5485da3a7b89e638730def809d177897f39356f5f52","src/readers/core/producers.rs":"4b42b7e1c9e22e7e2913d9da2291b491dc2d4fea417503d7ce99ad33c7beb439","src/readers/core/tables.rs":"cbe5b35893bd3929354b4487b344062ce6b540e6a70bde6eddf05a07a68574e9","src/readers/core/tags.rs":"c1dcfeb973195da9708549bcc2df4dd8ff282fe802c15a603bebc8a856f70949","src/readers/core/types.rs":"266a6c37ecdea656c235001b56b15564ad7777c23849a3f6e08ce63272347c7e","src/resources.rs":"b38b564ee425a392a30fb7440b50afa9e91be5ee933e4933b843e18c212a5871","src/validator.rs":"0dc406f1a61cf646719fa2d88675eae4d8c52c23cc3a4a222b6671cd25f84465","src/validator/component.rs":"4ca4d2d3c800e212a68e30577eead6bb69b2e7604f6d774d4f51f2aaa2f87084","src/validator/core.rs":"143f1a531485d411eb459fe608a64ca21f772740cbebe51e9f336e30ce3d1424","src/validator/func.rs":"63b66b7bb274be4115d8a26bce9b73128de0c079bd3318423288fadc1361fdb4","src/validator/operators.rs":"39b3bd04898b02b9dbd1d42c5727c79439593f5ef8fbf3c33fcc789d0b5be91a","src/validator/types.rs":"9ee9fb8a8afa0580c3e71bf9b39bd28c14b2a21f2d9acbb92e7d8ec14615ade2","tests/big-module.rs":"1f9241a4504d0421f6a5c759e3c688c87994fe04668b1d4e8912cedd98f2bd17"},"package":"48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b"} \ No newline at end of file diff --git a/third_party/rust/wasmparser/Cargo.lock b/third_party/rust/wasmparser/Cargo.lock index a1389faf4a0a..d65810ae1708 100644 --- a/third_party/rust/wasmparser/Cargo.lock +++ b/third_party/rust/wasmparser/Cargo.lock @@ -274,6 +274,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + [[package]] name = "libc" version = "0.2.139" @@ -637,9 +643,18 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "wasm-encoder" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7" +dependencies = [ + "leb128", +] + [[package]] name = "wasmparser" -version = "0.100.0" +version = "0.102.0" dependencies = [ "anyhow", "criterion", @@ -647,6 +662,7 @@ dependencies = [ "once_cell", "rayon", "url", + "wasm-encoder", ] [[package]] diff --git a/third_party/rust/wasmparser/Cargo.toml b/third_party/rust/wasmparser/Cargo.toml index 45ed37c7c758..9717ba19f86d 100644 --- a/third_party/rust/wasmparser/Cargo.toml +++ b/third_party/rust/wasmparser/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "wasmparser" -version = "0.100.0" +version = "0.102.0" authors = ["Yury Delendik "] exclude = ["benches/*.wasm"] description = """ @@ -49,3 +49,6 @@ version = "1.13.0" [dev-dependencies.rayon] version = "1.3" + +[dev-dependencies.wasm-encoder] +version = "0.25.0" diff --git a/third_party/rust/wasmparser/benches/benchmark.rs b/third_party/rust/wasmparser/benches/benchmark.rs index dcfc4c38bc08..5fb7b8390504 100644 --- a/third_party/rust/wasmparser/benches/benchmark.rs +++ b/third_party/rust/wasmparser/benches/benchmark.rs @@ -4,7 +4,10 @@ use once_cell::unsync::Lazy; use std::fs; use std::path::Path; use std::path::PathBuf; -use wasmparser::{DataKind, ElementKind, Parser, Payload, Validator, VisitOperator, WasmFeatures}; +use wasmparser::{ + DataKind, ElementKind, HeapType, Parser, Payload, ValType, Validator, VisitOperator, + WasmFeatures, +}; /// A benchmark input. pub struct BenchmarkInput { @@ -251,6 +254,7 @@ fn define_benchmarks(c: &mut Criterion) { mutable_global: true, saturating_float_to_int: true, sign_extension: true, + function_references: true, memory_control: true, }) } diff --git a/third_party/rust/wasmparser/src/binary_reader.rs b/third_party/rust/wasmparser/src/binary_reader.rs index e8651e31ae47..43fef14cdda7 100644 --- a/third_party/rust/wasmparser/src/binary_reader.rs +++ b/third_party/rust/wasmparser/src/binary_reader.rs @@ -686,21 +686,21 @@ impl<'a> BinaryReader<'a> { } // Check for a block type of form [] -> [t]. - if let Some(ty) = ValType::from_byte(b) { - self.position += 1; - return Ok(BlockType::Type(ty)); + if ValType::is_valtype_byte(b) { + return Ok(BlockType::Type(self.read()?)); } // Not empty or a singular type, so read the function type index let idx = self.read_var_s33()?; - if idx < 0 || idx > (std::u32::MAX as i64) { - return Err(BinaryReaderError::new( - "invalid function type", - self.original_position(), - )); + match u32::try_from(idx) { + Ok(idx) => Ok(BlockType::FuncType(idx)), + Err(_) => { + return Err(BinaryReaderError::new( + "invalid function type", + self.original_position(), + )); + } } - - Ok(BlockType::FuncType(idx as u32)) } /// Visit the next available operator with the specified [`VisitOperator`] instance. @@ -778,6 +778,8 @@ impl<'a> BinaryReader<'a> { } 0x12 => visitor.visit_return_call(self.read_var_u32()?), 0x13 => visitor.visit_return_call_indirect(self.read_var_u32()?, self.read_var_u32()?), + 0x14 => visitor.visit_call_ref(self.read()?), + 0x15 => visitor.visit_return_call_ref(self.read()?), 0x18 => visitor.visit_delegate(self.read_var_u32()?), 0x19 => visitor.visit_catch_all(), 0x1a => visitor.visit_drop(), @@ -971,6 +973,9 @@ impl<'a> BinaryReader<'a> { 0xd0 => visitor.visit_ref_null(self.read()?), 0xd1 => visitor.visit_ref_is_null(), 0xd2 => visitor.visit_ref_func(self.read_var_u32()?), + 0xd3 => visitor.visit_ref_as_non_null(), + 0xd4 => visitor.visit_br_on_null(self.read_var_u32()?), + 0xd6 => visitor.visit_br_on_non_null(self.read_var_u32()?), 0xfc => self.visit_0xfc_operator(pos, visitor)?, 0xfd => self.visit_0xfd_operator(pos, visitor)?, @@ -1347,14 +1352,14 @@ impl<'a> BinaryReader<'a> { 0xfe => visitor.visit_f64x2_convert_low_i32x4_s(), 0xff => visitor.visit_f64x2_convert_low_i32x4_u(), 0x100 => visitor.visit_i8x16_relaxed_swizzle(), - 0x101 => visitor.visit_i32x4_relaxed_trunc_sat_f32x4_s(), - 0x102 => visitor.visit_i32x4_relaxed_trunc_sat_f32x4_u(), - 0x103 => visitor.visit_i32x4_relaxed_trunc_sat_f64x2_s_zero(), - 0x104 => visitor.visit_i32x4_relaxed_trunc_sat_f64x2_u_zero(), - 0x105 => visitor.visit_f32x4_relaxed_fma(), - 0x106 => visitor.visit_f32x4_relaxed_fnma(), - 0x107 => visitor.visit_f64x2_relaxed_fma(), - 0x108 => visitor.visit_f64x2_relaxed_fnma(), + 0x101 => visitor.visit_i32x4_relaxed_trunc_f32x4_s(), + 0x102 => visitor.visit_i32x4_relaxed_trunc_f32x4_u(), + 0x103 => visitor.visit_i32x4_relaxed_trunc_f64x2_s_zero(), + 0x104 => visitor.visit_i32x4_relaxed_trunc_f64x2_u_zero(), + 0x105 => visitor.visit_f32x4_relaxed_madd(), + 0x106 => visitor.visit_f32x4_relaxed_nmadd(), + 0x107 => visitor.visit_f64x2_relaxed_madd(), + 0x108 => visitor.visit_f64x2_relaxed_nmadd(), 0x109 => visitor.visit_i8x16_relaxed_laneselect(), 0x10a => visitor.visit_i16x8_relaxed_laneselect(), 0x10b => visitor.visit_i32x4_relaxed_laneselect(), @@ -1364,9 +1369,8 @@ impl<'a> BinaryReader<'a> { 0x10f => visitor.visit_f64x2_relaxed_min(), 0x110 => visitor.visit_f64x2_relaxed_max(), 0x111 => visitor.visit_i16x8_relaxed_q15mulr_s(), - 0x112 => visitor.visit_i16x8_dot_i8x16_i7x16_s(), - 0x113 => visitor.visit_i32x4_dot_i8x16_i7x16_add_s(), - 0x114 => visitor.visit_f32x4_relaxed_dot_bf16x8_add_f32x4(), + 0x112 => visitor.visit_i16x8_relaxed_dot_i8x16_i7x16_s(), + 0x113 => visitor.visit_i32x4_relaxed_dot_i8x16_i7x16_add_s(), _ => bail!(pos, "unknown 0xfd subopcode: 0x{code:x}"), }) diff --git a/third_party/rust/wasmparser/src/lib.rs b/third_party/rust/wasmparser/src/lib.rs index bc173267c8f0..708809118d34 100644 --- a/third_party/rust/wasmparser/src/lib.rs +++ b/third_party/rust/wasmparser/src/lib.rs @@ -174,7 +174,7 @@ macro_rules! for_each_operator { @mvp I64Const { value: i64 } => visit_i64_const @mvp F32Const { value: $crate::Ieee32 } => visit_f32_const @mvp F64Const { value: $crate::Ieee64 } => visit_f64_const - @reference_types RefNull { ty: $crate::ValType } => visit_ref_null + @reference_types RefNull { hty: $crate::HeapType } => visit_ref_null @reference_types RefIsNull => visit_ref_is_null @reference_types RefFunc { function_index: u32 } => visit_ref_func @mvp I32Eqz => visit_i32_eqz @@ -658,14 +658,14 @@ macro_rules! for_each_operator { // Relaxed SIMD operators // https://github.com/WebAssembly/relaxed-simd @relaxed_simd I8x16RelaxedSwizzle => visit_i8x16_relaxed_swizzle - @relaxed_simd I32x4RelaxedTruncSatF32x4S => visit_i32x4_relaxed_trunc_sat_f32x4_s - @relaxed_simd I32x4RelaxedTruncSatF32x4U => visit_i32x4_relaxed_trunc_sat_f32x4_u - @relaxed_simd I32x4RelaxedTruncSatF64x2SZero => visit_i32x4_relaxed_trunc_sat_f64x2_s_zero - @relaxed_simd I32x4RelaxedTruncSatF64x2UZero => visit_i32x4_relaxed_trunc_sat_f64x2_u_zero - @relaxed_simd F32x4RelaxedFma => visit_f32x4_relaxed_fma - @relaxed_simd F32x4RelaxedFnma => visit_f32x4_relaxed_fnma - @relaxed_simd F64x2RelaxedFma => visit_f64x2_relaxed_fma - @relaxed_simd F64x2RelaxedFnma => visit_f64x2_relaxed_fnma + @relaxed_simd I32x4RelaxedTruncF32x4S => visit_i32x4_relaxed_trunc_f32x4_s + @relaxed_simd I32x4RelaxedTruncF32x4U => visit_i32x4_relaxed_trunc_f32x4_u + @relaxed_simd I32x4RelaxedTruncF64x2SZero => visit_i32x4_relaxed_trunc_f64x2_s_zero + @relaxed_simd I32x4RelaxedTruncF64x2UZero => visit_i32x4_relaxed_trunc_f64x2_u_zero + @relaxed_simd F32x4RelaxedMadd => visit_f32x4_relaxed_madd + @relaxed_simd F32x4RelaxedNmadd => visit_f32x4_relaxed_nmadd + @relaxed_simd F64x2RelaxedMadd => visit_f64x2_relaxed_madd + @relaxed_simd F64x2RelaxedNmadd => visit_f64x2_relaxed_nmadd @relaxed_simd I8x16RelaxedLaneselect => visit_i8x16_relaxed_laneselect @relaxed_simd I16x8RelaxedLaneselect => visit_i16x8_relaxed_laneselect @relaxed_simd I32x4RelaxedLaneselect => visit_i32x4_relaxed_laneselect @@ -675,9 +675,15 @@ macro_rules! for_each_operator { @relaxed_simd F64x2RelaxedMin => visit_f64x2_relaxed_min @relaxed_simd F64x2RelaxedMax => visit_f64x2_relaxed_max @relaxed_simd I16x8RelaxedQ15mulrS => visit_i16x8_relaxed_q15mulr_s - @relaxed_simd I16x8DotI8x16I7x16S => visit_i16x8_dot_i8x16_i7x16_s - @relaxed_simd I32x4DotI8x16I7x16AddS => visit_i32x4_dot_i8x16_i7x16_add_s - @relaxed_simd F32x4RelaxedDotBf16x8AddF32x4 => visit_f32x4_relaxed_dot_bf16x8_add_f32x4 + @relaxed_simd I16x8RelaxedDotI8x16I7x16S => visit_i16x8_relaxed_dot_i8x16_i7x16_s + @relaxed_simd I32x4RelaxedDotI8x16I7x16AddS => visit_i32x4_relaxed_dot_i8x16_i7x16_add_s + + // Typed Function references + @function_references CallRef { hty: $crate::HeapType } => visit_call_ref + @function_references ReturnCallRef { hty: $crate::HeapType } => visit_return_call_ref + @function_references RefAsNonNull => visit_ref_as_non_null + @function_references BrOnNull { relative_depth: u32 } => visit_br_on_null + @function_references BrOnNonNull { relative_depth: u32 } => visit_br_on_non_null } }; } diff --git a/third_party/rust/wasmparser/src/limits.rs b/third_party/rust/wasmparser/src/limits.rs index b803cae22c3c..e9ab7d06a637 100644 --- a/third_party/rust/wasmparser/src/limits.rs +++ b/third_party/rust/wasmparser/src/limits.rs @@ -37,9 +37,9 @@ pub const MAX_WASM_BR_TABLE_SIZE: usize = MAX_WASM_FUNCTION_SIZE; // Component-related limits pub const MAX_WASM_MODULE_SIZE: usize = 1024 * 1024 * 1024; //= 1 GiB -pub const MAX_WASM_MODULE_TYPE_DECLS: usize = 1000; -pub const MAX_WASM_COMPONENT_TYPE_DECLS: usize = 1000; -pub const MAX_WASM_INSTANCE_TYPE_DECLS: usize = 1000; +pub const MAX_WASM_MODULE_TYPE_DECLS: usize = 100_000; +pub const MAX_WASM_COMPONENT_TYPE_DECLS: usize = 100_000; +pub const MAX_WASM_INSTANCE_TYPE_DECLS: usize = 100_000; pub const MAX_WASM_RECORD_FIELDS: usize = 1000; pub const MAX_WASM_VARIANT_CASES: usize = 1000; pub const MAX_WASM_TUPLE_TYPES: usize = 1000; @@ -50,7 +50,7 @@ pub const MAX_WASM_INSTANTIATION_EXPORTS: usize = 1000; pub const MAX_WASM_CANONICAL_OPTIONS: usize = 10; pub const MAX_WASM_INSTANTIATION_ARGS: usize = 1000; pub const MAX_WASM_START_ARGS: usize = 1000; -pub const MAX_WASM_TYPE_SIZE: u32 = 100_000; +pub const MAX_WASM_TYPE_SIZE: u32 = 1_000_000; pub const MAX_WASM_MODULES: usize = 1_000; pub const MAX_WASM_COMPONENTS: usize = 1_000; pub const MAX_WASM_INSTANCES: usize = 1_000; diff --git a/third_party/rust/wasmparser/src/readers/core/code.rs b/third_party/rust/wasmparser/src/readers/core/code.rs index 8a4efafb5878..2a463727e827 100644 --- a/third_party/rust/wasmparser/src/readers/core/code.rs +++ b/third_party/rust/wasmparser/src/readers/core/code.rs @@ -51,7 +51,7 @@ impl<'a> FunctionBody<'a> { let count = reader.read_var_u32()?; for _ in 0..count { reader.read_var_u32()?; - reader.read_var_u32()?; + reader.read::()?; } Ok(()) } diff --git a/third_party/rust/wasmparser/src/readers/core/elements.rs b/third_party/rust/wasmparser/src/readers/core/elements.rs index ac271947e318..7e37e7d7b663 100644 --- a/third_party/rust/wasmparser/src/readers/core/elements.rs +++ b/third_party/rust/wasmparser/src/readers/core/elements.rs @@ -14,8 +14,8 @@ */ use crate::{ - BinaryReader, BinaryReaderError, ConstExpr, ExternalKind, FromReader, Result, SectionLimited, - ValType, + BinaryReader, BinaryReaderError, ConstExpr, ExternalKind, FromReader, RefType, Result, + SectionLimited, }; use std::ops::Range; @@ -27,7 +27,7 @@ pub struct Element<'a> { /// The initial elements of the element segment. pub items: ElementItems<'a>, /// The type of the elements. - pub ty: ValType, + pub ty: RefType, /// The range of the the element segment. pub range: Range, } @@ -107,7 +107,7 @@ impl<'a> FromReader<'a> for Element<'a> { reader.read()? } else { match reader.read()? { - ExternalKind::Func => ValType::FuncRef, + ExternalKind::Func => RefType::FUNCREF, _ => { return Err(BinaryReaderError::new( "only the function external type is supported in elem segment", @@ -117,7 +117,7 @@ impl<'a> FromReader<'a> for Element<'a> { } } } else { - ValType::FuncRef + RefType::FUNCREF }; // FIXME(#188) ideally wouldn't have to do skips here let data = reader.skip(|reader| { diff --git a/third_party/rust/wasmparser/src/readers/core/tables.rs b/third_party/rust/wasmparser/src/readers/core/tables.rs index f694accdf912..211e415efdc9 100644 --- a/third_party/rust/wasmparser/src/readers/core/tables.rs +++ b/third_party/rust/wasmparser/src/readers/core/tables.rs @@ -13,10 +13,55 @@ * limitations under the License. */ -use crate::{BinaryReader, FromReader, Result, SectionLimited, TableType}; +use crate::{BinaryReader, ConstExpr, FromReader, Result, SectionLimited, TableType}; /// A reader for the table section of a WebAssembly module. -pub type TableSectionReader<'a> = SectionLimited<'a, TableType>; +pub type TableSectionReader<'a> = SectionLimited<'a, Table<'a>>; + +/// Type information about a table defined in the table section of a WebAssembly +/// module. +#[derive(Debug)] +pub struct Table<'a> { + /// The type of this table, including its element type and its limits. + pub ty: TableType, + /// The initialization expression for the table. + pub init: TableInit<'a>, +} + +/// Different modes of initializing a table. +#[derive(Debug)] +pub enum TableInit<'a> { + /// The table is initialized to all null elements. + RefNull, + /// Each element in the table is initialized with the specified constant + /// expression. + Expr(ConstExpr<'a>), +} + +impl<'a> FromReader<'a> for Table<'a> { + fn from_reader(reader: &mut BinaryReader<'a>) -> Result { + let has_init_expr = if reader.peek()? == 0x40 { + reader.read_u8()?; + true + } else { + false + }; + + if has_init_expr { + if reader.read_u8()? != 0x00 { + bail!(reader.original_position() - 1, "invalid table encoding"); + } + } + + let ty = reader.read::()?; + let init = if has_init_expr { + TableInit::Expr(reader.read()?) + } else { + TableInit::RefNull + }; + Ok(Table { ty, init }) + } +} impl<'a> FromReader<'a> for TableType { fn from_reader(reader: &mut BinaryReader<'a>) -> Result { diff --git a/third_party/rust/wasmparser/src/readers/core/types.rs b/third_party/rust/wasmparser/src/readers/core/types.rs index f9755eda0625..4358e2670c88 100644 --- a/third_party/rust/wasmparser/src/readers/core/types.rs +++ b/third_party/rust/wasmparser/src/readers/core/types.rs @@ -30,43 +30,180 @@ pub enum ValType { F64, /// The value type is v128. V128, - /// The value type is a function reference. - FuncRef, - /// The value type is an extern reference. - ExternRef, + /// The value type is a reference. Which type of reference is decided by + /// RefType. This is a change in syntax from the function references proposal, + /// which now provides FuncRef and ExternRef as sugar for the generic ref + /// construct. + Ref(RefType), +} + +/// A reference type. When the function references feature is disabled, this +/// only represents funcref and externref, using the following format: +/// RefType { nullable: true, heap_type: Func | Extern }) +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[repr(packed)] +pub struct RefType { + /// Whether it's nullable + pub nullable: bool, + /// The relevant heap type + pub heap_type: HeapType, +} + +impl RefType { + /// Alias for the wasm `funcref` type. + pub const FUNCREF: RefType = RefType { + nullable: true, + heap_type: HeapType::Func, + }; + /// Alias for the wasm `externref` type. + pub const EXTERNREF: RefType = RefType { + nullable: true, + heap_type: HeapType::Extern, + }; +} + +impl From for ValType { + fn from(ty: RefType) -> ValType { + ValType::Ref(ty) + } +} + +/// Used as a performance optimization in HeapType. Call `.into()` to get the u32 +// A u16 forces 2-byte alignment, which forces HeapType to be 4 bytes, +// which forces ValType to 5 bytes. This newtype is annotated as unaligned to +// store the necessary bits compactly +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[repr(packed)] +pub struct PackedIndex(u16); + +impl TryFrom for PackedIndex { + type Error = (); + + fn try_from(idx: u32) -> Result { + idx.try_into().map(PackedIndex).map_err(|_| ()) + } +} + +impl From for u32 { + fn from(x: PackedIndex) -> u32 { + x.0 as u32 + } +} + +/// A heap type from function references. When the proposal is disabled, Index +/// is an invalid type. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum HeapType { + /// Function type index + /// Note: [PackedIndex] may need to be unpacked + TypedFunc(PackedIndex), + /// From reference types + Func, + /// From reference types + Extern, } impl ValType { + /// Alias for the wasm `funcref` type. + pub const FUNCREF: ValType = ValType::Ref(RefType::FUNCREF); + /// Alias for the wasm `externref` type. + pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF); + /// Returns whether this value type is a "reference type". /// /// Only reference types are allowed in tables, for example, and with some /// instructions. Current reference types include `funcref` and `externref`. pub fn is_reference_type(&self) -> bool { - matches!(self, ValType::FuncRef | ValType::ExternRef) + matches!(self, ValType::Ref(_)) + } + /// Whether the type is defaultable according to function references + /// spec. This amounts to whether it's a non-nullable ref + pub fn is_defaultable(&self) -> bool { + !matches!( + self, + ValType::Ref(RefType { + nullable: false, + .. + }) + ) } - pub(crate) fn from_byte(byte: u8) -> Option { + pub(crate) fn is_valtype_byte(byte: u8) -> bool { match byte { - 0x7F => Some(ValType::I32), - 0x7E => Some(ValType::I64), - 0x7D => Some(ValType::F32), - 0x7C => Some(ValType::F64), - 0x7B => Some(ValType::V128), - 0x70 => Some(ValType::FuncRef), - 0x6F => Some(ValType::ExternRef), - _ => None, + 0x7F | 0x7E | 0x7D | 0x7C | 0x7B | 0x70 | 0x6F | 0x6B | 0x6C => true, + _ => false, } } } impl<'a> FromReader<'a> for ValType { fn from_reader(reader: &mut BinaryReader<'a>) -> Result { - match ValType::from_byte(reader.peek()?) { - Some(ty) => { + match reader.peek()? { + 0x7F => { reader.position += 1; - Ok(ty) + Ok(ValType::I32) + } + 0x7E => { + reader.position += 1; + Ok(ValType::I64) + } + 0x7D => { + reader.position += 1; + Ok(ValType::F32) + } + 0x7C => { + reader.position += 1; + Ok(ValType::F64) + } + 0x7B => { + reader.position += 1; + Ok(ValType::V128) + } + 0x70 | 0x6F | 0x6B | 0x6C => Ok(ValType::Ref(reader.read()?)), + _ => bail!(reader.original_position(), "invalid value type"), + } + } +} + +impl<'a> FromReader<'a> for RefType { + fn from_reader(reader: &mut BinaryReader<'a>) -> Result { + match reader.read()? { + 0x70 => Ok(RefType::FUNCREF), + 0x6F => Ok(RefType::EXTERNREF), + byte @ (0x6B | 0x6C) => Ok(RefType { + nullable: byte == 0x6C, + heap_type: reader.read()?, + }), + _ => bail!(reader.original_position(), "malformed reference type"), + } + } +} + +impl<'a> FromReader<'a> for HeapType { + fn from_reader(reader: &mut BinaryReader<'a>) -> Result { + match reader.peek()? { + 0x70 => { + reader.position += 1; + Ok(HeapType::Func) + } + 0x6F => { + reader.position += 1; + Ok(HeapType::Extern) + } + _ => { + let idx = match u32::try_from(reader.read_var_s33()?) { + Ok(idx) => idx, + Err(_) => { + bail!(reader.original_position(), "invalid function heap type",); + } + }; + match idx.try_into() { + Ok(packed) => Ok(HeapType::TypedFunc(packed)), + Err(_) => { + bail!(reader.original_position(), "function index too large"); + } + } } - None => bail!(reader.original_position(), "invalid value type"), } } } @@ -142,7 +279,7 @@ impl FuncType { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct TableType { /// The table's element type. - pub element_type: ValType, + pub element_type: RefType, /// Initial size of this table, in elements. pub initial: u32, /// Optional maximum size of the table, in elements. diff --git a/third_party/rust/wasmparser/src/resources.rs b/third_party/rust/wasmparser/src/resources.rs index 3f6d4c671c0d..2f0cb5309d43 100644 --- a/third_party/rust/wasmparser/src/resources.rs +++ b/third_party/rust/wasmparser/src/resources.rs @@ -13,7 +13,10 @@ * limitations under the License. */ -use crate::{FuncType, GlobalType, MemoryType, TableType, ValType}; +use crate::{ + BinaryReaderError, FuncType, GlobalType, HeapType, MemoryType, RefType, TableType, ValType, + WasmFeatures, +}; use std::ops::Range; /// Types that qualify as Wasm function types for validation purposes. @@ -208,10 +211,44 @@ pub trait WasmModuleResources { fn global_at(&self, at: u32) -> Option; /// Returns the `FuncType` associated with the given type index. fn func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType>; + /// Returns the type index associated with the given function + /// index. type_of_function = func_type_at(type_index_of_function) + fn type_index_of_function(&self, func_idx: u32) -> Option; /// Returns the `FuncType` associated with the given function index. fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType>; /// Returns the element type at the given index. - fn element_type_at(&self, at: u32) -> Option; + fn element_type_at(&self, at: u32) -> Option; + /// Under the function references proposal, returns whether t1 <= + /// t2. Otherwise, returns whether t1 == t2 + fn matches(&self, t1: ValType, t2: ValType) -> bool; + /// Check a value type. This requires using func_type_at to check references + fn check_value_type( + &self, + t: ValType, + features: &WasmFeatures, + offset: usize, + ) -> Result<(), BinaryReaderError>; + + /// Checks that a `HeapType` is valid, notably its function index if one is + /// used. + fn check_heap_type( + &self, + heap_type: HeapType, + features: &WasmFeatures, + offset: usize, + ) -> Result<(), BinaryReaderError> { + // Delegate to the generic value type validation which will have the + // same validity checks. + self.check_value_type( + RefType { + nullable: true, + heap_type, + } + .into(), + features, + offset, + ) + } /// Returns the number of elements. fn element_count(&self) -> u32; @@ -243,12 +280,26 @@ where fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> { T::func_type_at(self, at) } + fn type_index_of_function(&self, func_idx: u32) -> Option { + T::type_index_of_function(self, func_idx) + } fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> { T::type_of_function(self, func_idx) } - fn element_type_at(&self, at: u32) -> Option { + fn check_value_type( + &self, + t: ValType, + features: &WasmFeatures, + offset: usize, + ) -> Result<(), BinaryReaderError> { + T::check_value_type(self, t, features, offset) + } + fn element_type_at(&self, at: u32) -> Option { T::element_type_at(self, at) } + fn matches(&self, t1: ValType, t2: ValType) -> bool { + T::matches(self, t1, t2) + } fn element_count(&self) -> u32 { T::element_count(self) @@ -287,14 +338,31 @@ where T::func_type_at(self, type_idx) } + fn type_index_of_function(&self, func_idx: u32) -> Option { + T::type_index_of_function(self, func_idx) + } + fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> { T::type_of_function(self, func_idx) } - fn element_type_at(&self, at: u32) -> Option { + fn check_value_type( + &self, + t: ValType, + features: &WasmFeatures, + offset: usize, + ) -> Result<(), BinaryReaderError> { + T::check_value_type(self, t, features, offset) + } + + fn element_type_at(&self, at: u32) -> Option { T::element_type_at(self, at) } + fn matches(&self, t1: ValType, t2: ValType) -> bool { + T::matches(self, t1, t2) + } + fn element_count(&self) -> u32 { T::element_count(self) } diff --git a/third_party/rust/wasmparser/src/validator.rs b/third_party/rust/wasmparser/src/validator.rs index fd0aed410184..04c207130bbe 100644 --- a/third_party/rust/wasmparser/src/validator.rs +++ b/third_party/rust/wasmparser/src/validator.rs @@ -14,8 +14,8 @@ */ use crate::{ - limits::*, BinaryReaderError, Encoding, FromReader, FunctionBody, Parser, Payload, Result, - SectionLimited, ValType, WASM_COMPONENT_VERSION, WASM_MODULE_VERSION, + limits::*, BinaryReaderError, Encoding, FromReader, FunctionBody, HeapType, Parser, Payload, + Result, SectionLimited, ValType, WASM_COMPONENT_VERSION, WASM_MODULE_VERSION, }; use std::mem; use std::ops::Range; @@ -240,11 +240,17 @@ pub struct WasmFeatures { pub extended_const: bool, /// The WebAssembly component model proposal. pub component_model: bool, + /// The WebAssembly typed function references proposal + pub function_references: bool, /// The WebAssembly memory control proposal pub memory_control: bool, } impl WasmFeatures { + /// NOTE: This only checks that the value type corresponds to the feature set!! + /// + /// To check that reference types are valid, we need access to the module + /// types. Use module.check_value_type. pub(crate) fn check_value_type(&self, ty: ValType) -> Result<(), &'static str> { match ty { ValType::I32 | ValType::I64 => Ok(()), @@ -255,9 +261,21 @@ impl WasmFeatures { Err("floating-point support is disabled") } } - ValType::FuncRef | ValType::ExternRef => { + ValType::Ref(r) => { if self.reference_types { - Ok(()) + if !self.function_references { + match (r.heap_type, r.nullable) { + (_, false) => { + Err("function references required for non-nullable types") + } + (HeapType::TypedFunc(_), _) => { + Err("function references required for index reference types") + } + _ => Ok(()), + } + } else { + Ok(()) + } } else { Err("reference types support is not enabled") } @@ -284,6 +302,7 @@ impl Default for WasmFeatures { memory64: false, extended_const: false, component_model: false, + function_references: false, memory_control: false, // On-by-default features (phase 4 or greater). @@ -515,8 +534,9 @@ impl Validator { if !self.features.component_model { bail!( range.start, - "unknown binary version: {num:#x}, \ - note: the WebAssembly component model feature is not enabled", + "unknown binary version and encoding combination: {num:#x} and 0x1, \ + note: encoded as a component but the WebAssembly component model feature \ + is not enabled - enable the feature to allow component validation", ); } if num == WASM_COMPONENT_VERSION { @@ -623,9 +643,7 @@ impl Validator { state.module.assert_mut().tables.reserve(count as usize); Ok(()) }, - |state, features, _, ty, offset| { - state.module.assert_mut().add_table(ty, features, offset) - }, + |state, features, types, table, offset| state.add_table(table, features, types, offset), ) } @@ -1169,13 +1187,13 @@ impl Validator { |components, _, count, offset| { let current = components.last_mut().unwrap(); check_max( - current.exports.len(), + current.externs.len(), count, MAX_WASM_EXPORTS, - "exports", + "imports and exports", offset, )?; - current.exports.reserve(count as usize); + current.externs.reserve(count as usize); Ok(()) }, |components, types, _, export, offset| { @@ -1351,7 +1369,7 @@ impl Validator { #[cfg(test)] mod tests { - use crate::{GlobalType, MemoryType, TableType, ValType, Validator, WasmFeatures}; + use crate::{GlobalType, MemoryType, RefType, TableType, ValType, Validator, WasmFeatures}; use anyhow::Result; #[test] @@ -1420,7 +1438,7 @@ mod tests { Some(TableType { initial: 10, maximum: None, - element_type: ValType::FuncRef, + element_type: RefType::FUNCREF, }) ); @@ -1448,7 +1466,7 @@ mod tests { _ => unreachable!(), } - assert_eq!(types.element_at(0), Some(ValType::FuncRef)); + assert_eq!(types.element_at(0), Some(RefType::FUNCREF)); Ok(()) } diff --git a/third_party/rust/wasmparser/src/validator/component.rs b/third_party/rust/wasmparser/src/validator/component.rs index 1a8f2cfc1b2b..641b18a2cc87 100644 --- a/third_party/rust/wasmparser/src/validator/component.rs +++ b/third_party/rust/wasmparser/src/validator/component.rs @@ -64,8 +64,8 @@ pub(crate) struct ComponentState { pub instances: Vec, pub components: Vec, - pub imports: IndexMap, ComponentEntityType)>, - pub exports: IndexMap, ComponentEntityType)>, + /// A set of all imports and exports since they share the same namespace. + pub externs: IndexMap, ComponentEntityType, ExternKind)>, // Note: URL validation requires unique URLs by byte comparison, so // strings are used here and the URLs are not normalized. @@ -76,6 +76,20 @@ pub(crate) struct ComponentState { type_size: u32, } +pub enum ExternKind { + Import, + Export, +} + +impl ExternKind { + fn desc(&self) -> &'static str { + match self { + ExternKind::Import => "import", + ExternKind::Export => "export", + } + } +} + impl ComponentState { pub fn type_count(&self) -> usize { self.core_types.len() + self.types.len() @@ -218,13 +232,14 @@ impl ComponentState { self.add_entity(entity, false, offset)?; let name = to_kebab_str(import.name, "import", offset)?; - match self.imports.entry(name.to_owned()) { + match self.externs.entry(name.to_owned()) { Entry::Occupied(e) => { bail!( offset, - "import name `{name}` conflicts with previous import name `{prev}`", + "import name `{name}` conflicts with previous {desc} name `{prev}`", name = import.name, - prev = e.key() + prev = e.key(), + desc = e.get().2.desc(), ); } Entry::Vacant(e) => { @@ -236,7 +251,7 @@ impl ComponentState { } self.type_size = combine_type_sizes(self.type_size, entity.type_size(), offset)?; - e.insert((url, entity)); + e.insert((url, entity, ExternKind::Import)); } } @@ -289,18 +304,25 @@ impl ComponentState { check_limit: bool, ) -> Result<()> { if check_limit { - check_max(self.exports.len(), 1, MAX_WASM_EXPORTS, "exports", offset)?; + check_max( + self.externs.len(), + 1, + MAX_WASM_EXPORTS, + "imports and exports", + offset, + )?; } self.add_entity(ty, true, offset)?; let name = to_kebab_str(name, "export", offset)?; - match self.exports.entry(name.to_owned()) { + match self.externs.entry(name.to_owned()) { Entry::Occupied(e) => { bail!( offset, - "export name `{name}` conflicts with previous export name `{prev}`", - prev = e.key() + "export name `{name}` conflicts with previous {desc} name `{prev}`", + prev = e.key(), + desc = e.get().2.desc(), ); } Entry::Vacant(e) => { @@ -312,7 +334,7 @@ impl ComponentState { } self.type_size = combine_type_sizes(self.type_size, ty.type_size(), offset)?; - e.insert((url, ty)); + e.insert((url, ty, ExternKind::Export)); } } @@ -388,12 +410,7 @@ impl ComponentState { } pub fn add_component(&mut self, component: &mut Self, types: &mut TypeAlloc) { - let ty = Type::Component(ComponentType { - type_size: component.type_size, - imports: mem::take(&mut component.imports), - exports: mem::take(&mut component.exports), - }); - + let ty = Type::Component(component.take_component_type()); let id = types.push_anon(ty); self.components.push(id); } @@ -848,13 +865,9 @@ impl ComponentState { }; } - let state = components.pop().unwrap(); + let mut state = components.pop().unwrap(); - Ok(ComponentType { - type_size: state.type_size, - imports: state.imports, - exports: state.exports, - }) + Ok(state.take_component_type()) } fn create_instance_type( @@ -889,7 +902,16 @@ impl ComponentState { Ok(ComponentInstanceType { type_size: state.type_size, - kind: ComponentInstanceTypeKind::Defined(state.exports), + kind: ComponentInstanceTypeKind::Defined( + state + .externs + .into_iter() + .filter_map(|(name, (url, ty, kind))| match kind { + ExternKind::Export => Some((name, (url, ty))), + ExternKind::Import => None, + }) + .collect(), + ), }) } @@ -1134,7 +1156,16 @@ impl ComponentState { )?; } ComponentExternalKind::Type => { - // Type arguments are ignored + let ty = self.type_at(component_arg.index, false, offset)?; + insert_arg( + component_arg.name, + ComponentEntityType::Type { + referenced: ty, + created: ty, + }, + &mut args, + offset, + )?; } } } @@ -1149,13 +1180,13 @@ impl ComponentState { | (ComponentEntityType::Component(_), ComponentEntityType::Component(_)) | (ComponentEntityType::Instance(_), ComponentEntityType::Instance(_)) | (ComponentEntityType::Func(_), ComponentEntityType::Func(_)) - | (ComponentEntityType::Value(_), ComponentEntityType::Value(_)) => {} + | (ComponentEntityType::Value(_), ComponentEntityType::Value(_)) + | (ComponentEntityType::Type { .. }, ComponentEntityType::Type { .. }) => {} _ => { bail!( offset, - "expected component instantiation argument \ - `{name}` to be of type `{}`", - expected.desc() + "expected component instantiation argument `{name}` to be a {desc}", + desc = expected.desc() ) } }; @@ -1163,8 +1194,7 @@ impl ComponentState { if !ComponentEntityType::internal_is_subtype_of(arg, types, expected, types) { bail!( offset, - "{} type mismatch for component instantiation argument `{name}`", - expected.desc(), + "type mismatch for component instantiation argument `{name}`" ); } } @@ -2024,6 +2054,25 @@ impl ComponentState { None => bail!(offset, "unknown memory {idx}: memory index out of bounds"), } } + + fn take_component_type(&mut self) -> ComponentType { + let mut ty = ComponentType { + type_size: self.type_size, + imports: Default::default(), + exports: Default::default(), + }; + + for (name, (url, t, kind)) in mem::take(&mut self.externs) { + let map = match kind { + ExternKind::Import => &mut ty.imports, + ExternKind::Export => &mut ty.exports, + }; + let prev = map.insert(name, (url, t)); + assert!(prev.is_none()); + } + + ty + } } impl Default for ComponentState { @@ -2042,10 +2091,9 @@ impl Default for ComponentState { values: Default::default(), instances: Default::default(), components: Default::default(), - imports: Default::default(), - exports: Default::default(), - import_urls: Default::default(), + externs: Default::default(), export_urls: Default::default(), + import_urls: Default::default(), has_start: Default::default(), type_size: 1, } diff --git a/third_party/rust/wasmparser/src/validator/core.rs b/third_party/rust/wasmparser/src/validator/core.rs index 94aa4e722cfe..5707e1e73bb3 100644 --- a/third_party/rust/wasmparser/src/validator/core.rs +++ b/third_party/rust/wasmparser/src/validator/core.rs @@ -2,27 +2,20 @@ //! use super::{ check_max, combine_type_sizes, - operators::{OperatorValidator, OperatorValidatorAllocations}, + operators::{ty_to_str, OperatorValidator, OperatorValidatorAllocations}, types::{EntityType, Type, TypeAlloc, TypeId, TypeList}, }; use crate::limits::*; use crate::validator::core::arc::MaybeOwned; use crate::{ BinaryReaderError, ConstExpr, Data, DataKind, Element, ElementKind, ExternalKind, FuncType, - Global, GlobalType, MemoryType, Result, TableType, TagType, TypeRef, ValType, VisitOperator, - WasmFeatures, WasmModuleResources, + Global, GlobalType, HeapType, MemoryType, RefType, Result, Table, TableInit, TableType, + TagType, TypeRef, ValType, VisitOperator, WasmFeatures, WasmFuncType, WasmModuleResources, }; use indexmap::IndexMap; use std::mem; use std::{collections::HashSet, sync::Arc}; -fn check_value_type(ty: ValType, features: &WasmFeatures, offset: usize) -> Result<()> { - match features.check_value_type(ty) { - Ok(()) => Ok(()), - Err(e) => Err(BinaryReaderError::new(e, offset)), - } -} - // Section order for WebAssembly modules. // // Component sections are unordered and allow for duplicates, @@ -140,12 +133,43 @@ impl ModuleState { offset: usize, ) -> Result<()> { self.module - .check_global_type(&global.ty, features, offset)?; + .check_global_type(&global.ty, features, types, offset)?; self.check_const_expr(&global.init_expr, global.ty.content_type, features, types)?; self.module.assert_mut().globals.push(global.ty); Ok(()) } + pub fn add_table( + &mut self, + table: Table<'_>, + features: &WasmFeatures, + types: &TypeList, + offset: usize, + ) -> Result<()> { + self.module + .check_table_type(&table.ty, features, types, offset)?; + + match &table.init { + TableInit::RefNull => { + if !table.ty.element_type.nullable { + bail!(offset, "type mismatch: non-defaultable element type"); + } + } + TableInit::Expr(expr) => { + if !features.function_references { + bail!( + offset, + "tables with expression initializers require \ + the function-references proposal" + ); + } + self.check_const_expr(expr, table.ty.element_type.into(), features, types)?; + } + } + self.module.assert_mut().tables.push(table.ty); + Ok(()) + } + pub fn add_data_segment( &mut self, data: Data, @@ -174,11 +198,9 @@ impl ModuleState { ) -> Result<()> { // the `funcref` value type is allowed all the way back to the MVP, so // don't check it here - if e.ty != ValType::FuncRef { - check_value_type(e.ty, features, offset)?; - } - if !e.ty.is_reference_type() { - return Err(BinaryReaderError::new("malformed reference type", offset)); + if e.ty != RefType::FUNCREF { + self.module + .check_value_type(ValType::Ref(e.ty), features, types, offset)?; } match e.kind { ElementKind::Active { @@ -186,9 +208,16 @@ impl ModuleState { offset_expr, } => { let table = self.module.table_at(table_index, offset)?; - if e.ty != table.element_type { + if !self + .module + .matches(ValType::Ref(e.ty), ValType::Ref(table.element_type), types) + { return Err(BinaryReaderError::new( - "invalid element type for table type", + format!( + "type mismatch: invalid element type `{}` for table type `{}`", + ty_to_str(e.ty.into()), + ty_to_str(table.element_type.into()), + ), offset, )); } @@ -217,15 +246,16 @@ impl ModuleState { }; match e.items { crate::ElementItems::Functions(reader) => { - validate_count(reader.count())?; + let count = reader.count(); + if !e.ty.nullable && count <= 0 { + return Err(BinaryReaderError::new( + "a non-nullable element must come with an initialization expression", + offset, + )); + } + validate_count(count)?; for f in reader.into_iter_with_offsets() { let (offset, f) = f?; - if e.ty != ValType::FuncRef { - return Err(BinaryReaderError::new( - "type mismatch: segment does not have funcref type", - offset, - )); - } self.module.get_func_type(f, types, offset)?; self.module.assert_mut().function_references.insert(f); } @@ -233,7 +263,7 @@ impl ModuleState { crate::ElementItems::Expressions(reader) => { validate_count(reader.count())?; for expr in reader { - self.check_const_expr(&expr?, e.ty, features, types)?; + self.check_const_expr(&expr?, ValType::Ref(e.ty), features, types)?; } } } @@ -448,7 +478,7 @@ pub(crate) struct Module { pub tables: Vec, pub memories: Vec, pub globals: Vec, - pub element_types: Vec, + pub element_types: Vec, pub data_count: Option, // Stores indexes into `types`. pub functions: Vec, @@ -473,7 +503,7 @@ impl Module { let ty = match ty { crate::Type::Func(t) => { for ty in t.params().iter().chain(t.results()) { - check_value_type(*ty, features, offset)?; + self.check_value_type(*ty, features, types, offset)?; } if t.results().len() > 1 && !features.multi_value { return Err(BinaryReaderError::new( @@ -586,17 +616,6 @@ impl Module { Ok(()) } - pub fn add_table( - &mut self, - ty: TableType, - features: &WasmFeatures, - offset: usize, - ) -> Result<()> { - self.check_table_type(&ty, features, offset)?; - self.tables.push(ty); - Ok(()) - } - pub fn add_memory( &mut self, ty: MemoryType, @@ -651,7 +670,7 @@ impl Module { EntityType::Func(self.types[*type_index as usize]) } TypeRef::Table(t) => { - self.check_table_type(t, features, offset)?; + self.check_table_type(t, features, types, offset)?; EntityType::Table(*t) } TypeRef::Memory(t) => { @@ -663,7 +682,7 @@ impl Module { EntityType::Tag(self.types[t.func_type_idx as usize]) } TypeRef::Global(t) => { - self.check_global_type(t, features, offset)?; + self.check_global_type(t, features, types, offset)?; EntityType::Global(*t) } }) @@ -673,20 +692,15 @@ impl Module { &self, ty: &TableType, features: &WasmFeatures, + types: &TypeList, offset: usize, ) -> Result<()> { // the `funcref` value type is allowed all the way back to the MVP, so // don't check it here - if ty.element_type != ValType::FuncRef { - check_value_type(ty.element_type, features, offset)?; + if ty.element_type != RefType::FUNCREF { + self.check_value_type(ValType::Ref(ty.element_type), features, types, offset)? } - if !ty.element_type.is_reference_type() { - return Err(BinaryReaderError::new( - "element is not reference type", - offset, - )); - } self.check_limits(ty.initial, ty.maximum, offset)?; if ty.initial > MAX_WASM_TABLE_ENTRIES as u32 { return Err(BinaryReaderError::new( @@ -766,6 +780,100 @@ impl Module { .collect::>() } + fn check_value_type( + &self, + ty: ValType, + features: &WasmFeatures, + types: &TypeList, + offset: usize, + ) -> Result<()> { + match features.check_value_type(ty) { + Ok(()) => Ok(()), + Err(e) => Err(BinaryReaderError::new(e, offset)), + }?; + // The above only checks the value type for features. + // We must check it if it's a reference. + match ty { + ValType::Ref(rt) => { + self.check_ref_type(rt, types, offset)?; + } + _ => (), + } + Ok(()) + } + + fn check_ref_type(&self, ty: RefType, types: &TypeList, offset: usize) -> Result<()> { + // Check that the heap type is valid + match ty.heap_type { + HeapType::Func | HeapType::Extern => (), + HeapType::TypedFunc(type_index) => { + // Just check that the index is valid + self.func_type_at(type_index.into(), types, offset)?; + } + } + Ok(()) + } + + fn eq_valtypes(&self, ty1: ValType, ty2: ValType, types: &TypeList) -> bool { + match (ty1, ty2) { + (ValType::Ref(rt1), ValType::Ref(rt2)) => { + rt1.nullable == rt2.nullable + && match (rt1.heap_type, rt2.heap_type) { + (HeapType::Func, HeapType::Func) => true, + (HeapType::Extern, HeapType::Extern) => true, + (HeapType::TypedFunc(n1), HeapType::TypedFunc(n2)) => { + let n1 = self.func_type_at(n1.into(), types, 0).unwrap(); + let n2 = self.func_type_at(n2.into(), types, 0).unwrap(); + self.eq_fns(n1, n2, types) + } + (_, _) => false, + } + } + _ => ty1 == ty2, + } + } + fn eq_fns(&self, f1: &impl WasmFuncType, f2: &impl WasmFuncType, types: &TypeList) -> bool { + f1.len_inputs() == f2.len_inputs() + && f2.len_outputs() == f2.len_outputs() + && f1 + .inputs() + .zip(f2.inputs()) + .all(|(t1, t2)| self.eq_valtypes(t1, t2, types)) + && f1 + .outputs() + .zip(f2.outputs()) + .all(|(t1, t2)| self.eq_valtypes(t1, t2, types)) + } + + pub(crate) fn matches(&self, ty1: ValType, ty2: ValType, types: &TypeList) -> bool { + fn matches_null(null1: bool, null2: bool) -> bool { + (null1 == null2) || null2 + } + + let matches_heap = |ty1: HeapType, ty2: HeapType, types: &TypeList| -> bool { + match (ty1, ty2) { + (HeapType::TypedFunc(n1), HeapType::TypedFunc(n2)) => { + // Check whether the defined types are (structurally) equivalent. + let n1 = self.func_type_at(n1.into(), types, 0).unwrap(); + let n2 = self.func_type_at(n2.into(), types, 0).unwrap(); + self.eq_fns(n1, n2, types) + } + (HeapType::TypedFunc(_), HeapType::Func) => true, + (_, _) => ty1 == ty2, + } + }; + + let matches_ref = |ty1: RefType, ty2: RefType, types: &TypeList| -> bool { + matches_heap(ty1.heap_type, ty2.heap_type, types) + && matches_null(ty1.nullable, ty2.nullable) + }; + + match (ty1, ty2) { + (ValType::Ref(rt1), ValType::Ref(rt2)) => matches_ref(rt1, rt2, types), + (_, _) => ty1 == ty2, + } + } + fn check_tag_type( &self, ty: &TagType, @@ -793,9 +901,10 @@ impl Module { &self, ty: &GlobalType, features: &WasmFeatures, + types: &TypeList, offset: usize, ) -> Result<()> { - check_value_type(ty.content_type, features, offset) + self.check_value_type(ty.content_type, features, types, offset) } fn check_limits(&self, initial: T, maximum: Option, offset: usize) -> Result<()> @@ -974,14 +1083,27 @@ impl WasmModuleResources for OperatorValidatorResources<'_> { ) } - fn type_of_function(&self, at: u32) -> Option<&Self::FuncType> { - self.func_type_at(*self.module.functions.get(at as usize)?) + fn type_index_of_function(&self, at: u32) -> Option { + self.module.functions.get(at as usize).cloned() } - fn element_type_at(&self, at: u32) -> Option { + fn type_of_function(&self, at: u32) -> Option<&Self::FuncType> { + self.func_type_at(self.type_index_of_function(at)?) + } + + fn check_value_type(&self, t: ValType, features: &WasmFeatures, offset: usize) -> Result<()> { + self.module + .check_value_type(t, features, self.types, offset) + } + + fn element_type_at(&self, at: u32) -> Option { self.module.element_types.get(at as usize).cloned() } + fn matches(&self, t1: ValType, t2: ValType) -> bool { + self.module.matches(t1, t2, self.types) + } + fn element_count(&self) -> u32 { self.module.element_types.len() as u32 } @@ -1030,14 +1152,27 @@ impl WasmModuleResources for ValidatorResources { ) } - fn type_of_function(&self, at: u32) -> Option<&Self::FuncType> { - self.func_type_at(*self.0.functions.get(at as usize)?) + fn type_index_of_function(&self, at: u32) -> Option { + self.0.functions.get(at as usize).cloned() } - fn element_type_at(&self, at: u32) -> Option { + fn type_of_function(&self, at: u32) -> Option<&Self::FuncType> { + self.func_type_at(self.type_index_of_function(at)?) + } + + fn check_value_type(&self, t: ValType, features: &WasmFeatures, offset: usize) -> Result<()> { + self.0 + .check_value_type(t, features, self.0.snapshot.as_ref().unwrap(), offset) + } + + fn element_type_at(&self, at: u32) -> Option { self.0.element_types.get(at as usize).cloned() } + fn matches(&self, t1: ValType, t2: ValType) -> bool { + self.0.matches(t1, t2, self.0.snapshot.as_ref().unwrap()) + } + fn element_count(&self) -> u32 { self.0.element_types.len() as u32 } diff --git a/third_party/rust/wasmparser/src/validator/func.rs b/third_party/rust/wasmparser/src/validator/func.rs index d6396fca982d..4d405f9615f7 100644 --- a/third_party/rust/wasmparser/src/validator/func.rs +++ b/third_party/rust/wasmparser/src/validator/func.rs @@ -119,7 +119,8 @@ impl FuncValidator { /// This should be used if the application is already reading local /// definitions and there's no need to re-parse the function again. pub fn define_locals(&mut self, offset: usize, count: u32, ty: ValType) -> Result<()> { - self.validator.define_locals(offset, count, ty) + self.validator + .define_locals(offset, count, ty, &self.resources) } /// Validates the next operator in a function. @@ -269,10 +270,24 @@ mod tests { fn func_type_at(&self, _type_idx: u32) -> Option<&Self::FuncType> { Some(&EmptyFuncType) } + fn type_index_of_function(&self, _at: u32) -> Option { + todo!() + } fn type_of_function(&self, _func_idx: u32) -> Option<&Self::FuncType> { todo!() } - fn element_type_at(&self, _at: u32) -> Option { + fn check_value_type( + &self, + _t: ValType, + _features: &WasmFeatures, + _offset: usize, + ) -> Result<()> { + Ok(()) + } + fn element_type_at(&self, _at: u32) -> Option { + todo!() + } + fn matches(&self, _t1: ValType, _t2: ValType) -> bool { todo!() } fn element_count(&self) -> u32 { diff --git a/third_party/rust/wasmparser/src/validator/operators.rs b/third_party/rust/wasmparser/src/validator/operators.rs index c43e6e79879c..54fee8acc609 100644 --- a/third_party/rust/wasmparser/src/validator/operators.rs +++ b/third_party/rust/wasmparser/src/validator/operators.rs @@ -23,25 +23,30 @@ // the various methods here. use crate::{ - limits::MAX_WASM_FUNCTION_LOCALS, BinaryReaderError, BlockType, BrTable, Ieee32, Ieee64, - MemArg, Result, ValType, VisitOperator, WasmFeatures, WasmFuncType, WasmModuleResources, V128, + limits::MAX_WASM_FUNCTION_LOCALS, BinaryReaderError, BlockType, BrTable, HeapType, Ieee32, + Ieee64, MemArg, RefType, Result, ValType, VisitOperator, WasmFeatures, WasmFuncType, + WasmModuleResources, V128, }; use std::ops::{Deref, DerefMut}; pub(crate) struct OperatorValidator { pub(super) locals: Locals, + pub(super) local_inits: Vec, // This is a list of flags for wasm features which are used to gate various // instructions. pub(crate) features: WasmFeatures, // Temporary storage used during the validation of `br_table`. - br_table_tmp: Vec>, + br_table_tmp: Vec, /// The `control` list is the list of blocks that we're currently in. control: Vec, /// The `operands` is the current type stack. - operands: Vec>, + operands: Vec, + /// When local_inits is modified, the relevant index is recorded here to be + /// undone when control pops + inits: Vec, /// Offset of the `end` instruction which emptied the `control` stack, which /// must be the end of the function. @@ -92,6 +97,8 @@ pub struct Frame { pub height: usize, /// Whether this frame is unreachable so far. pub unreachable: bool, + /// The number of initializations in the stack at the time of its creation + pub init_height: usize, } /// The kind of a control flow [`Frame`]. @@ -133,25 +140,55 @@ struct OperatorValidatorTemp<'validator, 'resources, T> { #[derive(Default)] pub struct OperatorValidatorAllocations { - br_table_tmp: Vec>, + br_table_tmp: Vec, control: Vec, - operands: Vec>, + operands: Vec, + local_inits: Vec, + inits: Vec, locals_first: Vec, locals_all: Vec<(u32, ValType)>, } +/// Type storage within the validator. +/// +/// This is used to manage the operand stack and notably isn't just `ValType` to +/// handle unreachable code and the "bottom" type. +#[derive(Debug, Copy, Clone)] +enum MaybeType { + Bot, + HeapBot, + Type(ValType), +} + +// The validator is pretty performance-sensitive and `MaybeType` is the main +// unit of storage, so assert that it doesn't exceed 4 bytes which is the +// current expected size. +const _: () = { + assert!(std::mem::size_of::() == 4); +}; + +impl From for MaybeType { + fn from(ty: ValType) -> MaybeType { + MaybeType::Type(ty) + } +} + impl OperatorValidator { fn new(features: &WasmFeatures, allocs: OperatorValidatorAllocations) -> Self { let OperatorValidatorAllocations { br_table_tmp, control, operands, + local_inits, + inits, locals_first, locals_all, } = allocs; debug_assert!(br_table_tmp.is_empty()); debug_assert!(control.is_empty()); debug_assert!(operands.is_empty()); + debug_assert!(local_inits.is_empty()); + debug_assert!(inits.is_empty()); debug_assert!(locals_first.is_empty()); debug_assert!(locals_all.is_empty()); OperatorValidator { @@ -160,6 +197,8 @@ impl OperatorValidator { first: locals_first, all: locals_all, }, + local_inits, + inits, features: *features, br_table_tmp, operands, @@ -189,6 +228,7 @@ impl OperatorValidator { block_type: BlockType::FuncType(ty), height: 0, unreachable: false, + init_height: 0, }); let params = OperatorValidatorTemp { // This offset is used by the `func_type_at` and `inputs`. @@ -200,6 +240,7 @@ impl OperatorValidator { .inputs(); for ty in params { ret.locals.define(1, ty); + ret.local_inits.push(true); } Ok(ret) } @@ -218,14 +259,19 @@ impl OperatorValidator { block_type: BlockType::Type(ty), height: 0, unreachable: false, + init_height: 0, }); ret } - pub fn define_locals(&mut self, offset: usize, count: u32, ty: ValType) -> Result<()> { - self.features - .check_value_type(ty) - .map_err(|e| BinaryReaderError::new(e, offset))?; + pub fn define_locals( + &mut self, + offset: usize, + count: u32, + ty: ValType, + resources: &impl WasmModuleResources, + ) -> Result<()> { + resources.check_value_type(ty, &self.features, offset)?; if count == 0 { return Ok(()); } @@ -235,6 +281,8 @@ impl OperatorValidator { offset, )); } + self.local_inits + .resize(self.local_inits.len() + count as usize, ty.is_defaultable()); Ok(()) } @@ -254,7 +302,10 @@ impl OperatorValidator { /// /// A `depth` of 0 will refer to the last operand on the stack. pub fn peek_operand_at(&self, depth: usize) -> Option> { - self.operands.iter().rev().nth(depth).copied() + Some(match self.operands.iter().rev().nth(depth)? { + MaybeType::Type(t) => Some(*t), + MaybeType::Bot | MaybeType::HeapBot => None, + }) } /// Returns the number of frames on the control flow stack. @@ -314,6 +365,8 @@ impl OperatorValidator { br_table_tmp: truncate(self.br_table_tmp), control: truncate(self.control), operands: truncate(self.operands), + local_inits: truncate(self.local_inits), + inits: truncate(self.inits), locals_first: truncate(self.locals.first), locals_all: truncate(self.locals.all), } @@ -341,7 +394,7 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R /// Otherwise the push operation always succeeds. fn push_operand(&mut self, ty: T) -> Result<()> where - T: Into>, + T: Into, { let maybe_ty = ty.into(); self.operands.push(maybe_ty); @@ -355,7 +408,7 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R /// simply that something is needed to be popped. /// /// If `expected` is `Some(T)` then this will be guaranteed to return - /// `Some(T)`, and it will only return success if the current block is + /// `T`, and it will only return success if the current block is /// unreachable or if `T` was found at the top of the operand stack. /// /// If `expected` is `None` then it indicates that something must be on the @@ -366,7 +419,7 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R /// matches `expected`. If `None` is returned then it means that `None` was /// expected and a type was successfully popped, but its exact type is /// indeterminate because the current block is unreachable. - fn pop_operand(&mut self, expected: Option) -> Result> { + fn pop_operand(&mut self, expected: Option) -> Result { // This method is one of the hottest methods in the validator so to // improve codegen this method contains a fast-path success case where // if the top operand on the stack is as expected it's returned @@ -378,17 +431,18 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R // matched against the state of the world to see if we could actually // pop it. If we shouldn't have popped it then it's passed to the slow // path to get pushed back onto the stack. - let popped = if let Some(actual_ty) = self.operands.pop() { - if actual_ty == expected { - if let Some(control) = self.control.last() { - if self.operands.len() >= control.height { - return Ok(actual_ty); + let popped = match self.operands.pop() { + Some(MaybeType::Type(actual_ty)) => { + if Some(actual_ty) == expected { + if let Some(control) = self.control.last() { + if self.operands.len() >= control.height { + return Ok(MaybeType::Type(actual_ty)); + } } } + Some(MaybeType::Type(actual_ty)) } - Some(actual_ty) - } else { - None + other => other, }; self._pop_operand(expected, popped) @@ -401,17 +455,17 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R fn _pop_operand( &mut self, expected: Option, - popped: Option>, - ) -> Result> { + popped: Option, + ) -> Result { self.operands.extend(popped); let control = match self.control.last() { Some(c) => c, None => return Err(self.err_beyond_end(self.offset)), }; - let actual = if self.operands.len() == control.height { - if control.unreachable { - None - } else { + let actual = if self.operands.len() == control.height && control.unreachable { + MaybeType::Bot + } else { + if self.operands.len() == control.height { let desc = match expected { Some(ty) => ty_to_str(ty), None => "a type", @@ -420,23 +474,59 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R self.offset, "type mismatch: expected {desc} but nothing on stack" ) + } else { + self.operands.pop().unwrap() } - } else { - self.operands.pop().unwrap() }; - if let (Some(actual_ty), Some(expected_ty)) = (actual, expected) { - if actual_ty != expected_ty { - bail!( - self.offset, - "type mismatch: expected {}, found {}", - ty_to_str(expected_ty), - ty_to_str(actual_ty) - ) + if let Some(expected) = expected { + match (actual, expected) { + // The bottom type matches all expectations + (MaybeType::Bot, _) + // The "heap bottom" type only matches other references types, + // but not any integer types. + | (MaybeType::HeapBot, ValType::Ref(_)) => {} + + // Use the `matches` predicate to test if a found type matches + // the expectation. + (MaybeType::Type(actual), expected) => { + if !self.resources.matches(actual, expected) { + bail!( + self.offset, + "type mismatch: expected {}, found {}", + ty_to_str(expected), + ty_to_str(actual) + ); + } + } + + // A "heap bottom" type cannot match any numeric types. + ( + MaybeType::HeapBot, + ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128, + ) => { + bail!( + self.offset, + "type mismatche: expected {}, found heap type", + ty_to_str(expected) + ) + } } } Ok(actual) } + fn pop_ref(&mut self) -> Result> { + match self.pop_operand(None)? { + MaybeType::Bot | MaybeType::HeapBot => Ok(None), + MaybeType::Type(ValType::Ref(rt)) => Ok(Some(rt)), + MaybeType::Type(ty) => bail!( + self.offset, + "type mismatch: expected ref but found {}", + ty_to_str(ty) + ), + } + } + /// Fetches the type for the local at `idx`, returning an error if it's out /// of bounds. fn local(&self, idx: u32) -> Result { @@ -473,11 +563,13 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R // Push a new frame which has a snapshot of the height of the current // operand stack. let height = self.operands.len(); + let init_height = self.inits.len(); self.control.push(Frame { kind, block_type: ty, height, unreachable: false, + init_height, }); // All of the parameters are now also available in this control frame, // so we push them here in order. @@ -500,6 +592,12 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R }; let ty = frame.block_type; let height = frame.height; + let init_height = frame.init_height; + + // reset_locals in the spec + for init in self.inits.split_off(init_height) { + self.local_inits[init as usize] = false; + } // Pop all the result types, in reverse order, from the operand stack. // These types will, possibly, be transferred to the next frame. @@ -587,10 +685,9 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R fn check_block_type(&self, ty: BlockType) -> Result<()> { match ty { BlockType::Empty => Ok(()), - BlockType::Type(ty) => self - .features - .check_value_type(ty) - .map_err(|e| BinaryReaderError::new(e, self.offset)), + BlockType::Type(t) => self + .resources + .check_value_type(t, &self.features, self.offset), BlockType::FuncType(idx) => { if !self.features.multi_value { bail!( @@ -608,13 +705,25 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R /// Validates a `call` instruction, ensuring that the function index is /// in-bounds and the right types are on the stack to call the function. fn check_call(&mut self, function_index: u32) -> Result<()> { - let ty = match self.resources.type_of_function(function_index) { + let ty = match self.resources.type_index_of_function(function_index) { Some(i) => i, None => { bail!( self.offset, - "unknown function {}: function index out of bounds", - function_index + "unknown function {function_index}: function index out of bounds", + ); + } + }; + self.check_call_ty(ty) + } + + fn check_call_ty(&mut self, type_index: u32) -> Result<()> { + let ty = match self.resources.func_type_at(type_index) { + Some(i) => i, + None => { + bail!( + self.offset, + "unknown type {type_index}: type index out of bounds", ); } }; @@ -634,10 +743,13 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R bail!(self.offset, "unknown table: table index out of bounds"); } Some(tab) => { - if tab.element_type != ValType::FuncRef { + if !self + .resources + .matches(ValType::Ref(tab.element_type), ValType::FUNCREF) + { bail!( self.offset, - "indirect calls must go through a table of funcref" + "indirect calls must go through a table with type <= funcref", ); } } @@ -780,14 +892,6 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R self.check_v128_binary_op() } - /// Checks a [`V128`] binary operator. - fn check_v128_relaxed_binary_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; - Ok(()) - } - /// Checks a [`V128`] binary operator. fn check_v128_unary_op(&mut self) -> Result<()> { self.pop_operand(Some(ValType::V128))?; @@ -801,15 +905,8 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R self.check_v128_unary_op() } - /// Checks a [`V128`] binary operator. - fn check_v128_relaxed_unary_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; - Ok(()) - } - /// Checks a [`V128`] relaxed ternary operator. - fn check_v128_relaxed_ternary_op(&mut self) -> Result<()> { + fn check_v128_ternary_op(&mut self) -> Result<()> { self.pop_operand(Some(ValType::V128))?; self.pop_operand(Some(ValType::V128))?; self.pop_operand(Some(ValType::V128))?; @@ -879,15 +976,31 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R } } -fn ty_to_str(ty: ValType) -> &'static str { +pub fn ty_to_str(ty: ValType) -> &'static str { match ty { ValType::I32 => "i32", ValType::I64 => "i64", ValType::F32 => "f32", ValType::F64 => "f64", ValType::V128 => "v128", - ValType::FuncRef => "funcref", - ValType::ExternRef => "externref", + ValType::FUNCREF => "funcref", + ValType::EXTERNREF => "externref", + ValType::Ref(RefType { + nullable: false, + heap_type: HeapType::Func, + }) => "(ref func)", + ValType::Ref(RefType { + nullable: false, + heap_type: HeapType::Extern, + }) => "(ref extern)", + ValType::Ref(RefType { + nullable: false, + heap_type: HeapType::TypedFunc(_), + }) => "(ref $type)", + ValType::Ref(RefType { + nullable: true, + heap_type: HeapType::TypedFunc(_), + }) => "(ref null $type)", } } @@ -936,6 +1049,7 @@ macro_rules! validate_proposal { (desc sign_extension) => ("sign extension operations"); (desc exceptions) => ("exceptions"); (desc tail_call) => ("tail calls"); + (desc function_references) => ("function references"); (desc memory_control) => ("memory control"); } @@ -1009,11 +1123,13 @@ where } // Start a new frame and push `exnref` value. let height = self.operands.len(); + let init_height = self.inits.len(); self.control.push(Frame { kind: FrameKind::Catch, block_type: frame.block_type, height, unreachable: false, + init_height, }); // Push exception argument types. let ty = self.tag_at(index)?; @@ -1071,11 +1187,13 @@ where bail!(self.offset, "catch_all found outside of a `try` block"); } let height = self.operands.len(); + let init_height = self.inits.len(); self.control.push(Frame { kind: FrameKind::CatchAll, block_type: frame.block_type, height, unreachable: false, + init_height, }); Ok(()) } @@ -1162,6 +1280,39 @@ where self.check_return()?; Ok(()) } + fn visit_call_ref(&mut self, hty: HeapType) -> Self::Output { + self.resources + .check_heap_type(hty, &self.features, self.offset)?; + // If `None` is popped then that means a "bottom" type was popped which + // is always considered equivalent to the `hty` tag. + if let Some(rt) = self.pop_ref()? { + let expected = RefType { + nullable: true, + heap_type: hty, + }; + if !self + .resources + .matches(ValType::Ref(rt), ValType::Ref(expected)) + { + bail!( + self.offset, + "type mismatch: funcref on stack does not match specified type", + ); + } + } + match hty { + HeapType::TypedFunc(type_index) => self.check_call_ty(type_index.into())?, + _ => bail!( + self.offset, + "type mismatch: instruction requires function reference type", + ), + } + Ok(()) + } + fn visit_return_call_ref(&mut self, hty: HeapType) -> Self::Output { + self.visit_call_ref(hty)?; + self.check_return() + } fn visit_call_indirect( &mut self, index: u32, @@ -1190,36 +1341,42 @@ where self.pop_operand(Some(ValType::I32))?; let ty1 = self.pop_operand(None)?; let ty2 = self.pop_operand(None)?; - fn is_num(ty: Option) -> bool { - matches!( - ty, - Some(ValType::I32) - | Some(ValType::I64) - | Some(ValType::F32) - | Some(ValType::F64) - | Some(ValType::V128) - | None - ) - } - if !is_num(ty1) || !is_num(ty2) { - bail!( - self.offset, - "type mismatch: select only takes integral types" - ) - } - if ty1 != ty2 && ty1.is_some() && ty2.is_some() { - bail!( - self.offset, - "type mismatch: select operands have different types" - ) - } - self.push_operand(ty1.or(ty2))?; + + let ty = match (ty1, ty2) { + // All heap-related types aren't allowed with the `select` + // instruction + (MaybeType::HeapBot, _) + | (_, MaybeType::HeapBot) + | (MaybeType::Type(ValType::Ref(_)), _) + | (_, MaybeType::Type(ValType::Ref(_))) => { + bail!( + self.offset, + "type mismatch: select only takes integral types" + ) + } + + // If one operand is the "bottom" type then whatever the other + // operand is is the result of the `select` + (MaybeType::Bot, t) | (t, MaybeType::Bot) => t, + + // Otherwise these are two integral types and they must match for + // `select` to typecheck. + (t @ MaybeType::Type(t1), MaybeType::Type(t2)) => { + if t1 != t2 { + bail!( + self.offset, + "type mismatch: select operands have different types" + ); + } + t + } + }; + self.push_operand(ty)?; Ok(()) } fn visit_typed_select(&mut self, ty: ValType) -> Self::Output { - self.features - .check_value_type(ty) - .map_err(|e| BinaryReaderError::new(e, self.offset))?; + self.resources + .check_value_type(ty, &self.features, self.offset)?; self.pop_operand(Some(ValType::I32))?; self.pop_operand(Some(ty))?; self.pop_operand(Some(ty))?; @@ -1228,17 +1385,29 @@ where } fn visit_local_get(&mut self, local_index: u32) -> Self::Output { let ty = self.local(local_index)?; + if !self.local_inits[local_index as usize] { + bail!(self.offset, "uninitialized local: {}", local_index); + } self.push_operand(ty)?; Ok(()) } fn visit_local_set(&mut self, local_index: u32) -> Self::Output { let ty = self.local(local_index)?; self.pop_operand(Some(ty))?; + if !self.local_inits[local_index as usize] { + self.local_inits[local_index as usize] = true; + self.inits.push(local_index); + } Ok(()) } fn visit_local_tee(&mut self, local_index: u32) -> Self::Output { let ty = self.local(local_index)?; self.pop_operand(Some(ty))?; + if !self.local_inits[local_index as usize] { + self.local_inits[local_index as usize] = true; + self.inits.push(local_index); + } + self.push_operand(ty)?; Ok(()) } @@ -2049,43 +2218,119 @@ where fn visit_atomic_fence(&mut self) -> Self::Output { Ok(()) } - fn visit_ref_null(&mut self, ty: ValType) -> Self::Output { - self.features - .check_value_type(ty) - .map_err(|e| BinaryReaderError::new(e, self.offset))?; - if !ty.is_reference_type() { - bail!(self.offset, "invalid non-reference type in ref.null"); + fn visit_ref_null(&mut self, heap_type: HeapType) -> Self::Output { + self.resources + .check_heap_type(heap_type, &self.features, self.offset)?; + self.push_operand(ValType::Ref(RefType { + nullable: true, + heap_type, + }))?; + Ok(()) + } + + fn visit_ref_as_non_null(&mut self) -> Self::Output { + let ty = match self.pop_ref()? { + Some(ty) => MaybeType::Type(ValType::Ref(RefType { + nullable: false, + heap_type: ty.heap_type, + })), + None => MaybeType::HeapBot, + }; + self.push_operand(ty)?; + Ok(()) + } + fn visit_br_on_null(&mut self, relative_depth: u32) -> Self::Output { + let ty = match self.pop_ref()? { + None => MaybeType::HeapBot, + Some(ty) => MaybeType::Type(ValType::Ref(RefType { + nullable: false, + heap_type: ty.heap_type, + })), + }; + let (ft, kind) = self.jump(relative_depth)?; + for ty in self.label_types(ft, kind)?.rev() { + self.pop_operand(Some(ty))?; + } + for ty in self.label_types(ft, kind)? { + self.push_operand(ty)?; } self.push_operand(ty)?; Ok(()) } - fn visit_ref_is_null(&mut self) -> Self::Output { - match self.pop_operand(None)? { - None => {} - Some(t) => { - if !t.is_reference_type() { + fn visit_br_on_non_null(&mut self, relative_depth: u32) -> Self::Output { + let ty = self.pop_ref()?; + let (ft, kind) = self.jump(relative_depth)?; + let mut lts = self.label_types(ft, kind)?; + match (lts.next_back(), ty) { + (None, _) => bail!( + self.offset, + "type mismatch: br_on_non_null target has no label types", + ), + (Some(ValType::Ref(_)), None) => {} + (Some(rt1 @ ValType::Ref(_)), Some(rt0)) => { + // Switch rt0, our popped type, to a non-nullable type and + // perform the match because if the branch is taken it's a + // non-null value. + let ty = RefType { + nullable: false, + heap_type: rt0.heap_type, + }; + if !self.resources.matches(ty.into(), rt1) { bail!( self.offset, - "type mismatch: invalid reference type in ref.is_null" - ); + "type mismatch: expected {} but found {}", + ty_to_str(rt0.into()), + ty_to_str(rt1) + ) } } + (Some(_), _) => bail!( + self.offset, + "type mismatch: br_on_non_null target does not end with heap type", + ), } + for ty in self.label_types(ft, kind)?.rev().skip(1) { + self.pop_operand(Some(ty))?; + } + for ty in lts { + self.push_operand(ty)?; + } + Ok(()) + } + fn visit_ref_is_null(&mut self) -> Self::Output { + self.pop_ref()?; self.push_operand(ValType::I32)?; Ok(()) } fn visit_ref_func(&mut self, function_index: u32) -> Self::Output { - if self.resources.type_of_function(function_index).is_none() { - bail!( + let type_index = match self.resources.type_index_of_function(function_index) { + Some(idx) => idx, + None => bail!( self.offset, "unknown function {}: function index out of bounds", function_index, - ); - } + ), + }; if !self.resources.is_function_referenced(function_index) { bail!(self.offset, "undeclared function reference"); } - self.push_operand(ValType::FuncRef)?; + + // FIXME(#924) this should not be conditional based on enabled + // proposals. + if self.features.function_references { + let heap_type = HeapType::TypedFunc(match type_index.try_into() { + Ok(packed) => packed, + Err(_) => { + bail!(self.offset, "type index of `ref.func` target too large") + } + }); + self.push_operand(ValType::Ref(RefType { + nullable: false, + heap_type, + }))?; + } else { + self.push_operand(ValType::FUNCREF)?; + } Ok(()) } fn visit_v128_load(&mut self, memarg: MemArg) -> Self::Output { @@ -2296,24 +2541,6 @@ where fn visit_f64x2_pmax(&mut self) -> Self::Output { self.check_v128_fbinary_op() } - fn visit_f32x4_relaxed_min(&mut self) -> Self::Output { - self.check_v128_relaxed_binary_op() - } - fn visit_f32x4_relaxed_max(&mut self) -> Self::Output { - self.check_v128_relaxed_binary_op() - } - fn visit_f64x2_relaxed_min(&mut self) -> Self::Output { - self.check_v128_relaxed_binary_op() - } - fn visit_f64x2_relaxed_max(&mut self) -> Self::Output { - self.check_v128_relaxed_binary_op() - } - fn visit_i16x8_relaxed_q15mulr_s(&mut self) -> Self::Output { - self.check_v128_relaxed_binary_op() - } - fn visit_i16x8_dot_i8x16_i7x16_s(&mut self) -> Self::Output { - self.check_v128_relaxed_binary_op() - } fn visit_i8x16_eq(&mut self) -> Self::Output { self.check_v128_binary_op() } @@ -2737,18 +2964,6 @@ where fn visit_i32x4_extadd_pairwise_i16x8_u(&mut self) -> Self::Output { self.check_v128_unary_op() } - fn visit_i32x4_relaxed_trunc_sat_f32x4_s(&mut self) -> Self::Output { - self.check_v128_relaxed_unary_op() - } - fn visit_i32x4_relaxed_trunc_sat_f32x4_u(&mut self) -> Self::Output { - self.check_v128_relaxed_unary_op() - } - fn visit_i32x4_relaxed_trunc_sat_f64x2_s_zero(&mut self) -> Self::Output { - self.check_v128_relaxed_unary_op() - } - fn visit_i32x4_relaxed_trunc_sat_f64x2_u_zero(&mut self) -> Self::Output { - self.check_v128_relaxed_unary_op() - } fn visit_v128_bitselect(&mut self) -> Self::Output { self.pop_operand(Some(ValType::V128))?; self.pop_operand(Some(ValType::V128))?; @@ -2756,35 +2971,68 @@ where self.push_operand(ValType::V128)?; Ok(()) } - fn visit_f32x4_relaxed_fma(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + fn visit_i8x16_relaxed_swizzle(&mut self) -> Self::Output { + self.pop_operand(Some(ValType::V128))?; + self.pop_operand(Some(ValType::V128))?; + self.push_operand(ValType::V128)?; + Ok(()) } - fn visit_f32x4_relaxed_fnma(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + fn visit_i32x4_relaxed_trunc_f32x4_s(&mut self) -> Self::Output { + self.check_v128_unary_op() } - fn visit_f64x2_relaxed_fma(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + fn visit_i32x4_relaxed_trunc_f32x4_u(&mut self) -> Self::Output { + self.check_v128_unary_op() } - fn visit_f64x2_relaxed_fnma(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + fn visit_i32x4_relaxed_trunc_f64x2_s_zero(&mut self) -> Self::Output { + self.check_v128_unary_op() + } + fn visit_i32x4_relaxed_trunc_f64x2_u_zero(&mut self) -> Self::Output { + self.check_v128_unary_op() + } + fn visit_f32x4_relaxed_madd(&mut self) -> Self::Output { + self.check_v128_ternary_op() + } + fn visit_f32x4_relaxed_nmadd(&mut self) -> Self::Output { + self.check_v128_ternary_op() + } + fn visit_f64x2_relaxed_madd(&mut self) -> Self::Output { + self.check_v128_ternary_op() + } + fn visit_f64x2_relaxed_nmadd(&mut self) -> Self::Output { + self.check_v128_ternary_op() } fn visit_i8x16_relaxed_laneselect(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + self.check_v128_ternary_op() } fn visit_i16x8_relaxed_laneselect(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + self.check_v128_ternary_op() } fn visit_i32x4_relaxed_laneselect(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + self.check_v128_ternary_op() } fn visit_i64x2_relaxed_laneselect(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + self.check_v128_ternary_op() } - fn visit_i32x4_dot_i8x16_i7x16_add_s(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + fn visit_f32x4_relaxed_min(&mut self) -> Self::Output { + self.check_v128_binary_op() } - fn visit_f32x4_relaxed_dot_bf16x8_add_f32x4(&mut self) -> Self::Output { - self.check_v128_relaxed_ternary_op() + fn visit_f32x4_relaxed_max(&mut self) -> Self::Output { + self.check_v128_binary_op() + } + fn visit_f64x2_relaxed_min(&mut self) -> Self::Output { + self.check_v128_binary_op() + } + fn visit_f64x2_relaxed_max(&mut self) -> Self::Output { + self.check_v128_binary_op() + } + fn visit_i16x8_relaxed_q15mulr_s(&mut self) -> Self::Output { + self.check_v128_binary_op() + } + fn visit_i16x8_relaxed_dot_i8x16_i7x16_s(&mut self) -> Self::Output { + self.check_v128_binary_op() + } + fn visit_i32x4_relaxed_dot_i8x16_i7x16_add_s(&mut self) -> Self::Output { + self.check_v128_ternary_op() } fn visit_v128_any_true(&mut self) -> Self::Output { self.check_v128_bitmask_op() @@ -2855,12 +3103,6 @@ where self.push_operand(ValType::V128)?; Ok(()) } - fn visit_i8x16_relaxed_swizzle(&mut self) -> Self::Output { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; - Ok(()) - } fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { self.pop_operand(Some(ValType::V128))?; self.pop_operand(Some(ValType::V128))?; @@ -3070,7 +3312,10 @@ where (Some(a), Some(b)) => (a, b), _ => bail!(self.offset, "table index out of bounds"), }; - if src.element_type != dst.element_type { + if !self.resources.matches( + ValType::Ref(src.element_type), + ValType::Ref(dst.element_type), + ) { bail!(self.offset, "type mismatch"); } self.pop_operand(Some(ValType::I32))?; @@ -3084,7 +3329,7 @@ where None => bail!(self.offset, "table index out of bounds"), }; self.pop_operand(Some(ValType::I32))?; - self.push_operand(ty)?; + self.push_operand(ValType::Ref(ty))?; Ok(()) } fn visit_table_set(&mut self, table: u32) -> Self::Output { @@ -3092,7 +3337,7 @@ where Some(ty) => ty.element_type, None => bail!(self.offset, "table index out of bounds"), }; - self.pop_operand(Some(ty))?; + self.pop_operand(Some(ValType::Ref(ty)))?; self.pop_operand(Some(ValType::I32))?; Ok(()) } @@ -3102,7 +3347,7 @@ where None => bail!(self.offset, "table index out of bounds"), }; self.pop_operand(Some(ValType::I32))?; - self.pop_operand(Some(ty))?; + self.pop_operand(Some(ValType::Ref(ty)))?; self.push_operand(ValType::I32)?; Ok(()) } @@ -3119,7 +3364,7 @@ where None => bail!(self.offset, "table index out of bounds"), }; self.pop_operand(Some(ValType::I32))?; - self.pop_operand(Some(ty))?; + self.pop_operand(Some(ValType::Ref(ty)))?; self.pop_operand(Some(ValType::I32))?; Ok(()) } diff --git a/third_party/rust/wasmparser/src/validator/types.rs b/third_party/rust/wasmparser/src/validator/types.rs index 418d1b67d609..ce0559d34c19 100644 --- a/third_party/rust/wasmparser/src/validator/types.rs +++ b/third_party/rust/wasmparser/src/validator/types.rs @@ -2,8 +2,8 @@ use super::{component::ComponentState, core::Module}; use crate::{ - ComponentExport, ComponentImport, Export, ExternalKind, FuncType, GlobalType, Import, - MemoryType, PrimitiveValType, TableType, TypeRef, ValType, + Export, ExternalKind, FuncType, GlobalType, Import, MemoryType, PrimitiveValType, RefType, + TableType, TypeRef, ValType, }; use indexmap::{IndexMap, IndexSet}; use std::collections::HashMap; @@ -1477,7 +1477,7 @@ impl<'a> TypesRef<'a> { /// /// Returns `None` if the type index is out of bounds or the type has not /// been parsed yet. - pub fn element_at(&self, index: u32) -> Option { + pub fn element_at(&self, index: u32) -> Option { match &self.kind { TypesRefKind::Module(module) => module.element_types.get(index as usize).copied(), TypesRefKind::Component(_) => None, @@ -1615,29 +1615,12 @@ impl<'a> TypesRef<'a> { } /// Gets the component entity type for the given component import. - pub fn component_entity_type_from_import( - &self, - import: &ComponentImport, - ) -> Option { + pub fn component_entity_type_of_extern(&self, name: &str) -> Option { match &self.kind { TypesRefKind::Module(_) => None, TypesRefKind::Component(component) => { - let key = KebabStr::new(import.name)?; - Some(component.imports.get(key)?.1) - } - } - } - - /// Gets the component entity type from the given component export. - pub fn component_entity_type_from_export( - &self, - export: &ComponentExport, - ) -> Option { - match &self.kind { - TypesRefKind::Module(_) => None, - TypesRefKind::Component(component) => { - let key = KebabStr::new(export.name)?; - Some(component.exports.get(key)?.1) + let key = KebabStr::new(name)?; + Some(component.externs.get(key)?.1) } } } @@ -1785,8 +1768,11 @@ impl Types { /// Gets the type of an element segment at the given element segment index. /// /// Returns `None` if the index is out of bounds. - pub fn element_at(&self, index: u32) -> Option { - self.as_ref().element_at(index) + pub fn element_at(&self, index: u32) -> Option { + match &self.kind { + TypesKind::Module(module) => module.element_types.get(index as usize).copied(), + TypesKind::Component(_) => None, + } } /// Gets the count of element segments. @@ -1897,20 +1883,10 @@ impl Types { self.as_ref().entity_type_from_export(export) } - /// Gets the component entity type for the given component import. - pub fn component_entity_type_from_import( - &self, - import: &ComponentImport, - ) -> Option { - self.as_ref().component_entity_type_from_import(import) - } - - /// Gets the component entity type from the given component export. - pub fn component_entity_type_from_export( - &self, - export: &ComponentExport, - ) -> Option { - self.as_ref().component_entity_type_from_export(export) + /// Gets the component entity type for the given component import or export + /// name. + pub fn component_entity_type_of_extern(&self, name: &str) -> Option { + self.as_ref().component_entity_type_of_extern(name) } /// Attempts to lookup the type id that `ty` is an alias of. diff --git a/third_party/rust/wasmparser/tests/big-module.rs b/third_party/rust/wasmparser/tests/big-module.rs new file mode 100644 index 000000000000..d5cf37f4a47b --- /dev/null +++ b/third_party/rust/wasmparser/tests/big-module.rs @@ -0,0 +1,32 @@ +use wasm_encoder::*; +#[test] +fn big_type_indices() { + const N: u32 = 100_000; + let mut module = Module::new(); + let mut types = TypeSection::new(); + for _ in 0..N { + types.function([], []); + } + module.section(&types); + let mut funcs = FunctionSection::new(); + funcs.function(N - 1); + module.section(&funcs); + + let mut elems = ElementSection::new(); + elems.declared(RefType::FUNCREF, Elements::Functions(&[0])); + module.section(&elems); + + let mut code = CodeSection::new(); + let mut body = Function::new([]); + body.instruction(&Instruction::RefFunc(0)); + body.instruction(&Instruction::Drop); + body.instruction(&Instruction::End); + code.function(&body); + module.section(&code); + + let wasm = module.finish(); + + wasmparser::Validator::default() + .validate_all(&wasm) + .unwrap(); +} diff --git a/third_party/rust/wast/.cargo-checksum.json b/third_party/rust/wast/.cargo-checksum.json index b22273df4752..bb516fdd552e 100644 --- a/third_party/rust/wast/.cargo-checksum.json +++ b/third_party/rust/wast/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"850e75bb52d3d9554e8a51133fcfdab2f749e3daade5af3d7ca1ce1031d37614","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"5a0d2b894a3ac74ee2be74715a2f22c40a08520cb4ac59183f4e7356f34ac566","src/component.rs":"23a62f4f2774ccfaf60f68e9d9416e68ba203eea782ce0c39cf553ad293f1df4","src/component/alias.rs":"0f7c281f5b3b6abd49f4722767781aff1167165528bf6876aa5514bdc895338d","src/component/binary.rs":"de704108b834de49cecbbaf0b0a62baa7e988e11f64509c09a92774e11234853","src/component/component.rs":"3a87e6507df7e4f9baab27e4e6ebfcea33f9bb3e640965402587f1175d2c9c44","src/component/custom.rs":"f5b23c34b73a716a986fd999fc8d8c9e24c341e83292088fe83325cd82dab4f5","src/component/expand.rs":"1b7ec67961913ca67ef0ff267173e91fe7abb27d579cc187fce1dfb5fc3c835c","src/component/export.rs":"40736da26dd22e7dee44c78aaae7834157d52283bddd547dbbf151cbdef86801","src/component/func.rs":"e6c499a0cc0675d9793684c74dabdbeaca077f8d026bce5ee0fe6d14d01c8d20","src/component/import.rs":"3bf1abfa8268b3b0c8a7ec972c634beff176929f541c7272b4bee7f731717624","src/component/instance.rs":"4590083b9fa05f3b343bd4fc91d11f546fbf50d705e8034abd3ea6be2243e6eb","src/component/item_ref.rs":"e8d2275fa06da4e00595e359adcf8b349cd1ae8dcf84573c1ffff2d2129331e1","src/component/module.rs":"d27a28199d1dea1c64294a514329a524432319288515b0a0e3091fa7d3a33f74","src/component/resolve.rs":"06f5b61305252f8b79eb82fa43618fe93e97ab6cd499ed322801888ecffb1c77","src/component/types.rs":"216119b457875cbd79e9c8f4ca221763304c201d11dbf92c2484f6a0df218b00","src/component/wast.rs":"cad13b2217134454d7d8b5f1f1cc9bc8a4f05c05c68da8ad39927833ed9f55be","src/core.rs":"24b71d1ab2ad874c4e37b4dd709b6532989b60e6bc503194434f95029cc1cda7","src/core/binary.rs":"827d53c74e47c6fbaa4bf733e8207e9e4396fe6601e3aa9e20402277ddf49138","src/core/custom.rs":"17a71b95c24c35e77ee082ad1f4f1a3bafd1df73ae3ad9bf31d58d7f52e47448","src/core/export.rs":"aa8f129a900f385de7577a7a15faefe927a1d36bdc7f68643a4d077898b2ac44","src/core/expr.rs":"18d126b299e2cc3cec8904a2f4044db6cf218c363f7a2c974404faafe05c94fc","src/core/func.rs":"d7df909a0799f0d93071a5d55da53fdaa93dfcb0570b1e509705c557bb586dc8","src/core/global.rs":"dec0abecadd2fde9298acb729259deba1ef3c4733ae5afcb4fe8cd4a633f5349","src/core/import.rs":"fcf7affc0d55d16a90ed45cd87ebda6faaeee4b8af7c4abe34ff20b0cb58d8fb","src/core/memory.rs":"d0c317a0df6cbc35048625091c46fab223594ca18a488056b7b84307487e6479","src/core/module.rs":"5d91a465ad4b1941af59fd00e15446ee9c73326d1e48cd3764c011bc15475130","src/core/resolve/deinline_import_export.rs":"b04b953baa68290aabcfe776ef97ef4080c42614f04671ef84ae53a626fb3d4f","src/core/resolve/mod.rs":"9b2680b00a1cafad2dbbfdac86aa1c135ea67203bbc4dee939302b27f4aff6d0","src/core/resolve/names.rs":"b3eebdb498a8221139229200b4ba71c107ae6e7a226d5e0a944cd77d0a8582e2","src/core/resolve/types.rs":"f3cfa900d14d372f0f7012642dd1b0f44d483a5f2d5c338f99233f35ad625139","src/core/table.rs":"a9e39954b3f7dd8d6d0cd295c35857f975bf6ca17d971f1f23f79b8a86ed224c","src/core/tag.rs":"8a3d4fcdb86dedd68cdaf25abd930ef52a461cf2a0e9393bb9cb6f425afaaf2e","src/core/types.rs":"1410e6fd5869c63384a7c28111829ad21824572a0efe136ba6f5260b34e2b539","src/core/wast.rs":"e0bac688470d15db05bb0aca4ce9ad835c323a96695a8064744651a80b2cfb99","src/encode.rs":"9f4baef7b63a7cdb473051929a06dd1e7713bc0d002f2d565ca679b712dd8147","src/error.rs":"4526260299c7983696a49ffe30a80139beb0d081fa8f42decc5e3283b361b1cb","src/gensym.rs":"b5e02e34443085f01deb5b657e541be7dc5d6dc952304e434a0b08320ea6c185","src/lexer.rs":"18592756bd124a0233c57ff58e8b9da7c7e9249e75415fd69bc07d6ca2caa25f","src/lib.rs":"5a39e63415adf7a7d42a0c6791514136f3ab70d9afbbcb04288c48621597ae4f","src/names.rs":"12aee27a752b4b9943bb0d24f759ff1685575988a888af4267b0460be86b314d","src/parser.rs":"0396149ae2f80d34bde6cdde35b26b048126f7ce305c96032132b1cbe7b426c9","src/token.rs":"abd4840c996b8110d7fc4cbe400bef14dabd87bdacd32f684ae253b60703d4b7","src/wast.rs":"db6f57f70436aaa23136821c1a98045809930b712fcb162547ccbb159d33ff25","src/wat.rs":"e8dbfad184a156c88ced3da82cbe8cddc4c0d4e5468cdd430110abc85415c14d","tests/annotations.rs":"06294077550600f93a5a8c0d7e3ac38b47f00bb8933f9dc390ff31868e873afb","tests/comments.rs":"2861aa6efb500b9b26633a151b27dddeca5b295a1f20d2f3892377889af60550","tests/parse-fail.rs":"0f1d5dffd1e6145105571222096703c89c4f4a46e25c848faa730f731155ea1c","tests/parse-fail/bad-index.wat":"d21489daeec3a35327dcc9e2ba2d0acdd05f4aeaff2272cca608fda4d2338497","tests/parse-fail/bad-index.wat.err":"dc11070de0c9160573006ea4e5fa3c4d28e71bc39b24b1938cf6ff3b03ea7154","tests/parse-fail/bad-name.wat":"e5ff5d410007779a0de6609ea4cc693f0e603d36a106b8f5098c1980dd9f8124","tests/parse-fail/bad-name.wat.err":"fb5638476c1b85d9d1919e3dbcb0f16f82d088a4a22d4a0c186d7b8ba6e1902b","tests/parse-fail/bad-name2.wat":"5a6a4d0c19e5f2e48d7cebf361aca9b9000b7ef0c652997b5bd0ffaadbd2ca8a","tests/parse-fail/bad-name2.wat.err":"129707cce45f1e3cfb3e2ca5c702182e16ca5eeb2dbb2edd0710b004a8e194a5","tests/parse-fail/bad-name3.wat":"c19133d738cc84e9174301f27d4050c216bda81c7e9918d03ac792b088f24a05","tests/parse-fail/bad-name3.wat.err":"84ea63d40a619a0782ec6e94fce63921188ab87b1c3875eacae0a371144ed83a","tests/parse-fail/block1.wat":"91e74b5c3b43be692e7a6ae74fbfa674c4b6197299eb61338c4eccf282b18f17","tests/parse-fail/block1.wat.err":"40a083ae496b41dee7002cc6a664c5db0c5e4d904ae03b815773a769c4493fca","tests/parse-fail/block2.wat":"a8c07b4c09d51f10a8ffdf19806586022552398701cd90eb6d09816d45df06e5","tests/parse-fail/block2.wat.err":"33c842ec5dd0f2fdd3a9ce8187dd98b45ceee48c12810802af809d05b9cd25e9","tests/parse-fail/block3.wat":"29739abfbabd7c55f00ddfbbb9ebd818b4a114ef2336d50514f0842f7e075905","tests/parse-fail/block3.wat.err":"fc667ae2e71a260f62a3c7393bc97272e7c0ff38b17594f4370847b8a5019060","tests/parse-fail/confusing-block-comment0.wat":"8f27c9d0d212bbb1862ea89ffd7cbeafde5dfd755d695c1ba696cd520aba1a1d","tests/parse-fail/confusing-block-comment0.wat.err":"b53cbaef7bcec3862c64e09c084b92cd61bd29b954125482b2d083db250cd9e2","tests/parse-fail/confusing-block-comment1.wat":"b1a0447c9a8eaab8938d15cd33bd4adbb8bb69c2d710209b604023991a4347cb","tests/parse-fail/confusing-block-comment1.wat.err":"2fc3b3e4f98416326e1e5ec034026301069b6a98fa24451bc7573e16b8cb3811","tests/parse-fail/confusing-block-comment2.wat":"e3f49c7a388fba81081beb25d87bbd7db0acce5dd8e3eaa04574905ed7ec420c","tests/parse-fail/confusing-block-comment2.wat.err":"2183231d6acd0b5a117f9aea747c3d5c12e758450a6cd74027bb954a3134cf19","tests/parse-fail/confusing-block-comment3.wat":"d83f89c582501eb8833e772b8462c8974984a2f7fbb80b1452dc399fac74e5ed","tests/parse-fail/confusing-block-comment3.wat.err":"8b2096a4833627905c63f49cdabe44be24336646578dcfbdc67e9bfb35cbc601","tests/parse-fail/confusing-block-comment4.wat":"b7c6c68844d918e9ef6dd5ab9c40c7de7b38f04f94fadad630eda4e596f3e0f8","tests/parse-fail/confusing-block-comment4.wat.err":"2f790cc511edfcd89a12c9207901be16039fc1a06a584d73095e77a52f861cd9","tests/parse-fail/confusing-block-comment5.wat":"a159808032638cc914fa80ac4354a68b0af4f435a09cbe3e2d577582e183eb0a","tests/parse-fail/confusing-block-comment5.wat.err":"6fe0d99894307442f83fe93beaa5da706e06c9bdaf8e39d7cbae4c4fffafcb94","tests/parse-fail/confusing-block-comment6.wat":"abe48bcba2587dca98bc80ddde4e813f94fbc8a3538704a0775ea85bca0f8466","tests/parse-fail/confusing-block-comment6.wat.err":"3c97b9bf1112bbb7335d7fe4be5befb6f91eea7bec7dd3e6b543792231003c56","tests/parse-fail/confusing-block-comment7.wat":"e125c416ea5fa0ac35a58295a83a6f345438e2d7ddc6a39bd76c8e89885b3f0e","tests/parse-fail/confusing-block-comment7.wat.err":"5c34528ff2019cd3f0b3df34fd42523c0b66120706321da2c88ec05793478d2e","tests/parse-fail/confusing-block-comment8.wat":"200cc4c0e5af21a25529d7a81633a03642cff807255d6cd72eb45cdccc605cec","tests/parse-fail/confusing-block-comment8.wat.err":"9b81237d150a784b71791eee88fb6264a8bd6412862660f7392945203809e517","tests/parse-fail/confusing-line-comment0.wat":"bcec4c5a1e52b3e392e07c6711c979aa8d7db8baaf2bcdf270ba16d1aa528d26","tests/parse-fail/confusing-line-comment0.wat.err":"41ec5a075dc6b73afe1aec6b3198c5c4ae3a1a900e1610115879058ce034d6f6","tests/parse-fail/confusing-line-comment1.wat":"a2afbcab00ec957dfd9e9bf21fa4238852247b27f0b054f4a00f6b172dddf853","tests/parse-fail/confusing-line-comment1.wat.err":"f19a645e6fb5cbd7a0dd2308732741edcf83dbae0ef62549972029856a9e7fc6","tests/parse-fail/confusing-line-comment2.wat":"7f2a68229d02aac56ec4dfccf139bf2d617a0e89430357b30444dc4239d8aa89","tests/parse-fail/confusing-line-comment2.wat.err":"08add3d33e10e1ab6b4f3ae431f5db61d6f6c0a2b7d6828482a1e51b3a2d3851","tests/parse-fail/confusing-line-comment3.wat":"61173ae54782f6de86685f9555ffb94bbe2cf20b234daf660abb69ba3326f1ff","tests/parse-fail/confusing-line-comment3.wat.err":"4a5333dc02efa3c1eeab9cafa7c707f78abe92defdb01a71d6fe20944e4785f0","tests/parse-fail/confusing-line-comment4.wat":"9ecbbbe82c750e6475af1bfb46fe7a06115e4446a437d19fc08ca3d002f2a1c9","tests/parse-fail/confusing-line-comment4.wat.err":"ddb8aee8006265253b09c313cf5eb5c2dc4da66f502b4f6d3e2e1de77b35aec9","tests/parse-fail/confusing-line-comment5.wat":"8a4c8d342111bc9d37c16dbdf67c52027e1a42632abc9f359b3e4f07a85748b5","tests/parse-fail/confusing-line-comment5.wat.err":"34e368719fc0eab2f1a43c9f8e6f1b31aa9be9f971085d72374e49bde39cbfe5","tests/parse-fail/confusing-line-comment6.wat":"15f0dcdec23736ce92db84b3a7cdfe8689c97f2a7d0b9b0bfb0dcd2675163ed1","tests/parse-fail/confusing-line-comment6.wat.err":"0570be2ede803f071925d249f3858d3a417b5a6d678c9da40fc851d788d12983","tests/parse-fail/confusing-line-comment7.wat":"c7ee59301a701dd52d56cad02df78b0ad3584460bc18efa42ee137fe0c35aef6","tests/parse-fail/confusing-line-comment7.wat.err":"feebbeee8c85d8b3b85cec89435ae18f3ade9f754ca180d747a41406b64ca07a","tests/parse-fail/confusing-line-comment8.wat":"17632a8142154624de88b3cf93516147ed3419d785200bcd7049499eca8e8f04","tests/parse-fail/confusing-line-comment8.wat.err":"9c209285f2295cd2bc999aa7a9534a654932493308ab1f102839ed15a4d04d17","tests/parse-fail/confusing-string0.wat":"497b679b32baddcd6a158f4cadd3d9a9dea3457bac2a8c2c3d4e09b7c2d80842","tests/parse-fail/confusing-string0.wat.err":"cb3d737f2319346675a038716694354cd3b272453daa8a96e32e9861a9277f7b","tests/parse-fail/confusing-string1.wat":"46654cbed1ea6aab5019aef3d20098a391e40dacafa1ad5e83bf4ec384109fce","tests/parse-fail/confusing-string1.wat.err":"de7e7da516dc6c244bd0e4f012577b69f0cacbcc10f727fadb4b50bb04e0e2b4","tests/parse-fail/confusing-string2.wat":"11938f217c14387c05312735130f00c91d9df2d3ff9df7f13395e0f2b81dad54","tests/parse-fail/confusing-string2.wat.err":"e7bd08b146a855d681fefaf9e0576a9c333a2d10044f8e268b916b22a54227c9","tests/parse-fail/confusing-string3.wat":"e0ca4903fcafb9a54a91cf99e5eac95d25c6d2eb67b076f88191ad396f839cb6","tests/parse-fail/confusing-string3.wat.err":"b88d5db9e445c798eb24f95b7661b9c0368934d27ee8208477cd1c99351b939a","tests/parse-fail/confusing-string4.wat":"3ee2aee7f77604d051519c6f1795634469c12e98ae347a98f0c8445eecf1ff3d","tests/parse-fail/confusing-string4.wat.err":"1edc65bb09d8d3eed6ff69e7d9a7a4b5941dc823fa3436fa375657510255f6f4","tests/parse-fail/confusing-string5.wat":"024e50943128840d53f17e31a9b9332ce4f0ee70a847a043015f435b1c3c6e76","tests/parse-fail/confusing-string5.wat.err":"a0f13ec40d596ea2d8b0c4292b0d28775a5116ab7e11d7de88b295d25428c661","tests/parse-fail/confusing-string6.wat":"79cf157e29319800d2652c5a7f3dc90e07ebe2145c9904a70fc12027cdee84b7","tests/parse-fail/confusing-string6.wat.err":"860555e7aa13e3de3639cc2a530d6a42b974b629c4659593e972cbb0f306abae","tests/parse-fail/confusing-string7.wat":"7d8e403766dfb4e569754160d31ed0f9a27f908ed6cff96be43ab3d37f5975d5","tests/parse-fail/confusing-string7.wat.err":"658b6a02ba6d769254485f35c20984e7135d914b4266929963d723f26a40be4a","tests/parse-fail/confusing-string8.wat":"5a9b222e578655d57ee6e9f19bc1ea8e29aa52d652975fac685213444ed6458f","tests/parse-fail/confusing-string8.wat.err":"9a4e1a510330c800a1df7966998ebc3cde931eda20b249e5360f5e9a905dce11","tests/parse-fail/inline1.wat":"4e9767d67207aace2ac5e6f63a30e7510e4aa245ba35420539509e2254470272","tests/parse-fail/inline1.wat.err":"0143017a9825e518baa6009bae2c8d63520051dedd3437705bbe36b038a57f41","tests/parse-fail/newline-in-string.wat":"5c01cf709544ade0a6cdfcc39a3836a3bc018b633dc42a6cd872b6defc763ea7","tests/parse-fail/newline-in-string.wat.err":"1504209cc37a78b2aee778f23eacf78606daf964cf7bff251f5700efcd27ffd7","tests/parse-fail/string1.wat":"620d46d585ce94b382b5fde628c1399f3e562014b7a44af46e92f7bd045ca86e","tests/parse-fail/string1.wat.err":"fc53f3a1c4a65d8f25e5af51dec7699f45cecba114ca9c7871781bc70f664320","tests/parse-fail/string10.wat":"f7409dd45e153a1b11cb23e38f4ed87da12bedde38f8f0ccfe91037b0a4d97bd","tests/parse-fail/string10.wat.err":"ce677db5e37e0ed81ca357ed6b5edb21d85c27303ee194855bea7a88457efb6a","tests/parse-fail/string11.wat":"f6e0400b8c6a2014efa1ac676c567e140d8f86b5f4d5129773e6d67af537b615","tests/parse-fail/string11.wat.err":"4c6a550d29eda38a4e1bf7a589596f11655dc779479d7b8d466cfc53f815a742","tests/parse-fail/string12.wat":"23e30070eef22271651cce096a801fc4f79f3c37343c88bb8d2fc99b32d3b8b9","tests/parse-fail/string12.wat.err":"b5ec59f2996b88b2ee157e22d1774dc3e36fc08ed5bfc621aea830d30f66f586","tests/parse-fail/string13.wat":"81a305b981159ee10e140749ea3220c9edaaff53605e63c21995de47382b5faf","tests/parse-fail/string13.wat.err":"959f26c6b54e0d367b51d11d1addd8a53b5b8ff3caf70ebdd46bbea8ccfa2418","tests/parse-fail/string14.wat":"c45c2cc9f7afbfbd4be8e513106d22f7e5e817091448576c6bdf0701b81d95dd","tests/parse-fail/string14.wat.err":"50b5bccba905ddbe275938edb7ed0b09a5ca53dcdad36a7ff736ce9bc8e7a338","tests/parse-fail/string15.wat":"b5e0d5ade40de53b2d767a132e28376bb8c7a6f6238c4d8c248ae717c41d7f1f","tests/parse-fail/string15.wat.err":"0e9fc502cc90f96d1f592a3f63369fd2a3574bc4a2345a70365dbb76804e870f","tests/parse-fail/string16.wat":"38c3688cee80a9d089d239aa06eb1d27c5364ad2bd270aca57d05997c20aa682","tests/parse-fail/string16.wat.err":"4274b3bbe4df4cf0373619b1fcd082d0c802990817d2aca26ed885168c80e489","tests/parse-fail/string2.wat":"1172964aed31537b8c466d1f045f3e756926e7b221f80b2aff4a9a6721ea0beb","tests/parse-fail/string2.wat.err":"4618d3b20a78a077337eb5d6cae14ac39d9853762f011fbd23cff8921618dbde","tests/parse-fail/string3.wat":"07e0fbcd6270c1db100917c151ee4ac3f935e4ee1b27bce3c453b22b4b74f4d6","tests/parse-fail/string3.wat.err":"08ffc6158a9e030b2e211d53bdb8aeacfd879815c7b284d6a83b030566e35928","tests/parse-fail/string4.wat":"c970da2051b0613bdd1de4664f10424e14f2ebabe604175d4fb9b763b37af577","tests/parse-fail/string4.wat.err":"406706594d305c560fabd66417ad4fc276939990b5e701bd9d13fc223d207219","tests/parse-fail/string5.wat":"386cf314bb05acdaaabdf4da1caf140167271a26bd08bf34c3a7427d4bc4431f","tests/parse-fail/string5.wat.err":"1e56b44a23a37b2b2ad05aa9dd7e1e18191b5cc22151f93bbcf9d618779a57bd","tests/parse-fail/string6.wat":"8f1fe2825ff96f2acee9130a7721f86fcc93c221baa9411bf1fb6f0870d38ccb","tests/parse-fail/string6.wat.err":"d55dfd84d94e893f167ae73b7a080aefb2bfb05cc8a1ec201c4d3066fb8549b4","tests/parse-fail/string7.wat":"b12f8c75313d7f834489d3c353422f90bc945b37139586446eda82e334a97cde","tests/parse-fail/string7.wat.err":"4cee0ca61992c249dd0faaf2529a073cf8deeb36111a3f69b43695e5682560a2","tests/parse-fail/string8.wat":"4c2e0e1f883bb4e8cba9313497ed792130e5848e62bde7716102788d7467be10","tests/parse-fail/string8.wat.err":"840c6def7c60dd7c2b7261549cab435ba78c9b3a937adf6d5d9595ff8af01c91","tests/parse-fail/string9.wat":"2b7670caed2b0688d535de6e4e416f35fa717cfbe096a6cc764a669085c8f52f","tests/parse-fail/string9.wat.err":"37b5a9c3af9631500f31f9e5e3efa821b8d96063c57d60fd01df6be6a5c323e1","tests/parse-fail/unbalanced.wat":"f664fbef53a0308f864ba496d38044eb90482636e32586512939d4930729f3fe","tests/parse-fail/unbalanced.wat.err":"aba579f7b836856e69afe05da8328aabe0643d94e369898e686aa7bb0b07e9c9","tests/recursive.rs":"ad8a2b07bf955121a7c9e326ed35f9b2bc56b440c8cc0bbde24d423a79945c1a"},"package":"8244fa24196b1d8fd3ca4a96a3a164c40f846498c5deab6caf414c67340ca4af"} \ No newline at end of file +{"files":{"Cargo.toml":"b613062acfebb71559b907cf69d0ec6480e298c4ec3c8a4e9a9d8df6e18def9d","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"5a0d2b894a3ac74ee2be74715a2f22c40a08520cb4ac59183f4e7356f34ac566","src/component.rs":"23a62f4f2774ccfaf60f68e9d9416e68ba203eea782ce0c39cf553ad293f1df4","src/component/alias.rs":"0f7c281f5b3b6abd49f4722767781aff1167165528bf6876aa5514bdc895338d","src/component/binary.rs":"4a234aa2ee833e1319ac8805ac1aaf4dbe6aff47322a7af5722e914bffb07b7d","src/component/component.rs":"3a87e6507df7e4f9baab27e4e6ebfcea33f9bb3e640965402587f1175d2c9c44","src/component/custom.rs":"f5b23c34b73a716a986fd999fc8d8c9e24c341e83292088fe83325cd82dab4f5","src/component/expand.rs":"1b7ec67961913ca67ef0ff267173e91fe7abb27d579cc187fce1dfb5fc3c835c","src/component/export.rs":"40736da26dd22e7dee44c78aaae7834157d52283bddd547dbbf151cbdef86801","src/component/func.rs":"e6c499a0cc0675d9793684c74dabdbeaca077f8d026bce5ee0fe6d14d01c8d20","src/component/import.rs":"3bf1abfa8268b3b0c8a7ec972c634beff176929f541c7272b4bee7f731717624","src/component/instance.rs":"4590083b9fa05f3b343bd4fc91d11f546fbf50d705e8034abd3ea6be2243e6eb","src/component/item_ref.rs":"e8d2275fa06da4e00595e359adcf8b349cd1ae8dcf84573c1ffff2d2129331e1","src/component/module.rs":"d27a28199d1dea1c64294a514329a524432319288515b0a0e3091fa7d3a33f74","src/component/resolve.rs":"06f5b61305252f8b79eb82fa43618fe93e97ab6cd499ed322801888ecffb1c77","src/component/types.rs":"216119b457875cbd79e9c8f4ca221763304c201d11dbf92c2484f6a0df218b00","src/component/wast.rs":"cad13b2217134454d7d8b5f1f1cc9bc8a4f05c05c68da8ad39927833ed9f55be","src/core.rs":"24b71d1ab2ad874c4e37b4dd709b6532989b60e6bc503194434f95029cc1cda7","src/core/binary.rs":"ed1544aac53ae05aee143fb2babda595cba98874b0c0b029caae47e7bd54da77","src/core/custom.rs":"17a71b95c24c35e77ee082ad1f4f1a3bafd1df73ae3ad9bf31d58d7f52e47448","src/core/export.rs":"aa8f129a900f385de7577a7a15faefe927a1d36bdc7f68643a4d077898b2ac44","src/core/expr.rs":"107984c1ae6ac4ac58fda480260ca4c2bb448eda202dc3d84824009cd8aadeff","src/core/func.rs":"d7df909a0799f0d93071a5d55da53fdaa93dfcb0570b1e509705c557bb586dc8","src/core/global.rs":"dec0abecadd2fde9298acb729259deba1ef3c4733ae5afcb4fe8cd4a633f5349","src/core/import.rs":"fcf7affc0d55d16a90ed45cd87ebda6faaeee4b8af7c4abe34ff20b0cb58d8fb","src/core/memory.rs":"d0c317a0df6cbc35048625091c46fab223594ca18a488056b7b84307487e6479","src/core/module.rs":"5d91a465ad4b1941af59fd00e15446ee9c73326d1e48cd3764c011bc15475130","src/core/resolve/deinline_import_export.rs":"b04b953baa68290aabcfe776ef97ef4080c42614f04671ef84ae53a626fb3d4f","src/core/resolve/mod.rs":"9b2680b00a1cafad2dbbfdac86aa1c135ea67203bbc4dee939302b27f4aff6d0","src/core/resolve/names.rs":"b3eebdb498a8221139229200b4ba71c107ae6e7a226d5e0a944cd77d0a8582e2","src/core/resolve/types.rs":"f3cfa900d14d372f0f7012642dd1b0f44d483a5f2d5c338f99233f35ad625139","src/core/table.rs":"4101cc2b23309ebb8c7a7e8c2f113b7f163a66dc7f752f09b70b3aff23aedc97","src/core/tag.rs":"8a3d4fcdb86dedd68cdaf25abd930ef52a461cf2a0e9393bb9cb6f425afaaf2e","src/core/types.rs":"1410e6fd5869c63384a7c28111829ad21824572a0efe136ba6f5260b34e2b539","src/core/wast.rs":"e0bac688470d15db05bb0aca4ce9ad835c323a96695a8064744651a80b2cfb99","src/encode.rs":"9f4baef7b63a7cdb473051929a06dd1e7713bc0d002f2d565ca679b712dd8147","src/error.rs":"4526260299c7983696a49ffe30a80139beb0d081fa8f42decc5e3283b361b1cb","src/gensym.rs":"b5e02e34443085f01deb5b657e541be7dc5d6dc952304e434a0b08320ea6c185","src/lexer.rs":"18592756bd124a0233c57ff58e8b9da7c7e9249e75415fd69bc07d6ca2caa25f","src/lib.rs":"5a39e63415adf7a7d42a0c6791514136f3ab70d9afbbcb04288c48621597ae4f","src/names.rs":"12aee27a752b4b9943bb0d24f759ff1685575988a888af4267b0460be86b314d","src/parser.rs":"0396149ae2f80d34bde6cdde35b26b048126f7ce305c96032132b1cbe7b426c9","src/token.rs":"abd4840c996b8110d7fc4cbe400bef14dabd87bdacd32f684ae253b60703d4b7","src/wast.rs":"db6f57f70436aaa23136821c1a98045809930b712fcb162547ccbb159d33ff25","src/wat.rs":"e8dbfad184a156c88ced3da82cbe8cddc4c0d4e5468cdd430110abc85415c14d","tests/annotations.rs":"06294077550600f93a5a8c0d7e3ac38b47f00bb8933f9dc390ff31868e873afb","tests/comments.rs":"2861aa6efb500b9b26633a151b27dddeca5b295a1f20d2f3892377889af60550","tests/parse-fail.rs":"0f1d5dffd1e6145105571222096703c89c4f4a46e25c848faa730f731155ea1c","tests/parse-fail/bad-index.wat":"d21489daeec3a35327dcc9e2ba2d0acdd05f4aeaff2272cca608fda4d2338497","tests/parse-fail/bad-index.wat.err":"dc11070de0c9160573006ea4e5fa3c4d28e71bc39b24b1938cf6ff3b03ea7154","tests/parse-fail/bad-name.wat":"e5ff5d410007779a0de6609ea4cc693f0e603d36a106b8f5098c1980dd9f8124","tests/parse-fail/bad-name.wat.err":"fb5638476c1b85d9d1919e3dbcb0f16f82d088a4a22d4a0c186d7b8ba6e1902b","tests/parse-fail/bad-name2.wat":"5a6a4d0c19e5f2e48d7cebf361aca9b9000b7ef0c652997b5bd0ffaadbd2ca8a","tests/parse-fail/bad-name2.wat.err":"129707cce45f1e3cfb3e2ca5c702182e16ca5eeb2dbb2edd0710b004a8e194a5","tests/parse-fail/bad-name3.wat":"c19133d738cc84e9174301f27d4050c216bda81c7e9918d03ac792b088f24a05","tests/parse-fail/bad-name3.wat.err":"84ea63d40a619a0782ec6e94fce63921188ab87b1c3875eacae0a371144ed83a","tests/parse-fail/block1.wat":"91e74b5c3b43be692e7a6ae74fbfa674c4b6197299eb61338c4eccf282b18f17","tests/parse-fail/block1.wat.err":"40a083ae496b41dee7002cc6a664c5db0c5e4d904ae03b815773a769c4493fca","tests/parse-fail/block2.wat":"a8c07b4c09d51f10a8ffdf19806586022552398701cd90eb6d09816d45df06e5","tests/parse-fail/block2.wat.err":"33c842ec5dd0f2fdd3a9ce8187dd98b45ceee48c12810802af809d05b9cd25e9","tests/parse-fail/block3.wat":"29739abfbabd7c55f00ddfbbb9ebd818b4a114ef2336d50514f0842f7e075905","tests/parse-fail/block3.wat.err":"fc667ae2e71a260f62a3c7393bc97272e7c0ff38b17594f4370847b8a5019060","tests/parse-fail/confusing-block-comment0.wat":"8f27c9d0d212bbb1862ea89ffd7cbeafde5dfd755d695c1ba696cd520aba1a1d","tests/parse-fail/confusing-block-comment0.wat.err":"b53cbaef7bcec3862c64e09c084b92cd61bd29b954125482b2d083db250cd9e2","tests/parse-fail/confusing-block-comment1.wat":"b1a0447c9a8eaab8938d15cd33bd4adbb8bb69c2d710209b604023991a4347cb","tests/parse-fail/confusing-block-comment1.wat.err":"2fc3b3e4f98416326e1e5ec034026301069b6a98fa24451bc7573e16b8cb3811","tests/parse-fail/confusing-block-comment2.wat":"e3f49c7a388fba81081beb25d87bbd7db0acce5dd8e3eaa04574905ed7ec420c","tests/parse-fail/confusing-block-comment2.wat.err":"2183231d6acd0b5a117f9aea747c3d5c12e758450a6cd74027bb954a3134cf19","tests/parse-fail/confusing-block-comment3.wat":"d83f89c582501eb8833e772b8462c8974984a2f7fbb80b1452dc399fac74e5ed","tests/parse-fail/confusing-block-comment3.wat.err":"8b2096a4833627905c63f49cdabe44be24336646578dcfbdc67e9bfb35cbc601","tests/parse-fail/confusing-block-comment4.wat":"b7c6c68844d918e9ef6dd5ab9c40c7de7b38f04f94fadad630eda4e596f3e0f8","tests/parse-fail/confusing-block-comment4.wat.err":"2f790cc511edfcd89a12c9207901be16039fc1a06a584d73095e77a52f861cd9","tests/parse-fail/confusing-block-comment5.wat":"a159808032638cc914fa80ac4354a68b0af4f435a09cbe3e2d577582e183eb0a","tests/parse-fail/confusing-block-comment5.wat.err":"6fe0d99894307442f83fe93beaa5da706e06c9bdaf8e39d7cbae4c4fffafcb94","tests/parse-fail/confusing-block-comment6.wat":"abe48bcba2587dca98bc80ddde4e813f94fbc8a3538704a0775ea85bca0f8466","tests/parse-fail/confusing-block-comment6.wat.err":"3c97b9bf1112bbb7335d7fe4be5befb6f91eea7bec7dd3e6b543792231003c56","tests/parse-fail/confusing-block-comment7.wat":"e125c416ea5fa0ac35a58295a83a6f345438e2d7ddc6a39bd76c8e89885b3f0e","tests/parse-fail/confusing-block-comment7.wat.err":"5c34528ff2019cd3f0b3df34fd42523c0b66120706321da2c88ec05793478d2e","tests/parse-fail/confusing-block-comment8.wat":"200cc4c0e5af21a25529d7a81633a03642cff807255d6cd72eb45cdccc605cec","tests/parse-fail/confusing-block-comment8.wat.err":"9b81237d150a784b71791eee88fb6264a8bd6412862660f7392945203809e517","tests/parse-fail/confusing-line-comment0.wat":"bcec4c5a1e52b3e392e07c6711c979aa8d7db8baaf2bcdf270ba16d1aa528d26","tests/parse-fail/confusing-line-comment0.wat.err":"41ec5a075dc6b73afe1aec6b3198c5c4ae3a1a900e1610115879058ce034d6f6","tests/parse-fail/confusing-line-comment1.wat":"a2afbcab00ec957dfd9e9bf21fa4238852247b27f0b054f4a00f6b172dddf853","tests/parse-fail/confusing-line-comment1.wat.err":"f19a645e6fb5cbd7a0dd2308732741edcf83dbae0ef62549972029856a9e7fc6","tests/parse-fail/confusing-line-comment2.wat":"7f2a68229d02aac56ec4dfccf139bf2d617a0e89430357b30444dc4239d8aa89","tests/parse-fail/confusing-line-comment2.wat.err":"08add3d33e10e1ab6b4f3ae431f5db61d6f6c0a2b7d6828482a1e51b3a2d3851","tests/parse-fail/confusing-line-comment3.wat":"61173ae54782f6de86685f9555ffb94bbe2cf20b234daf660abb69ba3326f1ff","tests/parse-fail/confusing-line-comment3.wat.err":"4a5333dc02efa3c1eeab9cafa7c707f78abe92defdb01a71d6fe20944e4785f0","tests/parse-fail/confusing-line-comment4.wat":"9ecbbbe82c750e6475af1bfb46fe7a06115e4446a437d19fc08ca3d002f2a1c9","tests/parse-fail/confusing-line-comment4.wat.err":"ddb8aee8006265253b09c313cf5eb5c2dc4da66f502b4f6d3e2e1de77b35aec9","tests/parse-fail/confusing-line-comment5.wat":"8a4c8d342111bc9d37c16dbdf67c52027e1a42632abc9f359b3e4f07a85748b5","tests/parse-fail/confusing-line-comment5.wat.err":"34e368719fc0eab2f1a43c9f8e6f1b31aa9be9f971085d72374e49bde39cbfe5","tests/parse-fail/confusing-line-comment6.wat":"15f0dcdec23736ce92db84b3a7cdfe8689c97f2a7d0b9b0bfb0dcd2675163ed1","tests/parse-fail/confusing-line-comment6.wat.err":"0570be2ede803f071925d249f3858d3a417b5a6d678c9da40fc851d788d12983","tests/parse-fail/confusing-line-comment7.wat":"c7ee59301a701dd52d56cad02df78b0ad3584460bc18efa42ee137fe0c35aef6","tests/parse-fail/confusing-line-comment7.wat.err":"feebbeee8c85d8b3b85cec89435ae18f3ade9f754ca180d747a41406b64ca07a","tests/parse-fail/confusing-line-comment8.wat":"17632a8142154624de88b3cf93516147ed3419d785200bcd7049499eca8e8f04","tests/parse-fail/confusing-line-comment8.wat.err":"9c209285f2295cd2bc999aa7a9534a654932493308ab1f102839ed15a4d04d17","tests/parse-fail/confusing-string0.wat":"497b679b32baddcd6a158f4cadd3d9a9dea3457bac2a8c2c3d4e09b7c2d80842","tests/parse-fail/confusing-string0.wat.err":"cb3d737f2319346675a038716694354cd3b272453daa8a96e32e9861a9277f7b","tests/parse-fail/confusing-string1.wat":"46654cbed1ea6aab5019aef3d20098a391e40dacafa1ad5e83bf4ec384109fce","tests/parse-fail/confusing-string1.wat.err":"de7e7da516dc6c244bd0e4f012577b69f0cacbcc10f727fadb4b50bb04e0e2b4","tests/parse-fail/confusing-string2.wat":"11938f217c14387c05312735130f00c91d9df2d3ff9df7f13395e0f2b81dad54","tests/parse-fail/confusing-string2.wat.err":"e7bd08b146a855d681fefaf9e0576a9c333a2d10044f8e268b916b22a54227c9","tests/parse-fail/confusing-string3.wat":"e0ca4903fcafb9a54a91cf99e5eac95d25c6d2eb67b076f88191ad396f839cb6","tests/parse-fail/confusing-string3.wat.err":"b88d5db9e445c798eb24f95b7661b9c0368934d27ee8208477cd1c99351b939a","tests/parse-fail/confusing-string4.wat":"3ee2aee7f77604d051519c6f1795634469c12e98ae347a98f0c8445eecf1ff3d","tests/parse-fail/confusing-string4.wat.err":"1edc65bb09d8d3eed6ff69e7d9a7a4b5941dc823fa3436fa375657510255f6f4","tests/parse-fail/confusing-string5.wat":"024e50943128840d53f17e31a9b9332ce4f0ee70a847a043015f435b1c3c6e76","tests/parse-fail/confusing-string5.wat.err":"a0f13ec40d596ea2d8b0c4292b0d28775a5116ab7e11d7de88b295d25428c661","tests/parse-fail/confusing-string6.wat":"79cf157e29319800d2652c5a7f3dc90e07ebe2145c9904a70fc12027cdee84b7","tests/parse-fail/confusing-string6.wat.err":"860555e7aa13e3de3639cc2a530d6a42b974b629c4659593e972cbb0f306abae","tests/parse-fail/confusing-string7.wat":"7d8e403766dfb4e569754160d31ed0f9a27f908ed6cff96be43ab3d37f5975d5","tests/parse-fail/confusing-string7.wat.err":"658b6a02ba6d769254485f35c20984e7135d914b4266929963d723f26a40be4a","tests/parse-fail/confusing-string8.wat":"5a9b222e578655d57ee6e9f19bc1ea8e29aa52d652975fac685213444ed6458f","tests/parse-fail/confusing-string8.wat.err":"9a4e1a510330c800a1df7966998ebc3cde931eda20b249e5360f5e9a905dce11","tests/parse-fail/inline1.wat":"4e9767d67207aace2ac5e6f63a30e7510e4aa245ba35420539509e2254470272","tests/parse-fail/inline1.wat.err":"0143017a9825e518baa6009bae2c8d63520051dedd3437705bbe36b038a57f41","tests/parse-fail/newline-in-string.wat":"5c01cf709544ade0a6cdfcc39a3836a3bc018b633dc42a6cd872b6defc763ea7","tests/parse-fail/newline-in-string.wat.err":"1504209cc37a78b2aee778f23eacf78606daf964cf7bff251f5700efcd27ffd7","tests/parse-fail/string1.wat":"620d46d585ce94b382b5fde628c1399f3e562014b7a44af46e92f7bd045ca86e","tests/parse-fail/string1.wat.err":"fc53f3a1c4a65d8f25e5af51dec7699f45cecba114ca9c7871781bc70f664320","tests/parse-fail/string10.wat":"f7409dd45e153a1b11cb23e38f4ed87da12bedde38f8f0ccfe91037b0a4d97bd","tests/parse-fail/string10.wat.err":"ce677db5e37e0ed81ca357ed6b5edb21d85c27303ee194855bea7a88457efb6a","tests/parse-fail/string11.wat":"f6e0400b8c6a2014efa1ac676c567e140d8f86b5f4d5129773e6d67af537b615","tests/parse-fail/string11.wat.err":"4c6a550d29eda38a4e1bf7a589596f11655dc779479d7b8d466cfc53f815a742","tests/parse-fail/string12.wat":"23e30070eef22271651cce096a801fc4f79f3c37343c88bb8d2fc99b32d3b8b9","tests/parse-fail/string12.wat.err":"b5ec59f2996b88b2ee157e22d1774dc3e36fc08ed5bfc621aea830d30f66f586","tests/parse-fail/string13.wat":"81a305b981159ee10e140749ea3220c9edaaff53605e63c21995de47382b5faf","tests/parse-fail/string13.wat.err":"959f26c6b54e0d367b51d11d1addd8a53b5b8ff3caf70ebdd46bbea8ccfa2418","tests/parse-fail/string14.wat":"c45c2cc9f7afbfbd4be8e513106d22f7e5e817091448576c6bdf0701b81d95dd","tests/parse-fail/string14.wat.err":"50b5bccba905ddbe275938edb7ed0b09a5ca53dcdad36a7ff736ce9bc8e7a338","tests/parse-fail/string15.wat":"b5e0d5ade40de53b2d767a132e28376bb8c7a6f6238c4d8c248ae717c41d7f1f","tests/parse-fail/string15.wat.err":"0e9fc502cc90f96d1f592a3f63369fd2a3574bc4a2345a70365dbb76804e870f","tests/parse-fail/string16.wat":"38c3688cee80a9d089d239aa06eb1d27c5364ad2bd270aca57d05997c20aa682","tests/parse-fail/string16.wat.err":"4274b3bbe4df4cf0373619b1fcd082d0c802990817d2aca26ed885168c80e489","tests/parse-fail/string2.wat":"1172964aed31537b8c466d1f045f3e756926e7b221f80b2aff4a9a6721ea0beb","tests/parse-fail/string2.wat.err":"4618d3b20a78a077337eb5d6cae14ac39d9853762f011fbd23cff8921618dbde","tests/parse-fail/string3.wat":"07e0fbcd6270c1db100917c151ee4ac3f935e4ee1b27bce3c453b22b4b74f4d6","tests/parse-fail/string3.wat.err":"08ffc6158a9e030b2e211d53bdb8aeacfd879815c7b284d6a83b030566e35928","tests/parse-fail/string4.wat":"c970da2051b0613bdd1de4664f10424e14f2ebabe604175d4fb9b763b37af577","tests/parse-fail/string4.wat.err":"406706594d305c560fabd66417ad4fc276939990b5e701bd9d13fc223d207219","tests/parse-fail/string5.wat":"386cf314bb05acdaaabdf4da1caf140167271a26bd08bf34c3a7427d4bc4431f","tests/parse-fail/string5.wat.err":"1e56b44a23a37b2b2ad05aa9dd7e1e18191b5cc22151f93bbcf9d618779a57bd","tests/parse-fail/string6.wat":"8f1fe2825ff96f2acee9130a7721f86fcc93c221baa9411bf1fb6f0870d38ccb","tests/parse-fail/string6.wat.err":"d55dfd84d94e893f167ae73b7a080aefb2bfb05cc8a1ec201c4d3066fb8549b4","tests/parse-fail/string7.wat":"b12f8c75313d7f834489d3c353422f90bc945b37139586446eda82e334a97cde","tests/parse-fail/string7.wat.err":"4cee0ca61992c249dd0faaf2529a073cf8deeb36111a3f69b43695e5682560a2","tests/parse-fail/string8.wat":"4c2e0e1f883bb4e8cba9313497ed792130e5848e62bde7716102788d7467be10","tests/parse-fail/string8.wat.err":"840c6def7c60dd7c2b7261549cab435ba78c9b3a937adf6d5d9595ff8af01c91","tests/parse-fail/string9.wat":"2b7670caed2b0688d535de6e4e416f35fa717cfbe096a6cc764a669085c8f52f","tests/parse-fail/string9.wat.err":"37b5a9c3af9631500f31f9e5e3efa821b8d96063c57d60fd01df6be6a5c323e1","tests/parse-fail/unbalanced.wat":"f664fbef53a0308f864ba496d38044eb90482636e32586512939d4930729f3fe","tests/parse-fail/unbalanced.wat.err":"aba579f7b836856e69afe05da8328aabe0643d94e369898e686aa7bb0b07e9c9","tests/recursive.rs":"ad8a2b07bf955121a7c9e326ed35f9b2bc56b440c8cc0bbde24d423a79945c1a"},"package":"4984d3e1406571f4930ba5cf79bd70f75f41d0e87e17506e0bd19b0e5d085f05"} \ No newline at end of file diff --git a/third_party/rust/wast/Cargo.toml b/third_party/rust/wast/Cargo.toml index 60ed427f9650..d8bbbbe0abe1 100644 --- a/third_party/rust/wast/Cargo.toml +++ b/third_party/rust/wast/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "wast" -version = "53.0.0" +version = "55.0.0" authors = ["Alex Crichton "] description = """ Customizable Rust parsers for the WebAssembly Text formats WAT and WAST @@ -37,7 +37,7 @@ version = "2.4.1" version = "0.1.9" [dependencies.wasm-encoder] -version = "0.23.0" +version = "0.25.0" [dev-dependencies.anyhow] version = "1.0.58" diff --git a/third_party/rust/wast/src/component/binary.rs b/third_party/rust/wast/src/component/binary.rs index 6caa3fce85b8..32045c3461cc 100644 --- a/third_party/rust/wast/src/component/binary.rs +++ b/third_party/rust/wast/src/component/binary.rs @@ -552,17 +552,32 @@ impl From> for wasm_encoder::ValType { core::ValType::F32 => Self::F32, core::ValType::F64 => Self::F64, core::ValType::V128 => Self::V128, - core::ValType::Ref(r) => r.into(), + core::ValType::Ref(r) => Self::Ref(r.into()), } } } -impl From> for wasm_encoder::ValType { +impl From> for wasm_encoder::RefType { fn from(r: core::RefType<'_>) -> Self { - match r.heap { - core::HeapType::Func => Self::FuncRef, - core::HeapType::Extern => Self::ExternRef, - _ => { + wasm_encoder::RefType { + nullable: r.nullable, + heap_type: r.heap.into(), + } + } +} + +impl From> for wasm_encoder::HeapType { + fn from(r: core::HeapType<'_>) -> Self { + match r { + core::HeapType::Func => Self::Func, + core::HeapType::Extern => Self::Extern, + core::HeapType::Index(Index::Num(i, _)) => Self::TypedFunc(i), + core::HeapType::Index(_) => panic!("unresolved index"), + core::HeapType::Any + | core::HeapType::Eq + | core::HeapType::Struct + | core::HeapType::Array + | core::HeapType::I31 => { todo!("encoding of GC proposal types not yet implemented") } } diff --git a/third_party/rust/wast/src/core/binary.rs b/third_party/rust/wast/src/core/binary.rs index d3f842f9e666..884bb92b3bfe 100644 --- a/third_party/rust/wast/src/core/binary.rs +++ b/third_party/rust/wast/src/core/binary.rs @@ -241,8 +241,11 @@ impl<'a> Encode for HeapType<'a> { HeapType::Struct => e.push(0x67), HeapType::Array => e.push(0x66), HeapType::I31 => e.push(0x6a), - HeapType::Index(index) => { - index.encode(e); + // Note that this is encoded as a signed leb128 so be sure to cast + // to an i64 first + HeapType::Index(Index::Num(n, _)) => i64::from(*n).encode(e), + HeapType::Index(Index::Id(n)) => { + panic!("unresolved index in emission: {:?}", n) } } } @@ -427,8 +430,14 @@ impl Encode for Table<'_> { fn encode(&self, e: &mut Vec) { assert!(self.exports.names.is_empty()); match &self.kind { - TableKind::Normal { ty, init_expr: None } => ty.encode(e), - TableKind::Normal { ty, init_expr: Some(init_expr) } => { + TableKind::Normal { + ty, + init_expr: None, + } => ty.encode(e), + TableKind::Normal { + ty, + init_expr: Some(init_expr), + } => { e.push(0x40); e.push(0x00); ty.encode(e); diff --git a/third_party/rust/wast/src/core/expr.rs b/third_party/rust/wast/src/core/expr.rs index b7be9f0553d3..298214104b31 100644 --- a/third_party/rust/wast/src/core/expr.rs +++ b/third_party/rust/wast/src/core/expr.rs @@ -1145,14 +1145,14 @@ instructions! { // Relaxed SIMD proposal I8x16RelaxedSwizzle : [0xfd, 0x100]: "i8x16.relaxed_swizzle", - I32x4RelaxedTruncSatF32x4S : [0xfd, 0x101]: "i32x4.relaxed_trunc_sat_f32x4_s" | "i32x4.relaxed_trunc_f32x4_s", - I32x4RelaxedTruncSatF32x4U : [0xfd, 0x102]: "i32x4.relaxed_trunc_sat_f32x4_u" | "i32x4.relaxed_trunc_f32x4_u", - I32x4RelaxedTruncSatF64x2SZero : [0xfd, 0x103]: "i32x4.relaxed_trunc_sat_f64x2_s_zero" | "i32x4.relaxed_trunc_f64x2_s_zero", - I32x4RelaxedTruncSatF64x2UZero : [0xfd, 0x104]: "i32x4.relaxed_trunc_sat_f64x2_u_zero" | "i32x4.relaxed_trunc_f64x2_u_zero", - F32x4RelaxedFma : [0xfd, 0x105]: "f32x4.relaxed_fma", - F32x4RelaxedFnma : [0xfd, 0x106]: "f32x4.relaxed_fnma", - F64x2RelaxedFma : [0xfd, 0x107]: "f64x2.relaxed_fma", - F64x2RelaxedFnma : [0xfd, 0x108]: "f64x2.relaxed_fnma", + I32x4RelaxedTruncF32x4S : [0xfd, 0x101]: "i32x4.relaxed_trunc_f32x4_s", + I32x4RelaxedTruncF32x4U : [0xfd, 0x102]: "i32x4.relaxed_trunc_f32x4_u", + I32x4RelaxedTruncF64x2SZero : [0xfd, 0x103]: "i32x4.relaxed_trunc_f64x2_s_zero", + I32x4RelaxedTruncF64x2UZero : [0xfd, 0x104]: "i32x4.relaxed_trunc_f64x2_u_zero", + F32x4RelaxedMadd : [0xfd, 0x105]: "f32x4.relaxed_madd", + F32x4RelaxedNmadd : [0xfd, 0x106]: "f32x4.relaxed_nmadd", + F64x2RelaxedMadd : [0xfd, 0x107]: "f64x2.relaxed_madd", + F64x2RelaxedNmadd : [0xfd, 0x108]: "f64x2.relaxed_nmadd", I8x16RelaxedLaneselect : [0xfd, 0x109]: "i8x16.relaxed_laneselect", I16x8RelaxedLaneselect : [0xfd, 0x10A]: "i16x8.relaxed_laneselect", I32x4RelaxedLaneselect : [0xfd, 0x10B]: "i32x4.relaxed_laneselect", @@ -1162,9 +1162,8 @@ instructions! { F64x2RelaxedMin : [0xfd, 0x10F]: "f64x2.relaxed_min", F64x2RelaxedMax : [0xfd, 0x110]: "f64x2.relaxed_max", I16x8RelaxedQ15mulrS: [0xfd, 0x111]: "i16x8.relaxed_q15mulr_s", - I16x8DotI8x16I7x16S: [0xfd, 0x112]: "i16x8.dot_i8x16_i7x16_s", - I32x4DotI8x16I7x16AddS: [0xfd, 0x113]: "i32x4.dot_i8x16_i7x16_add_s", - F32x4RelaxedDotBf16x8AddF32x4: [0xfd, 0x114]: "f32x4.relaxed_dot_bf16x8_add_f32x4", + I16x8RelaxedDotI8x16I7x16S: [0xfd, 0x112]: "i16x8.relaxed_dot_i8x16_i7x16_s", + I32x4RelaxedDotI8x16I7x16AddS: [0xfd, 0x113]: "i32x4.relaxed_dot_i8x16_i7x16_add_s", } } diff --git a/third_party/rust/wast/src/core/table.rs b/third_party/rust/wast/src/core/table.rs index 4f16861de4f8..f279e174b9e9 100644 --- a/third_party/rust/wast/src/core/table.rs +++ b/third_party/rust/wast/src/core/table.rs @@ -75,7 +75,7 @@ impl<'a> Parse<'a> for Table<'a> { } else if l.peek::() { TableKind::Normal { ty: parser.parse()?, - init_expr: if parser.peek::() { + init_expr: if !parser.is_empty() { Some(parser.parse::()?) } else { None