Skip to content

Commit

Permalink
Merge pull request #46 from dhil/wasmfx-merge
Browse files Browse the repository at this point in the history
Merge initial support for exception handling validation
  • Loading branch information
dhil authored Jan 9, 2024
2 parents e022c6a + 5bbe276 commit 1baeb76
Show file tree
Hide file tree
Showing 97 changed files with 1,436 additions and 952 deletions.
55 changes: 51 additions & 4 deletions crates/wasm-encoder/src/core/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,6 @@ pub enum Instruction<'a> {
Loop(BlockType),
If(BlockType),
Else,
Try(BlockType),
Delegate(u32),
Catch(u32),
CatchAll,
End,
Br(u32),
BrIf(u32),
Expand All @@ -333,7 +329,15 @@ pub enum Instruction<'a> {
ty: u32,
table: u32,
},
TryTable(BlockType, Cow<'a, [Catch]>),
Throw(u32),
ThrowRef,

// Deprecated exception-handling instructions
Try(BlockType),
Delegate(u32),
Catch(u32),
CatchAll,
Rethrow(u32),

// Parametric instructions.
Expand Down Expand Up @@ -1031,6 +1035,9 @@ impl Encode for Instruction<'_> {
sink.push(0x09);
l.encode(sink);
}
Instruction::ThrowRef => {
sink.push(0x0A);
}
Instruction::End => sink.push(0x0B),
Instruction::Br(l) => {
sink.push(0x0C);
Expand Down Expand Up @@ -1097,6 +1104,12 @@ impl Encode for Instruction<'_> {
[ty].encode(sink);
}

Instruction::TryTable(ty, ref catches) => {
sink.push(0x1f);
ty.encode(sink);
catches.encode(sink);
}

// Variable instructions.
Instruction::LocalGet(l) => {
sink.push(0x20);
Expand Down Expand Up @@ -3160,6 +3173,40 @@ impl Encode for Instruction<'_> {
}
}

#[derive(Clone, Debug)]
#[allow(missing_docs)]
pub enum Catch {
One { tag: u32, label: u32 },
OneRef { tag: u32, label: u32 },
All { label: u32 },
AllRef { label: u32 },
}

impl Encode for Catch {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
Catch::One { tag, label } => {
sink.push(0x00);
tag.encode(sink);
label.encode(sink);
}
Catch::OneRef { tag, label } => {
sink.push(0x01);
tag.encode(sink);
label.encode(sink);
}
Catch::All { label } => {
sink.push(0x02);
label.encode(sink);
}
Catch::AllRef { label } => {
sink.push(0x03);
label.encode(sink);
}
}
}
}

/// A constant expression.
///
/// Usable in contexts such as offsets or initializers.
Expand Down
8 changes: 8 additions & 0 deletions crates/wasm-encoder/src/core/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ impl NameSection {
names.encode(&mut self.bytes);
}

/// Appends a subsection for the names of all tags in this wasm module.
///
/// This section should come after the data name subsection (if present).
pub fn tag(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Tag, names.size());
names.encode(&mut self.bytes);
}

/// Appends a subsection for the names of fields within types in this
/// wasm module.
///
Expand Down
13 changes: 13 additions & 0 deletions crates/wasm-encoder/src/core/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ impl ValType {
pub const FUNCREF: ValType = ValType::Ref(RefType::FUNCREF);
/// Alias for the `externref` type in WebAssembly
pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF);
/// Alias for the `exnref` type in WebAssembly
pub const EXNREF: ValType = ValType::Ref(RefType::EXNREF);
}

impl Encode for StorageType {
Expand Down Expand Up @@ -305,6 +307,12 @@ impl RefType {
nullable: true,
heap_type: HeapType::Extern,
};

/// Alias for the `exnref` type in WebAssembly
pub const EXNREF: RefType = RefType {
nullable: true,
heap_type: HeapType::Exn,
};
}

