Skip to content

Commit

Permalink
GC: wasmparser: Add storage types (#1023)
Browse files Browse the repository at this point in the history
For array and struct fields.
  • Loading branch information
imikushin committed May 17, 2023
1 parent 7a15c5f commit 6d24468
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 10 deletions.
28 changes: 23 additions & 5 deletions crates/wasm-encoder/src/core/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
use crate::{encode_section, Encode, Section, SectionId};

/// Array or struct field type.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum StorageType {
/// The `i8` type.
I8,
/// The `i16` type.
I16,
/// A value type.
Val(ValType),
}

/// The type of a core WebAssembly value.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum ValType {
Expand Down Expand Up @@ -30,6 +41,16 @@ impl ValType {
pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF);
}

impl Encode for StorageType {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
StorageType::I8 => sink.push(0x7A),
StorageType::I16 => sink.push(0x79),
StorageType::Val(vt) => vt.encode(sink),
}
}
}

impl Encode for ValType {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
Expand Down Expand Up @@ -203,12 +224,9 @@ impl TypeSection {
}

/// Define an array type in this type section.
pub fn array<T>(&mut self, ty: T, mutable: bool) -> &mut Self
where
T: Into<ValType>,
{
pub fn array(&mut self, ty: StorageType, mutable: bool) -> &mut Self {
self.bytes.push(0x5e);
ty.into().encode(&mut self.bytes);
ty.encode(&mut self.bytes);
self.bytes.push(mutable as u8);
self.num_added += 1;
self
Expand Down
29 changes: 28 additions & 1 deletion crates/wasmparser/src/readers/core/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ pub enum ValType {
Ref(RefType),
}

/// Represents storage types introduced in the GC spec for array and struct fields.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum StorageType {
/// The storage type is i8.
I8,
/// The storage type is i16.
I16,
/// The storage type is a value type.
Val(ValType),
}

// The size of `ValType` is performance sensitive.
const _: () = {
assert!(std::mem::size_of::<ValType>() == 4);
Expand Down Expand Up @@ -78,6 +89,22 @@ impl ValType {
}
}

impl<'a> FromReader<'a> for StorageType {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
match reader.peek()? {
0x7A => {
reader.position += 1;
Ok(StorageType::I8)
}
0x79 => {
reader.position += 1;
Ok(StorageType::I16)
}
_ => Ok(StorageType::Val(reader.read()?)),
}
}
}

impl<'a> FromReader<'a> for ValType {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
match reader.peek()? {
Expand Down Expand Up @@ -659,7 +686,7 @@ pub struct FuncType {
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct ArrayType {
/// Array element type.
pub element_type: ValType,
pub element_type: StorageType,
/// Are elements mutable.
pub mutable: bool,
}
Expand Down
7 changes: 6 additions & 1 deletion crates/wasmparser/src/validator/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,12 @@ impl Module {
Type::Func(t)
}
crate::Type::Array(t) => {
self.check_value_type(t.element_type, features, offset)?;
match t.element_type {
crate::StorageType::I8 | crate::StorageType::I16 => {}
crate::StorageType::Val(value_type) => {
self.check_value_type(value_type, features, offset)?;
}
};
Type::Array(t)
}
};
Expand Down
11 changes: 10 additions & 1 deletion crates/wasmprinter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,13 +731,22 @@ impl Printer {
if ty.mutable {
self.result.push_str("(mut ");
}
self.print_valtype(ty.element_type)?;
self.print_storage_type(ty.element_type)?;
if ty.mutable {
self.result.push_str(")");
}
Ok(0)
}

fn print_storage_type(&mut self, ty: StorageType) -> Result<()> {
match ty {
StorageType::I8 => self.result.push_str("i8"),
StorageType::I16 => self.result.push_str("i16"),
StorageType::Val(val_type) => self.print_valtype(val_type)?,
}
Ok(())
}

fn print_valtype(&mut self, ty: ValType) -> Result<()> {
match ty {
ValType::I32 => self.result.push_str("i32"),
Expand Down
19 changes: 17 additions & 2 deletions crates/wit-component/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,13 @@ impl<'a> Module<'a> {
}
}

fn storagety(&mut self, ty: StorageType) {
match ty {
StorageType::I8 | StorageType::I16 => {}
StorageType::Val(ty) => self.valty(ty),
}
}

fn heapty(&mut self, ty: HeapType) {
match ty {
HeapType::Func
Expand Down Expand Up @@ -508,7 +515,7 @@ impl<'a> Module<'a> {
}
}
Type::Array(ty) => {
me.valty(ty.element_type);
me.storagety(ty.element_type);
}
};
Ok(())
Expand Down Expand Up @@ -577,7 +584,7 @@ impl<'a> Module<'a> {
}
}
Type::Array(ty) => {
types.array(map.valty(ty.element_type), ty.mutable);
types.array(map.storagety(ty.element_type), ty.mutable);
}
}
}
Expand Down Expand Up @@ -1107,6 +1114,14 @@ impl Encoder {
}
}

fn storagety(&self, ty: StorageType) -> wasm_encoder::StorageType {
match ty {
StorageType::I8 => wasm_encoder::StorageType::I8,
StorageType::I16 => wasm_encoder::StorageType::I16,
StorageType::Val(ty) => wasm_encoder::StorageType::Val(self.valty(ty)),
}
}

fn refty(&self, rt: wasmparser::RefType) -> wasm_encoder::RefType {
wasm_encoder::RefType {
nullable: rt.is_nullable(),
Expand Down
2 changes: 2 additions & 0 deletions tests/local/gc/gc-array-types.wat
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
(type $a (array i32))
(type $b (array (mut i32)))
(type $c (array (mut (ref null $b))))
(type $d (array i8))
(type $e (array (mut i16)))
)
2 changes: 2 additions & 0 deletions tests/snapshots/local/gc/gc-array-types.wat.print
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
(type $a (;0;) (array i32))
(type $b (;1;) (array (mut i32)))
(type $c (;2;) (array (mut (ref null 1))))
(type $d (;3;) (array i8))
(type $e (;4;) (array (mut i16)))
)

0 comments on commit 6d24468

Please sign in to comment.