Skip to content

Commit

Permalink
Migrate type section encoding in wast to wasm-encoder (#1799)
Browse files Browse the repository at this point in the history
Remove a few `Encode` impls and start laying some groundwork for other
sections to get migrated as well with a new trait/method to use.
  • Loading branch information
alexcrichton authored Sep 18, 2024
1 parent eb3d5e6 commit 47680b0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 112 deletions.
20 changes: 4 additions & 16 deletions crates/wast/src/component/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ use wasm_encoder::{
CanonicalFunctionSection, ComponentAliasSection, ComponentCoreTypeEncoder,
ComponentDefinedTypeEncoder, ComponentExportSection, ComponentImportSection,
ComponentInstanceSection, ComponentNameSection, ComponentSection, ComponentSectionId,
ComponentStartSection, ComponentTypeEncoder, ComponentTypeSection, CompositeType,
CoreTypeSection, InstanceSection, NameMap, NestedComponentSection, RawSection, SectionId,
SubType,
ComponentStartSection, ComponentTypeEncoder, ComponentTypeSection, CoreTypeSection,
InstanceSection, NameMap, NestedComponentSection, RawSection, SectionId, SubType,
};

pub fn encode(component: &Component<'_>, options: &EncodeOptions) -> Vec<u8> {
Expand Down Expand Up @@ -62,10 +61,7 @@ fn encode_core_type(encoder: ComponentCoreTypeEncoder, ty: &CoreTypeDef) {
let sub_type = SubType {
is_final: true,
supertype_idx: None,
composite_type: CompositeType {
shared: def.shared,
inner: (&def.kind).into(),
},
composite_type: def.to_composite_type(),
};
encoder.core().subtype(&sub_type);
}
Expand Down Expand Up @@ -881,15 +877,7 @@ impl From<&ModuleType<'_>> for wasm_encoder::ModuleType {
for decl in &ty.decls {
match decl {
ModuleTypeDecl::Type(t) => {
let sub_type = SubType {
is_final: t.final_type.unwrap_or(true),
supertype_idx: t.parent.map(u32::from),
composite_type: CompositeType {
shared: t.def.shared,
inner: (&t.def.kind).into(),
},
};
encoded.ty().subtype(&sub_type);
encoded.ty().subtype(&t.to_subtype());
}
ModuleTypeDecl::Alias(a) => match &a.target {
AliasTarget::Outer {
Expand Down
139 changes: 43 additions & 96 deletions crates/wast/src/core/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub(crate) fn encode(

e.custom_sections(BeforeFirst);

e.section_list(SectionId::Type, Type, &types);
e.typed_section(&types);
e.section_list(SectionId::Import, Import, &imports);

let functys = funcs.iter().map(|f| &f.ty).collect::<Vec<_>>();
Expand Down Expand Up @@ -248,6 +248,21 @@ impl Encoder<'_> {
self.custom_sections(CustomPlace::After(anchor));
}

fn typed_section<T>(&mut self, list: &[T])
where
T: SectionItem,
{
self.custom_sections(CustomPlace::Before(T::ANCHOR));
if !list.is_empty() {
let mut section = T::Section::default();
for item in list {
item.encode(&mut section);
}
self.wasm.section(&section);
}
self.custom_sections(CustomPlace::After(T::ANCHOR));
}

/// Encodes the code section of a wasm module module while additionally
/// handling the branch hinting proposal.
///
Expand Down Expand Up @@ -302,14 +317,11 @@ impl Encoder<'_> {
}
}

impl Encode for FunctionType<'_> {
fn encode(&self, e: &mut Vec<u8>) {
self.params.len().encode(e);
for (_, _, ty) in self.params.iter() {
ty.encode(e);
}
self.results.encode(e);
}
trait SectionItem {
type Section: wasm_encoder::Section + Default;
const ANCHOR: CustomPlaceAnchor;

fn encode(&self, section: &mut Self::Section);
}

impl From<&FunctionType<'_>> for wasm_encoder::FuncType {
Expand All @@ -321,16 +333,6 @@ impl From<&FunctionType<'_>> for wasm_encoder::FuncType {
}
}

impl Encode for StructType<'_> {
fn encode(&self, e: &mut Vec<u8>) {
self.fields.len().encode(e);
for field in self.fields.iter() {
field.ty.encode(e);
(field.mutable as i32).encode(e);
}
}
}

impl From<&StructType<'_>> for wasm_encoder::StructType {
fn from(st: &StructType) -> wasm_encoder::StructType {
wasm_encoder::StructType {
Expand All @@ -348,13 +350,6 @@ impl From<&StructField<'_>> for wasm_encoder::FieldType {
}
}

impl Encode for ArrayType<'_> {
fn encode(&self, e: &mut Vec<u8>) {
self.ty.encode(e);
(self.mutable as i32).encode(e);
}
}