impl Encode for RefType {
Expand Down Expand Up @@ -394,6 +402,9 @@ pub enum HeapType {
/// The unboxed `i31` heap type.
I31,

/// The abstract` exception` heap type.
Exn,

/// A concrete Wasm-defined type at the given index.
Concrete(u32),
}
Expand All @@ -411,6 +422,7 @@ impl Encode for HeapType {
HeapType::Struct => sink.push(0x6B),
HeapType::Array => sink.push(0x6A),
HeapType::I31 => sink.push(0x6C),
HeapType::Exn => sink.push(0x69),
// Note that this is encoded as a signed type rather than unsigned
// as it's decoded as an s33
HeapType::Concrete(i) => i64::from(*i).encode(sink),
Expand All @@ -437,6 +449,7 @@ impl TryFrom<wasmparser::HeapType> for HeapType {
wasmparser::HeapType::I31 => HeapType::I31,
wasmparser::HeapType::Cont => todo!(),
wasmparser::HeapType::NoCont => todo!(), // TODO(dhil): Shouldn't be too hard.
wasmparser::HeapType::Exn => HeapType::Exn,
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion crates/wasm-metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,8 @@ impl<'a> ModuleNames<'a> {
wasmparser::Name::Memory(m) => section.memories(&name_map(&m)?),
wasmparser::Name::Global(m) => section.globals(&name_map(&m)?),
wasmparser::Name::Element(m) => section.elements(&name_map(&m)?),
wasmparser::Name::Data(m) => section.types(&name_map(&m)?),
wasmparser::Name::Data(m) => section.data(&name_map(&m)?),
wasmparser::Name::Tag(m) => section.tags(&name_map(&m)?),
wasmparser::Name::Unknown { .. } => {} // wasm-encoder doesn't support it
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/wasm-mutate/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub fn map_ref_type(ref_ty: wasmparser::RefType) -> Result<RefType> {
wasmparser::HeapType::Array => HeapType::Array,
wasmparser::HeapType::I31 => HeapType::I31,
wasmparser::HeapType::Cont | wasmparser::HeapType::NoCont => todo!(), // TODO(dhil): Some day.
wasmparser::HeapType::Exn => HeapType::Exn,
wasmparser::HeapType::Concrete(i) => HeapType::Concrete(i.as_module_index().unwrap()),
},
})
Expand Down
7 changes: 7 additions & 0 deletions crates/wasm-mutate/src/mutators/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ pub fn heapty(t: &mut dyn Translator, ty: &wasmparser::HeapType) -> Result<HeapT
wasmparser::HeapType::Array => Ok(HeapType::Array),
wasmparser::HeapType::I31 => Ok(HeapType::I31),
wasmparser::HeapType::Cont | wasmparser::HeapType::NoCont => todo!(), // TODO(dhil): Some day.
wasmparser::HeapType::Exn => Ok(HeapType::Exn),
wasmparser::HeapType::Concrete(i) => Ok(HeapType::Concrete(
t.remap(Item::Type, i.as_module_index().unwrap())?,
)),
Expand Down Expand Up @@ -383,6 +384,7 @@ pub fn op(t: &mut dyn Translator, op: &Operator<'_>) -> Result<Instruction<'stat
(map $arg:ident field_index) => (*$arg);
(map $arg:ident from_type_nullable) => (*$arg);
(map $arg:ident to_type_nullable) => (*$arg);
(map $arg:ident try_table) => ($arg);

// This case takes the arguments of a wasmparser instruction and creates
// a wasm-encoder instruction. There are a few special cases for where
Expand All @@ -398,6 +400,7 @@ pub fn op(t: &mut dyn Translator, op: &Operator<'_>) -> Result<Instruction<'stat
(build F32Const $arg:ident) => (I::F32Const(f32::from_bits($arg.bits())));
(build F64Const $arg:ident) => (I::F64Const(f64::from_bits($arg.bits())));
(build V128Const $arg:ident) => (I::V128Const($arg.i128()));
(build TryTable $table:ident) => (unimplemented_try_table());
(build $op:ident $arg:ident) => (I::$op($arg));
(build CallIndirect $ty:ident $table:ident $_:ident) => (I::CallIndirect {
ty: $ty,
Expand All @@ -421,6 +424,10 @@ pub fn op(t: &mut dyn Translator, op: &Operator<'_>) -> Result<Instruction<'stat
wasmparser::for_each_operator!(translate)
}

fn unimplemented_try_table() -> wasm_encoder::Instruction<'static> {
unimplemented!()
}

pub fn block_type(t: &mut dyn Translator, ty: &wasmparser::BlockType) -> Result<BlockType> {
match ty {
wasmparser::BlockType::Empty => Ok(BlockType::Empty),
Expand Down
Loading

0 comments on commit 1baeb76

Please sign in to comment.