summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/tinywasm/src/export.rs17
-rw-r--r--crates/tinywasm/src/imports.rs235
-rw-r--r--crates/tinywasm/src/instance.rs110
-rw-r--r--crates/tinywasm/src/lib.rs8
-rw-r--r--crates/tinywasm/src/runtime/executor/mod.rs14
-rw-r--r--crates/tinywasm/src/store.rs94
-rw-r--r--crates/tinywasm/tests/generated/mvp.csv2
-rw-r--r--crates/types/src/lib.rs48
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 {