diff --git a/Cargo.lock b/Cargo.lock index 2fc6af5f..f9835150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aes" version = "0.7.5" @@ -310,6 +316,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "auditable-serde" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7bf8143dfc3c0258df908843e169b5cc5fcf76c7718bd66135ef4a9cd558c5" +dependencies = [ + "semver", + "serde 1.0.197", + "serde_json", + "topological-sort", +] + [[package]] name = "autocfg" version = "1.2.0" @@ -394,7 +412,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.2", "object", "rustc-demangle", ] @@ -635,7 +653,7 @@ dependencies = [ "encode_unicode", "lazy_static 1.4.0", "libc", - "unicode-width", + "unicode-width 0.1.11", "windows-sys 0.52.0", ] @@ -670,6 +688,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -1051,12 +1078,28 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +dependencies = [ + "crc32fast", + "miniz_oxide 0.8.5", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "foreign-types" version = "0.3.2" @@ -1255,7 +1298,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.2.6", + "indexmap 2.7.1", "slab", "tokio", "tokio-util", @@ -1270,9 +1313,13 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", + "serde 1.0.197", +] [[package]] name = "heck" @@ -1539,12 +1586,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.15.2", "serde 1.0.197", ] @@ -1558,7 +1605,7 @@ dependencies = [ "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.1.11", ] [[package]] @@ -1669,6 +1716,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "lexical-core" version = "0.7.6" @@ -1855,7 +1908,7 @@ dependencies = [ "terminal_size", "textwrap", "thiserror", - "unicode-width", + "unicode-width 0.1.11", ] [[package]] @@ -1894,6 +1947,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "0.8.11" @@ -2298,7 +2360,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.7.1", ] [[package]] @@ -3184,7 +3246,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.7.1", "serde 1.0.197", "serde_derive", "serde_json", @@ -3210,7 +3272,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.1", "itoa", "ryu", "serde 1.0.197", @@ -3530,7 +3592,7 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width", + "unicode-width 0.1.11", ] [[package]] @@ -3731,7 +3793,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.1", "toml_datetime", "winnow 0.5.40", ] @@ -3742,13 +3804,19 @@ version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.1", "serde 1.0.197", "serde_spanned", "toml_datetime", "winnow 0.6.5", ] +[[package]] +name = "topological-sort" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" + [[package]] name = "tower" version = "0.4.13" @@ -3925,6 +3993,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -3984,7 +4058,7 @@ version = "0.7.0-dev" dependencies = [ "anyhow", "clap", - "indexmap 2.2.6", + "indexmap 2.7.1", "indicatif", "log", "miette", @@ -4001,7 +4075,7 @@ dependencies = [ "wac-types", "warg-client", "warg-protocol", - "wasmprinter 0.202.0", + "wasmprinter 0.227.1", "wat", "wit-component", "wit-parser", @@ -4013,7 +4087,7 @@ version = "0.7.0-dev" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.7.1", "log", "petgraph", "pretty_assertions", @@ -4022,10 +4096,10 @@ dependencies = [ "serde_json", "thiserror", "wac-types", - "wasm-encoder 0.202.0", + "wasm-encoder 0.227.1", "wasm-metadata", - "wasmparser 0.202.0", - "wasmprinter 0.202.0", + "wasmparser 0.227.1", + "wasmprinter 0.227.1", "wat", "wit-component", "wit-parser", @@ -4037,7 +4111,7 @@ version = "0.7.0-dev" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.7.1", "log", "logos 0.14.0", "miette", @@ -4052,10 +4126,10 @@ dependencies = [ "tokio", "wac-graph", "wac-resolver", - "wasm-encoder 0.202.0", + "wasm-encoder 0.227.1", "wasm-metadata", - "wasmparser 0.202.0", - "wasmprinter 0.202.0", + "wasmparser 0.227.1", + "wasmprinter 0.227.1", ] [[package]] @@ -4064,12 +4138,13 @@ version = "0.7.0-dev" dependencies = [ "anyhow", "futures", - "indexmap 2.2.6", + "indexmap 2.7.1", "log", "miette", "pretty_assertions", "semver", "tempdir", + "tempfile", "thiserror", "tokio", "tokio-util", @@ -4080,7 +4155,7 @@ dependencies = [ "warg-crypto", "warg-protocol", "warg-server", - "wasmprinter 0.202.0", + "wasmprinter 0.227.1", "wat", "wit-component", "wit-parser", @@ -4092,11 +4167,11 @@ version = "0.7.0-dev" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.7.1", "semver", "serde 1.0.197", - "wasm-encoder 0.202.0", - "wasmparser 0.202.0", + "wasm-encoder 0.227.1", + "wasmparser 0.227.1", ] [[package]] @@ -4130,7 +4205,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44b422328c3a86be288f569694aa97df958ade0cd9514ed00bc562952c6778e" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.1", "itertools 0.12.1", "serde 1.0.197", "serde_with", @@ -4153,7 +4228,7 @@ dependencies = [ "dialoguer", "dirs", "futures-util", - "indexmap 2.2.6", + "indexmap 2.7.1", "itertools 0.12.1", "keyring", "libc", @@ -4234,7 +4309,7 @@ dependencies = [ "anyhow", "base64 0.21.7", "hex", - "indexmap 2.2.6", + "indexmap 2.7.1", "pbjson-types", "prost", "prost-types", @@ -4259,7 +4334,7 @@ dependencies = [ "bytes", "clap", "futures", - "indexmap 2.2.6", + "indexmap 2.7.1", "secrecy", "serde 1.0.197", "tempfile", @@ -4286,7 +4361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b950a71a544b7ac8f5a5e95f43886ac97c3fe5c7080b955b1b534037596d7be" dependencies = [ "anyhow", - "indexmap 2.2.6", + "indexmap 2.7.1", "prost", "thiserror", "warg-crypto", @@ -4374,7 +4449,7 @@ dependencies = [ "anyhow", "heck 0.4.1", "im-rc", - "indexmap 2.2.6", + "indexmap 2.7.1", "log", "petgraph", "serde 1.0.197", @@ -4398,27 +4473,31 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.202.0" +version = "0.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd106365a7f5f7aa3c1916a98cbb3ad477f5ff96ddb130285a91c6e7429e67a" +checksum = "80bb72f02e7fbf07183443b27b0f3d4144abf8c114189f2e088ed95b696a7822" dependencies = [ - "leb128", + "leb128fmt", + "wasmparser 0.227.1", ] [[package]] name = "wasm-metadata" -version = "0.202.0" +version = "0.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094aea3cb90e09f16ee25a4c0e324b3e8c934e7fd838bfa039aef5352f44a917" +checksum = "ce1ef0faabbbba6674e97a56bee857ccddf942785a336c8b47b42373c922a91d" dependencies = [ "anyhow", - "indexmap 2.2.6", + "auditable-serde", + "flate2", + "indexmap 2.7.1", "serde 1.0.197", "serde_derive", "serde_json", "spdx", - "wasm-encoder 0.202.0", - "wasmparser 0.202.0", + "url", + "wasm-encoder 0.227.1", + "wasmparser 0.227.1", ] [[package]] @@ -4441,19 +4520,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.5.0", - "indexmap 2.2.6", + "indexmap 2.7.1", "semver", ] [[package]] name = "wasmparser" -version = "0.202.0" +version = "0.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6998515d3cf3f8b980ef7c11b29a9b1017d4cf86b99ae93b546992df9931413" +checksum = "0f51cad774fb3c9461ab9bccc9c62dfb7388397b5deda31bf40e8108ccd678b2" dependencies = [ "bitflags 2.5.0", - "indexmap 2.2.6", + "hashbrown 0.15.2", + "indexmap 2.7.1", "semver", + "serde 1.0.197", ] [[package]] @@ -4468,32 +4549,33 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.202.0" +version = "0.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab1cc9508685eef9502e787f4d4123745f5651a1e29aec047645d3cac1e2da7a" +checksum = "32475a0459db5639e989206dd8833fb07110ec092a7cb3468c82341989cac4d3" dependencies = [ "anyhow", - "wasmparser 0.202.0", + "termcolor", + "wasmparser 0.227.1", ] [[package]] name = "wast" -version = "202.0.0" +version = "227.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbcb11204515c953c9b42ede0a46a1c5e17f82af05c4fae201a8efff1b0f4fe" +checksum = "85c14e5042b16c9d267da3b9b0f4529870455178415286312c25c34dfc1b2816" dependencies = [ "bumpalo", - "leb128", + "leb128fmt", "memchr", - "unicode-width", - "wasm-encoder 0.202.0", + "unicode-width 0.2.0", + "wasm-encoder 0.227.1", ] [[package]] name = "wat" -version = "1.202.0" +version = "1.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de4b15a47135c56a3573406e9977b9518787a6154459b4842a9b9d3d1684848" +checksum = "b3d394d5bef7006ff63338d481ca10f1af76601e65ebdf5ed33d29302994e9cc" dependencies = [ "wast", ] @@ -4758,40 +4840,40 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.202.0" +version = "0.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c836b1fd9932de0431c1758d8be08212071b6bba0151f7bac826dbc4312a2a9" +checksum = "635c3adc595422cbf2341a17fb73a319669cc8d33deed3a48368a841df86b676" dependencies = [ "anyhow", "bitflags 2.5.0", - "indexmap 2.2.6", + "indexmap 2.7.1", "log", "serde 1.0.197", "serde_derive", "serde_json", - "wasm-encoder 0.202.0", + "wasm-encoder 0.227.1", "wasm-metadata", - "wasmparser 0.202.0", + "wasmparser 0.227.1", "wat", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.202.0" +version = "0.227.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744237b488352f4f27bca05a10acb79474415951c450e52ebd0da784c1df2bcc" +checksum = "ddf445ed5157046e4baf56f9138c124a0824d4d1657e7204d71886ad8ce2fc11" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.7.1", "log", "semver", "serde 1.0.197", "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.202.0", + "wasmparser 0.227.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 05979752..ad22e312 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,12 @@ wit-component = { workspace = true } default = ["wit", "registry"] wat = ["wac-resolver/wat"] wit = ["wac-resolver/wit"] -registry = ["wac-resolver/registry", "dep:indicatif", "dep:warg-client", "dep:warg-protocol"] +registry = [ + "wac-resolver/registry", + "dep:indicatif", + "dep:warg-client", + "dep:warg-protocol", +] native-tls-vendored = ["warg-client?/native-tls-vendored"] [workspace] @@ -58,12 +63,13 @@ wac-parser = { path = "crates/wac-parser", version = "0.7.0-dev", default-featur wac-resolver = { path = "crates/wac-resolver", version = "0.7.0-dev", default-features = false } wac-graph = { path = "crates/wac-graph", version = "0.7.0-dev" } wac-types = { path = "crates/wac-types", version = "0.7.0-dev" } -wit-parser = "0.202.0" -wasmparser = "0.202.0" -wit-component = "0.202.0" -wasm-encoder = "0.202.0" -wasmprinter = "0.202.0" -wasm-metadata = "0.202.0" +wit-parser = "0.227.0" +wasmparser = "0.227.0" +wit-component = "0.227.0" +wasm-encoder = "0.227.0" +wasmprinter = "0.227.0" +wasm-metadata = "0.227.0" +wat = "1.227.0" anyhow = "1.0.81" clap = { version = "4.5.4", features = ["derive"] } semver = { version = "1.0.22", features = ["serde"] } @@ -78,7 +84,6 @@ indexmap = { version = "2.2.6", features = ["serde"] } id-arena = "2.2.1" serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.115" -wat = "1.202.0" logos = "0.14.0" miette = "7.2.0" thiserror = "1.0.58" diff --git a/crates/wac-graph/src/encoding.rs b/crates/wac-graph/src/encoding.rs index 16b82e39..691b104d 100644 --- a/crates/wac-graph/src/encoding.rs +++ b/crates/wac-graph/src/encoding.rs @@ -3,14 +3,15 @@ use indexmap::IndexMap; use petgraph::graph::NodeIndex; use std::collections::HashMap; use wac_types::{ - CoreExtern, DefinedType, DefinedTypeId, Enum, Flags, FuncResult, FuncTypeId, InterfaceId, - ItemKind, ModuleTypeId, PrimitiveType, Record, ResourceId, Type, Types, UsedType, ValueType, - Variant, WorldId, + CoreExtern, DefinedType, DefinedTypeId, Enum, Flags, FuncTypeId, InterfaceId, ItemKind, + ModuleTypeId, PrimitiveType, Record, ResourceId, Type, Types, UsedType, ValueType, Variant, + WorldId, }; use wasm_encoder::{ - Alias, ComponentBuilder, ComponentExportKind, ComponentOuterAliasKind, ComponentType, - ComponentTypeEncoder, ComponentTypeRef, ComponentValType, CoreTypeEncoder, EntityType, - GlobalType, InstanceType, MemoryType, ModuleType, TableType, TagKind, TagType, TypeBounds, + Alias, ComponentBuilder, ComponentCoreTypeEncoder, ComponentExportKind, + ComponentOuterAliasKind, ComponentType, ComponentTypeEncoder, ComponentTypeRef, + ComponentValType, EntityType, GlobalType, InstanceType, MemoryType, ModuleType, TableType, + TagKind, TagType, TypeBounds, }; /// A type used to abstract the API differences between a component builder, @@ -55,7 +56,7 @@ impl Encodable { } } - fn core_type(&mut self) -> CoreTypeEncoder { + fn core_type(&mut self) -> ComponentCoreTypeEncoder { match self { Encodable::Builder(t) => t.core_type().1, Encodable::Instance(t) => t.core_type(), @@ -226,27 +227,11 @@ impl<'a> TypeEncoder<'a> { .map(|(n, ty)| (n.as_str(), self.value_type(state, *ty))) .collect::>(); - let results = match &ty.results { - Some(FuncResult::Scalar(ty)) => vec![("", self.value_type(state, *ty))], - Some(FuncResult::List(results)) => results - .iter() - .map(|(n, ty)| (n.as_str(), self.value_type(state, *ty))) - .collect(), - None => Vec::new(), - }; - + let result = ty.result.map(|ty| self.value_type(state, ty)); let index = state.current.encodable.type_count(); let mut encoder = state.current.encodable.ty().function(); encoder.params(params); - - match &ty.results { - Some(FuncResult::Scalar(_)) => { - encoder.result(results[0].1); - } - _ => { - encoder.results(results); - } - } + encoder.result(result); log::debug!("function type encoded to type index {index}"); index @@ -268,6 +253,8 @@ impl<'a> TypeEncoder<'a> { DefinedType::Alias(ValueType::Borrow(id)) => self.borrow(state, *id), DefinedType::Alias(ValueType::Own(id)) => self.own(state, *id), DefinedType::Alias(ValueType::Defined(id)) => self.defined(state, *id), + DefinedType::Stream(ty) => self.stream(state, *ty), + DefinedType::Future(ty) => self.future(state, *ty), }; log::debug!("defined type encoded to type index {index}"); @@ -476,25 +463,36 @@ impl<'a> TypeEncoder<'a> { element_type, initial, maximum, + table64, + shared, } => EntityType::Table(TableType { element_type: (*element_type).into(), minimum: *initial, maximum: *maximum, + table64: *table64, + shared: *shared, }), CoreExtern::Memory { memory64, shared, initial, maximum, + page_size_log2, } => EntityType::Memory(MemoryType { minimum: *initial, maximum: *maximum, memory64: *memory64, shared: *shared, + page_size_log2: *page_size_log2, }), - CoreExtern::Global { val_type, mutable } => EntityType::Global(GlobalType { + CoreExtern::Global { + val_type, + mutable, + shared, + } => EntityType::Global(GlobalType { val_type: (*val_type).into(), mutable: *mutable, + shared: *shared, }), CoreExtern::Tag(func) => { let index = encodable.type_count(); @@ -554,6 +552,20 @@ impl<'a> TypeEncoder<'a> { index } + fn stream(&self, state: &mut State, ty: Option) -> u32 { + let ty = ty.map(|ty| self.value_type(state, ty)); + let index = state.current.encodable.type_count(); + state.current.encodable.ty().defined_type().stream(ty); + index + } + + fn future(&self, state: &mut State, ty: Option) -> u32 { + let ty = ty.map(|ty| self.value_type(state, ty)); + let index = state.current.encodable.type_count(); + state.current.encodable.ty().defined_type().future(ty); + index + } + fn option(&self, state: &mut State, ty: ValueType) -> u32 { let ty = self.value_type(state, ty); let index = state.current.encodable.type_count(); diff --git a/crates/wac-graph/tests/encoding.rs b/crates/wac-graph/tests/encoding.rs index f430e36e..509e6300 100644 --- a/crates/wac-graph/tests/encoding.rs +++ b/crates/wac-graph/tests/encoding.rs @@ -133,7 +133,11 @@ impl GraphFile { ) })?; - let mut module = wit_component::dummy_module(&resolve, world); + let mut module = wit_component::dummy_module( + &resolve, + world, + wit_parser::ManglingAndAbi::Legacy(wit_parser::LiftLowerAbi::Sync), + ); wit_component::embed_component_metadata( &mut module, &resolve, @@ -147,7 +151,7 @@ impl GraphFile { ) })?; - let encoder = ComponentEncoder::default().validate(true).module(&module)?; + let mut encoder = ComponentEncoder::default().validate(true).module(&module)?; encoder .encode() .with_context(|| format!("failed to encode a component from module derived from package `{path}` for test case `{test_case}`", path = path.display())) diff --git a/crates/wac-parser/src/ast/expr.rs b/crates/wac-parser/src/ast/expr.rs index af1f0e08..6b08cc67 100644 --- a/crates/wac-parser/src/ast/expr.rs +++ b/crates/wac-parser/src/ast/expr.rs @@ -237,7 +237,7 @@ impl Peek for InstantiationArgumentName<'_> { } } -impl<'a> InstantiationArgumentName<'a> { +impl InstantiationArgumentName<'_> { /// Gets the span of the instantiation argument name. pub fn span(&self) -> SourceSpan { match self { @@ -288,7 +288,7 @@ pub enum PostfixExpr<'a> { NamedAccess(NamedAccessExpr<'a>), } -impl<'a> PostfixExpr<'a> { +impl PostfixExpr<'_> { /// Gets the span of the postfix expression. pub fn span(&self) -> SourceSpan { match self { diff --git a/crates/wac-parser/src/ast/printer.rs b/crates/wac-parser/src/ast/printer.rs index dbe2fb91..e4f69d03 100644 --- a/crates/wac-parser/src/ast/printer.rs +++ b/crates/wac-parser/src/ast/printer.rs @@ -135,11 +135,6 @@ impl<'a, W: Write> DocumentPrinter<'a, W> { write!(self.writer, " -> ")?; self.ty(ty) } - ResultList::Named(results) => { - write!(self.writer, " -> (")?; - self.named_types(results)?; - write!(self.writer, ")") - } } } diff --git a/crates/wac-parser/src/ast/type.rs b/crates/wac-parser/src/ast/type.rs index 8708b4a3..9d1984b5 100644 --- a/crates/wac-parser/src/ast/type.rs +++ b/crates/wac-parser/src/ast/type.rs @@ -529,19 +529,12 @@ pub enum ResultList<'a> { Empty, /// The function returns a scalar value. Scalar(Type<'a>), - /// The function has named results. - Named(Vec>), } impl<'a> Parse<'a> for ResultList<'a> { fn parse(lexer: &mut Lexer<'a>) -> ParseResult { let mut lookahead = Lookahead::new(lexer); - if lookahead.peek(Token::OpenParen) { - parse_token(lexer, Token::OpenParen)?; - let results = parse_delimited(lexer, Token::CloseParen, true)?; - parse_token(lexer, Token::CloseParen)?; - Ok(Self::Named(results)) - } else if Type::peek(&mut lookahead) { + if Type::peek(&mut lookahead) { Ok(Self::Scalar(Parse::parse(lexer)?)) } else { Ok(Self::Empty) @@ -672,7 +665,7 @@ pub enum Type<'a> { Ident(Ident<'a>), } -impl<'a> Type<'a> { +impl Type<'_> { /// Gets the span of the type. pub fn span(&self) -> SourceSpan { match self { diff --git a/crates/wac-parser/src/lexer.rs b/crates/wac-parser/src/lexer.rs index b0a4e796..59502f45 100644 --- a/crates/wac-parser/src/lexer.rs +++ b/crates/wac-parser/src/lexer.rs @@ -516,7 +516,7 @@ impl<'a> Lexer<'a> { } } -impl<'a> Iterator for Lexer<'a> { +impl Iterator for Lexer<'_> { type Item = (LexerResult, SourceSpan); fn next(&mut self) -> Option { diff --git a/crates/wac-parser/src/resolution.rs b/crates/wac-parser/src/resolution.rs index a88612ca..d559a8a9 100644 --- a/crates/wac-parser/src/resolution.rs +++ b/crates/wac-parser/src/resolution.rs @@ -10,10 +10,10 @@ use std::{ }; use wac_graph::{ types::{ - BorrowedPackageKey, DefinedType, Enum, ExternKind, Flags, FuncKind, FuncResult, FuncType, - FuncTypeId, Interface, InterfaceId, ItemKind, Package, PackageKey, PrimitiveType, Record, - Resource, ResourceAlias, ResourceId, SubtypeChecker, Type, UsedType, ValueType, Variant, - World, WorldId, + BorrowedPackageKey, DefinedType, Enum, ExternKind, Flags, FuncKind, FuncType, FuncTypeId, + Interface, InterfaceId, ItemKind, Package, PackageKey, PrimitiveType, Record, Resource, + ResourceAlias, ResourceId, SubtypeChecker, Type, UsedType, ValueType, Variant, World, + WorldId, }, CompositionGraph, DefineTypeError, EncodeError, EncodeOptions, ExportError, ImportError, InstantiationArgumentError, NodeId, NodeKind, PackageId, Processor, @@ -664,7 +664,7 @@ pub struct Resolution<'a> { instantiation_spans: HashMap, } -impl<'a> Resolution<'a> { +impl Resolution<'_> { /// Gets the document that was resolved. pub fn document(&self) -> &Document { self.document @@ -2113,50 +2113,27 @@ impl<'a> AstResolver<'a> { } } - let results = match func_results { + let result = match func_results { ast::ResultList::Empty => { if kind == FuncKind::Constructor { - Some(FuncResult::Scalar(ValueType::Own(resource.unwrap()))) + Some(ValueType::Own(resource.unwrap())) } else { None } } - ast::ResultList::Named(results) => { - let mut list = IndexMap::new(); - for result in results { - let value_type = Self::ty(state, &result.ty)?; - if value_type.contains_borrow(state.graph.types()) { - return Err(Error::BorrowInResult { - span: result.ty.span(), - }); - } - - if list - .insert(result.id.string.to_owned(), value_type) - .is_some() - { - return Err(Error::DuplicateResult { - name: result.id.string.to_string(), - kind, - span: result.id.span, - }); - } - } - Some(FuncResult::List(list)) - } ast::ResultList::Scalar(ty) => { let value_type = Self::ty(state, ty)?; if value_type.contains_borrow(state.graph.types()) { return Err(Error::BorrowInResult { span: ty.span() }); } - Some(FuncResult::Scalar(value_type)) + Some(value_type) } }; Ok(state .graph .types_mut() - .add_func_type(FuncType { params, results })) + .add_func_type(FuncType { params, result })) } fn expr( diff --git a/crates/wac-parser/tests/parser/types.wac b/crates/wac-parser/tests/parser/types.wac index f1684f1d..6db5908b 100644 --- a/crates/wac-parser/tests/parser/types.wac +++ b/crates/wac-parser/tests/parser/types.wac @@ -72,7 +72,7 @@ record r { x: u32, y: string, z: v, -} +} /// Defining flags flags f { @@ -92,4 +92,3 @@ enum e { type t = e; type t2 = string; type t3 = func(a: u32, b: r) -> u32; -type t4 = func() -> (a: u32, b: string); diff --git a/crates/wac-parser/tests/parser/types.wac.result b/crates/wac-parser/tests/parser/types.wac.result index 93ec1706..25e00758 100644 --- a/crates/wac-parser/tests/parser/types.wac.result +++ b/crates/wac-parser/tests/parser/types.wac.result @@ -786,7 +786,7 @@ { "comment": "Defining flags", "span": { - "offset": 1190, + "offset": 1189, "length": 18 } } @@ -794,7 +794,7 @@ "id": { "string": "f", "span": { - "offset": 1215, + "offset": 1214, "length": 1 } }, @@ -804,7 +804,7 @@ "id": { "string": "a", "span": { - "offset": 1223, + "offset": 1222, "length": 1 } } @@ -814,7 +814,7 @@ "id": { "string": "b", "span": { - "offset": 1230, + "offset": 1229, "length": 1 } } @@ -824,7 +824,7 @@ "id": { "string": "c", "span": { - "offset": 1237, + "offset": 1236, "length": 1 } } @@ -842,7 +842,7 @@ { "comment": "Defining an enum", "span": { - "offset": 1243, + "offset": 1242, "length": 20 } } @@ -850,7 +850,7 @@ "id": { "string": "e", "span": { - "offset": 1269, + "offset": 1268, "length": 1 } }, @@ -860,7 +860,7 @@ "id": { "string": "a", "span": { - "offset": 1277, + "offset": 1276, "length": 1 } } @@ -870,7 +870,7 @@ "id": { "string": "b", "span": { - "offset": 1284, + "offset": 1283, "length": 1 } } @@ -880,7 +880,7 @@ "id": { "string": "c", "span": { - "offset": 1291, + "offset": 1290, "length": 1 } } @@ -898,7 +898,7 @@ { "comment": "Type aliases", "span": { - "offset": 1297, + "offset": 1296, "length": 16 } } @@ -906,7 +906,7 @@ "id": { "string": "t", "span": { - "offset": 1319, + "offset": 1318, "length": 1 } }, @@ -915,7 +915,7 @@ "ident": { "string": "e", "span": { - "offset": 1323, + "offset": 1322, "length": 1 } } @@ -933,14 +933,14 @@ "id": { "string": "t2", "span": { - "offset": 1331, + "offset": 1330, "length": 2 } }, "kind": { "type": { "string": { - "offset": 1336, + "offset": 1335, "length": 6 } } @@ -957,7 +957,7 @@ "id": { "string": "t3", "span": { - "offset": 1349, + "offset": 1348, "length": 2 } }, @@ -968,13 +968,13 @@ "id": { "string": "a", "span": { - "offset": 1359, + "offset": 1358, "length": 1 } }, "ty": { "u32": { - "offset": 1362, + "offset": 1361, "length": 3 } } @@ -983,7 +983,7 @@ "id": { "string": "b", "span": { - "offset": 1367, + "offset": 1366, "length": 1 } }, @@ -991,7 +991,7 @@ "ident": { "string": "r", "span": { - "offset": 1370, + "offset": 1369, "length": 1 } } @@ -1001,7 +1001,7 @@ "results": { "scalar": { "u32": { - "offset": 1376, + "offset": 1375, "length": 3 } } @@ -1011,61 +1011,6 @@ } } } - }, - { - "Type": { - "type": { - "alias": { - "docs": [], - "id": { - "string": "t4", - "span": { - "offset": 1386, - "length": 2 - } - }, - "kind": { - "func": { - "params": [], - "results": { - "named": [ - { - "id": { - "string": "a", - "span": { - "offset": 1402, - "length": 1 - } - }, - "ty": { - "u32": { - "offset": 1405, - "length": 3 - } - } - }, - { - "id": { - "string": "b", - "span": { - "offset": 1410, - "length": 1 - } - }, - "ty": { - "string": { - "offset": 1413, - "length": 6 - } - } - } - ] - } - } - } - } - } - } } ] } \ No newline at end of file diff --git a/crates/wac-parser/tests/resolution/fail/duplicate-func-result.wac b/crates/wac-parser/tests/resolution/fail/duplicate-func-result.wac deleted file mode 100644 index e8cc9923..00000000 --- a/crates/wac-parser/tests/resolution/fail/duplicate-func-result.wac +++ /dev/null @@ -1,3 +0,0 @@ -package test:comp; - -type f = func() -> (a: u32, a: s8); \ No newline at end of file diff --git a/crates/wac-parser/tests/resolution/fail/duplicate-func-result.wac.result b/crates/wac-parser/tests/resolution/fail/duplicate-func-result.wac.result deleted file mode 100644 index d50af8b6..00000000 --- a/crates/wac-parser/tests/resolution/fail/duplicate-func-result.wac.result +++ /dev/null @@ -1,9 +0,0 @@ -failed to resolve document - - × duplicate function result `a` - ╭─[tests/resolution/fail/duplicate-func-result.wac:3:29] - 2 │ - 3 │ type f = func() -> (a: u32, a: s8); - · ┬ - · ╰── duplicate result `a` - ╰──── diff --git a/crates/wac-parser/tests/resolution/fail/expected-result-named.wac.result b/crates/wac-parser/tests/resolution/fail/expected-result-named.wac.result index 90770b12..8ab104b3 100644 --- a/crates/wac-parser/tests/resolution/fail/expected-result-named.wac.result +++ b/crates/wac-parser/tests/resolution/fail/expected-result-named.wac.result @@ -1,11 +1,14 @@ failed to resolve document - × mismatched instantiation argument `x` - ├─▶ mismatched type for export `f` - ╰─▶ expected function that returns a named result, found function with a single result type - ╭─[tests/resolution/fail/expected-result-named.wac:7:23] + × failed to resolve package `foo:bar` + ╰─▶ unexpected token, expected one of: `bool`, `s8`, `u8`, `s16`, `u16`, `s32`, `u32`, `s64`, `u64`, `f32`, `f64`, `float32`, `float64`, `char`, `string`, `error-context` + --> tests/resolution/fail/expected-result-named/foo/bar.wat:3:31 + | + 3 | (export "f" (func (result "a" string))) + | ^ + ╭─[tests/resolution/fail/expected-result-named.wac:7:13] 6 │ 7 │ let i = new foo:bar { x }; - · ┬ - · ╰── mismatched argument `x` + · ───┬─── + · ╰── package `foo:bar` failed to resolve ╰──── diff --git a/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac b/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac index 5ac9a776..6795ac3d 100644 --- a/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac +++ b/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac @@ -1,7 +1,7 @@ package test:comp; import x: interface { - f: func() -> (x: u32, y: string); + f: func(); }; let i = new foo:bar { x }; diff --git a/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac.result b/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac.result index 70784ab2..ff13a967 100644 --- a/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac.result +++ b/crates/wac-parser/tests/resolution/fail/expected-result-scalar.wac.result @@ -2,7 +2,7 @@ failed to resolve document × mismatched instantiation argument `x` ├─▶ mismatched type for export `f` - ╰─▶ expected function that returns a single result type, found function that returns a named result + ╰─▶ expected function with a result, found function without a result ╭─[tests/resolution/fail/expected-result-scalar.wac:7:23] 6 │ 7 │ let i = new foo:bar { x }; diff --git a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name.wac b/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name.wac deleted file mode 100644 index 0ca87368..00000000 --- a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name.wac +++ /dev/null @@ -1,7 +0,0 @@ -package test:comp; - -import x: interface { - f: func() -> (a: string, c: u32); -}; - -let i = new foo:bar { x }; diff --git a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name.wac.result b/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name.wac.result deleted file mode 100644 index f63006e0..00000000 --- a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name.wac.result +++ /dev/null @@ -1,11 +0,0 @@ -failed to resolve document - - × mismatched instantiation argument `x` - ├─▶ mismatched type for export `f` - ╰─▶ expected function result 1 to be named `b`, found name `c` - ╭─[tests/resolution/fail/mismatched-func-result-name.wac:7:23] - 6 │ - 7 │ let i = new foo:bar { x }; - · ┬ - · ╰── mismatched argument `x` - ╰──── diff --git a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name/foo/bar.wat b/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name/foo/bar.wat deleted file mode 100644 index 73fa5cc4..00000000 --- a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-name/foo/bar.wat +++ /dev/null @@ -1,5 +0,0 @@ -(component - (instance (import "x") - (export "f" (func (result "a" string) (result "b" u32))) - ) -) diff --git a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type.wac b/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type.wac deleted file mode 100644 index 2131507b..00000000 --- a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type.wac +++ /dev/null @@ -1,7 +0,0 @@ -package test:comp; - -import x: interface { - f: func() -> (a: string, b: string); -}; - -let i = new foo:bar { x }; diff --git a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type.wac.result b/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type.wac.result deleted file mode 100644 index 1fd6527d..00000000 --- a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type.wac.result +++ /dev/null @@ -1,12 +0,0 @@ -failed to resolve document - - × mismatched instantiation argument `x` - ├─▶ mismatched type for export `f` - ├─▶ mismatched type for function result `b` - ╰─▶ expected u32, found string - ╭─[tests/resolution/fail/mismatched-func-result-type.wac:7:23] - 6 │ - 7 │ let i = new foo:bar { x }; - · ┬ - · ╰── mismatched argument `x` - ╰──── diff --git a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type/foo/bar.wat b/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type/foo/bar.wat deleted file mode 100644 index 73fa5cc4..00000000 --- a/crates/wac-parser/tests/resolution/fail/mismatched-func-result-type/foo/bar.wat +++ /dev/null @@ -1,5 +0,0 @@ -(component - (instance (import "x") - (export "f" (func (result "a" string) (result "b" u32))) - ) -) diff --git a/crates/wac-parser/tests/resolution/types.wac b/crates/wac-parser/tests/resolution/types.wac index 4001107d..e6c832f6 100644 --- a/crates/wac-parser/tests/resolution/types.wac +++ b/crates/wac-parser/tests/resolution/types.wac @@ -78,7 +78,7 @@ record r { x: u32, y: string, z: v, -} +} /// Defining flags flags %flags { @@ -98,4 +98,3 @@ enum e { type t = e; type t2 = string; type t3 = func(a: u32, b: r) -> u32; -type t4 = func() -> (a: u32, b: string); diff --git a/crates/wac-parser/tests/resolution/types.wac.result b/crates/wac-parser/tests/resolution/types.wac.result index 4790325e..4a25e191 100644 --- a/crates/wac-parser/tests/resolution/types.wac.result +++ b/crates/wac-parser/tests/resolution/types.wac.result @@ -13,7 +13,6 @@ digraph { 11 [ label = "type definition \"t\""; kind = "enum"; export = "t"] 12 [ label = "type definition \"t2\""; kind = "string"; export = "t2"] 13 [ label = "type definition \"t3\""; kind = "function type"; export = "t3"] - 14 [ label = "type definition \"t4\""; kind = "function type"; export = "t4"] 6 -> 7 [ label = "dependency of" ] 7 -> 8 [ label = "dependency of" ] 8 -> 13 [ label = "dependency of" ] diff --git a/crates/wac-resolver/Cargo.toml b/crates/wac-resolver/Cargo.toml index 8aa8a381..6200d6e0 100644 --- a/crates/wac-resolver/Cargo.toml +++ b/crates/wac-resolver/Cargo.toml @@ -34,9 +34,16 @@ warg-server = { workspace = true } pretty_assertions = { workspace = true } tokio-util = "0.7.10" tempdir = "0.3.7" +tempfile = "3.2.0" [features] default = ["registry"] wat = ["dep:wat"] wit = ["dep:wit-parser"] -registry = ["dep:warg-client", "dep:warg-protocol", "dep:warg-crypto", "dep:tokio", "dep:futures"] +registry = [ + "dep:warg-client", + "dep:warg-protocol", + "dep:warg-crypto", + "dep:tokio", + "dep:futures", +] diff --git a/crates/wac-resolver/src/fs.rs b/crates/wac-resolver/src/fs.rs index 6e5c1dcc..ecf78bf3 100644 --- a/crates/wac-resolver/src/fs.rs +++ b/crates/wac-resolver/src/fs.rs @@ -95,9 +95,7 @@ impl FileSystemPackageResolver { let (pkg, _) = resolve.push_dir(&path).map_err(pkg_res_failure)?; Some(pkg) } else if path.extension().and_then(std::ffi::OsStr::to_str) == Some("wit") { - let unresolved = wit_parser::UnresolvedPackage::parse_file(&path) - .map_err(pkg_res_failure)?; - let pkg = resolve.push(unresolved).map_err(pkg_res_failure)?; + let pkg = resolve.push_file(&path).map_err(pkg_res_failure)?; Some(pkg) } else { None @@ -105,7 +103,7 @@ impl FileSystemPackageResolver { if let Some(pkg) = pkg { packages.insert( *key, - wit_component::encode(Some(true), &resolve, pkg) + wit_component::encode(&resolve, pkg) .with_context(|| { format!( "failed to encode WIT package from `{path}`", diff --git a/crates/wac-resolver/tests/support/mod.rs b/crates/wac-resolver/tests/support/mod.rs index 2281be17..d2ddb23a 100644 --- a/crates/wac-resolver/tests/support/mod.rs +++ b/crates/wac-resolver/tests/support/mod.rs @@ -9,7 +9,7 @@ use warg_client::{ use warg_crypto::signing::PrivateKey; use warg_protocol::{operator::NamespaceState, registry::PackageName}; use warg_server::{policy::content::WasmContentPolicy, Config, Server}; -use wit_parser::{Resolve, UnresolvedPackage}; +use wit_parser::Resolve; pub fn test_operator_key() -> &'static str { "ecdsa-p256:I+UlDo0HxyBBFeelhPPWmD+LnklOpqZDkrFP5VduASk=" @@ -43,16 +43,17 @@ pub async fn publish_wit( wit: &str, init: bool, ) -> Result<()> { + use std::io::Write; let mut resolve = Resolve::new(); + let mut tmp = tempfile::NamedTempFile::new()?; + tmp.write(wit.as_bytes())?; + let path = tmp.path(); let pkg = resolve - .push( - UnresolvedPackage::parse(Path::new("foo.wit"), wit) - .context("failed to parse wit for publishing")?, - ) + .push_file(path) .context("failed to resolve wit for publishing")?; - let bytes = wit_component::encode(Some(true), &resolve, pkg) - .context("failed to encode wit for publishing")?; + let bytes = + wit_component::encode(&resolve, pkg).context("failed to encode wit for publishing")?; publish(config, &name.parse()?, version, bytes, init).await } diff --git a/crates/wac-types/src/aggregator.rs b/crates/wac-types/src/aggregator.rs index 8ba1de12..ee406770 100644 --- a/crates/wac-types/src/aggregator.rs +++ b/crates/wac-types/src/aggregator.rs @@ -1,5 +1,5 @@ use crate::{ - DefinedType, DefinedTypeId, FuncResult, FuncType, FuncTypeId, Interface, InterfaceId, ItemKind, + DefinedType, DefinedTypeId, FuncType, FuncTypeId, Interface, InterfaceId, ItemKind, ModuleTypeId, Record, Resource, ResourceAlias, ResourceId, SubtypeChecker, Type, Types, UsedType, ValueType, Variant, World, WorldId, }; @@ -604,23 +604,9 @@ impl TypeAggregator { .iter() .map(|(n, ty)| Ok((n.clone(), self.remap_value_type(types, *ty, checker)?))) .collect::>()?, - results: ty - .results - .as_ref() - .map(|r| -> Result<_> { - match r { - FuncResult::Scalar(ty) => Ok(FuncResult::Scalar( - self.remap_value_type(types, *ty, checker)?, - )), - FuncResult::List(tys) => Ok(FuncResult::List( - tys.iter() - .map(|(n, ty)| { - Ok((n.clone(), self.remap_value_type(types, *ty, checker)?)) - }) - .collect::>()?, - )), - } - }) + result: ty + .result + .map(|ty| self.remap_value_type(types, ty, checker)) .transpose()?, }; @@ -842,6 +828,8 @@ impl TypeAggregator { DefinedType::Alias(ty) => { DefinedType::Alias(self.remap_value_type(types, *ty, checker)?) } + DefinedType::Stream(s) => DefinedType::Stream(*s), + DefinedType::Future(f) => DefinedType::Future(*f), }; let remapped = self.types.add_defined_type(defined); diff --git a/crates/wac-types/src/checker.rs b/crates/wac-types/src/checker.rs index 5d87bf6e..7acd34f1 100644 --- a/crates/wac-types/src/checker.rs +++ b/crates/wac-types/src/checker.rs @@ -1,7 +1,7 @@ use crate::{ - CoreExtern, CoreFuncType, DefinedType, DefinedTypeId, Enum, Flags, FuncResult, FuncTypeId, - InterfaceId, ItemKind, ModuleTypeId, PrimitiveType, Record, ResourceId, Type, Types, ValueType, - Variant, WorldId, + CoreExtern, CoreFuncType, DefinedType, DefinedTypeId, Enum, Flags, FuncTypeId, InterfaceId, + ItemKind, ModuleTypeId, PrimitiveType, Record, ResourceId, Type, Types, ValueType, Variant, + WorldId, }; use anyhow::{bail, Context, Result}; use indexmap::IndexMap; @@ -79,7 +79,13 @@ impl<'a> SubtypeChecker<'a> { (ItemKind::Component(a), ItemKind::Component(b)) => self.world(a, at, b, bt), (ItemKind::Module(a), ItemKind::Module(b)) => self.module(a, at, b, bt), (ItemKind::Value(a), ItemKind::Value(b)) => self.value_type(a, at, b, bt), - _ => { + + (ItemKind::Type(_), _) + | (ItemKind::Func(_), _) + | (ItemKind::Instance(_), _) + | (ItemKind::Component(_), _) + | (ItemKind::Module(_), _) + | (ItemKind::Value(_), _) => { let (expected, expected_types, found, found_types) = self.expected_found(&a, at, &b, bt); bail!( @@ -128,22 +134,29 @@ impl<'a> SubtypeChecker<'a> { fn ty(&mut self, a: Type, at: &Types, b: Type, bt: &Types) -> Result<()> { match (a, b) { - (Type::Resource(a), Type::Resource(b)) => return self.resource(a, at, b, bt), - (Type::Func(a), Type::Func(b)) => return self.func(a, at, b, bt), - (Type::Value(a), Type::Value(b)) => return self.value_type(a, at, b, bt), - (Type::Interface(a), Type::Interface(b)) => return self.interface(a, at, b, bt), - (Type::World(a), Type::World(b)) => return self.world(a, at, b, bt), - (Type::Module(a), Type::Module(b)) => return self.module(a, at, b, bt), - _ => {} - } - - let (expected, expected_types, found, found_types) = self.expected_found(&a, at, &b, bt); - - bail!( - "expected {expected}, found {found}", - expected = expected.desc(expected_types), - found = found.desc(found_types) - ) + (Type::Resource(a), Type::Resource(b)) => self.resource(a, at, b, bt), + (Type::Func(a), Type::Func(b)) => self.func(a, at, b, bt), + (Type::Value(a), Type::Value(b)) => self.value_type(a, at, b, bt), + (Type::Interface(a), Type::Interface(b)) => self.interface(a, at, b, bt), + (Type::World(a), Type::World(b)) => self.world(a, at, b, bt), + (Type::Module(a), Type::Module(b)) => self.module(a, at, b, bt), + + (Type::Func(_), _) + | (Type::Resource(_), _) + | (Type::Value(_), _) + | (Type::Interface(_), _) + | (Type::World(_), _) + | (Type::Module(_), _) => { + let (expected, expected_types, found, found_types) = + self.expected_found(&a, at, &b, bt); + + bail!( + "expected {expected}, found {found}", + expected = expected.desc(expected_types), + found = found.desc(found_types) + ) + } + } } fn func(&self, a: FuncTypeId, at: &Types, b: FuncTypeId, bt: &Types) -> Result<()> { @@ -177,51 +190,27 @@ impl<'a> SubtypeChecker<'a> { .with_context(|| format!("mismatched type for function parameter `{bn}`"))?; } - match (&a.results, &b.results) { + match (&a.result, &b.result) { (None, None) => return Ok(()), - (Some(FuncResult::Scalar(a)), Some(FuncResult::Scalar(b))) => { + (Some(a), Some(b)) => { return self .value_type(*a, at, *b, bt) .context("mismatched type for function result"); } - (Some(FuncResult::List(a)), Some(FuncResult::List(b))) => { - for (i, ((an, a), (bn, b))) in a.iter().zip(b.iter()).enumerate() { - if an != bn { - let (expected, _, found, _) = self.expected_found(an, at, bn, bt); - bail!("expected function result {i} to be named `{expected}`, found name `{found}`"); - } - - self.value_type(*a, at, *b, bt) - .with_context(|| format!("mismatched type for function result `{bn}`"))?; - } - - return Ok(()); - } - (Some(FuncResult::List(_)), Some(FuncResult::Scalar(_))) - | (Some(FuncResult::Scalar(_)), Some(FuncResult::List(_))) - | (Some(_), None) - | (None, Some(_)) => { + (None, _) | (Some(_), _) => { // Handle the mismatch below } } let (expected, _, found, _) = self.expected_found(a, at, b, bt); - match (&expected.results, &found.results) { - (Some(FuncResult::List(_)), Some(FuncResult::Scalar(_))) => { - bail!("expected function that returns a named result, found function with a single result type") - } - (Some(FuncResult::Scalar(_)), Some(FuncResult::List(_))) => { - bail!("expected function that returns a single result type, found function that returns a named result") - } + match (&expected.result, &found.result) { (Some(_), None) => { bail!("expected function with a result, found function without a result") } (None, Some(_)) => { bail!("expected function without a result, found function with a result") } - (Some(FuncResult::Scalar(_)), Some(FuncResult::Scalar(_))) - | (Some(FuncResult::List(_)), Some(FuncResult::List(_))) - | (None, None) => panic!("should already be handled"), + (Some(_), Some(_)) | (None, None) => panic!("should already be handled"), } } @@ -416,17 +405,21 @@ impl<'a> SubtypeChecker<'a> { } match (a, b) { - (CoreExtern::Func(a), CoreExtern::Func(b)) => return self.core_func(a, at, b, bt), + (CoreExtern::Func(a), CoreExtern::Func(b)) => self.core_func(a, at, b, bt), ( CoreExtern::Table { element_type: ae, initial: ai, maximum: am, + table64: _a64, + shared: _ashared, }, CoreExtern::Table { element_type: be, initial: bi, maximum: bm, + table64: _b64, + shared: _bshared, }, ) => { if ae != be { @@ -438,7 +431,7 @@ impl<'a> SubtypeChecker<'a> { bail!("mismatched table limits"); } - return Ok(()); + Ok(()) } ( CoreExtern::Memory { @@ -446,12 +439,14 @@ impl<'a> SubtypeChecker<'a> { shared: ashared, initial: ai, maximum: am, + page_size_log2: _apsl, }, CoreExtern::Memory { memory64: b64, shared: bshared, initial: bi, maximum: bm, + page_size_log2: _bpsl, }, ) => { if ashared != bshared { @@ -466,16 +461,18 @@ impl<'a> SubtypeChecker<'a> { bail!("mismatched memory limits"); } - return Ok(()); + Ok(()) } ( CoreExtern::Global { val_type: avt, mutable: am, + shared: _ashared, }, CoreExtern::Global { val_type: bvt, mutable: bm, + shared: _bshared, }, ) => { if am != bm { @@ -487,14 +484,19 @@ impl<'a> SubtypeChecker<'a> { bail!("expected global type {expected}, found {found}"); } - return Ok(()); + Ok(()) + } + (CoreExtern::Tag(a), CoreExtern::Tag(b)) => self.core_func(a, at, b, bt), + + (CoreExtern::Func(_), _) + | (CoreExtern::Table { .. }, _) + | (CoreExtern::Memory { .. }, _) + | (CoreExtern::Global { .. }, _) + | (CoreExtern::Tag(_), _) => { + let (expected, _, found, _) = self.expected_found(a, at, b, bt); + bail!("expected {expected}, found {found}"); } - (CoreExtern::Tag(a), CoreExtern::Tag(b)) => return self.core_func(a, at, b, bt), - _ => {} } - - let (expected, _, found, _) = self.expected_found(a, at, b, bt); - bail!("expected {expected}, found {found}"); } fn core_func(&self, a: &CoreFuncType, at: &Types, b: &CoreFuncType, bt: &Types) -> Result<()> { @@ -515,7 +517,11 @@ impl<'a> SubtypeChecker<'a> { (ValueType::Defined(a), ValueType::Defined(b)) => self.defined_type(a, at, b, bt), (ValueType::Borrow(a), ValueType::Borrow(b)) | (ValueType::Own(a), ValueType::Own(b)) => self.resource(a, at, b, bt), - _ => { + + (ValueType::Primitive(_), _) + | (ValueType::Defined(_), _) + | (ValueType::Borrow(_), _) + | (ValueType::Own(_), _) => { let (expected, expected_types, found, found_types) = self.expected_found(&a, at, &b, bt); bail!( @@ -545,6 +551,12 @@ impl<'a> SubtypeChecker<'a> { (DefinedType::List(a), DefinedType::List(b)) => self .value_type(*a, at, *b, bt) .context("mismatched type for list element"), + (DefinedType::Future(a), DefinedType::Future(b)) => self + .payload(*a, at, *b, bt) + .context("mismatched type for future payload"), + (DefinedType::Stream(a), DefinedType::Stream(b)) => self + .payload(*a, at, *b, bt) + .context("mismatched type for stream payload"), (DefinedType::Option(a), DefinedType::Option(b)) => self .value_type(*a, at, *b, bt) .context("mismatched type for option"), @@ -568,7 +580,17 @@ impl<'a> SubtypeChecker<'a> { (DefinedType::Alias(_), _) | (_, DefinedType::Alias(_)) => { panic!("aliases should have been resolved") } - _ => { + + (DefinedType::Tuple(_), _) + | (DefinedType::List(_), _) + | (DefinedType::Option(_), _) + | (DefinedType::Result { .. }, _) + | (DefinedType::Variant(_), _) + | (DefinedType::Record(_), _) + | (DefinedType::Flags(_), _) + | (DefinedType::Enum(_), _) + | (DefinedType::Stream(_), _) + | (DefinedType::Future(_), _) => { let (expected, expected_types, found, found_types) = self.expected_found(a, at, b, bt); bail!( @@ -734,6 +756,21 @@ impl<'a> SubtypeChecker<'a> { Ok(()) } + fn payload( + &self, + a: Option, + at: &Types, + b: Option, + bt: &Types, + ) -> Result<()> { + match (a, b) { + (Some(a), Some(b)) => self.value_type(a, at, b, bt), + (None, None) => Ok(()), + (Some(_), None) => bail!("expected a type payload, found none"), + (None, Some(_)) => bail!("expected no type payload, found one"), + } + } + fn primitive(&self, a: PrimitiveType, at: &Types, b: PrimitiveType, bt: &Types) -> Result<()> { // Note: currently subtyping for primitive types is done in terms of equality // rather than actual subtyping; the reason for this is that implementing diff --git a/crates/wac-types/src/component.rs b/crates/wac-types/src/component.rs index 54d7239c..0cd1bb38 100644 --- a/crates/wac-types/src/component.rs +++ b/crates/wac-types/src/component.rs @@ -515,6 +515,8 @@ pub enum PrimitiveType { Bool, /// A `string` type. String, + /// An `error-context` type. + ErrorContext, } impl PrimitiveType { @@ -534,6 +536,7 @@ impl PrimitiveType { Self::Char => "char", Self::Bool => "bool", Self::String => "string", + Self::ErrorContext => "error-context", } } } @@ -554,6 +557,7 @@ impl From for PrimitiveType { wasmparser::PrimitiveValType::F64 => Self::F64, wasmparser::PrimitiveValType::Char => Self::Char, wasmparser::PrimitiveValType::String => Self::String, + wasmparser::PrimitiveValType::ErrorContext => Self::ErrorContext, } } } @@ -574,6 +578,7 @@ impl From for wasm_encoder::PrimitiveValType { PrimitiveType::Char => Self::Char, PrimitiveType::Bool => Self::Bool, PrimitiveType::String => Self::String, + PrimitiveType::ErrorContext => Self::ErrorContext, } } } @@ -640,7 +645,7 @@ impl serde::Serialize for ValueType { Self::Primitive(ty) => ty.serialize(serializer), Self::Borrow(id) => format!("borrow<{id}>", id = id.0.index()).serialize(serializer), Self::Own(id) => format!("own<{id}>", id = id.0.index()).serialize(serializer), - Self::Defined { id, .. } => id.serialize(serializer), + Self::Defined(id) => id.serialize(serializer), } } } @@ -673,6 +678,10 @@ pub enum DefinedType { Enum(Enum), /// The type is an alias to another value type. Alias(ValueType), + /// A stream type. + Stream(Option), + /// A futures type. + Future(Option), } impl DefinedType { @@ -694,6 +703,8 @@ impl DefinedType { Self::Flags(_) => false, Self::Enum(_) => false, Self::Alias(ty) => ty.contains_borrow(types), + Self::Stream(ty) => ty.map(|ty| ty.contains_borrow(types)).unwrap_or(false), + Self::Future(ty) => ty.map(|ty| ty.contains_borrow(types)).unwrap_or(false), } } @@ -739,10 +750,17 @@ impl DefinedType { Ok(()) } DefinedType::Flags(_) | DefinedType::Enum(_) | DefinedType::Alias(_) => Ok(()), + DefinedType::Stream(ty) | DefinedType::Future(ty) => { + if let Some(ty) = ty { + ty._visit_defined_types(types, visitor, false)?; + } + + Ok(()) + } } } - /// Gets a description of the defined type. + /// Gets atyd | DefinedType::Future(t)escription of the defined type. pub fn desc(&self, types: &Types) -> &'static str { match self { Self::Tuple(_) => "tuple", @@ -754,6 +772,8 @@ impl DefinedType { Self::Flags(_) => "flags", Self::Enum(_) => "enum", Self::Alias(ty) => ty.desc(types), + Self::Stream(_) => "stream", + Self::Future(_) => "future", } } } @@ -848,8 +868,8 @@ pub struct Enum(pub IndexSet); pub struct FuncType { /// The parameters of the function. pub params: IndexMap, - /// The results of the function. - pub results: Option, + /// The result of the function. + pub result: Option, } impl FuncType { @@ -862,44 +882,14 @@ impl FuncType { ty._visit_defined_types(types, visitor, false)?; } - if let Some(results) = self.results.as_ref() { - results._visit_defined_types(types, visitor)?; + if let Some(ty) = &self.result { + ty._visit_defined_types(types, visitor, false)?; } Ok(()) } } -/// Represents a function result. -#[derive(Debug, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub enum FuncResult { - /// A scalar result. - Scalar(ValueType), - /// A list of named results. - List(IndexMap), -} - -impl FuncResult { - fn _visit_defined_types<'a, E>( - &self, - types: &'a Types, - visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>, - ) -> Result<(), E> { - match self { - FuncResult::Scalar(ty) => ty._visit_defined_types(types, visitor, false), - FuncResult::List(tys) => { - for ty in tys.values() { - ty._visit_defined_types(types, visitor, false)?; - } - - Ok(()) - } - } - } -} - /// Represents a used type. #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] @@ -988,7 +978,7 @@ impl World { pub fn implicit_imported_interfaces<'a>( &'a self, types: &'a Types, - ) -> IndexMap<&str, ItemKind> { + ) -> IndexMap<&'a str, ItemKind> { let mut interfaces = IndexMap::new(); let mut add_interface_for_used_type = |used_item: &UsedType| { let used_interface_id = used_item.interface; diff --git a/crates/wac-types/src/core.rs b/crates/wac-types/src/core.rs index c7142186..c5a19143 100644 --- a/crates/wac-types/src/core.rs +++ b/crates/wac-types/src/core.rs @@ -27,9 +27,20 @@ pub enum CoreExtern { /// The table's element type. element_type: CoreRefType, /// Initial size of this table, in elements. - initial: u32, + initial: u64, /// Optional maximum size of the table, in elements. - maximum: Option, + maximum: Option, + /// Whether or not this is a 64-bit table, using i64 as an index. If this + /// is false it's a 32-bit memory using i32 as an index. + /// + /// This is part of the memory64 proposal in WebAssembly. + table64: bool, + /// Whether or not this is a "shared" memory, indicating that it should be + /// send-able across threads and the `maximum` field is always present for + /// valid types. + /// + /// This is part of the threads proposal in WebAssembly. + shared: bool, }, /// The item is a memory. #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] @@ -59,6 +70,16 @@ pub enum CoreExtern { /// be at most `u32::MAX` for valid types. This field is always present for /// valid wasm memories when `shared` is `true`. maximum: Option, + + /// The log base 2 of the memory's custom page size. + /// + /// Memory pages are, by default, 64KiB large (i.e. 216 or + /// `65536`). + /// + /// [The custom-page-sizes proposal] allows changing it to other values. + /// + /// [The custom-page-sizes proposal]: https://github.com/WebAssembly/custom-page-sizes + page_size_log2: Option, }, /// The item is a global. #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] @@ -67,6 +88,12 @@ pub enum CoreExtern { val_type: CoreType, /// Whether or not the global is mutable. mutable: bool, + /// Whether or not this is a "shared" memory, indicating that it should be + /// send-able across threads and the `maximum` field is always present for + /// valid types. + /// + /// This is part of the threads proposal in WebAssembly. + shared: bool, }, /// The item is a tag. Tag(CoreFuncType), @@ -90,6 +117,8 @@ impl From for CoreExtern { element_type: ty.element_type.into(), initial: ty.initial, maximum: ty.maximum, + table64: ty.table64, + shared: ty.shared, } } } @@ -101,6 +130,7 @@ impl From for CoreExtern { shared: ty.shared, initial: ty.initial, maximum: ty.maximum, + page_size_log2: ty.page_size_log2, } } } @@ -110,6 +140,7 @@ impl From for CoreExtern { Self::Global { val_type: ty.content_type.into(), mutable: ty.mutable, + shared: ty.shared, } } } @@ -198,6 +229,9 @@ impl fmt::Display for CoreRefType { (true, HeapType::Array) => "arrayref", (true, HeapType::I31) => "i31ref", (true, HeapType::Exn) => "exnref", + (true, HeapType::NoExn) => "nullexnref", + (true, HeapType::Cont) => "contref", + (true, HeapType::NoCont) => "nullcontref", (false, HeapType::Func) => "(ref func)", (false, HeapType::Extern) => "(ref extern)", (false, HeapType::Concrete(i)) => return write!(f, "(ref {i})"), @@ -210,6 +244,9 @@ impl fmt::Display for CoreRefType { (false, HeapType::Array) => "(ref array)", (false, HeapType::I31) => "(ref i31)", (false, HeapType::Exn) => "(ref exn)", + (false, HeapType::NoExn) => "(ref noexn)", + (false, HeapType::Cont) => "(ref cont)", + (false, HeapType::NoCont) => "(ref nocont)", }; f.write_str(s) @@ -265,22 +302,42 @@ pub enum HeapType { /// /// Introduced in the exception-handling proposal. Exn, + /// The common subtype (a.k.a. bottom) of all exception types. + /// + /// Introduced in the exception-handling proposal. + NoExn, + /// The abstract `continuation` heap type. + /// + /// Introduced in the stack-switching proposal. + Cont, + /// The common subtype (a.k.a. bottom) of all continuation types. + /// + /// Introduced in the stack-switching proposal. + NoCont, } impl From for HeapType { fn from(ty: wasmparser::HeapType) -> Self { match ty { - wasmparser::HeapType::Any => Self::Any, - wasmparser::HeapType::Func => Self::Func, - wasmparser::HeapType::Extern => Self::Extern, - wasmparser::HeapType::Eq => Self::Eq, - wasmparser::HeapType::I31 => Self::I31, - wasmparser::HeapType::None => Self::None, - wasmparser::HeapType::NoExtern => Self::NoExtern, - wasmparser::HeapType::NoFunc => Self::NoFunc, - wasmparser::HeapType::Struct => Self::Struct, - wasmparser::HeapType::Array => Self::Array, - wasmparser::HeapType::Exn => Self::Exn, + wasmparser::HeapType::Abstract { shared: false, ty } => match ty { + wasmparser::AbstractHeapType::Any => Self::Any, + wasmparser::AbstractHeapType::Func => Self::Func, + wasmparser::AbstractHeapType::Extern => Self::Extern, + wasmparser::AbstractHeapType::Eq => Self::Eq, + wasmparser::AbstractHeapType::I31 => Self::I31, + wasmparser::AbstractHeapType::None => Self::None, + wasmparser::AbstractHeapType::NoExtern => Self::NoExtern, + wasmparser::AbstractHeapType::NoFunc => Self::NoFunc, + wasmparser::AbstractHeapType::Struct => Self::Struct, + wasmparser::AbstractHeapType::Array => Self::Array, + wasmparser::AbstractHeapType::Exn => Self::Exn, + wasmparser::AbstractHeapType::NoExn => Self::NoExn, + wasmparser::AbstractHeapType::Cont => Self::Cont, + wasmparser::AbstractHeapType::NoCont => Self::NoCont, + }, + wasmparser::HeapType::Abstract { shared: true, ty } => { + panic!("shared heap types are not supported: {:?}", ty) + } wasmparser::HeapType::Concrete(index) => { Self::Concrete(index.as_module_index().unwrap()) } @@ -289,20 +346,68 @@ impl From for HeapType { } impl From for wasm_encoder::HeapType { + /// Converts a `HeapType` into a `wasm_encoder::HeapType`. + /// Shared types are not supported, so defaults to `false` + /// for Abstract types. fn from(value: HeapType) -> Self { match value { HeapType::Concrete(index) => Self::Concrete(index), - HeapType::Func => Self::Func, - HeapType::Extern => Self::Extern, - HeapType::Any => Self::Any, - HeapType::None => Self::None, - HeapType::NoExtern => Self::NoExtern, - HeapType::NoFunc => Self::NoFunc, - HeapType::Eq => Self::Eq, - HeapType::Struct => Self::Struct, - HeapType::Array => Self::Array, - HeapType::I31 => Self::I31, - HeapType::Exn => Self::Exn, + HeapType::Func => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Func, + }, + HeapType::Extern => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Extern, + }, + HeapType::Any => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Any, + }, + HeapType::None => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::None, + }, + HeapType::NoExtern => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::NoExtern, + }, + HeapType::NoFunc => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::NoFunc, + }, + HeapType::Eq => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Eq, + }, + HeapType::Struct => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Struct, + }, + HeapType::Array => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Array, + }, + HeapType::I31 => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::I31, + }, + HeapType::Exn => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Exn, + }, + HeapType::NoExn => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::NoExn, + }, + HeapType::Cont => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::Cont, + }, + HeapType::NoCont => Self::Abstract { + shared: false, + ty: wasm_encoder::AbstractHeapType::NoCont, + }, } } } diff --git a/crates/wac-types/src/package.rs b/crates/wac-types/src/package.rs index d83b440b..8bb1aab7 100644 --- a/crates/wac-types/src/package.rs +++ b/crates/wac-types/src/package.rs @@ -1,7 +1,7 @@ use crate::{ - CoreExtern, CoreFuncType, DefinedType, Enum, Flags, FuncResult, FuncType, FuncTypeId, - Interface, InterfaceId, ItemKind, ModuleType, ModuleTypeId, Record, Resource, ResourceAlias, - ResourceId, Type, Types, UsedType, ValueType, Variant, World, WorldId, + CoreExtern, CoreFuncType, DefinedType, Enum, Flags, FuncType, FuncTypeId, Interface, + InterfaceId, ItemKind, ModuleType, ModuleTypeId, Record, Resource, ResourceAlias, ResourceId, + Type, Types, UsedType, ValueType, Variant, World, WorldId, }; use anyhow::{bail, Context, Result}; use indexmap::IndexMap; @@ -10,8 +10,8 @@ use std::borrow::Borrow; use std::fmt; use std::{collections::HashMap, path::Path, rc::Rc}; use wasmparser::{ + component_types::{self as wasm}, names::{ComponentName, ComponentNameKind}, - types::{self as wasm, ComponentAnyTypeId}, Chunk, Encoding, Parser, Payload, ValidPayload, Validator, WasmFeatures, }; @@ -133,7 +133,7 @@ impl PartialEq for (dyn BorrowedKey + '_) { } } -impl<'a> std::hash::Hash for (dyn BorrowedKey + 'a) { +impl std::hash::Hash for (dyn BorrowedKey + '_) { fn hash(&self, state: &mut H) { self.borrowed_key().hash(state) } @@ -388,14 +388,14 @@ enum Entity { /// representations. struct TypeConverter<'a> { types: &'a mut Types, - wasm_types: Rc, + wasm_types: Rc, cache: HashMap, resource_map: HashMap, owners: HashMap, } impl<'a> TypeConverter<'a> { - fn new(types: &'a mut Types, wasm_types: wasm::Types) -> Self { + fn new(types: &'a mut Types, wasm_types: wasmparser::types::Types) -> Self { Self { types, wasm_types: Rc::new(wasm_types), @@ -438,28 +438,12 @@ impl<'a> TypeConverter<'a> { .map(|(name, ty)| Ok((name.to_string(), self.component_val_type(*ty)?))) .collect::>()?; - let results = if func_ty.results.len() == 0 { - None - } else if func_ty.results.len() == 1 && func_ty.results[0].0.is_none() { - Some(FuncResult::Scalar( - self.component_val_type(func_ty.results[0].1)?, - )) - } else { - Some(FuncResult::List( - func_ty - .results - .iter() - .map(|(name, ty)| { - Ok(( - name.as_ref().unwrap().to_string(), - self.component_val_type(*ty)?, - )) - }) - .collect::>()?, - )) + let result = match func_ty.result { + Some(ty) => Some(self.component_val_type(ty)?), + None => None, }; - let id = self.types.add_func_type(FuncType { params, results }); + let id = self.types.add_func_type(FuncType { params, result }); self.cache.insert(key, Entity::Type(Type::Func(id))); Ok(id) } @@ -594,8 +578,8 @@ impl<'a> TypeConverter<'a> { &mut self, owner: Owner, name: &str, - referenced: ComponentAnyTypeId, - created: ComponentAnyTypeId, + referenced: wasm::ComponentAnyTypeId, + created: wasm::ComponentAnyTypeId, ) { if let Some((other, orig)) = self.find_owner(referenced) { match *other { @@ -762,6 +746,14 @@ impl<'a> TypeConverter<'a> { _ => panic!("expected a resource"), }, ), + wasm::ComponentDefinedType::Stream(ty) => { + let stream = ty.map(|ty| self.component_val_type(ty)).transpose()?; + ValueType::Defined(self.types.add_defined_type(DefinedType::Stream(stream))) + } + wasm::ComponentDefinedType::Future(ty) => { + let option = ty.map(|ty| self.component_val_type(ty)).transpose()?; + ValueType::Defined(self.types.add_defined_type(DefinedType::Future(option))) + } }; self.cache.insert(key, Entity::Type(Type::Value(ty))); @@ -782,7 +774,7 @@ impl<'a> TypeConverter<'a> { let alias_id = self.types.add_resource(Resource { name: name.to_owned(), alias: Some(ResourceAlias { - owner: match self.find_owner(ComponentAnyTypeId::Resource(id)) { + owner: match self.find_owner(wasm::ComponentAnyTypeId::Resource(id)) { Some((Owner::Interface(id), _)) => Some(*id), _ => None, }, @@ -804,17 +796,17 @@ impl<'a> TypeConverter<'a> { resource_id } - fn entity_type(&self, ty: wasm::EntityType) -> CoreExtern { + fn entity_type(&self, ty: wasmparser::types::EntityType) -> CoreExtern { match ty { - wasm::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)), - wasm::EntityType::Table(ty) => ty.into(), - wasm::EntityType::Memory(ty) => ty.into(), - wasm::EntityType::Global(ty) => ty.into(), - wasm::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)), + wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)), + wasmparser::types::EntityType::Table(ty) => ty.into(), + wasmparser::types::EntityType::Memory(ty) => ty.into(), + wasmparser::types::EntityType::Global(ty) => ty.into(), + wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)), } } - fn func_type(&self, ty: wasm::CoreTypeId) -> CoreFuncType { + fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> CoreFuncType { let func_ty = self.wasm_types[ty].unwrap_func(); CoreFuncType { params: func_ty.params().iter().copied().map(Into::into).collect(), diff --git a/src/commands/targets.rs b/src/commands/targets.rs index df3f04f7..2512e6ac 100644 --- a/src/commands/targets.rs +++ b/src/commands/targets.rs @@ -95,10 +95,9 @@ fn encode_wit_as_component(path: &Path) -> anyhow::Result> { let (pkg, _) = resolve.push_dir(path)?; pkg } else { - let unresolved = wit_parser::UnresolvedPackage::parse_file(path)?; - resolve.push(unresolved)? + resolve.push_path(path)?.0 }; - let encoded = wit_component::encode(Some(true), &resolve, pkg).with_context(|| { + let encoded = wit_component::encode(&resolve, pkg).with_context(|| { format!( "failed to encode WIT package from `{path}`", path = path.display()