diff --git a/crates/wit-component/src/encoding/wit/v1.rs b/crates/wit-component/src/encoding/wit.rs similarity index 85% rename from crates/wit-component/src/encoding/wit/v1.rs rename to crates/wit-component/src/encoding/wit.rs index ed6c39a35f..8ee658960a 100644 --- a/crates/wit-component/src/encoding/wit/v1.rs +++ b/crates/wit-component/src/encoding/wit.rs @@ -6,6 +6,30 @@ use std::mem; use wasm_encoder::*; use wit_parser::*; +/// Encodes the given `package` within `resolve` to a binary WebAssembly +/// representation. +/// +/// This function is the root of the implementation of serializing a WIT package +/// into a WebAssembly representation. The wasm representation serves two +/// purposes: +/// +/// * One is to be a binary encoding of a WIT document which is ideally more +/// stable than the WIT textual format itself. +/// * Another is to provide a clear mapping of all WIT features into the +/// component model through use of its binary representation. +/// +/// The `resolve` provided is a set of packages and types and such and the +/// `package` argument is an ID within the world provided. The documents within +/// `package` will all be encoded into the binary returned. +/// +/// The binary returned can be [`decode`d](crate::decode) to recover the WIT +/// package provided. +pub fn encode(resolve: &Resolve, package: PackageId) -> Result> { + let mut component = encode_component(resolve, package)?; + component.raw_custom_section(&crate::base_producers().raw_custom_section()); + Ok(component.finish()) +} + /// Encodes the given `package` within `resolve` to a binary WebAssembly /// representation. /// @@ -41,6 +65,82 @@ pub fn encode_component(resolve: &Resolve, package: PackageId) -> Result Result { + let mut component = InterfaceEncoder::new(resolve); + let world = &resolve.worlds[world_id]; + log::trace!("encoding world {}", world.name); + + // This sort is similar in purpose to the sort below in + // `encode_instance`, but different in its sort. The purpose here is + // to ensure that when a document is either printed as WIT or + // encoded as wasm that decoding from those artifacts produces the + // same WIT package. Namely both encoding processes should encode + // things in the same order. + // + // When printing worlds in WIT freestanding function imports are + // printed first, then types. Resource functions are attached to + // types which means that they all come last. Sort all + // resource-related functions here to the back of the `imports` list + // while keeping everything else in front, using a stable sort to + // preserve preexisting ordering. + let mut imports = world.imports.iter().collect::>(); + imports.sort_by_key(|(_name, import)| match import { + WorldItem::Function(f) => match f.kind { + FunctionKind::Freestanding => 0, + _ => 1, + }, + _ => 0, + }); + + // Encode the imports + for (name, import) in imports { + let name = resolve.name_world_key(name); + log::trace!("encoding import {name}"); + let ty = match import { + WorldItem::Interface { id, .. } => { + component.interface = Some(*id); + let idx = component.encode_instance(*id)?; + ComponentTypeRef::Instance(idx) + } + WorldItem::Function(f) => { + component.interface = None; + let idx = component.encode_func_type(resolve, f)?; + ComponentTypeRef::Func(idx) + } + WorldItem::Type(t) => { + component.interface = None; + component.import_types = true; + component.encode_valtype(resolve, &Type::Id(*t))?; + component.import_types = false; + continue; + } + }; + component.outer.import(&name, ty); + } + // Encode the exports + for (name, export) in world.exports.iter() { + let name = resolve.name_world_key(name); + log::trace!("encoding export {name}"); + let ty = match export { + WorldItem::Interface { id, .. } => { + component.interface = Some(*id); + let idx = component.encode_instance(*id)?; + ComponentTypeRef::Instance(idx) + } + WorldItem::Function(f) => { + component.interface = None; + let idx = component.encode_func_type(resolve, f)?; + ComponentTypeRef::Func(idx) + } + WorldItem::Type(_) => unreachable!(), + }; + component.outer.export(&name, ty); + } + + Ok(component.outer) +} + struct Encoder<'a> { component: ComponentBuilder, resolve: &'a Resolve, @@ -49,6 +149,34 @@ struct Encoder<'a> { impl Encoder<'_> { fn run(&mut self) -> Result<()> { + // Encode all interfaces as component types and then export them. + for (name, &id) in self.resolve.packages[self.package].interfaces.iter() { + let component_ty = self.encode_interface(id)?; + let ty = self.component.type_component(&component_ty); + self.component + .export(name.as_ref(), ComponentExportKind::Type, ty, None); + } + + // For each `world` encode it directly as a component and then create a + // wrapper component that exports that component. + for (name, &world) in self.resolve.packages[self.package].worlds.iter() { + let component_ty = encode_world(self.resolve, world)?; + + let world = &self.resolve.worlds[world]; + let mut wrapper = ComponentType::new(); + wrapper.ty().component(&component_ty); + let pkg = &self.resolve.packages[world.package.unwrap()]; + wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0)); + + let ty = self.component.type_component(&wrapper); + self.component + .export(name.as_ref(), ComponentExportKind::Type, ty, None); + } + + Ok(()) + } + + fn encode_interface(&mut self, id: InterfaceId) -> Result { // Build a set of interfaces reachable from this document, including the // interfaces in the document itself. This is used to import instances // into the component type we're encoding. Note that entire interfaces @@ -58,9 +186,7 @@ impl Encoder<'_> { // notably on the order that types are defined in to assist with // roundtripping. let mut interfaces = IndexSet::new(); - for (_, id) in self.resolve.packages[self.package].interfaces.iter() { - self.add_live_interfaces(&mut interfaces, *id); - } + self.add_live_interfaces(&mut interfaces, id); // Seed the set of used names with all exported interfaces to ensure // that imported interfaces choose different names as the import names @@ -73,23 +199,15 @@ impl Encoder<'_> { assert!(first); } } - for (name, _world) in self.resolve.packages[self.package].worlds.iter() { - let first = used_names.insert(name.clone()); - assert!(first); - } - // Encode all interfaces, foreign and local, into this component type. - // Local interfaces get their functions defined as well and are - // exported. Foreign interfaces are imported and only have their types - // encoded. let mut encoder = InterfaceEncoder::new(self.resolve); for interface in interfaces { encoder.interface = Some(interface); let iface = &self.resolve.interfaces[interface]; let name = self.resolve.id_of(interface).unwrap(); - log::trace!("encoding interface {name}"); - if iface.package == Some(self.package) { + if interface == id { let idx = encoder.encode_instance(interface)?; + log::trace!("exporting self as {idx}"); encoder.outer.export(&name, ComponentTypeRef::Instance(idx)); } else { encoder.push_instance(); @@ -104,21 +222,10 @@ impl Encoder<'_> { encoder.outer.import(&name, ComponentTypeRef::Instance(idx)); } } - encoder.interface = None; - for (name, world) in self.resolve.packages[self.package].worlds.iter() { - let component_ty = encode_world(self.resolve, *world)?; - let idx = encoder.outer.type_count(); - encoder.outer.ty().component(&component_ty); - let id = self.resolve.packages[self.package].name.interface_id(name); - encoder.outer.export(&id, ComponentTypeRef::Component(idx)); - } + encoder.interface = None; - let ty = self.component.type_component(&encoder.outer); - let id = self.resolve.packages[self.package].name.interface_id("wit"); - self.component - .export(&id, ComponentExportKind::Type, ty, None); - Ok(()) + Ok(encoder.outer) } /// Recursively add all live interfaces reachable from `id` into the @@ -317,79 +424,3 @@ impl<'a> ValtypeEncoder<'a> for InterfaceEncoder<'a> { &mut self.func_type_map } } - -/// Encodes a `world` as a component type. -pub fn encode_world(resolve: &Resolve, world_id: WorldId) -> Result { - let mut component = InterfaceEncoder::new(resolve); - let world = &resolve.worlds[world_id]; - log::trace!("encoding world {}", world.name); - - // This sort is similar in purpose to the sort below in - // `encode_instance`, but different in its sort. The purpose here is - // to ensure that when a document is either printed as WIT or - // encoded as wasm that decoding from those artifacts produces the - // same WIT package. Namely both encoding processes should encode - // things in the same order. - // - // When printing worlds in WIT freestanding function imports are - // printed first, then types. Resource functions are attached to - // types which means that they all come last. Sort all - // resource-related functions here to the back of the `imports` list - // while keeping everything else in front, using a stable sort to - // preserve preexisting ordering. - let mut imports = world.imports.iter().collect::>(); - imports.sort_by_key(|(_name, import)| match import { - WorldItem::Function(f) => match f.kind { - FunctionKind::Freestanding => 0, - _ => 1, - }, - _ => 0, - }); - - // Encode the imports - for (name, import) in imports { - let name = resolve.name_world_key(name); - log::trace!("encoding import {name}"); - let ty = match import { - WorldItem::Interface { id, .. } => { - component.interface = Some(*id); - let idx = component.encode_instance(*id)?; - ComponentTypeRef::Instance(idx) - } - WorldItem::Function(f) => { - component.interface = None; - let idx = component.encode_func_type(resolve, f)?; - ComponentTypeRef::Func(idx) - } - WorldItem::Type(t) => { - component.interface = None; - component.import_types = true; - component.encode_valtype(resolve, &Type::Id(*t))?; - component.import_types = false; - continue; - } - }; - component.outer.import(&name, ty); - } - // Encode the exports - for (name, export) in world.exports.iter() { - let name = resolve.name_world_key(name); - log::trace!("encoding export {name}"); - let ty = match export { - WorldItem::Interface { id, .. } => { - component.interface = Some(*id); - let idx = component.encode_instance(*id)?; - ComponentTypeRef::Instance(idx) - } - WorldItem::Function(f) => { - component.interface = None; - let idx = component.encode_func_type(resolve, f)?; - ComponentTypeRef::Func(idx) - } - WorldItem::Type(_) => unreachable!(), - }; - component.outer.export(&name, ty); - } - - Ok(component.outer) -} diff --git a/crates/wit-component/src/encoding/wit/mod.rs b/crates/wit-component/src/encoding/wit/mod.rs deleted file mode 100644 index a5b61a5370..0000000000 --- a/crates/wit-component/src/encoding/wit/mod.rs +++ /dev/null @@ -1,58 +0,0 @@ -use anyhow::Result; -use wasm_encoder::{ComponentBuilder, ComponentType}; -use wit_parser::{PackageId, Resolve, WorldId}; - -mod v1; -mod v2; - -const ENCODE_V2_BY_DEFAULT: bool = true; - -fn use_v2_encoding() -> bool { - match std::env::var("WIT_COMPONENT_ENCODING_V2") { - Ok(s) => s == "1", - Err(_) => ENCODE_V2_BY_DEFAULT, - } -} - -/// Encodes the given `package` within `resolve` to a binary WebAssembly -/// representation. -/// -/// This function is the root of the implementation of serializing a WIT package -/// into a WebAssembly representation. The wasm representation serves two -/// purposes: -/// -/// * One is to be a binary encoding of a WIT document which is ideally more -/// stable than the WIT textual format itself. -/// * Another is to provide a clear mapping of all WIT features into the -/// component model through use of its binary representation. -/// -/// The `resolve` provided is a set of packages and types and such and the -/// `package` argument is an ID within the world provided. The documents within -/// `package` will all be encoded into the binary returned. -/// -/// The binary returned can be [`decode`d](crate::decode) to recover the WIT -/// package provided. -pub fn encode(use_v2: Option, resolve: &Resolve, package: PackageId) -> Result> { - let mut component = encode_component(use_v2, resolve, package)?; - component.raw_custom_section(&crate::base_producers().raw_custom_section()); - Ok(component.finish()) -} - -/// Exactly like `encode`, except gives an unfinished `ComponentBuilder` in case you need -/// to append anything else before finishing. -pub fn encode_component( - use_v2: Option, - resolve: &Resolve, - package: PackageId, -) -> Result { - if use_v2.unwrap_or_else(use_v2_encoding) { - v2::encode_component(resolve, package) - } else { - v1::encode_component(resolve, package) - } -} - -/// Encodes a `world` as a component type. -pub fn encode_world(resolve: &Resolve, world_id: WorldId) -> Result { - v1::encode_world(resolve, world_id) -} diff --git a/crates/wit-component/src/encoding/wit/v2.rs b/crates/wit-component/src/encoding/wit/v2.rs deleted file mode 100644 index 7024c6ccf6..0000000000 --- a/crates/wit-component/src/encoding/wit/v2.rs +++ /dev/null @@ -1,333 +0,0 @@ -use crate::encoding::types::{FunctionKey, ValtypeEncoder}; -use anyhow::Result; -use indexmap::IndexSet; -use std::collections::HashMap; -use std::mem; -use wasm_encoder::*; -use wit_parser::*; - -/// Encodes the given `package` within `resolve` to a binary WebAssembly -/// representation. -/// -/// This function is the root of the implementation of serializing a WIT package -/// into a WebAssembly representation. The wasm representation serves two -/// purposes: -/// -/// * One is to be a binary encoding of a WIT document which is ideally more -/// stable than the WIT textual format itself. -/// * Another is to provide a clear mapping of all WIT features into the -/// component model through use of its binary representation. -/// -/// The `resolve` provided is a set of packages and types and such and the -/// `package` argument is an ID within the world provided. The documents within -/// `package` will all be encoded into the binary returned. -/// -/// The binary returned can be [`decode`d](crate::decode) to recover the WIT -/// package provided. -pub fn encode_component(resolve: &Resolve, package: PackageId) -> Result { - let mut encoder = Encoder { - component: ComponentBuilder::default(), - resolve, - package, - }; - encoder.run()?; - - let package_metadata = PackageMetadata::extract(resolve, package); - encoder.component.custom_section(&CustomSection { - name: PackageMetadata::SECTION_NAME.into(), - data: package_metadata.encode()?.into(), - }); - - Ok(encoder.component) -} - -struct Encoder<'a> { - component: ComponentBuilder, - resolve: &'a Resolve, - package: PackageId, -} - -impl Encoder<'_> { - fn run(&mut self) -> Result<()> { - // Build a set of interfaces reachable from this document, including the - // interfaces in the document itself. This is used to import instances - // into the component type we're encoding. Note that entire interfaces - // are imported with all their types as opposed to just the needed types - // in an interface for this document. That's done to assist with the - // decoding process where everyone's view of a foreign document agrees - // notably on the order that types are defined in to assist with - // roundtripping. - for (name, &id) in self.resolve.packages[self.package].interfaces.iter() { - let component_ty = self.encode_interface(id)?; - let ty = self.component.type_component(&component_ty); - self.component - .export(name.as_ref(), ComponentExportKind::Type, ty, None); - } - - for (name, &world) in self.resolve.packages[self.package].worlds.iter() { - // Encode the `world` directly as a component, then create a wrapper - // component that exports that component. - let component_ty = super::encode_world(self.resolve, world)?; - - let world = &self.resolve.worlds[world]; - let mut wrapper = ComponentType::new(); - wrapper.ty().component(&component_ty); - let pkg = &self.resolve.packages[world.package.unwrap()]; - wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0)); - - let ty = self.component.type_component(&wrapper); - self.component - .export(name.as_ref(), ComponentExportKind::Type, ty, None); - } - - Ok(()) - } - - fn encode_interface(&mut self, id: InterfaceId) -> Result { - // Build a set of interfaces reachable from this document, including the - // interfaces in the document itself. This is used to import instances - // into the component type we're encoding. Note that entire interfaces - // are imported with all their types as opposed to just the needed types - // in an interface for this document. That's done to assist with the - // decoding process where everyone's view of a foreign document agrees - // notably on the order that types are defined in to assist with - // roundtripping. - let mut interfaces = IndexSet::new(); - self.add_live_interfaces(&mut interfaces, id); - - // Seed the set of used names with all exported interfaces to ensure - // that imported interfaces choose different names as the import names - // aren't used during decoding. - let mut used_names = IndexSet::new(); - for id in interfaces.iter() { - let iface = &self.resolve.interfaces[*id]; - if iface.package == Some(self.package) { - let first = used_names.insert(iface.name.as_ref().unwrap().clone()); - assert!(first); - } - } - - let mut encoder = InterfaceEncoder::new(self.resolve); - for interface in interfaces { - encoder.interface = Some(interface); - let iface = &self.resolve.interfaces[interface]; - let name = self.resolve.id_of(interface).unwrap(); - if interface == id { - let idx = encoder.encode_instance(interface)?; - log::trace!("exporting self as {idx}"); - encoder.outer.export(&name, ComponentTypeRef::Instance(idx)); - } else { - encoder.push_instance(); - for (_, id) in iface.types.iter() { - encoder.encode_valtype(self.resolve, &Type::Id(*id))?; - } - let instance = encoder.pop_instance(); - let idx = encoder.outer.type_count(); - encoder.outer.ty().instance(&instance); - encoder.import_map.insert(interface, encoder.instances); - encoder.instances += 1; - encoder.outer.import(&name, ComponentTypeRef::Instance(idx)); - } - } - - encoder.interface = None; - - Ok(encoder.outer) - } - - /// Recursively add all live interfaces reachable from `id` into the - /// `interfaces` set, and then add `id` to the set. - fn add_live_interfaces(&self, interfaces: &mut IndexSet, id: InterfaceId) { - if interfaces.contains(&id) { - return; - } - for id in self.resolve.interface_direct_deps(id) { - self.add_live_interfaces(interfaces, id); - } - assert!(interfaces.insert(id)); - } -} - -struct InterfaceEncoder<'a> { - resolve: &'a Resolve, - outer: ComponentType, - ty: Option, - func_type_map: HashMap, u32>, - type_map: HashMap, - saved_types: Option<(HashMap, HashMap, u32>)>, - import_map: HashMap, - outer_type_map: HashMap, - instances: u32, - import_types: bool, - interface: Option, -} - -impl InterfaceEncoder<'_> { - fn new(resolve: &Resolve) -> InterfaceEncoder<'_> { - InterfaceEncoder { - resolve, - outer: ComponentType::new(), - ty: None, - type_map: Default::default(), - func_type_map: Default::default(), - import_map: Default::default(), - outer_type_map: Default::default(), - instances: 0, - saved_types: None, - import_types: false, - interface: None, - } - } - - fn encode_instance(&mut self, interface: InterfaceId) -> Result { - self.push_instance(); - let iface = &self.resolve.interfaces[interface]; - let mut type_order = IndexSet::new(); - for (_, id) in iface.types.iter() { - self.encode_valtype(self.resolve, &Type::Id(*id))?; - type_order.insert(*id); - } - - // Sort functions based on whether or not they're associated with - // resources. - // - // This is done here to ensure that when a WIT package is printed as WIT - // then decoded, or if it's printed as Wasm then decoded, the final - // result is the same. When printing via WIT resource methods are - // attached to the resource types themselves meaning that they'll appear - // intermingled with the rest of the types, namely first before all - // other functions. The purpose of this sort is to perform a stable sort - // over all functions by shuffling the resource-related functions first, - // in order of when their associated resource was encoded, and putting - // freestanding functions last. - // - // Note that this is not actually required for correctness, it's - // basically here to make fuzzing happy. - let mut funcs = iface.functions.iter().collect::>(); - funcs.sort_by_key(|(_name, func)| match func.kind { - FunctionKind::Freestanding => type_order.len(), - FunctionKind::Method(id) | FunctionKind::Constructor(id) | FunctionKind::Static(id) => { - type_order.get_index_of(&id).unwrap() - } - }); - - for (name, func) in funcs { - let ty = self.encode_func_type(self.resolve, func)?; - self.ty - .as_mut() - .unwrap() - .export(name, ComponentTypeRef::Func(ty)); - } - let instance = self.pop_instance(); - let idx = self.outer.type_count(); - self.outer.ty().instance(&instance); - self.import_map.insert(interface, self.instances); - self.instances += 1; - Ok(idx) - } - - fn push_instance(&mut self) { - assert!(self.ty.is_none()); - assert!(self.saved_types.is_none()); - self.saved_types = Some(( - mem::take(&mut self.type_map), - mem::take(&mut self.func_type_map), - )); - self.ty = Some(InstanceType::default()); - } - - fn pop_instance(&mut self) -> InstanceType { - let (types, funcs) = self.saved_types.take().unwrap(); - self.type_map = types; - self.func_type_map = funcs; - mem::take(&mut self.ty).unwrap() - } -} - -impl<'a> ValtypeEncoder<'a> for InterfaceEncoder<'a> { - fn defined_type(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) { - match &mut self.ty { - Some(ty) => (ty.type_count(), ty.ty().defined_type()), - None => (self.outer.type_count(), self.outer.ty().defined_type()), - } - } - fn define_function_type(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) { - match &mut self.ty { - Some(ty) => (ty.type_count(), ty.ty().function()), - None => (self.outer.type_count(), self.outer.ty().function()), - } - } - fn export_type(&mut self, index: u32, name: &'a str) -> Option { - match &mut self.ty { - Some(ty) => { - assert!(!self.import_types); - let ret = ty.type_count(); - ty.export(name, ComponentTypeRef::Type(TypeBounds::Eq(index))); - Some(ret) - } - None => { - let ret = self.outer.type_count(); - if self.import_types { - self.outer - .import(name, ComponentTypeRef::Type(TypeBounds::Eq(index))); - } else { - self.outer - .export(name, ComponentTypeRef::Type(TypeBounds::Eq(index))); - } - Some(ret) - } - } - } - fn export_resource(&mut self, name: &'a str) -> u32 { - let type_ref = ComponentTypeRef::Type(TypeBounds::SubResource); - match &mut self.ty { - Some(ty) => { - assert!(!self.import_types); - ty.export(name, type_ref); - ty.type_count() - 1 - } - None => { - if self.import_types { - self.outer.import(name, type_ref); - } else { - self.outer.export(name, type_ref); - } - self.outer.type_count() - 1 - } - } - } - fn type_map(&mut self) -> &mut HashMap { - &mut self.type_map - } - fn interface(&self) -> Option { - self.interface - } - fn import_type(&mut self, owner: InterfaceId, id: TypeId) -> u32 { - let ty = &self.resolve.types[id]; - let instance = self.import_map[&owner]; - let outer_idx = *self.outer_type_map.entry(id).or_insert_with(|| { - let ret = self.outer.type_count(); - self.outer.alias(Alias::InstanceExport { - instance, - name: ty.name.as_ref().unwrap(), - kind: ComponentExportKind::Type, - }); - ret - }); - match &mut self.ty { - Some(ty) => { - let ret = ty.type_count(); - ty.alias(Alias::Outer { - count: 1, - index: outer_idx, - kind: ComponentOuterAliasKind::Type, - }); - ret - } - None => outer_idx, - } - } - fn func_type_map(&mut self) -> &mut HashMap, u32> { - &mut self.func_type_map - } -} diff --git a/crates/wit-component/tests/interfaces.rs b/crates/wit-component/tests/interfaces.rs index ccd66c11e4..6e0f70d767 100644 --- a/crates/wit-component/tests/interfaces.rs +++ b/crates/wit-component/tests/interfaces.rs @@ -58,7 +58,7 @@ fn run_test(path: &Path, is_dir: bool) -> Result<()> { // First convert the WIT package to a binary WebAssembly output, then // convert that binary wasm to textual wasm, then assert it matches the // expectation. - let wasm = wit_component::encode(Some(true), &resolve, package)?; + let wasm = wit_component::encode(&resolve, package)?; let wat = wasmprinter::print_bytes(&wasm)?; assert_output(&path.with_extension("wat"), &wat)?; wasmparser::Validator::new() @@ -76,7 +76,7 @@ fn run_test(path: &Path, is_dir: bool) -> Result<()> { // Finally convert the decoded package to wasm again and make sure it // matches the prior wasm. - let wasm2 = wit_component::encode(Some(true), resolve, decoded_package)?; + let wasm2 = wit_component::encode(resolve, decoded_package)?; if wasm != wasm2 { let wat2 = wasmprinter::print_bytes(&wasm)?; assert_eq!(wat, wat2, "document did not roundtrip correctly"); diff --git a/crates/wit-smith/src/lib.rs b/crates/wit-smith/src/lib.rs index 0ec425cd92..b702c5903e 100644 --- a/crates/wit-smith/src/lib.rs +++ b/crates/wit-smith/src/lib.rs @@ -38,5 +38,5 @@ pub fn smith(config: &Config, u: &mut Unstructured<'_>) -> Result> { } let pkg = last.unwrap(); - Ok(wit_component::encode(Some(true), &resolve, pkg).expect("failed to encode WIT document")) + Ok(wit_component::encode(&resolve, pkg).expect("failed to encode WIT document")) } diff --git a/fuzz/src/roundtrip_wit.rs b/fuzz/src/roundtrip_wit.rs index ee31598005..c771bc6d88 100644 --- a/fuzz/src/roundtrip_wit.rs +++ b/fuzz/src/roundtrip_wit.rs @@ -22,8 +22,7 @@ pub fn run(u: &mut Unstructured<'_>) -> Result<()> { DecodedWasm::Component(..) => unreachable!(), }; - let wasm2 = - wit_component::encode(Some(true), &resolve2, pkg2).expect("failed to encode WIT document"); + let wasm2 = wit_component::encode(&resolve2, pkg2).expect("failed to encode WIT document"); write_file("doc2.wasm", &wasm2); roundtrip_through_printing("doc2", &resolve2, pkg2, &wasm2); @@ -91,7 +90,7 @@ fn roundtrip_through_printing(file: &str, resolve: &Resolve, pkg: PackageId, was // Finally encode the `new_resolve` which should be the exact same as // before. - let wasm2 = wit_component::encode(Some(true), &new_resolve, new_pkg).unwrap(); + let wasm2 = wit_component::encode(&new_resolve, new_pkg).unwrap(); write_file(&format!("{file}-reencoded.wasm"), &wasm2); if wasm != wasm2 { panic!("failed to roundtrip through text printing"); diff --git a/src/bin/wasm-tools/component.rs b/src/bin/wasm-tools/component.rs index adfd394567..3fa9eefdf9 100644 --- a/src/bin/wasm-tools/component.rs +++ b/src/bin/wasm-tools/component.rs @@ -610,7 +610,7 @@ impl WitOpts { assert!(self.out_dir.is_none()); let decoded_package = decoded.package(); - let bytes = wit_component::encode(None, decoded.resolve(), decoded_package)?; + let bytes = wit_component::encode(decoded.resolve(), decoded_package)?; if !self.skip_validation { wasmparser::Validator::new().validate_all(&bytes)?; }