diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/cli/bin.rs | 49 | ||||
| -rw-r--r-- | crates/tinywasm/src/engine/executer.rs | 1 | ||||
| -rw-r--r-- | crates/tinywasm/src/engine/mod.rs | 20 | ||||
| -rw-r--r-- | crates/tinywasm/src/engine/stack/call.rs (renamed from crates/tinywasm/src/runtime/stack/call.rs) | 1 | ||||
| -rw-r--r-- | crates/tinywasm/src/engine/stack/mod.rs (renamed from crates/tinywasm/src/runtime/stack/mod.rs) | 16 | ||||
| -rw-r--r-- | crates/tinywasm/src/engine/types.rs (renamed from crates/tinywasm/src/runtime/types.rs) | 36 | ||||
| -rw-r--r-- | crates/tinywasm/src/instance.rs | 0 | ||||
| -rw-r--r-- | crates/tinywasm/src/instructions.rs | 106 | ||||
| -rw-r--r-- | crates/tinywasm/src/lib.rs | 32 | ||||
| -rw-r--r-- | crates/tinywasm/src/module/mod.rs | 111 | ||||
| -rw-r--r-- | crates/tinywasm/src/module/reader.rs | 2 | ||||
| -rw-r--r-- | crates/tinywasm/src/naive/mod.rs (renamed from crates/tinywasm/src/naive_runtime.rs) | 5 | ||||
| -rw-r--r-- | crates/tinywasm/src/naive/module.rs | 92 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/mod.rs | 6 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/store.rs | 14 | ||||
| -rw-r--r-- | crates/tinywasm/src/store.rs | 51 |
16 files changed, 318 insertions, 224 deletions
diff --git a/crates/cli/bin.rs b/crates/cli/bin.rs index 6875eac..18b61cc 100644 --- a/crates/cli/bin.rs +++ b/crates/cli/bin.rs @@ -1,6 +1,8 @@ +use std::str::FromStr; + use argh::FromArgs; use color_eyre::eyre::Result; -use tinywasm::{self, Module, WasmValue}; +use tinywasm::{self, WasmValue}; use util::install_tracing; mod util; @@ -18,6 +20,23 @@ enum TinyWasmSubcommand { Run(Run), } +enum Engine { + Main, + Naive, +} + +impl FromStr for Engine { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "naive" => Ok(Self::Naive), + "main" => Ok(Self::Main), + _ => Err(format!("unknown engine: {}", s)), + } + } +} + #[derive(FromArgs)] /// run a wasm file #[argh(subcommand, name = "run")] @@ -25,6 +44,10 @@ struct Run { /// wasm file to run #[argh(positional)] wasm_file: String, + + /// engine to use + #[argh(option, short = 'e', default = "Engine::Main")] + engine: Engine, } fn main() -> Result<()> { @@ -34,22 +57,32 @@ fn main() -> Result<()> { let args: TinyWasmCli = argh::from_env(); match args.nested { - TinyWasmSubcommand::Run(Run { wasm_file }) => { - let wasm = std::fs::read(wasm_file).unwrap(); - run(&wasm)?; - Ok(()) + TinyWasmSubcommand::Run(Run { wasm_file, engine }) => { + let wasm = std::fs::read(wasm_file)?; + match engine { + Engine::Main => run(&wasm), + Engine::Naive => run_naive(&wasm), + } } } } fn run(wasm: &[u8]) -> Result<()> { - let mut module = Module::new(wasm)?; + let mut store = tinywasm::Store::default(); + let mut module = tinywasm::Module::try_new(&mut store, wasm)?; + let instance = tinywasm::ModuleInstance::new(&mut module)?; + + Ok(()) +} + +fn run_naive(wasm: &[u8]) -> Result<()> { + let mut module = tinywasm::naive::Module::new(wasm)?; let args = [WasmValue::I32(1), WasmValue::I32(2)]; - let res = tinywasm::naive_runtime::run(&mut module, "add", &args)?; + let res = tinywasm::naive::run(&mut module, "add", &args)?; println!("res: {:?}", res); let args = [WasmValue::I64(1), WasmValue::I64(2)]; - let res = tinywasm::naive_runtime::run(&mut module, "add_64", &args)?; + let res = tinywasm::naive::run(&mut module, "add_64", &args)?; println!("res: {:?}", res); Ok(()) diff --git a/crates/tinywasm/src/engine/executer.rs b/crates/tinywasm/src/engine/executer.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/crates/tinywasm/src/engine/executer.rs @@ -0,0 +1 @@ + diff --git a/crates/tinywasm/src/engine/mod.rs b/crates/tinywasm/src/engine/mod.rs new file mode 100644 index 0000000..a134659 --- /dev/null +++ b/crates/tinywasm/src/engine/mod.rs @@ -0,0 +1,20 @@ +mod executer; +mod stack; +mod types; + +pub use executer::*; +pub use stack::*; +pub use types::*; + +#[derive(Debug)] +pub struct Engine { + pub stack: Stack, +} + +impl Default for Engine { + fn default() -> Self { + Self { + stack: Stack::default(), + } + } +} diff --git a/crates/tinywasm/src/runtime/stack/call.rs b/crates/tinywasm/src/engine/stack/call.rs index a58e2ef..0d0ffae 100644 --- a/crates/tinywasm/src/runtime/stack/call.rs +++ b/crates/tinywasm/src/engine/stack/call.rs @@ -1,5 +1,6 @@ use alloc::vec::Vec; +#[derive(Debug)] pub struct CallFrame { pub instr_ptr: usize, pub func_ptr: usize, diff --git a/crates/tinywasm/src/runtime/stack/mod.rs b/crates/tinywasm/src/engine/stack/mod.rs index 68f02ff..f7ffdf3 100644 --- a/crates/tinywasm/src/runtime/stack/mod.rs +++ b/crates/tinywasm/src/engine/stack/mod.rs @@ -4,9 +4,13 @@ use alloc::vec::Vec; mod call; pub use call::CallFrame; +// minimum stack size pub const STACK_SIZE: usize = 1024; +// minimum call stack size +pub const CALL_STACK_SIZE: usize = 1024; /// A WebAssembly Stack +#[derive(Debug)] pub struct Stack { /// Locals // TODO: maybe store the locals on the stack instead? @@ -21,3 +25,15 @@ pub struct Stack { pub call_stack: Vec<CallFrame>, pub call_stack_top: usize, } + +impl Default for Stack { + fn default() -> Self { + Self { + 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, + } + } +} diff --git a/crates/tinywasm/src/runtime/types.rs b/crates/tinywasm/src/engine/types.rs index a9be605..ab81b9d 100644 --- a/crates/tinywasm/src/runtime/types.rs +++ b/crates/tinywasm/src/engine/types.rs @@ -1,6 +1,8 @@ use alloc::{string::String, vec::Vec}; use wasmparser::{FuncType, OperatorsIterator, ValType}; +use crate::module::ModuleInstance; + /// A WebAssembly Label pub struct Label(Addr); @@ -8,40 +10,30 @@ pub struct Label(Addr); /// These are indexes into the respective stores. /// See https://webassembly.github.io/spec/core/exec/runtime.html#addresses pub type Addr = u32; -pub struct FuncAddr(pub Addr); -pub struct TableAddr(pub Addr); -pub struct MemAddr(pub Addr); -pub struct GlobalAddr(pub Addr); -pub struct ElmAddr(pub Addr); -pub struct DataAddr(pub Addr); -pub struct ExternAddr(pub Addr); - -/// A WebAssembly Module Instance. -/// See https://webassembly.github.io/spec/core/exec/runtime.html#module-instances -pub struct ModuleInstance { - pub types: Vec<FuncType>, - pub func_addrs: Vec<FuncAddr>, - pub table_addrs: Vec<TableAddr>, - pub mem_addrs: Vec<MemAddr>, - pub global_addrs: Vec<GlobalAddr>, - pub elem_addrs: Vec<ElmAddr>, - pub data_addrs: Vec<DataAddr>, - pub exports: Vec<ExportInst>, -} +pub type FuncAddr = Addr; +pub type TableAddr = Addr; +pub type MemAddr = Addr; +pub type GlobalAddr = Addr; +pub type ElmAddr = Addr; +pub type DataAddr = Addr; +pub type ExternAddr = Addr; /// A WebAssembly Function Instance. /// See https://webassembly.github.io/spec/core/exec/runtime.html#function-instances +#[derive(Debug)] pub enum FuncInst { Host(HostFunc), Module(ModuleFunc), } +#[derive(Debug)] pub struct HostFunc { pub ty: FuncType, pub hostcode: fn() -> (), } +#[derive(Debug)] pub struct ModuleFunc { pub ty: FuncType, - pub module: ModuleInstance, + pub module: Addr, pub code: FuncAddr, } pub struct Func<'a> { @@ -52,6 +44,7 @@ pub struct Func<'a> { /// A WebAssembly Export Instance. /// https://webassembly.github.io/spec/core/exec/runtime.html#export-instances +#[derive(Debug)] pub struct ExportInst { pub name: String, pub value: ExternVal, @@ -59,6 +52,7 @@ pub struct ExportInst { /// A WebAssembly External Value. /// https://webassembly.github.io/spec/core/exec/runtime.html#external-values +#[derive(Debug)] pub enum ExternVal { Func(FuncAddr), Table(TableAddr), diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs deleted file mode 100644 index e69de29..0000000 --- a/crates/tinywasm/src/instance.rs +++ /dev/null diff --git a/crates/tinywasm/src/instructions.rs b/crates/tinywasm/src/instructions.rs deleted file mode 100644 index e3e6a08..0000000 --- a/crates/tinywasm/src/instructions.rs +++ /dev/null @@ -1,106 +0,0 @@ -// https://webassembly.github.io/spec/core/binary/instructions.html - -// Controll Instructions -pub mod control { - pub const WASM_UNREACHABLE: u8 = 0x00; - pub const WASM_NOP: u8 = 0x01; // do nothing - - // stuctured instructions - pub const WASM_BLOCK: u8 = 0x02; - pub const WASM_LOOP: u8 = 0x03; - pub const WASM_IF: u8 = 0x04; - - pub const WASM_ELSE: u8 = 0x05; - pub const WASM_END: u8 = 0x0B; - pub const WASM_BR: u8 = 0x0C; - pub const WASM_BR_IF: u8 = 0x0D; - pub const WASM_BR_TABLE: u8 = 0x0E; - pub const WASM_RETURN: u8 = 0x0F; - pub const WASM_CALL: u8 = 0x10; - pub const WASM_CALL_INDIRECT: u8 = 0x11; - pub const WASM_DROP: u8 = 0x1A; -} - -// Reference Instructions -pub mod reference { - pub const WASM_REF_NULL: u8 = 0xD0; - pub const WASM_REF_IS_NULL: u8 = 0xD1; - pub const WASM_REF_FUNC: u8 = 0xD2; -} - -// Parametric Instructions -pub mod parametric { - pub const WASM_DROP: u8 = 0x1A; - pub const WASM_SELECT: u8 = 0x1B; - pub const WASM_SELECT_T: u8 = 0x1C; -} - -// Variable Instructions -pub mod variable { - pub const WASM_LOCAL_GET: u8 = 0x20; - pub const WASM_LOCAL_SET: u8 = 0x21; - pub const WASM_LOCAL_TEE: u8 = 0x22; - pub const WASM_GLOBAL_GET: u8 = 0x23; - pub const WASM_GLOBAL_SET: u8 = 0x24; -} - -// Table Instructions -pub mod table { - pub const WASM_TABLE_GET: u8 = 0x25; - pub const WASM_TABLE_SET: u8 = 0x26; - pub const WASM_TABLE_INIT: u8 = 0xFC; - pub const WASM_ELEM_DROP: u8 = 0xFC; - pub const WASM_TABLE_COPY: u8 = 0xFC; - pub const WASM_TABLE_GROW: u8 = 0xFC; - pub const WASM_TABLE_SIZE: u8 = 0xFC; - pub const WASM_TABLE_FILL: u8 = 0xFC; -} - -// Memory Instructions -pub mod memory { - pub const WASM_I32_LOAD: u8 = 0x28; - pub const WASM_I64_LOAD: u8 = 0x29; - pub const WASM_F32_LOAD: u8 = 0x2A; - pub const WASM_F64_LOAD: u8 = 0x2B; - pub const WASM_I32_LOAD8_S: u8 = 0x2C; - pub const WASM_I32_LOAD8_U: u8 = 0x2D; - pub const WASM_I32_LOAD16_S: u8 = 0x2E; - pub const WASM_I32_LOAD16_U: u8 = 0x2F; - pub const WASM_I64_LOAD8_S: u8 = 0x30; - pub const WASM_I64_LOAD8_U: u8 = 0x31; - pub const WASM_I64_LOAD16_S: u8 = 0x32; - pub const WASM_I64_LOAD16_U: u8 = 0x33; - pub const WASM_I64_LOAD32_S: u8 = 0x34; - pub const WASM_I64_LOAD32_U: u8 = 0x35; - pub const WASM_I32_STORE: u8 = 0x36; - pub const WASM_I64_STORE: u8 = 0x37; - pub const WASM_F32_STORE: u8 = 0x38; - pub const WASM_F64_STORE: u8 = 0x39; - pub const WASM_I32_STORE8: u8 = 0x3A; - pub const WASM_I32_STORE16: u8 = 0x3B; - pub const WASM_I64_STORE8: u8 = 0x3C; - pub const WASM_I64_STORE16: u8 = 0x3D; - pub const WASM_I64_STORE32: u8 = 0x3E; - pub const WASM_MEMORY_SIZE: u8 = 0x3F; - pub const WASM_MEMORY_GROW: u8 = 0x40; - pub const WASM_MEMORY_INIT: u8 = 0xFC; - pub const WASM_DATA_DROP: u8 = 0xFC; - pub const WASM_MEMORY_COPY: u8 = 0xFC; - pub const WASM_MEMORY_FILL: u8 = 0xFC; -} - -// Numeric Instructions -pub mod numeric { - // Constants - pub const WASM_I32_CONST: u8 = 0x41; - pub const WASM_I64_CONST: u8 = 0x42; - pub const WASM_F32_CONST: u8 = 0x43; - pub const WASM_F64_CONST: u8 = 0x44; - - // Operations - pub const START_NUMERIC: u8 = 0x45; - pub const END_NUMERIC: u8 = 0xC4; - pub const WASM_SATURATING_TRUNC: u8 = 0xFC; -} - -pub const WASM_VEC: u8 = 0xFD; diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 6b2cd3f..f4bdd65 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -6,28 +6,38 @@ mod std; extern crate alloc; mod error; -pub mod instructions; -pub mod module; pub use error::*; + +pub mod store; +pub use store::Store; + +pub mod module; pub use module::Module; +pub use module::ModuleInstance; + pub mod types; pub use types::*; -pub mod runtime; -pub mod naive_runtime; - -pub struct Store {} - -pub struct Instance {} +pub mod engine; +pub mod naive; #[cfg(test)] mod tests { - use crate::{error::Result, Module}; + use crate::std::println; + use crate::{error::Result, naive, WasmValue}; #[test] - fn it_works() -> Result<()> { + fn naive_add() -> Result<()> { let wasm = include_bytes!("../../../examples/wasm/add.wasm"); - let module = Module::new(wasm)?; + let mut module = naive::Module::new(wasm)?; + + let args = [WasmValue::I32(1), WasmValue::I32(2)]; + let res = naive::run(&mut module, "add", &args)?; + println!("res: {:?}", res); + + let args = [WasmValue::I64(1), WasmValue::I64(2)]; + let res = naive::run(&mut module, "add_64", &args)?; + println!("res: {:?}", res); Ok(()) } diff --git a/crates/tinywasm/src/module/mod.rs b/crates/tinywasm/src/module/mod.rs index 23c2a93..51731e9 100644 --- a/crates/tinywasm/src/module/mod.rs +++ b/crates/tinywasm/src/module/mod.rs @@ -1,63 +1,44 @@ -use core::fmt::Debug; - -use crate::error::{Error, Result}; use alloc::vec::Vec; -use wasmparser::*; +use wasmparser::{Export, FuncType, Validator}; + +use crate::{engine::FuncAddr, Error, Result, Store}; -mod reader; use self::reader::ModuleReader; +pub mod reader; + #[derive(Debug)] -pub struct ModuleMetadata { - pub version: u16, +pub struct Module<'a> { + store: &'a mut Store<'a>, + reader: ModuleReader<'a>, } -pub struct Module<'data> { - pub meta: ModuleMetadata, +/// A WebAssembly Module Instance. +/// See https://webassembly.github.io/spec/core/exec/runtime.html#module-instances +#[derive(Debug)] +pub struct ModuleInstance<'m, 'data> { + pub module: &'m Module<'data>, pub types: Vec<FuncType>, - pub functions: Vec<u32>, + pub func_addrs: Vec<FuncAddr>, + // pub table_addrs: Vec<TableAddr>, + // pub mem_addrs: Vec<MemAddr>, + // pub global_addrs: Vec<GlobalAddr>, + // pub elem_addrs: Vec<ElmAddr>, + // pub data_addrs: Vec<DataAddr>, pub exports: Vec<Export<'data>>, - pub code: Vec<FunctionBody<'data>>, - - marker: core::marker::PhantomData<&'data ()>, } -impl Debug for Module<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("Module") - .field("meta", &self.meta) - .field("types", &self.types) - .field("functions", &self.functions) - .field("exports", &self.exports) - .field("code", &self.code) - .finish() - } -} - -impl<'data> Module<'data> { - pub fn new(wasm: &'data [u8]) -> Result<Self> { - let mut validator = Validator::new(); - let mut reader = ModuleReader::new(); - - for payload in wasmparser::Parser::new(0).parse_all(wasm) { - reader.process_payload(payload?, &mut validator)?; - } - - if !reader.end_reached { - return Error::other("End not reached"); - } - - Self::from_reader(reader) - } - - fn from_reader(reader: ModuleReader<'data>) -> Result<Self> { - let types = reader +impl<'m, 'data> ModuleInstance<'m, 'data> { + pub fn new(module: &'m mut Module<'data>) -> Result<Self> { + let types = module + .reader .type_section + .take() .map(|s| { s.into_iter() .map(|ty| { - let Type::Func(func) = ty?; + let wasmparser::Type::Func(func) = ty?; Ok(func) }) .collect::<Result<Vec<_>>>() @@ -65,31 +46,49 @@ impl<'data> Module<'data> { .transpose()? .unwrap_or_default(); - let functions = reader + let func_addrs = module + .reader .function_section + .take() .map(|s| s.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()) .transpose()? .unwrap_or_default(); - let exports = reader + let exports = module + .reader .export_section + .take() .map(|s| s.into_iter().map(|e| Ok(e?)).collect::<Result<Vec<_>>>()) .transpose()? .unwrap_or_default(); - let code = reader.code_section.map(|s| s.functions).unwrap_or_default(); - - let meta = ModuleMetadata { - version: reader.version.unwrap_or(1), - }; - Ok(Self { - marker: core::marker::PhantomData, - meta, + module, + types, + func_addrs, + // table_addrs, + // mem_addrs, + // global_addrs, + // elem_addrs, + // data_addrs, exports, - functions, - code, }) } } + +impl<'a> Module<'a> { + pub fn try_new(store: &'a mut Store<'a>, wasm: &'a [u8]) -> Result<Module<'a>> { + let mut validator = Validator::new(); + let mut reader = ModuleReader::new(); + + for payload in wasmparser::Parser::new(0).parse_all(&wasm) { + reader.process_payload(payload?, &mut validator)?; + } + if !reader.end_reached { + return Error::other("End not reached"); + } + + Ok(Self { store, reader }) + } +} diff --git a/crates/tinywasm/src/module/reader.rs b/crates/tinywasm/src/module/reader.rs index 5ccadea..50d1012 100644 --- a/crates/tinywasm/src/module/reader.rs +++ b/crates/tinywasm/src/module/reader.rs @@ -46,7 +46,7 @@ impl Debug for ModuleReader<'_> { } impl<'a> ModuleReader<'a> { - pub fn new() -> Self { + pub fn new() -> ModuleReader<'a> { Self::default() } diff --git a/crates/tinywasm/src/naive_runtime.rs b/crates/tinywasm/src/naive/mod.rs index 6e6c709..44b40af 100644 --- a/crates/tinywasm/src/naive_runtime.rs +++ b/crates/tinywasm/src/naive/mod.rs @@ -2,7 +2,10 @@ use alloc::{format, string::ToString, vec, vec::Vec}; use tracing::info; use wasmparser::Operator; -use crate::{Error, Module, Result, WasmValue}; +mod module; +pub use self::module::Module; + +use crate::{Error, Result, WasmValue}; pub fn run(module: &mut Module, func_name: &str, args: &[WasmValue]) -> Result<Vec<WasmValue>> { let func = module diff --git a/crates/tinywasm/src/naive/module.rs b/crates/tinywasm/src/naive/module.rs new file mode 100644 index 0000000..24f2d55 --- /dev/null +++ b/crates/tinywasm/src/naive/module.rs @@ -0,0 +1,92 @@ +use core::fmt::Debug; + +use crate::{ + error::{Error, Result}, + module::reader::ModuleReader, +}; +use alloc::vec::Vec; +use wasmparser::*; + +#[derive(Debug)] +pub struct ModuleMetadata { + pub version: u16, +} + +pub struct Module<'data> { + pub meta: ModuleMetadata, + + pub types: Vec<FuncType>, + pub functions: Vec<u32>, + pub exports: Vec<Export<'data>>, + pub code: Vec<FunctionBody<'data>>, +} + +impl Debug for Module<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Module") + .field("meta", &self.meta) + .field("types", &self.types) + .field("functions", &self.functions) + .field("exports", &self.exports) + .field("code", &self.code) + .finish() + } +} + +impl<'data> Module<'data> { + pub fn new(wasm: &'data [u8]) -> Result<Self> { + let mut validator = Validator::new(); + let mut reader = ModuleReader::new(); + + for payload in wasmparser::Parser::new(0).parse_all(wasm) { + reader.process_payload(payload?, &mut validator)?; + } + + if !reader.end_reached { + return Error::other("End not reached"); + } + + Self::from_reader(reader) + } + + fn from_reader(reader: ModuleReader<'data>) -> Result<Self> { + let types = reader + .type_section + .map(|s| { + s.into_iter() + .map(|ty| { + let Type::Func(func) = ty?; + Ok(func) + }) + .collect::<Result<Vec<_>>>() + }) + .transpose()? + .unwrap_or_default(); + + let functions = reader + .function_section + .map(|s| s.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()) + .transpose()? + .unwrap_or_default(); + + let exports = reader + .export_section + .map(|s| s.into_iter().map(|e| Ok(e?)).collect::<Result<Vec<_>>>()) + .transpose()? + .unwrap_or_default(); + + let code = reader.code_section.map(|s| s.functions).unwrap_or_default(); + + let meta = ModuleMetadata { + version: reader.version.unwrap_or(1), + }; + + Ok(Self { + meta, + types, + exports, + functions, + code, + }) + } +} diff --git a/crates/tinywasm/src/runtime/mod.rs b/crates/tinywasm/src/runtime/mod.rs deleted file mode 100644 index 0504365..0000000 --- a/crates/tinywasm/src/runtime/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod stack; -mod store; -mod types; -pub use stack::*; -pub use store::*; -pub use types::*; diff --git a/crates/tinywasm/src/runtime/store.rs b/crates/tinywasm/src/runtime/store.rs deleted file mode 100644 index cf0163b..0000000 --- a/crates/tinywasm/src/runtime/store.rs +++ /dev/null @@ -1,14 +0,0 @@ -use alloc::vec::Vec; - -use super::FuncInst; - -/// global state that can be manipulated by WebAssembly programs -/// https://webassembly.github.io/spec/core/exec/runtime.html#store -pub struct Store { - pub funcs: Vec<FuncInst>, - // tables: Vec<TableType>, - // mems: Vec<MemoryType>, - // globals: Vec<GlobalType>, - // elems: Vec<Element>, - // data: Vec<Data>, -} diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs new file mode 100644 index 0000000..3c70c2f --- /dev/null +++ b/crates/tinywasm/src/store.rs @@ -0,0 +1,51 @@ +use alloc::vec::Vec; +use wasmparser::FunctionBody; + +use crate::{engine::Engine, module::reader::ModuleReader, Result}; + +/// global state that can be manipulated by WebAssembly programs +/// https://webassembly.github.io/spec/core/exec/runtime.html#store +#[derive(Debug)] +pub struct Store<'data> { + pub data: StoreData<'data>, + pub engine: Engine, +} + +#[derive(Debug)] +pub struct StoreData<'data> { + pub funcs: Vec<FunctionBody<'data>>, + // pub tables: Vec<TableAddr>, + // pub mems: Vec<MemAddr>, + // pub globals: Vec<GlobalAddr>, +} + +impl<'data> Default for StoreData<'data> { + fn default() -> Self { + Self { + funcs: Vec::new(), + // tables: Vec::new(), + // mems: Vec::new(), + // globals: Vec::new(), + } + } +} + +impl<'data> Store<'data> { + pub(crate) fn initialize(&'data mut self, reader: &'data mut ModuleReader) -> Result<()> { + let code = reader.code_section.take().ok_or_else(|| { + crate::Error::Other("Module must have a code section to initialize the store".into()) + })?; + + self.data.funcs = code.functions; + Ok(()) + } +} + +impl Default for Store<'_> { + fn default() -> Self { + Self { + data: StoreData::default(), + engine: Engine::default(), + } + } +} |
