Update wasmparser for exception handling (#2431)

This commit is contained in:
Yury Delendik
2020-11-19 14:08:10 -06:00
committed by GitHub
parent 72811d35ae
commit e34b410381
16 changed files with 131 additions and 41 deletions

View File

@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
edition = "2018"
[dependencies]
wasmparser = { version = "0.67.0", default-features = false }
wasmparser = { version = "0.68.0", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.68.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.68.0" }
cranelift-frontend = { path = "../frontend", version = "0.68.0", default-features = false }

View File

@@ -534,6 +534,17 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
state.popn(return_count);
state.reachable = false;
}
/********************************** Exception handing **********************************/
Operator::Try { .. }
| Operator::Catch
| Operator::BrOnExn { .. }
| Operator::Throw { .. }
| Operator::Rethrow => {
return Err(wasm_unsupported!(
"proposed exception handling operator {:?}",
op
));
}
/************************************ Calls ****************************************
* The call instructions pop off their arguments from the stack and append their
* return values to it. `call_indirect` needs environment support because there is an

View File

@@ -8,8 +8,8 @@
use crate::state::FuncTranslationState;
use crate::translation_utils::{
DataIndex, ElemIndex, EntityType, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, Table,
TableIndex, TypeIndex,
DataIndex, ElemIndex, EntityType, Event, EventIndex, FuncIndex, Global, GlobalIndex, Memory,
MemoryIndex, Table, TableIndex, TypeIndex,
};
use core::convert::From;
use core::convert::TryFrom;
@@ -44,6 +44,8 @@ pub enum WasmType {
FuncRef,
/// ExternRef type
ExternRef,
/// ExnRef type
ExnRef,
}
impl TryFrom<wasmparser::Type> for WasmType {
@@ -58,6 +60,7 @@ impl TryFrom<wasmparser::Type> for WasmType {
V128 => Ok(WasmType::V128),
FuncRef => Ok(WasmType::FuncRef),
ExternRef => Ok(WasmType::ExternRef),
ExnRef => Ok(WasmType::ExnRef),
EmptyBlockType | Func => Err(WasmError::InvalidWebAssembly {
message: "unexpected value type".to_string(),
offset: 0,
@@ -76,6 +79,7 @@ impl From<WasmType> for wasmparser::Type {
WasmType::V128 => wasmparser::Type::V128,
WasmType::FuncRef => wasmparser::Type::FuncRef,
WasmType::ExternRef => wasmparser::Type::ExternRef,
WasmType::ExnRef => wasmparser::Type::ExnRef,
}
}
}
@@ -689,6 +693,17 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
field: &'data str,
) -> WasmResult<()>;
/// Declares an event import to the environment.
fn declare_event_import(
&mut self,
event: Event,
module: &'data str,
field: &'data str,
) -> WasmResult<()> {
drop((event, module, field));
Err(WasmError::Unsupported("wasm events".to_string()))
}
/// Declares a global import to the environment.
fn declare_global_import(
&mut self,
@@ -751,6 +766,18 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
/// Declares a memory to the environment
fn declare_memory(&mut self, memory: Memory) -> WasmResult<()>;
/// Provides the number of defined events up front. By default this does nothing, but
/// implementations can use this to preallocate memory if desired.
fn reserve_events(&mut self, _num: u32) -> WasmResult<()> {
Ok(())
}
/// Declares an event to the environment
fn declare_event(&mut self, event: Event) -> WasmResult<()> {
drop(event);
Err(WasmError::Unsupported("wasm events".to_string()))
}
/// Provides the number of defined globals up front. By default this does nothing, but
/// implementations can use this to preallocate memory if desired.
fn reserve_globals(&mut self, _num: u32) -> WasmResult<()> {
@@ -780,6 +807,16 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
name: &'data str,
) -> WasmResult<()>;
/// Declares an event export to the environment.
fn declare_event_export(
&mut self,
event_index: EventIndex,
name: &'data str,
) -> WasmResult<()> {
drop((event_index, name));
Err(WasmError::Unsupported("wasm events".to_string()))
}
/// Declares a global export to the environment.
fn declare_global_export(
&mut self,

View File

@@ -2,9 +2,9 @@
//! to deal with each part of it.
use crate::environ::{ModuleEnvironment, WasmResult};
use crate::sections_translator::{
parse_data_section, parse_element_section, parse_export_section, parse_function_section,
parse_global_section, parse_import_section, parse_memory_section, parse_name_section,
parse_start_section, parse_table_section, parse_type_section,
parse_data_section, parse_element_section, parse_event_section, parse_export_section,
parse_function_section, parse_global_section, parse_import_section, parse_memory_section,
parse_name_section, parse_start_section, parse_table_section, parse_type_section,
};
use crate::state::ModuleTranslationState;
use cranelift_codegen::timing;
@@ -65,6 +65,11 @@ pub fn translate_module<'data>(
parse_memory_section(memories, environ)?;
}
Payload::EventSection(events) => {
validator.event_section(&events)?;
parse_event_section(events, environ)?;
}
Payload::GlobalSection(globals) => {
validator.global_section(&globals)?;
parse_global_section(globals, environ)?;

View File

@@ -10,8 +10,9 @@
use crate::environ::{ModuleEnvironment, WasmError, WasmResult};
use crate::state::ModuleTranslationState;
use crate::translation_utils::{
tabletype_to_type, type_to_type, DataIndex, ElemIndex, EntityType, FuncIndex, Global,
GlobalIndex, GlobalInit, Memory, MemoryIndex, Table, TableElementType, TableIndex, TypeIndex,
tabletype_to_type, type_to_type, DataIndex, ElemIndex, EntityType, Event, EventIndex,
FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, Table, TableElementType,
TableIndex, TypeIndex,
};
use crate::wasm_unsupported;
use core::convert::TryFrom;
@@ -24,10 +25,10 @@ use std::boxed::Box;
use std::vec::Vec;
use wasmparser::{
self, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems, ElementKind,
ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader,
GlobalSectionReader, GlobalType, ImportSectionEntryType, ImportSectionReader,
MemorySectionReader, MemoryType, NameSectionReader, Naming, Operator, TableSectionReader,
TableType, TypeDef, TypeSectionReader,
ElementSectionReader, EventSectionReader, EventType, Export, ExportSectionReader, ExternalKind,
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, Operator,
TableSectionReader, TableType, TypeDef, TypeSectionReader,
};
fn entity_type(
@@ -39,6 +40,7 @@ fn entity_type(
ImportSectionEntryType::Module(sig) => EntityType::Module(TypeIndex::from_u32(sig)),
ImportSectionEntryType::Instance(sig) => EntityType::Instance(TypeIndex::from_u32(sig)),
ImportSectionEntryType::Memory(ty) => EntityType::Memory(memory(ty)),
ImportSectionEntryType::Event(evt) => EntityType::Event(event(evt)),
ImportSectionEntryType::Global(ty) => {
EntityType::Global(global(ty, environ, GlobalInit::Import)?)
}
@@ -58,6 +60,12 @@ fn memory(ty: MemoryType) -> Memory {
}
}
fn event(e: EventType) -> Event {
Event {
ty: TypeIndex::from_u32(e.type_index),
}
}
fn table(ty: TableType, environ: &mut dyn ModuleEnvironment<'_>) -> WasmResult<Table> {
Ok(Table {
wasm_ty: ty.element_type.try_into()?,
@@ -163,6 +171,7 @@ pub fn parse_import_section<'data>(
EntityType::Memory(ty) => {
environ.declare_memory_import(ty, module_name, field_name)?;
}
EntityType::Event(e) => environ.declare_event_import(e, module_name, field_name)?,
EntityType::Global(ty) => {
environ.declare_global_import(ty, module_name, field_name)?;
}
@@ -227,6 +236,21 @@ pub fn parse_memory_section(
Ok(())
}
/// Parses the Event section of the wasm module.
pub fn parse_event_section(
events: EventSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_events(events.get_count())?;
for entry in events {
let event = event(entry?);
environ.declare_event(event)?;
}
Ok(())
}
/// Parses the Global section of the wasm module.
pub fn parse_global_section(
globals: GlobalSectionReader,
@@ -290,6 +314,7 @@ pub fn parse_export_section<'data>(
ExternalKind::Memory => {
environ.declare_memory_export(MemoryIndex::new(index), field)?
}
ExternalKind::Event => environ.declare_event_export(EventIndex::new(index), field)?,
ExternalKind::Global => {
environ.declare_global_export(GlobalIndex::new(index), field)?
}

View File

@@ -91,6 +91,12 @@ entity_impl!(ModuleIndex);
pub struct InstanceIndex(u32);
entity_impl!(InstanceIndex);
/// Index type of an event inside the WebAssembly module.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct EventIndex(u32);
entity_impl!(EventIndex);
/// An index of an entity.
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
@@ -119,6 +125,8 @@ pub enum EntityType {
Global(Global),
/// A linear memory with the specified limits
Memory(Memory),
/// An event definition.
Event(Event),
/// A table with the specified element type and limits
Table(Table),
/// A function type where the index points to the type section and records a
@@ -212,6 +220,14 @@ pub struct Memory {
pub shared: bool,
}
/// WebAssembly event.
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Event {
/// The event signature type.
pub ty: TypeIndex,
}
/// Helper function translating wasmparser types to Cranelift types when possible.
pub fn type_to_type<PE: TargetEnvironment + ?Sized>(
ty: wasmparser::Type,