Update wasmparser for exception handling (#2431)
This commit is contained in:
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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)?
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user