summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock16
-rw-r--r--crates/tinywasm/src/export.rs17
-rw-r--r--crates/tinywasm/src/func.rs21
-rw-r--r--crates/tinywasm/src/imports.rs264
-rw-r--r--crates/tinywasm/src/instance.rs118
-rw-r--r--crates/tinywasm/src/lib.rs8
-rw-r--r--crates/tinywasm/src/runtime/executor/macros.rs7
-rw-r--r--crates/tinywasm/src/runtime/executor/mod.rs43
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs31
-rw-r--r--crates/tinywasm/src/store.rs306
-rw-r--r--crates/tinywasm/tests/generated/mvp.csv2
-rw-r--r--crates/tinywasm/tests/generated/progress-mvp.svg6
-rw-r--r--crates/tinywasm/tests/testsuite/run.rs9
-rw-r--r--crates/types/src/lib.rs52
-rw-r--r--rustfmt.toml1
15 files changed, 428 insertions, 473 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 67a12d6..32ebc37 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -855,9 +855,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.76"
+version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
@@ -919,9 +919,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.10.2"
+version = "1.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [
"aho-corasick",
"memchr",
@@ -931,9 +931,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.3"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a"
dependencies = [
"aho-corasick",
"memchr",
@@ -1272,9 +1272,9 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "uuid"
-version = "1.6.1"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
+checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
[[package]]
name = "version_check"
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/func.rs b/crates/tinywasm/src/func.rs
index 74043a9..8546b9f 100644
--- a/crates/tinywasm/src/func.rs
+++ b/crates/tinywasm/src/func.rs
@@ -52,7 +52,13 @@ impl FuncHandle {
}
}
- let wasm_func = &func_inst.assert_wasm()?;
+ let wasm_func = match &func_inst.func {
+ crate::Function::Host(h) => {
+ let func = h.func.clone();
+ return (func)(store, params);
+ }
+ crate::Function::Wasm(ref f) => f,
+ };
// 6. Let f be the dummy frame
debug!("locals: {:?}", wasm_func.locals);
@@ -76,11 +82,7 @@ impl FuncHandle {
let res = stack.values.last_n(result_m)?;
// The values are returned as the results of the invocation.
- Ok(res
- .iter()
- .zip(func_ty.results.iter())
- .map(|(v, ty)| v.attach_type(*ty))
- .collect())
+ Ok(res.iter().zip(func_ty.results.iter()).map(|(v, ty)| v.attach_type(*ty)).collect())
}
}
@@ -184,11 +186,8 @@ macro_rules! impl_from_wasm_value_tuple_single {
fn from_wasm_value_tuple(values: Vec<WasmValue>) -> Result<Self> {
#[allow(unused_variables, unused_mut)]
let mut iter = values.into_iter();
- Ok($T::try_from(
- iter.next()
- .ok_or(Error::Other("Not enough values in WasmValue vector".to_string()))?,
- )
- .map_err(|_| Error::Other("Could not convert WasmValue to expected type".to_string()))?)
+ $T::try_from(iter.next().ok_or(Error::Other("Not enough values in WasmValue vector".to_string()))?)
+ .map_err(|_| Error::Other("Could not convert WasmValue to expected type".to_string()))
}
}
};
diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs
index 41dd1a2..ff9d061 100644
--- a/crates/tinywasm/src/imports.rs
+++ b/crates/tinywasm/src/imports.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)]
+
use core::fmt::Debug;
use crate::{
@@ -10,32 +12,45 @@ use alloc::{
sync::Arc,
vec::Vec,
};
-use tinywasm_types::{
- ExternVal, ExternalKind, GlobalType, MemoryType, ModuleInstanceAddr, TableType, WasmFunction, WasmValue,
-};
+use tinywasm_types::*;
-#[derive(Debug)]
-pub(crate) enum Function {
+/// The internal representation of a function
+#[derive(Debug, Clone)]
+pub enum Function {
+ /// A host function
Host(HostFunction),
+
+ /// A function defined in WebAssembly
Wasm(WasmFunction),
}
+impl Function {
+ /// Get the function's type
+ pub fn ty(&self, module: &crate::ModuleInstance) -> tinywasm_types::FuncType {
+ match self {
+ Self::Host(f) => f.ty.clone(),
+ Self::Wasm(f) => module.func_ty(f.ty_addr).clone(),
+ }
+ }
+}
+
/// 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>,
+ pub(crate) func: HostFuncInner,
}
+pub(crate) type HostFuncInner =
+ Arc<dyn Fn(&mut crate::Store, &[WasmValue]) -> Result<Vec<WasmValue>> + 'static + Send + Sync>;
+
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 {
@@ -49,31 +64,29 @@ pub enum Extern {
Memory(ExternMemory),
/// A function
- Func(HostFunction),
+ Func(Function),
}
/// A function
-#[derive(Debug)]
-pub struct ExternFunc {
- pub(crate) inner: HostFunction,
-}
+#[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,
}
@@ -81,13 +94,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
@@ -110,10 +117,7 @@ impl Extern {
func(store, &args)
};
- Self::Func(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
@@ -128,15 +132,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(HostFunction {
- func: Arc::new(inner_func),
- ty: ty.clone(),
- })
+ Self::Func(Function::Host(HostFunction { func: Arc::new(inner_func), ty }))
}
pub(crate) fn kind(&self) -> ExternalKind {
@@ -156,6 +154,12 @@ pub struct ExternName {
name: String,
}
+impl From<&Import> for ExternName {
+ fn from(import: &Import) -> Self {
+ Self { module: import.module.to_string(), name: import.name.to_string() }
+ }
+}
+
#[derive(Debug, Default)]
/// Imports for a module instance
pub struct Imports {
@@ -163,30 +167,31 @@ pub struct Imports {
modules: BTreeMap<String, ModuleInstanceAddr>,
}
-pub(crate) struct LinkedImports {
- // externs that were defined and need to be instantiated
- pub(crate) externs: BTreeMap<ExternName, Extern>,
+pub(crate) enum ResolvedExtern<S, V> {
+ // already in the store
+ Store(S),
- // externs that were linked to other modules and already exist in the store
- pub(crate) linked_externs: BTreeMap<ExternName, ExternVal>,
+ // needs to be added to the store, provided value
+ Extern(V),
}
-impl LinkedImports {
- pub(crate) fn get(&self, module: &str, name: &str) -> Option<&Extern> {
- self.externs.get(&ExternName {
- module: module.to_string(),
- name: name.to_string(),
- })
+pub(crate) struct ResolvedImports {
+ 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() }
}
}
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
@@ -199,87 +204,106 @@ 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 link(self, store: &mut crate::Store, module: &crate::Module) -> Result<LinkedImports> {
- let mut links = BTreeMap::new();
-
- for import in module.data.imports.iter() {
- if let Some(i) = self.values.get(&ExternName {
- module: import.module.to_string(),
- name: import.name.to_string(),
- }) {
- if i.kind() != (&import.kind).into() {
- return Err(crate::Error::InvalidImportType {
- module: import.module.to_string(),
- name: import.name.to_string(),
- });
- }
+ pub(crate) fn take(
+ &mut self,
+ _store: &mut crate::Store,
+ import: &Import,
+ ) -> Option<ResolvedExtern<ExternVal, Extern>> {
+ let name = ExternName::from(import);
+ 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();
- continue;
- }
+ // let export = exports.get_untyped(&import.name)?;
+ // let addr = match export.kind {
+ // ExternalKind::Global(g) => ExternVal::Global(),
+ // };
- let module_addr =
- self.modules
- .get(&import.module.to_string())
- .ok_or_else(|| crate::Error::MissingImport {
- module: import.module.to_string(),
- name: import.name.to_string(),
- })?;
+ // return Some(ResolvedExtern::Store());
+ // }
- let module =
- store
- .get_module_instance(*module_addr)
- .ok_or_else(|| crate::Error::CouldNotResolveImport {
- module: import.module.to_string(),
- name: import.name.to_string(),
- })?;
+ None
+ }
- let export =
- module
- .exports()
- .get_untyped(&import.name)
- .ok_or_else(|| crate::Error::CouldNotResolveImport {
- module: import.module.to_string(),
- name: import.name.to_string(),
- })?;
+ pub(crate) fn link(
+ mut self,
+ store: &mut crate::Store,
+ module: &crate::Module,
+ idx: ModuleInstanceAddr,
+ ) -> Result<ResolvedImports> {
+ let mut imports = ResolvedImports::new();
- // validate import
- if export.kind != (&import.kind).into() {
- return Err(crate::Error::InvalidImportType {
+ for import in module.data.imports.iter() {
+ let Some(val) = self.take(store, import) else {
+ return Err(crate::Error::MissingImport {
module: import.module.to_string(),
name: import.name.to_string(),
});
- }
-
- 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),
};
- links.insert(
- ExternName {
- module: import.module.to_string(),
- name: import.name.to_string(),
- },
- val,
- );
+ 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
+
+ // 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),
+ }
+ }
+
+ // 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),
+ }
+ }
+ }
}
- // TODO: link to other modules (currently only direct imports are supported)
- Ok(LinkedImports {
- externs: self.values,
- linked_externs: links,
- })
+ Ok(imports)
}
}
diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs
index ad1b53c..fb5f5b3 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,37 +53,40 @@ impl ModuleInstance {
let idx = store.next_module_instance_idx();
let imports = imports.unwrap_or_default();
- // TODO: doesn't link other modules yet
- let linked_imports = imports.link(store, &module)?;
- let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &linked_imports, 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)?);
- let table_addrs = store.add_tables(module.data.table_types.into(), idx);
- let mem_addrs = store.add_mems(module.data.memory_types.into(), idx)?;
+ log::info!("init_mems: {:?}", addrs.mems);
+ addrs.mems.extend(store.init_mems(data.memory_types.into(), idx)?);
+ log::info!("init_mems2: {:?}", addrs.mems);
+ log::info!("init_mems g: {:?}", store.data.mems.len());
- // TODO: active/declared elems need to be initialized
- let elem_addrs = store.add_elems(module.data.elements.into(), idx)?;
+ let elem_addrs = store.init_elems(&addrs.tables, data.elements.into(), idx)?;
+ log::info!("init_elems: {:?}", addrs.mems);
- // TODO: active data segments need to be initialized
- let data_addrs = store.add_datas(module.data.data.into(), idx)?;
+ let data_addrs = store.init_datas(&addrs.mems, data.data.into(), idx)?;
+ log::info!("init_datas: {:?}", addrs.mems);
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);
@@ -92,8 +96,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] {
@@ -113,26 +126,22 @@ impl ModuleInstance {
}
pub(crate) fn func_ty(&self, addr: FuncAddr) -> &FuncType {
- &self.0.types[addr as usize]
+ self.0.types.get(addr as usize).expect("No func type for func, this is a bug")
}
// resolve a function address to the global store address
pub(crate) fn resolve_func_addr(&self, addr: FuncAddr) -> FuncAddr {
- self.0.func_addrs[addr as usize]
+ *self.0.func_addrs.get(addr as usize).expect("No func addr for func, this is a bug")
}
// resolve a table address to the global store address
pub(crate) fn resolve_table_addr(&self, addr: TableAddr) -> TableAddr {
- self.0.table_addrs[addr as usize]
- }
-
- pub(crate) fn resolve_elem_addr(&self, addr: ElemAddr) -> ElemAddr {
- self.0.elem_addrs[addr as usize]
+ *self.0.table_addrs.get(addr as usize).expect("No table addr for table, this is a bug")
}
// resolve a memory address to the global store address
pub(crate) fn resolve_mem_addr(&self, addr: MemAddr) -> MemAddr {
- self.0.mem_addrs[addr as usize]
+ *self.0.mem_addrs.get(addr as usize).expect("No mem addr for mem, this is a bug")
}
// resolve a global address to the global store address
@@ -146,23 +155,15 @@ 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 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_addr = self.0.func_addrs[export.index 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 = func_inst.func.ty(self);
- 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: ty.clone() })
}
/// Get a typed exported function by name
@@ -172,10 +173,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
@@ -194,30 +192,20 @@ 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();
+ let ty = func_inst.func.ty(self);
- 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/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs
index c1bb50f..5b20851 100644
--- a/crates/tinywasm/src/runtime/executor/macros.rs
+++ b/crates/tinywasm/src/runtime/executor/macros.rs
@@ -63,8 +63,7 @@ macro_rules! mem_store {
let val = val as $store_type;
let val = val.to_le_bytes();
- mem.borrow_mut()
- .store(($arg.offset + addr) as usize, $arg.align as usize, &val)?;
+ mem.borrow_mut().store(($arg.offset + addr) as usize, $arg.align as usize, &val)?;
}};
}
@@ -225,9 +224,7 @@ macro_rules! checked_int_arithmetic {
return Err(Error::Trap(crate::Trap::DivisionByZero));
}
- let result = a_casted
- .$op(b_casted)
- .ok_or_else(|| Error::Trap(crate::Trap::IntegerOverflow))?;
+ let result = a_casted.$op(b_casted).ok_or_else(|| Error::Trap(crate::Trap::IntegerOverflow))?;
// Cast back to original type if different
$stack.values.push((result as $from).into());
diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs
index 5e191cc..1072577 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());
@@ -26,7 +25,7 @@ impl DefaultRuntime {
// The function to execute, gets updated from ExecResult::Call
let mut func_inst = store.get_func(cf.func_ptr)?.clone();
- let mut wasm_func = func_inst.assert_wasm()?;
+ let mut wasm_func = func_inst.assert_wasm().expect("exec expected wasm function");
let mut instrs = &wasm_func.instructions;
// TODO: we might be able to index into the instructions directly
@@ -37,7 +36,7 @@ impl DefaultRuntime {
ExecResult::Call => {
cf = stack.call_stack.pop()?;
func_inst = store.get_func(cf.func_ptr)?.clone();
- wasm_func = func_inst.assert_wasm()?;
+ wasm_func = func_inst.assert_wasm().expect("call expected wasm function");
instrs = &wasm_func.instructions;
continue;
}
@@ -129,14 +128,24 @@ fn exec_one(
// prepare the call frame
let func_idx = module.resolve_func_addr(*v);
let func_inst = store.get_func(func_idx as usize)?;
- let func = func_inst.assert_wasm()?;
+ let func = match &func_inst.func {
+ crate::Function::Wasm(ref f) => f,
+ crate::Function::Host(host_func) => {
+ let func = host_func.func.clone();
+ let params = stack.values.pop_params(&host_func.ty.params)?;
+ let res = (func)(store, &params)?;
+ stack.values.extend_from_typed(&res);
+ return Ok(ExecResult::Ok);
+ }
+ };
+
let func_ty = module.func_ty(func.ty_addr);
debug!("params: {:?}", func_ty.params);
debug!("stack: {:?}", stack.values);
let params = stack.values.pop_n(func_ty.params.len())?;
- let call_frame = CallFrame::new_raw(*v as usize, &params, func.locals.to_vec());
+ let call_frame = CallFrame::new_raw(func_idx as usize, &params, func.locals.to_vec());
// push the call frame
cf.instr_ptr += 1; // skip the call instruction
@@ -158,15 +167,22 @@ fn exec_one(
// prepare the call frame
let func_inst = store.get_func(func_addr as usize)?;
- let func = func_inst.assert_wasm()?;
+ let func = match &func_inst.func {
+ crate::Function::Wasm(ref f) => f,
+ crate::Function::Host(host_func) => {
+ let func = host_func.func.clone();
+ let params = stack.values.pop_params(&host_func.ty.params)?;
+ let res = (func)(store, &params)?;
+ stack.values.extend_from_typed(&res);
+ return Ok(ExecResult::Ok);
+ }
+ };
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 +585,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/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs
index 10054bc..1021289 100644
--- a/crates/tinywasm/src/runtime/stack/value_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/value_stack.rs
@@ -2,6 +2,7 @@ use core::ops::Range;
use crate::{runtime::RawWasmValue, Error, Result};
use alloc::vec::Vec;
+use tinywasm_types::{ValType, WasmValue};
// minimum stack size
pub(crate) const STACK_SIZE: usize = 1024;
@@ -16,10 +17,7 @@ pub(crate) struct ValueStack {
impl Default for ValueStack {
fn default() -> Self {
- Self {
- stack: Vec::with_capacity(STACK_SIZE),
- top: 0,
- }
+ Self { stack: Vec::with_capacity(STACK_SIZE), top: 0 }
}
}
@@ -31,6 +29,12 @@ impl ValueStack {
}
#[inline]
+ pub(crate) fn extend_from_typed(&mut self, values: &[WasmValue]) {
+ self.top += values.len();
+ self.stack.extend(values.iter().map(|v| RawWasmValue::from(*v)));
+ }
+
+ #[inline]
pub(crate) fn len(&self) -> usize {
assert!(self.top <= self.stack.len());
self.top
@@ -38,10 +42,7 @@ impl ValueStack {
pub(crate) fn truncate_keep(&mut self, n: usize, end_keep: usize) {
let total_to_keep = n + end_keep;
- assert!(
- self.top >= total_to_keep,
- "Total to keep should be less than or equal to self.top"
- );
+ assert!(self.top >= total_to_keep, "Total to keep should be less than or equal to self.top");
let current_size = self.stack.len();
if current_size <= total_to_keep {
@@ -79,9 +80,19 @@ impl ValueStack {
self.stack.pop().ok_or(Error::StackUnderflow)
}
+ #[inline]
+ pub(crate) fn pop_params(&mut self, types: &[ValType]) -> Result<Vec<WasmValue>> {
+ let n = types.len();
+ if self.top < n {
+ return Err(Error::StackUnderflow);
+ }
+ self.top -= n;
+ let res = self.stack.drain(self.top..).rev().map(|v| v.attach_type(types[n - 1])).collect();
+ Ok(res)
+ }
+
pub(crate) fn break_to(&mut self, new_stack_size: usize, result_count: usize) {
- self.stack
- .copy_within((self.top - result_count)..self.top, new_stack_size);
+ self.stack.copy_within((self.top - result_count)..self.top, new_stack_size);
self.top = new_stack_size + result_count;
self.stack.truncate(self.top);
}
diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs
index 6293cca..e9908d2 100644
--- a/crates/tinywasm/src/store.rs
+++ b/crates/tinywasm/src/store.rs
@@ -1,19 +1,14 @@
-#![allow(dead_code)] // TODO: remove this
-
use core::{
cell::RefCell,
sync::atomic::{AtomicUsize, Ordering},
};
use alloc::{format, rc::Rc, string::ToString, vec, vec::Vec};
-use tinywasm_types::{
- Addr, Data, Element, ElementKind, FuncAddr, Global, GlobalType, Import, Instruction, MemAddr, MemoryArch,
- MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, WasmFunction,
-};
+use tinywasm_types::*;
use crate::{
runtime::{self, DefaultRuntime},
- Error, Extern, Function, LinkedImports, ModuleInstance, RawWasmValue, Result, Trap,
+ Error, Function, ModuleInstance, RawWasmValue, Result, Trap,
};
// global store id counter
@@ -49,7 +44,7 @@ impl Store {
Self::default()
}
- pub(crate) fn get_module_instance(&self, addr: ModuleInstanceAddr) -> Option<&ModuleInstance> {
+ pub(crate) fn _get_module_instance(&self, addr: ModuleInstanceAddr) -> Option<&ModuleInstance> {
self.module_instances.get(addr as usize)
}
@@ -106,52 +101,45 @@ impl Store {
self.module_instance_count as ModuleInstanceAddr
}
- /// Initialize the store with global state from the given module
pub(crate) fn add_instance(&mut self, instance: ModuleInstance) -> Result<()> {
+ assert!(instance.id() == self.module_instance_count as ModuleInstanceAddr);
self.module_instances.push(instance);
self.module_instance_count += 1;
Ok(())
}
/// Add functions to the store, returning their addresses in the store
- pub(crate) fn add_funcs(&mut self, funcs: Vec<WasmFunction>, idx: ModuleInstanceAddr) -> 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 (i, func) in funcs.into_iter().enumerate() {
- self.data.funcs.push(Rc::new(FunctionInstance {
- func: Function::Wasm(func),
- owner: idx,
- }));
+ self.data.funcs.push(Rc::new(FunctionInstance { func: Function::Wasm(func), _owner: idx }));
func_addrs.push((i + func_count) as FuncAddr);
}
- func_addrs
+ Ok(func_addrs)
}
/// Add tables to the store, returning their addresses in the store
- pub(crate) fn add_tables(&mut self, tables: Vec<TableType>, idx: ModuleInstanceAddr) -> 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() {
- self.data
- .tables
- .push(Rc::new(RefCell::new(TableInstance::new(table, idx))));
-
+ self.data.tables.push(Rc::new(RefCell::new(TableInstance::new(table, idx))));
table_addrs.push((i + table_count) as TableAddr);
}
- table_addrs
+ Ok(table_addrs)
}
/// 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() {
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))));
+ log::info!("adding memory: {:?}", mem);
+ self.data.mems.push(Rc::new(RefCell::new(MemoryInstance::new(mem, idx))));
mem_addrs.push((i + mem_count) as MemAddr);
}
@@ -159,53 +147,9 @@ impl Store {
}
/// Add globals to the store, returning their addresses in the store
- pub(crate) fn add_globals(
- &mut self,
- globals: Vec<Global>,
- wasm_imports: &[Import],
- user_imports: &LinkedImports,
- idx: ModuleInstanceAddr,
- ) -> Result<Vec<Addr>> {
- // TODO: initialize imported globals
- #![allow(clippy::unnecessary_filter_map)] // this is cleaner
- let imported_globals = wasm_imports
- .iter()
- .filter_map(|import| match &import.kind {
- tinywasm_types::ImportKind::Global(_) => Some(import),
- _ => None,
- })
- .map(|import| {
- let Some(global) = user_imports.get(&import.module, &import.name) else {
- return Err(Error::Other(format!(
- "global import not found for {}::{}",
- import.module, import.name
- )));
- };
- match global {
- Extern::Global(global) => Ok(global),
- _ => Err(Error::Other(format!(
- "expected global import for {}::{}",
- import.module, import.name
- ))),
- }
- })
- .collect::<Result<Vec<_>>>()?;
-
+ 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);
- log::debug!("globals: {:?}", globals);
-
- // first add the imported globals
- for (i, global) in imported_globals.iter().enumerate() {
- self.data.globals.push(Rc::new(RefCell::new(GlobalInstance::new(
- global.ty,
- global.val.into(),
- idx,
- ))));
- global_addrs.push((i + global_count) as Addr);
- }
-
- // then add the module globals
for (i, global) in globals.iter().enumerate() {
self.data.globals.push(Rc::new(RefCell::new(GlobalInstance::new(
global.ty,
@@ -218,43 +162,14 @@ impl Store {
Ok(global_addrs)
}
- pub(crate) fn eval_i32_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<i32> {
- use tinywasm_types::ConstInstruction::*;
- let val = match const_instr {
- I32Const(i) => *i,
- GlobalGet(addr) => {
- let addr = *addr as usize;
- let global = self.data.globals[addr].clone();
- let val = global.borrow().value;
- i32::from(val)
- }
- _ => return Err(Error::Other("expected i32".to_string())),
- };
- Ok(val)
- }
-
- pub(crate) fn eval_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<RawWasmValue> {
- use tinywasm_types::ConstInstruction::*;
- let val = match const_instr {
- F32Const(f) => RawWasmValue::from(*f),
- F64Const(f) => RawWasmValue::from(*f),
- I32Const(i) => RawWasmValue::from(*i),
- I64Const(i) => RawWasmValue::from(*i),
- GlobalGet(addr) => {
- let addr = *addr as usize;
- let global = self.data.globals[addr].clone();
- let val = global.borrow().value;
- val
- }
- RefNull(v) => v.default_value().into(),
- RefFunc(idx) => RawWasmValue::from(*idx as i64),
- };
- Ok(val)
- }
-
/// Add elements to the store, returning their addresses in the store
/// Should be called after the tables have been added
- pub(crate) fn add_elems(&mut self, elems: Vec<Element>, idx: ModuleInstanceAddr) -> Result<Vec<Addr>> {
+ pub(crate) fn init_elems(
+ &mut self,
+ table_addrs: &[TableAddr],
+ elems: Vec<Element>,
+ idx: ModuleInstanceAddr,
+ ) -> Result<Vec<Addr>> {
let elem_count = self.data.elems.len();
let mut elem_addrs = Vec::with_capacity(elem_count);
for (i, elem) in elems.into_iter().enumerate() {
@@ -281,13 +196,17 @@ impl Store {
// this one is active, so we need to initialize it (essentially a `table.init` instruction)
ElementKind::Active { offset, table } => {
let offset = self.eval_i32_const(&offset)?;
+ let table_addr = table_addrs
+ .get(table as usize)
+ .copied()
+ .ok_or_else(|| Error::Other(format!("table {} not found for element {}", table, i)))?;
// a. Let n be the length of the vector elem[i].init
// b. Execute the instruction sequence einstrs
// c. Execute the instruction i32.const 0
// d. Execute the instruction i32.const n
// e. Execute the instruction table.init tableidx i
- if let Some(table) = self.data.tables.get_mut(table as usize) {
+ if let Some(table) = self.data.tables.get_mut(table_addr as usize) {
table.borrow_mut().init(offset, &init)?;
} else {
log::error!("table {} not found", table);
@@ -306,7 +225,12 @@ impl Store {
}
/// Add data to the store, returning their addresses in the store
- pub(crate) fn add_datas(&mut self, datas: Vec<Data>, idx: ModuleInstanceAddr) -> Result<Vec<Addr>> {
+ pub(crate) fn init_datas(
+ &mut self,
+ mem_addrs: &[MemAddr],
+ datas: Vec<Data>,
+ idx: ModuleInstanceAddr,
+ ) -> Result<Vec<Addr>> {
let data_count = self.data.datas.len();
let mut data_addrs = Vec::with_capacity(data_count);
for (i, data) in datas.into_iter().enumerate() {
@@ -315,11 +239,14 @@ 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 mem_addr = mem_addrs
+ .get(mem_addr as usize)
+ .copied()
+ .ok_or_else(|| Error::Other(format!("memory {} not found for data segment {}", mem_addr, i)))?;
+
let offset = self.eval_i32_const(&offset)?;
let mem =
@@ -329,7 +256,7 @@ impl Store {
mem.borrow_mut().store(offset as usize, 0, &data.data)?;
- // drop the date
+ // drop the data
continue;
}
Passive => {}
@@ -341,35 +268,78 @@ impl Store {
Ok(data_addrs)
}
+ 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))));
+ 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))));
+ Ok(self.data.tables.len() as TableAddr - 1)
+ }
+
+ pub(crate) fn add_mem(&mut self, mem: MemoryType, idx: ModuleInstanceAddr) -> Result<MemAddr> {
+ 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))));
+ Ok(self.data.mems.len() as MemAddr - 1)
+ }
+
+ pub(crate) fn add_func(&mut self, func: Function, idx: ModuleInstanceAddr) -> Result<FuncAddr> {
+ self.data.funcs.push(Rc::new(FunctionInstance { func, _owner: idx }));
+ 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 {
+ I32Const(i) => *i,
+ GlobalGet(addr) => {
+ let addr = *addr as usize;
+ let global = self.data.globals[addr].clone();
+ let val = global.borrow().value;
+ i32::from(val)
+ }
+ _ => return Err(Error::Other("expected i32".to_string())),
+ };
+ 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 {
+ F32Const(f) => RawWasmValue::from(*f),
+ F64Const(f) => RawWasmValue::from(*f),
+ I32Const(i) => RawWasmValue::from(*i),
+ I64Const(i) => RawWasmValue::from(*i),
+ GlobalGet(addr) => {
+ let addr = *addr as usize;
+ let global = self.data.globals[addr].clone();
+ let val = global.borrow().value;
+ val
+ }
+ RefNull(v) => v.default_value().into(),
+ RefFunc(idx) => RawWasmValue::from(*idx as i64),
+ };
+ Ok(val)
+ }
+
/// 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)))
- }
-
- 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.tables.get(addr).ok_or_else(|| Error::Other(format!("table {} not found", addr)))
}
/// Get the global at the actual index in the store
@@ -396,7 +366,7 @@ impl Store {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
pub struct FunctionInstance {
pub(crate) func: Function,
- pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances, none for host functions
+ pub(crate) _owner: ModuleInstanceAddr, // index into store.module_instances, none for host functions
}
// TODO: check if this actually helps
@@ -421,25 +391,18 @@ impl FunctionInstance {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
#[derive(Debug)]
pub(crate) struct TableInstance {
- pub(crate) kind: TableType,
pub(crate) elements: Vec<Addr>,
- pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances
+ pub(crate) _kind: TableType,
+ pub(crate) _owner: ModuleInstanceAddr, // index into store.module_instances
}
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: kind, _owner: 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<()> {
@@ -457,20 +420,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);
@@ -490,7 +444,7 @@ pub(crate) struct MemoryInstance {
pub(crate) kind: MemoryType,
pub(crate) data: Vec<u8>,
pub(crate) page_count: usize,
- pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances
+ pub(crate) _owner: ModuleInstanceAddr, // index into store.module_instances
}
impl MemoryInstance {
@@ -502,17 +456,13 @@ impl MemoryInstance {
kind,
data: vec![0; PAGE_SIZE * kind.page_count_initial as usize],
page_count: kind.page_count_initial as usize,
- owner,
+ _owner: owner,
}
}
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 {
@@ -533,20 +483,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
@@ -590,14 +532,14 @@ impl MemoryInstance {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
#[derive(Debug)]
pub(crate) struct GlobalInstance {
- pub(crate) ty: GlobalType,
pub(crate) value: RawWasmValue,
- owner: ModuleInstanceAddr, // index into store.module_instances
+ pub(crate) _ty: GlobalType,
+ pub(crate) _owner: ModuleInstanceAddr, // index into store.module_instances
}
impl GlobalInstance {
pub(crate) fn new(ty: GlobalType, value: RawWasmValue, owner: ModuleInstanceAddr) -> Self {
- Self { ty, value, owner }
+ Self { _ty: ty, value, _owner: owner }
}
}
@@ -606,14 +548,14 @@ impl GlobalInstance {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#element-instances>
#[derive(Debug)]
pub(crate) struct ElemInstance {
- kind: ElementKind,
- items: Option<Vec<u32>>, // none is the element was dropped
- owner: ModuleInstanceAddr, // index into store.module_instances
+ _kind: ElementKind,
+ _items: Option<Vec<u32>>, // none is the element was dropped
+ _owner: ModuleInstanceAddr, // index into store.module_instances
}
impl ElemInstance {
pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr, items: Option<Vec<u32>>) -> Self {
- Self { kind, owner, items }
+ Self { _kind: kind, _owner: owner, _items: items }
}
}
@@ -622,12 +564,12 @@ impl ElemInstance {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#data-instances>
#[derive(Debug)]
pub(crate) struct DataInstance {
- pub(crate) data: Vec<u8>,
- owner: ModuleInstanceAddr, // index into store.module_instances
+ pub(crate) _data: Vec<u8>,
+ pub(crate) _owner: ModuleInstanceAddr, // index into store.module_instances
}
impl DataInstance {
pub(crate) fn new(data: Vec<u8>, owner: ModuleInstanceAddr) -> Self {
- Self { data, owner }
+ Self { _data: data, _owner: owner }
}
}
diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv
index 7749a65..824bf55 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,19806,422,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":88,"failed":3},{"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":31,"failed":5},{"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":50,"failed":133},{"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":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":484,"failed":2},{"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":57,"failed":1},{"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,19831,397,[{"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":155,"failed":15},{"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":61,"failed":0},{"name":"elem.wast","passed":69,"failed":30},{"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":170,"failed":2},{"name":"func_ptrs.wast","passed":20,"failed":16},{"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":70,"failed":113},{"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":79,"failed":0},{"name":"memory_grow.wast","passed":92,"failed":4},{"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":486,"failed":0},{"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":20,"failed":0},{"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/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg
index 5e3f57b..1f8316a 100644
--- a/crates/tinywasm/tests/generated/progress-mvp.svg
+++ b/crates/tinywasm/tests/generated/progress-mvp.svg
@@ -53,12 +53,12 @@ v0.2.0 (19344)
</text>
<polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="716,345 716,350 "/>
<text x="898" y="355" dy="0.76em" text-anchor="middle" font-family="Victor Mono" font-size="12.096774193548388" opacity="1" fill="#000000">
-v0.3.0-alpha.0 (19775)
+v0.3.0-alpha.0 (19831)
</text>
<polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="898,345 898,350 "/>
<rect x="266" y="185" width="172" height="159" opacity="0.5" fill="#0000FF" stroke="none"/>
-<rect x="630" y="67" width="172" height="277" opacity="0.5" fill="#0000FF" stroke="none"/>
+<rect x="812" y="60" width="172" height="284" opacity="0.5" fill="#0000FF" stroke="none"/>
<rect x="85" y="212" width="171" height="132" opacity="0.5" fill="#0000FF" stroke="none"/>
-<rect x="812" y="61" width="172" height="283" opacity="0.5" fill="#0000FF" stroke="none"/>
+<rect x="630" y="67" width="172" height="277" opacity="0.5" fill="#0000FF" stroke="none"/>
<rect x="448" y="92" width="172" height="252" opacity="0.5" fill="#0000FF" stroke="none"/>
</svg>
diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs
index 5dd42ee..d2eab6c 100644
--- a/crates/tinywasm/tests/testsuite/run.rs
+++ b/crates/tinywasm/tests/testsuite/run.rs
@@ -57,8 +57,8 @@ impl TestSuite {
Ok(())
});
- let print_i64_f64 = Extern::typed_func(|_: &mut tinywasm::Store, args: (i64, f64)| {
- log::debug!("print_i64_f64: {}, {}", args.0, args.1);
+ let print_f64_f64 = Extern::typed_func(|_: &mut tinywasm::Store, args: (f64, f64)| {
+ log::debug!("print_f64_f64: {}, {}", args.0, args.1);
Ok(())
});
@@ -75,9 +75,10 @@ impl TestSuite {
.define("spectest", "print_f32", print_f32)?
.define("spectest", "print_f64", print_f64)?
.define("spectest", "print_i32_f32", print_i32_f32)?
- .define("spectest", "print_i64_f64", print_i64_f64)?;
+ .define("spectest", "print_f64_f64", print_f64_f64)?;
for (name, addr) in registered_modules {
+ log::debug!("registering module: {}", name);
imports.link_module(&name, addr)?;
}
@@ -137,7 +138,7 @@ impl TestSuite {
Wat(mut module) => {
// TODO: modules are not properly isolated from each other - tests fail because of this otherwise
- store = tinywasm::Store::default();
+ // store = tinywasm::Store::default();
debug!("got wat module");
let result = catch_unwind_silent(|| {
let m = parse_module_bytes(&module.encode().expect("failed to encode module"))
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index 069f134..965c97e 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)]
@@ -28,7 +25,7 @@ extern crate alloc;
mod instructions;
use core::{fmt::Debug, ops::Range};
-use alloc::{boxed::Box, sync::Arc, vec::Vec};
+use alloc::boxed::Box;
pub use instructions::*;
/// A TinyWasm WebAssembly Module
@@ -306,7 +303,7 @@ pub type ModuleInstanceAddr = Addr;
/// A WebAssembly External Value.
///
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#external-values>
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum ExternVal {
Func(FuncAddr),
Table(TableAddr),
@@ -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 {
diff --git a/rustfmt.toml b/rustfmt.toml
index 94ac875..589b2d2 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1 +1,2 @@
max_width=120
+use_small_heuristics="Max"