Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove support for 33+ flags and multiple returns #2050

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 3 additions & 22 deletions crates/wasm-compose/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,26 +476,12 @@ impl<'a> TypeEncoder<'a> {
.map(|(name, ty)| (name.as_str(), self.component_val_type(state, *ty)))
.collect::<Vec<_>>();

let results = ty
.results
.iter()
.map(|(name, ty)| (name.as_deref(), self.component_val_type(state, *ty)))
.collect::<Vec<_>>();
let result = ty.result.map(|ty| self.component_val_type(state, ty));

let index = state.cur.encodable.type_count();
let mut f = state.cur.encodable.ty().function();

f.params(params);

if results.len() == 1 && results[0].0.is_none() {
f.result(results[0].1);
} else {
f.results(
results
.into_iter()
.map(|(name, ty)| (name.unwrap().as_str(), ty)),
);
}
f.params(params).result(result);

index
}
Expand Down Expand Up @@ -1239,12 +1225,7 @@ impl DependencyRegistrar<'_, '_> {

fn func(&mut self, ty: ComponentFuncTypeId) {
let ty = &self.types[ty];
for ty in ty
.params
.iter()
.map(|p| p.1)
.chain(ty.results.iter().map(|p| p.1))
{
for ty in ty.params.iter().map(|p| p.1).chain(ty.result) {
self.val_type(ty);
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-encoder/src/component/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl Encode for ComponentTypeRef {
/// ("b", PrimitiveValType::String)
/// ]
/// )
/// .result(PrimitiveValType::String);
/// .result(Some(PrimitiveValType::String.into()));
///
/// // This imports a function named `f` with the type defined above
/// let mut imports = ComponentImportSection::new();
Expand Down
41 changes: 11 additions & 30 deletions crates/wasm-encoder/src/component/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,38 +401,19 @@ impl<'a> ComponentFuncTypeEncoder<'a> {
///
/// This method will panic if the function is called twice, called before
/// the `params` method, or called in addition to the `results` method.
pub fn result(&mut self, ty: impl Into<ComponentValType>) -> &mut Self {
pub fn result(&mut self, ty: Option<ComponentValType>) -> &mut Self {
assert!(self.params_encoded);
assert!(!self.results_encoded);
self.results_encoded = true;
self.sink.push(0x00);
ty.into().encode(self.sink);
self
}

/// Defines named results.
///
/// This method cannot be used with `result`.
///
/// # Panics
///
/// This method will panic if the function is called twice, called before
/// the `params` method, or called in addition to the `result` method.
pub fn results<'b, R, T>(&mut self, results: R) -> &mut Self
where
R: IntoIterator<Item = (&'b str, T)>,
R::IntoIter: ExactSizeIterator,
T: Into<ComponentValType>,
{
assert!(self.params_encoded);
assert!(!self.results_encoded);
self.results_encoded = true;
self.sink.push(0x01);
let results = results.into_iter();
results.len().encode(self.sink);
for (name, ty) in results {
name.encode(self.sink);
ty.into().encode(self.sink);
match ty {
Some(ty) => {
self.sink.push(0x00);
ty.encode(self.sink);
}
None => {
self.sink.push(0x01);
self.sink.push(0x00);
}
}
self
}
Expand Down Expand Up @@ -709,7 +690,7 @@ impl ComponentDefinedTypeEncoder<'_> {
/// ("b", PrimitiveValType::String)
/// ]
/// )
/// .result(PrimitiveValType::String);
/// .result(Some(PrimitiveValType::String.into()));
///
/// let mut component = Component::new();
/// component.section(&types);
Expand Down
14 changes: 2 additions & 12 deletions crates/wasm-encoder/src/reencode/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,18 +735,8 @@ pub mod component_utils {
.into_iter()
.map(|(name, ty)| (name, reencoder.component_val_type(ty))),
);
match ty.results {
wasmparser::ComponentFuncResult::Unnamed(ty) => {
func.result(reencoder.component_val_type(ty));
}
wasmparser::ComponentFuncResult::Named(list) => {
func.results(
Vec::from(list)
.into_iter()
.map(|(name, ty)| (name, reencoder.component_val_type(ty))),
);
}
}
let result = ty.result.map(|ty| reencoder.component_val_type(ty));
func.result(result);
Ok(())
}

Expand Down
12 changes: 1 addition & 11 deletions crates/wasm-smith/src/component/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,7 @@ impl Type {
let mut f = enc.function();

f.params(func_ty.params.iter().map(|(name, ty)| (name.as_str(), *ty)));

if let Some(ty) = func_ty.unnamed_result_ty() {
f.result(ty);
} else {
f.results(
func_ty
.results
.iter()
.map(|(name, ty)| (name.as_deref().unwrap(), *ty)),
);
}
f.result(func_ty.unnamed_result_ty());
}
Self::Component(comp_ty) => {
let mut enc_comp_ty = wasm_encoder::ComponentType::new();
Expand Down
10 changes: 5 additions & 5 deletions crates/wasm-wave/src/value/wit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ pub fn resolve_wit_func_type(
) -> Result<value::FuncType, WasmValueError> {
let resolver = TypeResolver { resolve };
let params = resolver.resolve_params(&function.params)?;
let results = match &function.results {
wit_parser::Results::Named(results) => resolver.resolve_params(results)?,
wit_parser::Results::Anon(ty) => vec![("".into(), resolver.resolve_type(*ty)?)],
let results = match &function.result {
Some(ty) => vec![("".into(), resolver.resolve_type(*ty)?)],
None => Vec::new(),
};
value::FuncType::new(params, results)
}
Expand Down Expand Up @@ -184,7 +184,7 @@ interface types {
type uint8 = u8;
no-results: func(a: uint8, b: string);
one-result: func(c: uint8, d: string) -> uint8;
named-results: func(e: uint8, f: string) -> (x: u8, y: string);
named-results: func(e: uint8, f: string) -> tuple<u8, string>;
}
"#,
)
Expand All @@ -195,7 +195,7 @@ interface types {
("one-result", "func(c: u8, d: string) -> u8"),
(
"named-results",
"func(e: u8, f: string) -> (x: u8, y: string)",
"func(e: u8, f: string) -> tuple<u8, string>",
),
] {
let function = resolve
Expand Down
4 changes: 0 additions & 4 deletions crates/wasmparser/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,6 @@ define_wasm_features! {
pub component_model_values: COMPONENT_MODEL_VALUES(1 << 21) = false;
/// Support for the nested namespaces and projects in component model names.
pub component_model_nested_names: COMPONENT_MODEL_NESTED_NAMES(1 << 22) = false;
/// Support for more than 32 flags per-type in the component model.
pub component_model_more_flags: COMPONENT_MODEL_MORE_FLAGS(1 << 23) = false;
/// Support for multiple return values in a component model function.
pub component_model_multiple_returns: COMPONENT_MODEL_MULTIPLE_RETURNS(1 << 24) = false;
/// The WebAssembly legacy exception handling proposal (phase 1)
///
/// # Note
Expand Down
74 changes: 10 additions & 64 deletions crates/wasmparser/src/readers/component/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,15 @@ impl<'a> FromReader<'a> for ComponentType<'a> {
let params = reader
.read_iter(MAX_WASM_FUNCTION_PARAMS, "component function parameters")?
.collect::<Result<_>>()?;
let results = reader.read()?;
ComponentType::Func(ComponentFuncType { params, results })
let result = match reader.read_u8()? {
0x00 => Some(reader.read()?),
0x01 => match reader.read_u8()? {
0x00 => None,
x => return reader.invalid_leading_byte(x, "number of results"),
},
x => return reader.invalid_leading_byte(x, "component function results"),
};
ComponentType::Func(ComponentFuncType { params, result })
}
0x41 => ComponentType::Component(
reader
Expand Down Expand Up @@ -380,74 +387,13 @@ impl<'a> FromReader<'a> for InstanceTypeDeclaration<'a> {
}
}

/// Represents the result type of a component function.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ComponentFuncResult<'a> {
/// The function returns a singular, unnamed type.
Unnamed(ComponentValType),
/// The function returns zero or more named types.
Named(Box<[(&'a str, ComponentValType)]>),
}

impl<'a> FromReader<'a> for ComponentFuncResult<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read_u8()? {
0x00 => ComponentFuncResult::Unnamed(reader.read()?),
0x01 => ComponentFuncResult::Named(
reader
.read_iter(MAX_WASM_FUNCTION_RETURNS, "component function results")?
.collect::<Result<_>>()?,
),
x => return reader.invalid_leading_byte(x, "component function results"),
})
}
}

impl ComponentFuncResult<'_> {
/// Gets the count of types returned by the function.
pub fn type_count(&self) -> usize {
match self {
Self::Unnamed(_) => 1,
Self::Named(vec) => vec.len(),
}
}

/// Iterates over the types returned by the function.
pub fn iter(&self) -> impl Iterator<Item = (Option<&str>, &ComponentValType)> {
enum Either<L, R> {
Left(L),
Right(R),
}

impl<L, R> Iterator for Either<L, R>
where
L: Iterator,
R: Iterator<Item = L::Item>,
{
type Item = L::Item;

fn next(&mut self) -> Option<Self::Item> {
match self {
Either::Left(l) => l.next(),
Either::Right(r) => r.next(),
}
}
}

match self {
Self::Unnamed(ty) => Either::Left(core::iter::once(ty).map(|ty| (None, ty))),
Self::Named(vec) => Either::Right(vec.iter().map(|(n, ty)| (Some(*n), ty))),
}
}
}

/// Represents a type of a function in a WebAssembly component.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ComponentFuncType<'a> {
/// The function parameters.
pub params: Box<[(&'a str, ComponentValType)]>,
/// The function result.
pub results: ComponentFuncResult<'a>,
pub result: Option<ComponentValType>,
}

/// Represents a case in a variant type.
Expand Down
Loading