diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2024-01-21 22:27:20 +0100 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2024-01-21 22:27:20 +0100 |
| commit | 1eb6f3160a5c6036926bd3db757d2ff3ca4b1a53 (patch) | |
| tree | 6bded53fedfa9816685d86c186f457a64b388659 /crates | |
| parent | 1b6f5dfc63e2f64aa1c1fed1a6b4c3e1e32db1b9 (diff) | |
fix export isolation issues
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/tinywasm/src/export.rs | 17 | ||||
| -rw-r--r-- | crates/tinywasm/src/imports.rs | 235 | ||||
| -rw-r--r-- | crates/tinywasm/src/instance.rs | 110 | ||||
| -rw-r--r-- | crates/tinywasm/src/lib.rs | 8 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/executor/mod.rs | 14 | ||||
| -rw-r--r-- | crates/tinywasm/src/store.rs | 94 | ||||
| -rw-r--r-- | crates/tinywasm/tests/generated/mvp.csv | 2 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 48 |
8 files changed, 200 insertions, 328 deletions
diff --git a/crates/tinywasm/src/export.rs b/crates/tinywasm/src/export.rs index 52adc6f..8b13789 100644 --- a/crates/tinywasm/src/export.rs +++ b/crates/tinywasm/src/export.rs @@ -1,18 +1 @@ -use alloc::boxed::Box; -use tinywasm_types::{Export, ExternalKind}; -#[derive(Debug)] -/// Exports of a module instance -// TODO: Maybe use a BTreeMap instead? -pub struct ExportInstance(pub(crate) Box<[Export]>); - -impl ExportInstance { - /// Get an export by name - pub fn get(&self, name: &str, ty: ExternalKind) -> Option<&Export> { - self.0.iter().find(|e| e.name == name.into() && e.kind == ty) - } - - pub(crate) fn get_untyped(&self, name: &str) -> Option<&Export> { - self.0.iter().find(|e| e.name == name.into()) - } -} diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index e7f9b81..f89ba64 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -11,12 +11,12 @@ use alloc::{ vec::Vec, }; use tinywasm_types::{ - ExternVal, ExternalKind, FuncAddr, GlobalAddr, GlobalType, Import, MemAddr, MemoryType, ModuleInstanceAddr, - TableAddr, TableType, WasmFunction, WasmValue, + Addr, Export, ExternVal, ExternalKind, FuncAddr, GlobalAddr, GlobalType, Import, MemAddr, MemoryType, + ModuleInstanceAddr, TableAddr, TableType, WasmFunction, WasmValue, }; /// The internal representation of a function -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Function { /// A host function Host(HostFunction), @@ -26,6 +26,7 @@ pub enum Function { } /// A host function +#[derive(Clone)] pub struct HostFunction { pub(crate) ty: tinywasm_types::FuncType, pub(crate) func: Arc<dyn Fn(&mut crate::Store, &[WasmValue]) -> Result<Vec<WasmValue>> + 'static + Send + Sync>, @@ -33,14 +34,11 @@ pub struct HostFunction { impl Debug for HostFunction { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("HostFunction") - .field("ty", &self.ty) - .field("func", &"...") - .finish() + f.debug_struct("HostFunction").field("ty", &self.ty).field("func", &"...").finish() } } -#[derive(Debug)] +#[derive(Debug, Clone)] #[non_exhaustive] /// An external value pub enum Extern { @@ -58,25 +56,25 @@ pub enum Extern { } /// A function -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExternFunc(pub(crate) HostFunction); /// A global value -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExternGlobal { pub(crate) ty: GlobalType, pub(crate) val: WasmValue, } /// A table -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExternTable { pub(crate) ty: TableType, pub(crate) val: WasmValue, } /// A memory -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExternMemory { pub(crate) ty: MemoryType, } @@ -84,13 +82,7 @@ pub struct ExternMemory { impl Extern { /// Create a new global import pub fn global(val: WasmValue, mutable: bool) -> Self { - Self::Global(ExternGlobal { - ty: GlobalType { - ty: val.val_type(), - mutable, - }, - val, - }) + Self::Global(ExternGlobal { ty: GlobalType { ty: val.val_type(), mutable }, val }) } /// Create a new table import @@ -113,10 +105,7 @@ impl Extern { func(store, &args) }; - Self::Func(Function::Host(HostFunction { - func: Arc::new(inner_func), - ty: ty.clone(), - })) + Self::Func(Function::Host(HostFunction { func: Arc::new(inner_func), ty: ty.clone() })) } /// Create a new typed function import @@ -131,15 +120,9 @@ impl Extern { Ok(result.into_wasm_value_tuple()) }; - let ty = tinywasm_types::FuncType { - params: P::val_types(), - results: R::val_types(), - }; + let ty = tinywasm_types::FuncType { params: P::val_types(), results: R::val_types() }; - Self::Func(Function::Host(HostFunction { - func: Arc::new(inner_func), - ty, - })) + Self::Func(Function::Host(HostFunction { func: Arc::new(inner_func), ty })) } pub(crate) fn kind(&self) -> ExternalKind { @@ -161,10 +144,7 @@ pub struct ExternName { impl From<&Import> for ExternName { fn from(import: &Import) -> Self { - Self { - module: import.module.to_string(), - name: import.name.to_string(), - } + Self { module: import.module.to_string(), name: import.name.to_string() } } } @@ -183,79 +163,23 @@ pub(crate) enum ResolvedExtern<S, V> { Extern(V), } -pub(crate) enum ResolvedImport { - Extern(Extern), - Store(ExternVal), -} - -impl ResolvedImport { - fn initialize(self, store: &mut crate::Store, idx: ModuleInstanceAddr) -> Result<ExternVal> { - match self { - Self::Extern(extern_) => match extern_ { - Extern::Global(global) => { - let addr = store.add_global(global.ty, global.val.into(), idx)?; - Ok(ExternVal::Global(addr)) - } - Extern::Table(table) => { - // todo: do something with the initial value - let addr = store.add_table(table.ty, idx)?; - Ok(ExternVal::Table(addr)) - } - Extern::Memory(memory) => { - let addr = store.add_mem(memory.ty, idx)?; - Ok(ExternVal::Mem(addr)) - } - Extern::Func(func) => { - let addr = store.add_func(func, idx)?; - Ok(ExternVal::Func(addr)) - } - }, - Self::Store(extern_val) => Ok(extern_val.clone()), - } - } -} - pub(crate) struct ResolvedImports { - pub(crate) globals: Vec<ResolvedExtern<GlobalAddr, ExternGlobal>>, - pub(crate) tables: Vec<ResolvedExtern<TableAddr, ExternTable>>, - pub(crate) mems: Vec<ResolvedExtern<MemAddr, ExternMemory>>, - pub(crate) funcs: Vec<ResolvedExtern<FuncAddr, ExternFunc>>, + pub(crate) globals: Vec<GlobalAddr>, + pub(crate) tables: Vec<TableAddr>, + pub(crate) mems: Vec<MemAddr>, + pub(crate) funcs: Vec<FuncAddr>, } impl ResolvedImports { pub(crate) fn new() -> Self { - Self { - globals: Vec::new(), - tables: Vec::new(), - mems: Vec::new(), - funcs: Vec::new(), - } - } - - pub(crate) fn globals(&self) -> &[ResolvedExtern<GlobalAddr, ExternGlobal>] { - &self.globals - } - - pub(crate) fn tables(&self) -> &[ResolvedExtern<TableAddr, ExternTable>] { - &self.tables - } - - pub(crate) fn mems(&self) -> &[ResolvedExtern<MemAddr, ExternMemory>] { - &self.mems - } - - pub(crate) fn funcs(&self) -> &[ResolvedExtern<FuncAddr, ExternFunc>] { - &self.funcs + Self { globals: Vec::new(), tables: Vec::new(), mems: Vec::new(), funcs: Vec::new() } } } impl Imports { /// Create a new empty import set pub fn new() -> Self { - Imports { - values: BTreeMap::new(), - modules: BTreeMap::new(), - } + Imports { values: BTreeMap::new(), modules: BTreeMap::new() } } /// Link a module @@ -268,39 +192,43 @@ impl Imports { /// Define an import pub fn define(&mut self, module: &str, name: &str, value: Extern) -> Result<&mut Self> { - self.values.insert( - ExternName { - module: module.to_string(), - name: name.to_string(), - }, - value, - ); + self.values.insert(ExternName { module: module.to_string(), name: name.to_string() }, value); Ok(self) } - pub(crate) fn take(&mut self, store: &mut crate::Store, import: &Import) -> Option<ResolvedImport> { - // TODO: compare types - + pub(crate) fn take( + &mut self, + store: &mut crate::Store, + import: &Import, + ) -> Option<ResolvedExtern<ExternVal, Extern>> { let name = ExternName::from(import); - if let Some(v) = self.values.remove(&name) { - return Some(ResolvedImport::Extern(v)); + log::error!("provided externs: {:?}", self.values.keys()); + if let Some(v) = self.values.get(&name) { + return Some(ResolvedExtern::Extern(v.clone())); } + log::error!("failed to resolve import: {:?}", name); + // TODO: + // if let Some(addr) = self.modules.get(&name.module) { + // let instance = store.get_module_instance(*addr)?; + // let exports = instance.exports(); - return None; - - // TODO: allow linking to other modules - // if let Some(module_addr) = self.modules.get(&name.module) { - // let Some(module) = store.get_module_instance(*module_addr) else { - // return None; + // let export = exports.get_untyped(&import.name)?; + // let addr = match export.kind { + // ExternalKind::Global(g) => ExternVal::Global(), // }; - // let export = module.exports().get_untyped(&name.name)?; - // }; + // return Some(ResolvedExtern::Store()); + // } - // then check if the import is defined + None } - pub(crate) fn link(mut self, store: &mut crate::Store, module: &crate::Module) -> Result<ResolvedImports> { + pub(crate) fn link( + mut self, + store: &mut crate::Store, + module: &crate::Module, + idx: ModuleInstanceAddr, + ) -> Result<ResolvedImports> { let mut imports = ResolvedImports::new(); for import in module.data.imports.iter() { @@ -311,28 +239,57 @@ impl Imports { }); }; - // validate import - // if export.kind != (&import.kind).into() { - // return Err(crate::Error::InvalidImportType { - // module: import.module.to_string(), - // name: import.name.to_string(), - // }); - // } + match val { + // A link to something that needs to be added to the store + ResolvedExtern::Extern(ex) => { + // check if the kind matches + let kind = ex.kind(); + if kind != (&import.kind).into() { + return Err(crate::Error::InvalidImportType { + module: import.module.to_string(), + name: import.name.to_string(), + }); + } + + // TODO: check if the type matches - // let val = match export.kind { - // ExternalKind::Func => ExternVal::Func(export.index), - // ExternalKind::Global => ExternVal::Global(export.index), - // ExternalKind::Table => ExternVal::Table(export.index), - // ExternalKind::Memory => ExternVal::Mem(export.index), - // }; + // add it to the store and get the address + let addr = match ex { + Extern::Global(g) => store.add_global(g.ty, g.val.into(), idx)?, + Extern::Table(t) => store.add_table(t.ty, idx)?, + Extern::Memory(m) => store.add_mem(m.ty, idx)?, + Extern::Func(f) => store.add_func(f, idx)?, + }; + + // store the link + match &kind { + ExternalKind::Global => imports.globals.push(addr), + ExternalKind::Table => imports.tables.push(addr), + ExternalKind::Memory => imports.mems.push(addr), + ExternalKind::Func => imports.funcs.push(addr), + } + } - // imports.0.insert( - // ExternName { - // module: import.module.to_string(), - // name: import.name.to_string(), - // }, - // ResolvedImport::Store(val), - // ); + // A link to something already in the store + ResolvedExtern::Store(val) => { + // check if the kind matches + if val.kind() != (&import.kind).into() { + return Err(crate::Error::InvalidImportType { + module: import.module.to_string(), + name: import.name.to_string(), + }); + } + + // TODO: check if the type matches + + match val { + ExternVal::Global(g) => imports.globals.push(g), + ExternVal::Table(t) => imports.tables.push(t), + ExternVal::Mem(m) => imports.mems.push(m), + ExternVal::Func(f) => imports.funcs.push(f), + } + } + } } Ok(imports) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index b8f87d7..92db518 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -1,11 +1,12 @@ use alloc::{boxed::Box, format, string::ToString, sync::Arc, vec::Vec}; use tinywasm_types::{ - DataAddr, ElemAddr, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr, TableAddr, + DataAddr, ElemAddr, Export, ExternVal, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, + ModuleInstanceAddr, TableAddr, }; use crate::{ func::{FromWasmValueTuple, IntoWasmValueTuple}, - Error, ExportInstance, FuncHandle, Imports, Module, Result, Store, TypedFuncHandle, + Error, FuncHandle, Imports, Module, Result, Store, TypedFuncHandle, }; /// A WebAssembly Module Instance @@ -32,7 +33,7 @@ pub(crate) struct ModuleInstanceInner { pub(crate) func_start: Option<FuncAddr>, pub(crate) imports: Box<[Import]>, - pub(crate) exports: ExportInstance, + pub(crate) exports: Box<[Export]>, } impl ModuleInstance { @@ -52,36 +53,33 @@ impl ModuleInstance { let idx = store.next_module_instance_idx(); let imports = imports.unwrap_or_default(); - let linked_imports = imports.link(store, &module)?; - let global_addrs = store.add_globals(module.data.globals.into(), idx)?; + let mut addrs = imports.link(store, &module, idx)?; + let data = module.data; - // TODO: imported functions missing - let func_addrs = store.add_funcs(module.data.funcs.into(), idx)?; + addrs.globals.extend(store.init_globals(data.globals.into(), idx)?); + addrs.funcs.extend(store.init_funcs(data.funcs.into(), idx)?); + addrs.tables.extend(store.init_tables(data.table_types.into(), idx)?); + addrs.mems.extend(store.init_mems(data.memory_types.into(), idx)?); - let table_addrs = store.add_tables(module.data.table_types.into(), idx)?; - let mem_addrs = store.add_mems(module.data.memory_types.into(), idx)?; - - // TODO: active/declared elems need to be initialized - let elem_addrs = store.add_elems(module.data.elements.into(), idx)?; - - // TODO: active data segments need to be initialized - let data_addrs = store.add_datas(module.data.data.into(), idx)?; + let elem_addrs = store.add_elems(data.elements.into(), idx)?; + let data_addrs = store.add_datas(data.data.into(), idx)?; let instance = ModuleInstanceInner { store_id: store.id(), idx, - types: module.data.func_types, - func_addrs, - table_addrs, - mem_addrs, - global_addrs, + types: data.func_types, + + func_addrs: addrs.funcs, + table_addrs: addrs.tables, + mem_addrs: addrs.mems, + global_addrs: addrs.globals, elem_addrs, data_addrs, - func_start: module.data.start_func, - imports: module.data.imports, - exports: crate::ExportInstance(module.data.exports), + func_start: data.start_func, + imports: data.imports, + exports: data.exports, }; let instance = ModuleInstance::new(instance); @@ -91,8 +89,17 @@ impl ModuleInstance { } /// Get the module's exports - pub fn exports(&self) -> &ExportInstance { - &self.0.exports + pub(crate) fn export(&self, name: &str) -> Option<ExternVal> { + let exports = self.0.exports.iter().find(|e| e.name == name.into())?; + let kind = exports.kind.clone(); + let addr = match kind { + ExternalKind::Func => self.0.func_addrs.get(exports.index as usize)?, + ExternalKind::Table => self.0.table_addrs.get(exports.index as usize)?, + ExternalKind::Memory => self.0.mem_addrs.get(exports.index as usize)?, + ExternalKind::Global => self.0.global_addrs.get(exports.index as usize)?, + }; + + Some(ExternVal::new(kind, *addr)) } pub(crate) fn func_addrs(&self) -> &[FuncAddr] { @@ -145,28 +152,21 @@ impl ModuleInstance { return Err(Error::InvalidStore); } - let export = self - .0 - .exports - .get(name, ExternalKind::Func) - .ok_or_else(|| Error::Other(format!("Export not found: {}", name)))?; - - let func_addr = self - .0 - .func_addrs - .get(export.index as usize) - .expect("No func addr for export, this is a bug"); + let export = self.export(name).ok_or_else(|| Error::Other(format!("Export not found: {}", name)))?; + let ExternVal::Func(func_addr) = export else { + return Err(Error::Other(format!("Export is not a function: {}", name))); + }; - let func_inst = store.get_func(*func_addr as usize)?; + let func_inst = store.get_func(func_addr as usize)?; let func = func_inst.assert_wasm()?; - let ty = self.0.types[func.ty_addr as usize].clone(); + let ty = self + .0 + .types + .get(func.ty_addr as usize) + .ok_or_else(|| Error::Other(format!("Invalid function type address: {}", func.ty_addr)))? + .clone(); - Ok(FuncHandle { - addr: export.index, - module: self.clone(), - name: Some(name.to_string()), - ty, - }) + Ok(FuncHandle { addr: func_addr, module: self.clone(), name: Some(name.to_string()), ty }) } /// Get a typed exported function by name @@ -176,10 +176,7 @@ impl ModuleInstance { R: FromWasmValueTuple, { let func = self.exported_func_by_name(store, name)?; - Ok(TypedFuncHandle { - func, - marker: core::marker::PhantomData, - }) + Ok(TypedFuncHandle { func, marker: core::marker::PhantomData }) } /// Get the start function of the module @@ -198,30 +195,21 @@ impl ModuleInstance { Some(func_index) => func_index, None => { // alternatively, check for a _start function in the exports - let Some(start) = self.0.exports.get("_start", ExternalKind::Func) else { + let Some(ExternVal::Func(func_addr)) = self.export("_start") else { return Ok(None); }; - start.index + func_addr } }; - let func_addr = self - .0 - .func_addrs - .get(func_index as usize) - .expect("No func addr for start func, this is a bug"); + let func_addr = self.0.func_addrs.get(func_index as usize).expect("No func addr for start func, this is a bug"); let func_inst = store.get_func(*func_addr as usize)?; let func = func_inst.assert_wasm()?; let ty = self.0.types[func.ty_addr as usize].clone(); - Ok(Some(FuncHandle { - module: self.clone(), - addr: *func_addr, - ty, - name: None, - })) + Ok(Some(FuncHandle { module: self.clone(), addr: *func_addr, ty, name: None })) } /// Invoke the start function of the module diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 0c1863f..64d34df 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -2,10 +2,7 @@ #![forbid(unsafe_code)] #![doc(test( no_crate_inject, - attr( - deny(warnings, rust_2018_idioms), - allow(dead_code, unused_assignments, unused_variables) - ) + attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_assignments, unused_variables)) ))] #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] #![cfg_attr(nightly, feature(error_in_core))] @@ -89,9 +86,6 @@ pub use module::Module; mod instance; pub use instance::ModuleInstance; -mod export; -pub use export::ExportInstance; - mod func; pub use func::{FuncHandle, TypedFuncHandle}; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 5e191cc..62f17e7 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -16,7 +16,6 @@ use traits::*; impl DefaultRuntime { pub(crate) fn exec(&self, store: &mut Store, stack: &mut Stack, module: ModuleInstance) -> Result<()> { - log::debug!("exports: {:?}", module.exports()); log::debug!("func_addrs: {:?}", module.func_addrs()); log::debug!("func_ty_addrs: {:?}", module.func_ty_addrs().len()); log::debug!("store funcs: {:?}", store.data.funcs.len()); @@ -162,11 +161,9 @@ fn exec_one( let func_ty = module.func_ty(func.ty_addr); if func_ty != call_ty { - return Err(Trap::IndirectCallTypeMismatch { - actual: func_ty.clone(), - expected: call_ty.clone(), - } - .into()); + return Err( + Trap::IndirectCallTypeMismatch { actual: func_ty.clone(), expected: call_ty.clone() }.into() + ); } let params = stack.values.pop_n(func_ty.params.len())?; @@ -569,10 +566,7 @@ fn exec_one( i => { log::error!("unimplemented instruction: {:?}", i); - return Err(Error::UnsupportedFeature(alloc::format!( - "unimplemented instruction: {:?}", - i - ))); + return Err(Error::UnsupportedFeature(alloc::format!("unimplemented instruction: {:?}", i))); } }; diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index 9b2f711..426ca78 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -7,7 +7,7 @@ use core::{ use alloc::{format, rc::Rc, string::ToString, vec, vec::Vec}; use tinywasm_types::{ - Addr, Data, DataAddr, ElemAddr, Element, ElementKind, FuncAddr, Global, GlobalType, Import, MemAddr, MemoryArch, + Addr, Data, DataAddr, ElemAddr, Element, ElementKind, FuncAddr, Global, GlobalType, MemAddr, MemoryArch, MemoryType, ModuleInstanceAddr, TableAddr, TableType, WasmFunction, }; @@ -114,7 +114,7 @@ impl Store { } /// Add functions to the store, returning their addresses in the store - pub(crate) fn add_funcs(&mut self, funcs: Vec<WasmFunction>, idx: ModuleInstanceAddr) -> Result<Vec<FuncAddr>> { + pub(crate) fn init_funcs(&mut self, funcs: Vec<WasmFunction>, idx: ModuleInstanceAddr) -> Result<Vec<FuncAddr>> { let func_count = self.data.funcs.len(); let mut func_addrs = Vec::with_capacity(func_count); for func in funcs.into_iter() { @@ -124,7 +124,7 @@ impl Store { } /// Add tables to the store, returning their addresses in the store - pub(crate) fn add_tables(&mut self, tables: Vec<TableType>, idx: ModuleInstanceAddr) -> Result<Vec<TableAddr>> { + pub(crate) fn init_tables(&mut self, tables: Vec<TableType>, idx: ModuleInstanceAddr) -> Result<Vec<TableAddr>> { let table_count = self.data.tables.len(); let mut table_addrs = Vec::with_capacity(table_count); for (i, table) in tables.into_iter().enumerate() { @@ -134,7 +134,7 @@ impl Store { } /// Add memories to the store, returning their addresses in the store - pub(crate) fn add_mems(&mut self, mems: Vec<MemoryType>, idx: ModuleInstanceAddr) -> Result<Vec<MemAddr>> { + pub(crate) fn init_mems(&mut self, mems: Vec<MemoryType>, idx: ModuleInstanceAddr) -> Result<Vec<MemAddr>> { let mem_count = self.data.mems.len(); let mut mem_addrs = Vec::with_capacity(mem_count); for (i, mem) in mems.into_iter().enumerate() { @@ -144,7 +144,7 @@ impl Store { } /// Add globals to the store, returning their addresses in the store - pub(crate) fn add_globals(&mut self, globals: Vec<Global>, idx: ModuleInstanceAddr) -> Result<Vec<Addr>> { + pub(crate) fn init_globals(&mut self, globals: Vec<Global>, idx: ModuleInstanceAddr) -> Result<Vec<Addr>> { let global_count = self.data.globals.len(); let mut global_addrs = Vec::with_capacity(global_count); // then add the module globals @@ -156,16 +156,12 @@ impl Store { } pub(crate) fn add_global(&mut self, ty: GlobalType, value: RawWasmValue, idx: ModuleInstanceAddr) -> Result<Addr> { - self.data - .globals - .push(Rc::new(RefCell::new(GlobalInstance::new(ty, value, idx)))); + self.data.globals.push(Rc::new(RefCell::new(GlobalInstance::new(ty, value, idx)))); Ok(self.data.globals.len() as Addr - 1) } pub(crate) fn add_table(&mut self, table: TableType, idx: ModuleInstanceAddr) -> Result<TableAddr> { - self.data - .tables - .push(Rc::new(RefCell::new(TableInstance::new(table, idx)))); + self.data.tables.push(Rc::new(RefCell::new(TableInstance::new(table, idx)))); Ok(self.data.tables.len() as TableAddr - 1) } @@ -173,9 +169,7 @@ impl Store { if let MemoryArch::I64 = mem.arch { return Err(Error::UnsupportedFeature("64-bit memories".to_string())); } - self.data - .mems - .push(Rc::new(RefCell::new(MemoryInstance::new(mem, idx)))); + self.data.mems.push(Rc::new(RefCell::new(MemoryInstance::new(mem, idx)))); Ok(self.data.mems.len() as MemAddr - 1) } @@ -203,6 +197,7 @@ impl Store { Ok(self.data.funcs.len() as FuncAddr - 1) } + /// Evaluate a constant expression, only supporting i32 globals and i32.const pub(crate) fn eval_i32_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<i32> { use tinywasm_types::ConstInstruction::*; let val = match const_instr { @@ -218,6 +213,7 @@ impl Store { Ok(val) } + /// Evaluate a constant expression pub(crate) fn eval_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<RawWasmValue> { use tinywasm_types::ConstInstruction::*; let val = match const_instr { @@ -300,9 +296,7 @@ impl Store { Active { mem: mem_addr, offset } => { // a. Assert: memidx == 0 if mem_addr != 0 { - return Err(Error::UnsupportedFeature( - "data segments for non-zero memories".to_string(), - )); + return Err(Error::UnsupportedFeature("data segments for non-zero memories".to_string())); } let offset = self.eval_i32_const(&offset)?; @@ -328,33 +322,21 @@ impl Store { /// Get the function at the actual index in the store pub(crate) fn get_func(&self, addr: usize) -> Result<&Rc<FunctionInstance>> { - self.data - .funcs - .get(addr) - .ok_or_else(|| Error::Other(format!("function {} not found", addr))) + self.data.funcs.get(addr).ok_or_else(|| Error::Other(format!("function {} not found", addr))) } /// Get the memory at the actual index in the store pub(crate) fn get_mem(&self, addr: usize) -> Result<&Rc<RefCell<MemoryInstance>>> { - self.data - .mems - .get(addr) - .ok_or_else(|| Error::Other(format!("memory {} not found", addr))) + self.data.mems.get(addr).ok_or_else(|| Error::Other(format!("memory {} not found", addr))) } /// Get the table at the actual index in the store pub(crate) fn get_table(&self, addr: usize) -> Result<&Rc<RefCell<TableInstance>>> { - self.data - .tables - .get(addr) - .ok_or_else(|| Error::Other(format!("table {} not found", addr))) + self.data.tables.get(addr).ok_or_else(|| Error::Other(format!("table {} not found", addr))) } pub(crate) fn get_elem(&self, addr: usize) -> Result<&ElemInstance> { - self.data - .elems - .get(addr) - .ok_or_else(|| Error::Other(format!("element {} not found", addr))) + self.data.elems.get(addr).ok_or_else(|| Error::Other(format!("element {} not found", addr))) } /// Get the global at the actual index in the store @@ -413,18 +395,11 @@ pub(crate) struct TableInstance { impl TableInstance { pub(crate) fn new(kind: TableType, owner: ModuleInstanceAddr) -> Self { - Self { - elements: vec![0; kind.size_initial as usize], - kind, - owner, - } + Self { elements: vec![0; kind.size_initial as usize], kind, owner } } pub(crate) fn get(&self, addr: usize) -> Result<Addr> { - self.elements - .get(addr) - .copied() - .ok_or_else(|| Trap::UndefinedElement { index: addr }.into()) + self.elements.get(addr).copied().ok_or_else(|| Trap::UndefinedElement { index: addr }.into()) } pub(crate) fn set(&mut self, addr: usize, value: Addr) -> Result<()> { @@ -442,20 +417,11 @@ impl TableInstance { pub(crate) fn init(&mut self, offset: i32, init: &[Addr]) -> Result<()> { let offset = offset as usize; let end = offset.checked_add(init.len()).ok_or_else(|| { - Error::Trap(crate::Trap::TableOutOfBounds { - offset, - len: init.len(), - max: self.elements.len(), - }) + Error::Trap(crate::Trap::TableOutOfBounds { offset, len: init.len(), max: self.elements.len() }) })?; if end > self.elements.len() || end < offset { - return Err(crate::Trap::TableOutOfBounds { - offset, - len: init.len(), - max: self.elements.len(), - } - .into()); + return Err(crate::Trap::TableOutOfBounds { offset, len: init.len(), max: self.elements.len() }.into()); } self.elements[offset..end].copy_from_slice(init); @@ -493,11 +459,7 @@ impl MemoryInstance { pub(crate) fn store(&mut self, addr: usize, _align: usize, data: &[u8]) -> Result<()> { let end = addr.checked_add(data.len()).ok_or_else(|| { - Error::Trap(crate::Trap::MemoryOutOfBounds { - offset: addr, - len: data.len(), - max: self.data.len(), - }) + Error::Trap(crate::Trap::MemoryOutOfBounds { offset: addr, len: data.len(), max: self.data.len() }) })?; if end > self.data.len() || end < addr { @@ -518,20 +480,12 @@ impl MemoryInstance { } pub(crate) fn load(&self, addr: usize, _align: usize, len: usize) -> Result<&[u8]> { - let end = addr.checked_add(len).ok_or_else(|| { - Error::Trap(crate::Trap::MemoryOutOfBounds { - offset: addr, - len, - max: self.max_pages(), - }) - })?; + let end = addr + .checked_add(len) + .ok_or_else(|| Error::Trap(crate::Trap::MemoryOutOfBounds { offset: addr, len, max: self.max_pages() }))?; if end > self.data.len() { - return Err(Error::Trap(crate::Trap::MemoryOutOfBounds { - offset: addr, - len, - max: self.data.len(), - })); + return Err(Error::Trap(crate::Trap::MemoryOutOfBounds { offset: addr, len, max: self.data.len() })); } // WebAssembly doesn't require alignment for loads diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index e175639..a1eaf8c 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}] 0.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}] 0.2.0,19344,884,[{"name":"address.wast","passed":181,"failed":79},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":220,"failed":3},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":171,"failed":3},{"name":"call.wast","passed":73,"failed":18},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":168,"failed":4},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":103,"failed":7},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":231,"failed":10},{"name":"imports.wast","passed":80,"failed":103},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":26,"failed":3},{"name":"left-to-right.wast","passed":92,"failed":4},{"name":"linking.wast","passed":29,"failed":103},{"name":"load.wast","passed":93,"failed":4},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":93,"failed":4},{"name":"loop.wast","passed":116,"failed":4},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":91,"failed":5},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":78,"failed":10},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":114,"failed":34},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":11,"failed":9},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}] -0.3.0-alpha.0,19816,412,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":220,"failed":3},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":76,"failed":15},{"name":"call_indirect.wast","passed":159,"failed":11},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":48,"failed":13},{"name":"elem.wast","passed":76,"failed":23},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":7,"failed":1},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":32,"failed":4},{"name":"global.wast","passed":96,"failed":14},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":232,"failed":9},{"name":"imports.wast","passed":52,"failed":131},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":26,"failed":3},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":20,"failed":112},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":116,"failed":4},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":95,"failed":1},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":78,"failed":10},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":143,"failed":5},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":17,"failed":3},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}] +0.3.0-alpha.0,19691,537,[{"name":"address.wast","passed":223,"failed":37},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":220,"failed":3},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":76,"failed":15},{"name":"call_indirect.wast","passed":151,"failed":19},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":54,"failed":7},{"name":"elem.wast","passed":61,"failed":38},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":7,"failed":1},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":80,"failed":10},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":169,"failed":3},{"name":"func_ptrs.wast","passed":19,"failed":17},{"name":"global.wast","passed":106,"failed":4},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":232,"failed":9},{"name":"imports.wast","passed":65,"failed":118},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":26,"failed":3},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":18,"failed":114},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":116,"failed":4},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":89,"failed":7},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":78,"failed":10},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":143,"failed":5},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":14,"failed":6},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}] diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index ac7f854..4d3c59a 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -2,10 +2,7 @@ #![forbid(unsafe_code)] #![doc(test( no_crate_inject, - attr( - deny(warnings, rust_2018_idioms), - allow(dead_code, unused_assignments, unused_variables) - ) + attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_assignments, unused_variables)) ))] #![warn(missing_debug_implementations, rust_2018_idioms, unreachable_pub)] @@ -314,6 +311,26 @@ pub enum ExternVal { Global(GlobalAddr), } +impl ExternVal { + pub fn kind(&self) -> ExternalKind { + match self { + Self::Func(_) => ExternalKind::Func, + Self::Table(_) => ExternalKind::Table, + Self::Mem(_) => ExternalKind::Memory, + Self::Global(_) => ExternalKind::Global, + } + } + + pub fn new(kind: ExternalKind, addr: Addr) -> Self { + match kind { + ExternalKind::Func => Self::Func(addr), + ExternalKind::Table => Self::Table(addr), + ExternalKind::Memory => Self::Mem(addr), + ExternalKind::Global => Self::Global(addr), + } + } +} + /// The type of a WebAssembly Function. /// /// See <https://webassembly.github.io/spec/core/syntax/types.html#function-types> @@ -326,10 +343,7 @@ pub struct FuncType { impl FuncType { /// Get the number of parameters of a function type. pub fn empty() -> Self { - Self { - params: Box::new([]), - results: Box::new([]), - } + Self { params: Box::new([]), results: Box::new([]) } } } @@ -372,19 +386,11 @@ pub struct TableType { impl TableType { pub fn empty() -> Self { - Self { - element_type: ValType::FuncRef, - size_initial: 0, - size_max: None, - } + Self { element_type: ValType::FuncRef, size_initial: 0, size_max: None } } pub fn new(element_type: ValType, size_initial: u32, size_max: Option<u32>) -> Self { - Self { - element_type, - size_initial, - size_max, - } + Self { element_type, size_initial, size_max } } } @@ -400,11 +406,7 @@ pub struct MemoryType { impl MemoryType { pub fn new_32(page_count_initial: u64, page_count_max: Option<u64>) -> Self { - Self { - arch: MemoryArch::I32, - page_count_initial, - page_count_max, - } + Self { arch: MemoryArch::I32, page_count_initial, page_count_max } } // pub fn new_64(page_count_initial: u64, page_count_max: Option<u64>) -> Self { |