impl From<&ArrayType<'_>> for wasm_encoder::ArrayType {
fn from(at: &ArrayType) -> Self {
let field = wasm_encoder::FieldType {
Expand All @@ -377,74 +372,38 @@ enum RecOrType<'a> {
Rec(&'a Rec<'a>),
}

impl Encode for RecOrType<'_> {
fn encode(&self, e: &mut Vec<u8>) {
impl SectionItem for RecOrType<'_> {
type Section = wasm_encoder::TypeSection;
const ANCHOR: CustomPlaceAnchor = CustomPlaceAnchor::Type;

fn encode(&self, types: &mut wasm_encoder::TypeSection) {
match self {
RecOrType::Type(ty) => ty.encode(e),
RecOrType::Rec(rec) => rec.encode(e),
RecOrType::Type(ty) => types.ty().subtype(&ty.to_subtype()),
RecOrType::Rec(rec) => types.ty().rec(rec.types.iter().map(|t| t.to_subtype())),
}
}
}

impl Encode for Type<'_> {
fn encode(&self, e: &mut Vec<u8>) {
match (&self.parent, self.final_type) {
(Some(parent), Some(true)) => {
// Type is final with a supertype
e.push(0x4f);
e.push(0x01);
parent.encode(e);
}
(Some(parent), Some(false) | None) => {
// Type is not final and has a declared supertype
e.push(0x50);
e.push(0x01);
parent.encode(e);
}
(None, Some(false)) => {
// Sub was used without any declared supertype
e.push(0x50);
e.push(0x00);
}
(None, _) => {} // No supertype, sub wasn't used
}
if self.def.shared {
e.push(0x65);
}
match &self.def.kind {
InnerTypeKind::Func(func) => {
e.push(0x60);
func.encode(e)
}
InnerTypeKind::Struct(r#struct) => {
e.push(0x5f);
r#struct.encode(e)
}
InnerTypeKind::Array(array) => {
e.push(0x5e);
array.encode(e)
}
impl Type<'_> {
pub(crate) fn to_subtype(&self) -> wasm_encoder::SubType {
wasm_encoder::SubType {
composite_type: self.def.to_composite_type(),
is_final: self.final_type.unwrap_or(true),
supertype_idx: self.parent.map(|i| i.unwrap_u32()),
}
}
}

impl From<&InnerTypeKind<'_>> for wasm_encoder::CompositeInnerType {
fn from(kind: &InnerTypeKind) -> Self {
impl TypeDef<'_> {
pub(crate) fn to_composite_type(&self) -> wasm_encoder::CompositeType {
use wasm_encoder::CompositeInnerType::*;
match kind {
InnerTypeKind::Func(ft) => Func(ft.into()),
InnerTypeKind::Struct(st) => Struct(st.into()),
InnerTypeKind::Array(at) => Array(at.into()),
}
}
}

impl Encode for Rec<'_> {
fn encode(&self, e: &mut Vec<u8>) {
e.push(0x4e);
self.types.len().encode(e);
for ty in &self.types {
ty.encode(e);
wasm_encoder::CompositeType {
inner: match &self.kind {
InnerTypeKind::Func(ft) => Func(ft.into()),
InnerTypeKind::Struct(st) => Struct(st.into()),
InnerTypeKind::Array(at) => Array(at.into()),
},
shared: self.shared,
}
}
}
Expand Down Expand Up @@ -542,18 +501,6 @@ impl<'a> Encode for RefType<'a> {
}
}

impl<'a> Encode for StorageType<'a> {
fn encode(&self, e: &mut Vec<u8>) {
match self {
StorageType::I8 => e.push(0x78),
StorageType::I16 => e.push(0x77),
StorageType::Val(ty) => {
ty.encode(e);
}
}
}
}

impl From<StorageType<'_>> for wasm_encoder::StorageType {
fn from(st: StorageType) -> Self {
use wasm_encoder::StorageType::*;
Expand Down

0 comments on commit 47680b0

Please sign in to comment.