Skip to content

Commit

Permalink
Allow parsing rectypes in components (#1764)
Browse files Browse the repository at this point in the history
* Allow parsing `rectypes` in components

This change supports [#392], which adds a way to use GC's `rectypes` as
type definitions in components. Previously, only function types were
supported and there was no way express array and struct types. This
keeps the previous function decoding support based on peeking the
function type `0x60` prefix but adds support for encoding `rectypes`
with a new `0x00` prefix.

[#392]: WebAssembly/component-model#392

Co-authored-by: Alex Crichton <[email protected]>

* Apply `0x00` prefix to non-final `sub`; add tests

This follows along with the most recent discussion in the component
model PR ([#392]).

[#392]: WebAssembly/component-model#392

Co-authored-by: Alex Crichton <[email protected]>

* review: keep variant as `ComponentCoreTypeId::Sub`

* review: remove leftover comment

* review: remove resolved TODOs

* review: move `From` implementations to `core/binary.rs`

* review: remove `parse_component_sub_type`

---------

Co-authored-by: Alex Crichton <[email protected]>
  • Loading branch information
abrown and alexcrichton authored Sep 10, 2024
1 parent 8b899d9 commit 5ee4030
Show file tree
Hide file tree
Showing 30 changed files with 439 additions and 333 deletions.
2 changes: 1 addition & 1 deletion crates/wasm-compose/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Encodable {
}
}

fn core_type(&mut self) -> CoreTypeEncoder {
fn core_type(&mut self) -> ComponentCoreTypeEncoder {
match self {
Encodable::Component(t) => t.core_type(),
Encodable::Instance(t) => t.core_type(),
Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-encoder/src/component/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl ComponentBuilder {
}

/// Creates a new encoder for the next core type in this component.
pub fn core_type(&mut self) -> (u32, CoreTypeEncoder<'_>) {
pub fn core_type(&mut self) -> (u32, ComponentCoreTypeEncoder<'_>) {
(inc(&mut self.core_types), self.core_types().ty())
}

Expand Down
70 changes: 22 additions & 48 deletions crates/wasm-encoder/src/component/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::CORE_TYPE_SORT;
use crate::{
encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection,
ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType,
ComponentSectionId, ComponentTypeRef, CoreTypeEncoder, Encode, EntityType, ValType,
};

/// Represents the type of a core module.
Expand Down Expand Up @@ -36,7 +36,10 @@ impl ModuleType {
self.bytes.push(0x01);
self.num_added += 1;
self.types_added += 1;
CoreTypeEncoder(&mut self.bytes)
CoreTypeEncoder {
push_prefix_if_component_core_type: false,
bytes: &mut self.bytes,
}
}

/// Defines an outer core type alias in this module type.
Expand Down Expand Up @@ -76,31 +79,22 @@ impl Encode for ModuleType {

/// Used to encode core types.
#[derive(Debug)]
pub struct CoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>);

impl<'a> CoreTypeEncoder<'a> {
/// Define a function type.
pub fn function<P, R>(self, params: P, results: R)
where
P: IntoIterator<Item = ValType>,
P::IntoIter: ExactSizeIterator,
R: IntoIterator<Item = ValType>,
R::IntoIter: ExactSizeIterator,
{
let params = params.into_iter();
let results = results.into_iter();

self.0.push(0x60);
params.len().encode(self.0);
params.for_each(|p| p.encode(self.0));
results.len().encode(self.0);
results.for_each(|p| p.encode(self.0));
}
pub struct ComponentCoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>);

impl<'a> ComponentCoreTypeEncoder<'a> {
/// Define a module type.
pub fn module(self, ty: &ModuleType) {
ty.encode(self.0);
}

/// Define any core type other than a module type.
#[must_use = "the encoder must be used to encode the type"]
pub fn core(self) -> CoreTypeEncoder<'a> {
CoreTypeEncoder {
bytes: self.0,
push_prefix_if_component_core_type: true,
}
}
}

/// An encoder for the core type section of WebAssembly components.
Expand All @@ -112,7 +106,7 @@ impl<'a> CoreTypeEncoder<'a> {
///
/// let mut types = CoreTypeSection::new();
///
/// types.module(&ModuleType::new());
/// types.ty().module(&ModuleType::new());
///
/// let mut component = Component::new();
/// component.section(&types);
Expand Down Expand Up @@ -145,29 +139,9 @@ impl CoreTypeSection {
///
/// The returned encoder must be finished before adding another type.
#[must_use = "the encoder must be used to encode the type"]
pub fn ty(&mut self) -> CoreTypeEncoder<'_> {
pub fn ty(&mut self) -> ComponentCoreTypeEncoder<'_> {
self.num_added += 1;
CoreTypeEncoder(&mut self.bytes)
}

/// Define a function type in this type section.
pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
where
P: IntoIterator<Item = ValType>,
P::IntoIter: ExactSizeIterator,
R: IntoIterator<Item = ValType>,
R::IntoIter: ExactSizeIterator,
{
self.ty().function(params, results);
self
}

/// Define a module type in this type section.
///
/// Currently this is only used for core type sections in components.
pub fn module(&mut self, ty: &ModuleType) -> &mut Self {
self.ty().module(ty);
self
ComponentCoreTypeEncoder(&mut self.bytes)
}
}

Expand Down Expand Up @@ -203,11 +177,11 @@ impl ComponentType {
///
/// The returned encoder must be used before adding another definition.
#[must_use = "the encoder must be used to encode the type"]
pub fn core_type(&mut self) -> CoreTypeEncoder {
pub fn core_type(&mut self) -> ComponentCoreTypeEncoder {
self.bytes.push(0x00);
self.num_added += 1;
self.core_types_added += 1;
CoreTypeEncoder(&mut self.bytes)
ComponentCoreTypeEncoder(&mut self.bytes)
}

/// Define a type in this component type.
Expand Down Expand Up @@ -316,7 +290,7 @@ impl InstanceType {
///
/// The returned encoder must be used before adding another definition.
#[must_use = "the encoder must be used to encode the type"]
pub fn core_type(&mut self) -> CoreTypeEncoder {
pub fn core_type(&mut self) -> ComponentCoreTypeEncoder {
self.0.core_type()
}

Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-encoder/src/core/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::borrow::Cow;
/// };
///
/// let mut types = TypeSection::new();
/// types.function(vec![], vec![ValType::I32]);
/// types.ty().function(vec![], vec![ValType::I32]);
///
/// let mut functions = FunctionSection::new();
/// let type_index = 0;
Expand Down
Loading

0 comments on commit 5ee4030

Please sign in to comment.