summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/cli/bin.rs4
-rw-r--r--crates/parser/src/lib.rs2
-rw-r--r--crates/tinywasm/src/lib.rs5
-rw-r--r--crates/tinywasm/src/module/mod.rs69
-rw-r--r--crates/tinywasm/src/runtime/stack/mod.rs13
-rw-r--r--crates/tinywasm/src/store.rs9
-rw-r--r--crates/tinywasm/src/types.rs47
-rw-r--r--crates/types/src/lib.rs30
8 files changed, 91 insertions, 88 deletions
diff --git a/crates/cli/bin.rs b/crates/cli/bin.rs
index 015f34a..ce33544 100644
--- a/crates/cli/bin.rs
+++ b/crates/cli/bin.rs
@@ -82,9 +82,9 @@ fn run(wasm: &[u8]) -> Result<()> {
let mut store = tinywasm::Store::default();
let module = tinywasm::Module::parse_bytes(wasm)?;
- let instance = module.instantiate(&mut store)?;
+ let mut instance = module.instantiate(&mut store)?;
- let func = instance.get_func(&mut store, "add")?;
+ let mut func = instance.get_func(&mut store, "add")?;
let params = vec![WasmValue::I32(2), WasmValue::I32(2)];
let res = func.call(&mut store, params)?;
info!("{res:?}");
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index 6c49af0..0d12990 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -98,7 +98,7 @@ impl TryFrom<ModuleReader> for TinyWasmModule {
.into_iter()
.zip(func_types)
.map(|(f, ty)| Function {
- body: f.body,
+ instructions: f.body,
locals: f.locals,
ty,
})
diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs
index da24d19..eecf325 100644
--- a/crates/tinywasm/src/lib.rs
+++ b/crates/tinywasm/src/lib.rs
@@ -15,9 +15,8 @@ pub mod module;
pub use module::Module;
pub use module::ModuleInstance;
-pub mod types;
-pub use types::*;
-
+pub use tinywasm_parser as parser;
+pub use tinywasm_types::*;
pub mod runtime;
#[cfg(test)]
diff --git a/crates/tinywasm/src/module/mod.rs b/crates/tinywasm/src/module/mod.rs
index a692175..2a5141c 100644
--- a/crates/tinywasm/src/module/mod.rs
+++ b/crates/tinywasm/src/module/mod.rs
@@ -6,12 +6,13 @@ use alloc::{
vec::Vec,
};
use log::info;
-use tinywasm_types::{Export, ExternalKind, FuncAddr, FuncType, TinyWasmModule};
+use tinywasm_types::{
+ Export, ExternalKind, FuncAddr, FuncType, TinyWasmModule, ValType, WasmValue,
+};
use crate::{
- runtime::Runtime,
store::{self, StoreData},
- Error, Result, Store, WasmValue,
+ Error, Result, Store,
};
#[derive(Debug)]
@@ -55,7 +56,7 @@ impl Module {
store: &mut Store,
// imports: Option<()>,
) -> Result<ModuleInstance> {
- let i = ModuleInstance::new(store, self)?;
+ let mut i = ModuleInstance::new(store, self)?;
let _ = i.start(store)?;
Ok(i)
}
@@ -79,7 +80,7 @@ pub struct ModuleInstance {
impl ModuleInstance {
/// Get an exported function by name
- pub fn get_func(&self, store: &store::Store, name: &str) -> Result<FuncHandle> {
+ pub fn get_func(&mut self, store: &store::Store, name: &str) -> Result<FuncHandle> {
let export = self
.exports
.iter()
@@ -87,39 +88,39 @@ impl ModuleInstance {
.ok_or(Error::Other(format!("export {} not found", name)))?;
let func = store.get_func(export.index as usize)?;
- let ty = &self.types[func.ty as usize];
+ let ty = self.types[func.ty as usize].clone();
Ok(FuncHandle {
addr: export.index,
- module: &self,
+ module: self,
name: Some(name.to_string()),
- ty: ty.clone(),
+ ty,
})
}
/// Get the start function of the module
- pub fn get_start_func(&self, store: &store::Store) -> Result<Option<FuncHandle>> {
- let Some(func_addr) = self.func_start else {
+ pub fn get_start_func(&mut self, store: &store::Store) -> Result<Option<FuncHandle>> {
+ let Some(addr) = self.func_start else {
return Ok(None);
};
- let func = store.get_func(func_addr as usize)?;
- let ty = &self.types[func.ty as usize];
+ let func = store.get_func(addr as usize)?;
+ let ty = self.types[func.ty as usize].clone();
+
Ok(Some(FuncHandle {
- module: &self,
- addr: func_addr,
- ty: ty.clone(),
+ module: self,
+ addr,
+ ty,
name: None,
}))
}
- pub fn new(store: &mut Store, module: Module) -> Result<Self> {
+ pub fn new(store: &mut Store, mut module: Module) -> Result<Self> {
let store_data = StoreData {
funcs: module.data.funcs,
};
store.initialize(store_data)?;
-
Ok(Self {
types: module.data.types,
func_start: module.data.start_func,
@@ -135,8 +136,8 @@ impl ModuleInstance {
/// Invoke the start function of the module
/// Returns None if the module has no start function
/// https://webassembly.github.io/spec/core/syntax/modules.html#syntax-start
- pub fn start(&self, store: &mut store::Store) -> Result<Option<()>> {
- let Some(func) = self.get_start_func(store)? else {
+ pub fn start(&mut self, store: &mut store::Store) -> Result<Option<()>> {
+ let Some(mut func) = self.get_start_func(store)? else {
return Ok(None);
};
@@ -147,7 +148,7 @@ impl ModuleInstance {
#[derive(Debug)]
pub struct FuncHandle<'a> {
- module: &'a ModuleInstance,
+ module: &'a mut ModuleInstance,
addr: FuncAddr,
ty: FuncType,
pub name: Option<String>,
@@ -155,17 +156,35 @@ pub struct FuncHandle<'a> {
impl<'a> FuncHandle<'a> {
/// Call a function
- pub fn call(&self, store: &mut Store, params: Vec<WasmValue>) -> Result<Vec<WasmValue>> {
- let func = store.get_func(self.addr as usize)?;
+ pub fn call(&mut self, store: &mut Store, params: Vec<WasmValue>) -> Result<Vec<WasmValue>> {
+ let func = store
+ .data
+ .funcs
+ .get(self.addr as usize)
+ .ok_or(Error::Other(format!("function {} not found", self.addr)))?;
+
let func_ty = &self.ty;
- let mut runtime = Runtime::default();
+ // check that params match func_ty params
+ for (ty, param) in func_ty.params.iter().zip(params.clone()) {
+ if ty != &param.val_type() {
+ return Err(Error::Other(format!(
+ "param type mismatch: expected {:?}, got {:?}",
+ ty, param
+ )));
+ }
+ }
+
+ let mut local_types: Vec<ValType> = Vec::new();
+ local_types.extend(func_ty.params.iter());
+ local_types.extend(func.locals.iter());
+
+ let runtime = &mut store.runtime;
let stack = &mut runtime.stack;
let locals = &mut stack.locals;
locals.extend(params);
- let mut instrs = func.body.iter();
-
+ let mut instrs = func.instructions.iter();
while let Some(instr) = instrs.next() {
use tinywasm_types::Instruction::*;
match instr {
diff --git a/crates/tinywasm/src/runtime/stack/mod.rs b/crates/tinywasm/src/runtime/stack/mod.rs
index f7ffdf3..1149429 100644
--- a/crates/tinywasm/src/runtime/stack/mod.rs
+++ b/crates/tinywasm/src/runtime/stack/mod.rs
@@ -1,8 +1,8 @@
-use crate::WasmValue;
use alloc::vec::Vec;
mod call;
pub use call::CallFrame;
+use tinywasm_types::WasmValue;
// minimum stack size
pub const STACK_SIZE: usize = 1024;
@@ -20,10 +20,9 @@ pub struct Stack {
// TODO: Split into Vec<u8> and Vec<ValType> for better memory usage?
pub value_stack: Vec<WasmValue>, // keeping this typed for now to make it easier to debug
pub value_stack_top: usize,
-
- /// The call stack
- pub call_stack: Vec<CallFrame>,
- pub call_stack_top: usize,
+ // /// The call stack
+ // pub call_stack: Vec<CallFrame>,
+ // pub call_stack_top: usize,
}
impl Default for Stack {
@@ -32,8 +31,8 @@ impl Default for Stack {
locals: Vec::new(),
value_stack: Vec::with_capacity(STACK_SIZE),
value_stack_top: 0,
- call_stack: Vec::with_capacity(CALL_STACK_SIZE),
- call_stack_top: 0,
+ // call_stack: Vec::with_capacity(CALL_STACK_SIZE),
+ // call_stack_top: 0,
}
}
}
diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs
index 6fc5860..fc64bc4 100644
--- a/crates/tinywasm/src/store.rs
+++ b/crates/tinywasm/src/store.rs
@@ -1,15 +1,22 @@
use alloc::{boxed::Box, format};
use tinywasm_types::Function;
-use crate::{Error, Result};
+use crate::{runtime::Runtime, Error, Result};
/// global state that can be manipulated by WebAssembly programs
/// https://webassembly.github.io/spec/core/exec/runtime.html#store
#[derive(Debug, Default)]
pub struct Store {
pub(crate) data: StoreData,
+ pub(crate) runtime: Runtime,
}
+// #[derive(Debug)]
+// pub struct FunctionInstance {
+// pub(crate) func: Function,
+// pub(crate) module: usize,
+// }
+
#[derive(Debug, Default)]
pub struct StoreData {
pub funcs: Box<[Function]>,
diff --git a/crates/tinywasm/src/types.rs b/crates/tinywasm/src/types.rs
deleted file mode 100644
index 0ce721f..0000000
--- a/crates/tinywasm/src/types.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-/// A WebAssembly value.
-/// See https://webassembly.github.io/spec/core/syntax/types.html#value-types
-#[derive(Debug, Clone, PartialEq)]
-pub enum WasmValue {
- // Num types
- I32(i32),
- I64(i64),
- F32(f32),
- F64(f64),
-
- // Vec types
- V128(i128),
-}
-
-/// Type of a WebAssembly value.
-#[derive(Debug, Clone, PartialEq)]
-pub enum ValType {
- I32,
- I64,
- F32,
- F64,
- V128,
- FuncRef,
- ExternRef,
-}
-
-impl From<WasmValue> for ValType {
- fn from(wasm_value: WasmValue) -> Self {
- match wasm_value {
- WasmValue::I32(_) => ValType::I32,
- WasmValue::I64(_) => ValType::I64,
- WasmValue::F32(_) => ValType::F32,
- WasmValue::F64(_) => ValType::F64,
- WasmValue::V128(_) => ValType::V128,
- }
- }
-}
-
-impl WasmValue {
- pub fn type_of(&self) -> ValType {
- self.clone().into()
- }
-
- pub fn is(&self, ty: ValType) -> bool {
- self.type_of() == ty
- }
-}
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index 39ced78..9477dc7 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -1,6 +1,8 @@
extern crate alloc;
mod instructions;
+use core::fmt::Debug;
+
pub use instructions::*;
#[derive(Debug)]
@@ -21,7 +23,7 @@ pub struct TinyWasmModule {
/// A WebAssembly value.
/// See https://webassembly.github.io/spec/core/syntax/types.html#value-types
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Clone, PartialEq)]
pub enum WasmValue {
// Num types
I32(i32),
@@ -33,6 +35,30 @@ pub enum WasmValue {
V128(i128),
}
+impl Debug for WasmValue {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ WasmValue::I32(i) => write!(f, "i32({})", i),
+ WasmValue::I64(i) => write!(f, "i64({})", i),
+ WasmValue::F32(i) => write!(f, "f32({})", i),
+ WasmValue::F64(i) => write!(f, "f64({})", i),
+ WasmValue::V128(i) => write!(f, "v128({})", i),
+ }
+ }
+}
+
+impl WasmValue {
+ pub fn val_type(&self) -> ValType {
+ match self {
+ Self::I32(_) => ValType::I32,
+ Self::I64(_) => ValType::I64,
+ Self::F32(_) => ValType::F32,
+ Self::F64(_) => ValType::F64,
+ Self::V128(_) => ValType::V128,
+ }
+ }
+}
+
/// Type of a WebAssembly value.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValType {
@@ -102,7 +128,7 @@ pub struct FuncType {
pub struct Function {
pub ty: TypeAddr,
pub locals: Box<[ValType]>,
- pub body: Box<[Instruction]>,
+ pub instructions: Box<[Instruction]>,
}
/// A WebAssembly Module Export