From 266afb16777970b37a61889039a0a2ea1ad1f83a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 1 Dec 2023 04:05:51 +0100 Subject: chore: add instructions Signed-off-by: Henry Gressmann --- crates/cli/bin.rs | 2 +- crates/tinywasm/src/error.rs | 10 +- crates/tinywasm/src/module/data.rs | 68 +++++ crates/tinywasm/src/module/instructions.rs | 399 +++++++++++++++++++++++++++++ crates/tinywasm/src/module/mod.rs | 89 +++---- crates/tinywasm/src/module/reader.rs | 32 +-- crates/tinywasm/src/runtime/types.rs | 46 ++-- 7 files changed, 557 insertions(+), 89 deletions(-) create mode 100644 crates/tinywasm/src/module/data.rs create mode 100644 crates/tinywasm/src/module/instructions.rs diff --git a/crates/cli/bin.rs b/crates/cli/bin.rs index b085ae1..2c554cd 100644 --- a/crates/cli/bin.rs +++ b/crates/cli/bin.rs @@ -70,7 +70,7 @@ fn main() -> Result<()> { fn run(wasm: &[u8]) -> Result<()> { let mut store = tinywasm::Store::default(); - let module = tinywasm::Module::try_new(wasm)?; + let module = tinywasm::Module::from_bytes(wasm)?; let instance = module.instantiate(&mut store)?; let func = instance.get_func("add").unwrap(); diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index 9b97a59..112b2b5 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -3,9 +3,15 @@ use core::fmt::Display; #[derive(Debug)] pub enum Error { - ParseError { message: String, offset: usize }, + ParseError { + message: String, + offset: usize, + }, UnsupportedFeature(String), Other(String), + + #[cfg(feature = "std")] + Io(crate::std::io::Error), } impl Display for Error { @@ -16,6 +22,8 @@ impl Display for Error { } Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {}", feature), Self::Other(message) => write!(f, "unknown error: {}", message), + #[cfg(feature = "std")] + Self::Io(err) => write!(f, "I/O error: {}", err), } } } diff --git a/crates/tinywasm/src/module/data.rs b/crates/tinywasm/src/module/data.rs new file mode 100644 index 0000000..0fa8a27 --- /dev/null +++ b/crates/tinywasm/src/module/data.rs @@ -0,0 +1,68 @@ +use alloc::{boxed::Box, string::ToString, vec::Vec}; +use wasmparser::{ExternalKind, FuncType, FunctionBody, ValType}; + +use crate::Result; + +use super::instructions::Instruction; + +/// A WebAssembly Function +pub struct Function { + pub locals: Box<[ValType]>, + pub body: Box<[Instruction]>, +} + +impl Function { + pub fn new(body: FunctionBody) -> Result { + let locals_reader = body.get_locals_reader()?; + let count = locals_reader.get_count(); + let mut locals = Vec::with_capacity(count as usize); + locals.extend( + locals_reader + .into_iter() + .filter_map(|l| l.ok()) + .map(|l| l.1), + ); + + if locals.len() != count as usize { + return Err(crate::Error::Other("Invalid local index".to_string())); + } + + let body_reader = body.get_operators_reader()?; + let body = body_reader + .into_iter() + .map(|op| (op?).try_into()) + .collect::>>()?; + + Ok(Self { + locals: locals.into_boxed_slice(), + body: body.into_boxed_slice(), + }) + } +} + +/// A WebAssembly Module Export +#[derive(Debug)] +pub struct Export { + /// The name of the export. + pub name: Box, + /// The kind of the export. + pub kind: ExternalKind, + /// The index of the exported item. + pub index: u32, +} + +// TODO: maybe support rkyv serialization +pub struct ModuleData { + pub version: Option, + pub start_func: Option, + + pub types: Box<[FuncType]>, + pub functions: Box<[Function]>, + pub exports: Box<[Export]>, + // pub tables: Option, + // pub memories: Option, + // pub globals: Option, + // pub elements: Option>, + // pub imports: Option>, + // pub data_segments: Option>, +} diff --git a/crates/tinywasm/src/module/instructions.rs b/crates/tinywasm/src/module/instructions.rs new file mode 100644 index 0000000..b7fadf5 --- /dev/null +++ b/crates/tinywasm/src/module/instructions.rs @@ -0,0 +1,399 @@ +use alloc::{format, vec::Vec}; +use wasmparser::{BlockType, MemArg}; + +use crate::{ + runtime::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr}, + Result, +}; + +/// A WebAssembly Instruction +/// See https://webassembly.github.io/spec/core/binary/instructions.html +/// Currently includes all instructions from the MVP (1.0) spec +pub enum Instruction { + // Control Instructions + // See https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions + Unreachable, + Nop, + Block(BlockType), + Loop(BlockType), + If(BlockType), + Else, + End, + Br(LabelAddr), + BrIf(LabelAddr), + BrTable(Vec, LabelAddr), // not to spec, instead of a vector of labels, we have a label and a count + Return, + Call(FuncAddr), + CallIndirect(TypeAddr, TableAddr), + + // Parametric Instructions + // See https://webassembly.github.io/spec/core/binary/instructions.html#parametric-instructions + Drop, + Select, + + // Variable Instructions + // See https://webassembly.github.io/spec/core/binary/instructions.html#variable-instructions + LocalGet(LocalAddr), + LocalSet(LocalAddr), + LocalTee(LocalAddr), + GlobalGet(GlobalAddr), + GlobalSet(GlobalAddr), + + // Memory Instructions + I32Load(MemArg), + I64Load(MemArg), + F32Load(MemArg), + F64Load(MemArg), + I32Load8S(MemArg), + I32Load8U(MemArg), + I32Load16S(MemArg), + I32Load16U(MemArg), + I64Load8S(MemArg), + I64Load8U(MemArg), + I64Load16S(MemArg), + I64Load16U(MemArg), + I64Load32S(MemArg), + I64Load32U(MemArg), + I32Store(MemArg), + I64Store(MemArg), + F32Store(MemArg), + F64Store(MemArg), + I32Store8(MemArg), + I32Store16(MemArg), + I64Store8(MemArg), + I64Store16(MemArg), + I64Store32(MemArg), + MemorySize, + MemoryGrow, + + // Constants + I32Const(i32), + I64Const(i64), + F32Const(f32), + F64Const(f64), + + // Numeric Instructions + // See https://webassembly.github.io/spec/core/binary/instructions.html#numeric-instructions + I32Eqz, + I32Eq, + I32Ne, + I32LtS, + I32LtU, + I32GtS, + I32GtU, + I32LeS, + I32LeU, + I32GeS, + I32GeU, + I64Eqz, + I64Eq, + I64Ne, + I64LtS, + I64LtU, + I64GtS, + I64GtU, + I64LeS, + I64LeU, + I64GeS, + I64GeU, + F32Eq, + F32Ne, + F32Lt, + F32Gt, + F32Le, + F32Ge, + F64Eq, + F64Ne, + F64Lt, + F64Gt, + F64Le, + F64Ge, + I32Clz, + I32Ctz, + I32Popcnt, + I32Add, + I32Sub, + I32Mul, + I32DivS, + I32DivU, + I32RemS, + I32RemU, + I32And, + I32Or, + I32Xor, + I32Shl, + I32ShrS, + I32ShrU, + I32Rotl, + I32Rotr, + I64Clz, + I64Ctz, + I64Popcnt, + I64Add, + I64Sub, + I64Mul, + I64DivS, + I64DivU, + I64RemS, + I64RemU, + I64And, + I64Or, + I64Xor, + I64Shl, + I64ShrS, + I64ShrU, + I64Rotl, + I64Rotr, + F32Abs, + F32Neg, + F32Ceil, + F32Floor, + F32Trunc, + F32Nearest, + F32Sqrt, + F32Add, + F32Sub, + F32Mul, + F32Div, + F32Min, + F32Max, + F32Copysign, + F64Abs, + F64Neg, + F64Ceil, + F64Floor, + F64Trunc, + F64Nearest, + F64Sqrt, + F64Add, + F64Sub, + F64Mul, + F64Div, + F64Min, + F64Max, + F64Copysign, + I32WrapI64, + I32TruncF32S, + I32TruncF32U, + I32TruncF64S, + I32TruncF64U, + I64ExtendI32S, + I64ExtendI32U, + I64TruncF32S, + I64TruncF32U, + I64TruncF64S, + I64TruncF64U, + F32ConvertI32S, + F32ConvertI32U, + F32ConvertI64S, + F32ConvertI64U, + F32DemoteF64, + F64ConvertI32S, + F64ConvertI32U, + F64ConvertI64S, + F64ConvertI64U, + F64PromoteF32, + I32ReinterpretF32, + I64ReinterpretF64, + F32ReinterpretI32, + F64ReinterpretI64, +} + +impl TryFrom> for Instruction { + type Error = crate::Error; + + fn try_from(value: wasmparser::Operator<'_>) -> Result { + use wasmparser::Operator::*; + + let v = match value { + Unreachable => Self::Unreachable, + Nop => Self::Nop, + Block { blockty } => Self::Block(blockty), + Loop { blockty } => Self::Loop(blockty), + If { blockty } => Self::If(blockty), + Else => Self::Else, + End => Self::End, + Br { relative_depth } => Self::Br(relative_depth), + BrIf { relative_depth } => Self::BrIf(relative_depth), + BrTable { targets } => { + let default = targets.default(); + let targets = targets + .targets() + .map(|t| Ok(t?)) + .collect::>>()?; + + Self::BrTable(targets, default) + } + Return => Self::Return, + Call { function_index } => Self::Call(function_index), + CallIndirect { + type_index, + table_index, + .. + } => Self::CallIndirect(type_index, table_index), + Drop => Self::Drop, + Select => Self::Select, + LocalGet { local_index } => Self::LocalGet(local_index), + LocalSet { local_index } => Self::LocalSet(local_index), + LocalTee { local_index } => Self::LocalTee(local_index), + GlobalGet { global_index } => Self::GlobalGet(global_index), + GlobalSet { global_index } => Self::GlobalSet(global_index), + MemorySize { .. } => Self::MemorySize, + MemoryGrow { .. } => Self::MemoryGrow, + I32Load { memarg } => Self::I32Load(memarg), + I64Load { memarg } => Self::I64Load(memarg), + F32Load { memarg } => Self::F32Load(memarg), + F64Load { memarg } => Self::F64Load(memarg), + I32Load8S { memarg } => Self::I32Load8S(memarg), + I32Load8U { memarg } => Self::I32Load8U(memarg), + I32Load16S { memarg } => Self::I32Load16S(memarg), + I32Load16U { memarg } => Self::I32Load16U(memarg), + I64Load8S { memarg } => Self::I64Load8S(memarg), + I64Load8U { memarg } => Self::I64Load8U(memarg), + I64Load16S { memarg } => Self::I64Load16S(memarg), + I64Load16U { memarg } => Self::I64Load16U(memarg), + I64Load32S { memarg } => Self::I64Load32S(memarg), + I64Load32U { memarg } => Self::I64Load32U(memarg), + I32Store { memarg } => Self::I32Store(memarg), + I64Store { memarg } => Self::I64Store(memarg), + F32Store { memarg } => Self::F32Store(memarg), + F64Store { memarg } => Self::F64Store(memarg), + I32Store8 { memarg } => Self::I32Store8(memarg), + I32Store16 { memarg } => Self::I32Store16(memarg), + I64Store8 { memarg } => Self::I64Store8(memarg), + I64Store16 { memarg } => Self::I64Store16(memarg), + I64Store32 { memarg } => Self::I64Store32(memarg), + I32Eqz => Self::I32Eqz, + I32Eq => Self::I32Eq, + I32Ne => Self::I32Ne, + I32LtS => Self::I32LtS, + I32LtU => Self::I32LtU, + I32GtS => Self::I32GtS, + I32GtU => Self::I32GtU, + I32LeS => Self::I32LeS, + I32LeU => Self::I32LeU, + I32GeS => Self::I32GeS, + I32GeU => Self::I32GeU, + I64Eqz => Self::I64Eqz, + I64Eq => Self::I64Eq, + I64Ne => Self::I64Ne, + I64LtS => Self::I64LtS, + I64LtU => Self::I64LtU, + I64GtS => Self::I64GtS, + I64GtU => Self::I64GtU, + I64LeS => Self::I64LeS, + I64LeU => Self::I64LeU, + I64GeS => Self::I64GeS, + I64GeU => Self::I64GeU, + F32Eq => Self::F32Eq, + F32Ne => Self::F32Ne, + F32Lt => Self::F32Lt, + F32Gt => Self::F32Gt, + F32Le => Self::F32Le, + F32Ge => Self::F32Ge, + F64Eq => Self::F64Eq, + F64Ne => Self::F64Ne, + F64Lt => Self::F64Lt, + F64Gt => Self::F64Gt, + F64Le => Self::F64Le, + F64Ge => Self::F64Ge, + I32Clz => Self::I32Clz, + I32Ctz => Self::I32Ctz, + I32Popcnt => Self::I32Popcnt, + I32Add => Self::I32Add, + I32Sub => Self::I32Sub, + I32Mul => Self::I32Mul, + I32DivS => Self::I32DivS, + I32DivU => Self::I32DivU, + I32RemS => Self::I32RemS, + I32RemU => Self::I32RemU, + I32And => Self::I32And, + I32Or => Self::I32Or, + I32Xor => Self::I32Xor, + I32Shl => Self::I32Shl, + I32ShrS => Self::I32ShrS, + I32ShrU => Self::I32ShrU, + I32Rotl => Self::I32Rotl, + I32Rotr => Self::I32Rotr, + I64Clz => Self::I64Clz, + I64Ctz => Self::I64Ctz, + I64Popcnt => Self::I64Popcnt, + I64Add => Self::I64Add, + I64Sub => Self::I64Sub, + I64Mul => Self::I64Mul, + I64DivS => Self::I64DivS, + I64DivU => Self::I64DivU, + I64RemS => Self::I64RemS, + I64RemU => Self::I64RemU, + I64And => Self::I64And, + I64Or => Self::I64Or, + I64Xor => Self::I64Xor, + I64Shl => Self::I64Shl, + I64ShrS => Self::I64ShrS, + I64ShrU => Self::I64ShrU, + I64Rotl => Self::I64Rotl, + I64Rotr => Self::I64Rotr, + F32Abs => Self::F32Abs, + F32Neg => Self::F32Neg, + F32Ceil => Self::F32Ceil, + F32Floor => Self::F32Floor, + F32Trunc => Self::F32Trunc, + F32Nearest => Self::F32Nearest, + F32Sqrt => Self::F32Sqrt, + F32Add => Self::F32Add, + F32Sub => Self::F32Sub, + F32Mul => Self::F32Mul, + F32Div => Self::F32Div, + F32Min => Self::F32Min, + F32Max => Self::F32Max, + F32Copysign => Self::F32Copysign, + F64Abs => Self::F64Abs, + F64Neg => Self::F64Neg, + F64Ceil => Self::F64Ceil, + F64Floor => Self::F64Floor, + F64Trunc => Self::F64Trunc, + F64Nearest => Self::F64Nearest, + F64Sqrt => Self::F64Sqrt, + F64Add => Self::F64Add, + F64Sub => Self::F64Sub, + F64Mul => Self::F64Mul, + F64Div => Self::F64Div, + F64Min => Self::F64Min, + F64Max => Self::F64Max, + F64Copysign => Self::F64Copysign, + I32WrapI64 => Self::I32WrapI64, + I32TruncF32S => Self::I32TruncF32S, + I32TruncF32U => Self::I32TruncF32U, + I32TruncF64S => Self::I32TruncF64S, + I32TruncF64U => Self::I32TruncF64U, + I64ExtendI32S => Self::I64ExtendI32S, + I64ExtendI32U => Self::I64ExtendI32U, + I64TruncF32S => Self::I64TruncF32S, + I64TruncF32U => Self::I64TruncF32U, + I64TruncF64S => Self::I64TruncF64S, + I64TruncF64U => Self::I64TruncF64U, + F32ConvertI32S => Self::F32ConvertI32S, + F32ConvertI32U => Self::F32ConvertI32U, + F32ConvertI64S => Self::F32ConvertI64S, + F32ConvertI64U => Self::F32ConvertI64U, + F32DemoteF64 => Self::F32DemoteF64, + F64ConvertI32S => Self::F64ConvertI32S, + F64ConvertI32U => Self::F64ConvertI32U, + F64ConvertI64S => Self::F64ConvertI64S, + F64ConvertI64U => Self::F64ConvertI64U, + F64PromoteF32 => Self::F64PromoteF32, + I32ReinterpretF32 => Self::I32ReinterpretF32, + I64ReinterpretF64 => Self::I64ReinterpretF64, + F32ReinterpretI32 => Self::F32ReinterpretI32, + F64ReinterpretI64 => Self::F64ReinterpretI64, + _ => { + return Err(crate::Error::UnsupportedFeature(format!( + "Unsupported instruction: {:?}", + value + ))) + } + }; + + Ok(v) + } +} diff --git a/crates/tinywasm/src/module/mod.rs b/crates/tinywasm/src/module/mod.rs index a50235a..94f4b78 100644 --- a/crates/tinywasm/src/module/mod.rs +++ b/crates/tinywasm/src/module/mod.rs @@ -1,22 +1,21 @@ use alloc::{format, vec, vec::Vec}; use wasmparser::{Export, FuncType, Validator}; -use crate::{ - runtime::{FuncAddr, ModuleFunc}, - Error, Result, Store, WasmValue, -}; +use crate::{runtime::FuncAddr, Error, Result, Store, WasmValue}; use self::reader::ModuleReader; +pub mod data; +pub mod instructions; pub mod reader; #[derive(Debug)] pub struct Module<'data> { - reader: ModuleReader<'data>, + data: ModuleReader<'data>, } impl<'data> Module<'data> { - pub fn try_new(wasm: &'data [u8]) -> Result> { + pub fn from_bytes(wasm: &'data [u8]) -> Result> { let mut validator = Validator::new(); let mut reader = ModuleReader::new(); @@ -27,22 +26,19 @@ impl<'data> Module<'data> { return Error::other("End not reached"); } - Ok(Self { reader }) + Ok(Self { data: reader }) } /// Instantiate the module in the given store /// See https://webassembly.github.io/spec/core/exec/modules.html#exec-instantiation /// Runs the start function if it exists /// If you want to run the start function yourself, use `ModuleInstance::new` - pub fn instantiate<'m>( - &'m self, + pub fn instantiate( + &self, store: &'data mut Store<'data>, // imports: Option<()>, - ) -> Result> - where - 'm: 'data, - { - let i = ModuleInstance::new(store, &self)?; + ) -> Result> { + let i = ModuleInstance::new(store, self)?; let _ = i.start()?; Ok(i) } @@ -52,12 +48,10 @@ impl<'data> Module<'data> { /// Addrs are indices into the store's data structures. /// See https://webassembly.github.io/spec/core/exec/runtime.html#module-instances #[derive(Debug)] -pub struct ModuleInstance<'m, 'data> { - pub(crate) module: &'m Module<'data>, - +pub struct ModuleInstance<'data> { pub(crate) func_start: Option, pub(crate) types: Vec, - pub(crate) func_addrs: Vec, + // pub(crate) func_addrs: Vec, // pub table_addrs: Vec, // pub mem_addrs: Vec, // pub global_addrs: Vec, @@ -66,36 +60,39 @@ pub struct ModuleInstance<'m, 'data> { pub(crate) exports: Vec>, } -impl<'m, 'data> ModuleInstance<'m, 'data> -where - 'm: 'data, -{ +#[derive(Debug)] +pub struct ModuleFunc { + pub ty: FuncType, + pub code: FuncAddr, +} + +impl<'data> ModuleInstance<'data> { /// Get an exported function by name pub fn get_func(&self, name: &str) -> Option { let export = self .exports .iter() .find(|e| e.name == name && e.kind == wasmparser::ExternalKind::Func)?; - let func_addr = self.func_addrs.get(export.index as usize)?; + // let func_addr = self.func_addrs.get(export.index as usize)?; Some(ModuleFunc { - code: *func_addr, - ty: self.types.get(*func_addr as usize)?.clone(), + code: export.index, + ty: self.types.get(export.index as usize)?.clone(), }) } pub fn get_start_func(&self) -> Option { - let func_addr = self.func_addrs.get(self.func_start? as usize)?; + let func_addr = self.func_start?; Some(ModuleFunc { - code: *func_addr, - ty: self.types.get(*func_addr as usize)?.clone(), + code: func_addr, + ty: self.types.get(func_addr as usize)?.clone(), }) } - pub fn new(store: &'data mut Store<'data>, module: &'m Module<'data>) -> Result { + pub fn new(store: &'data mut Store<'data>, module: &Module<'data>) -> Result { let types = module - .reader + .data .type_section .as_ref() .map(|s| { @@ -110,21 +107,21 @@ where .transpose()? .unwrap_or_default(); - let func_addrs = module - .reader - .function_section - .as_ref() - .map(|s| { - s.clone() - .into_iter() - .map(|f| Ok(f?)) - .collect::>>() - }) - .transpose()? - .unwrap_or_default(); + // let func_addrs = module + // .data + // .function_section + // .as_ref() + // .map(|s| { + // s.clone() + // .into_iter() + // .map(|f| Ok(f?)) + // .collect::>>() + // }) + // .transpose()? + // .unwrap_or_default(); let exports = module - .reader + .data .export_section .as_ref() .map(|s| { @@ -135,14 +132,12 @@ where }) .transpose()? .unwrap_or_default(); - let func_start = module.reader.start_func; + let func_start = module.data.start_func; - store.initialize(&module.reader)?; + store.initialize(&module.data)?; Ok(Self { - module, types, func_start, - func_addrs, // table_addrs, // mem_addrs, // global_addrs, diff --git a/crates/tinywasm/src/module/reader.rs b/crates/tinywasm/src/module/reader.rs index 082296c..7bcface 100644 --- a/crates/tinywasm/src/module/reader.rs +++ b/crates/tinywasm/src/module/reader.rs @@ -2,9 +2,7 @@ use alloc::{format, vec::Vec}; use core::fmt::Debug; use tracing::debug; use wasmparser::{ - DataSectionReader, ElementSectionReader, ExportSectionReader, FunctionBody, - FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader, Payload, - TableSectionReader, TypeSectionReader, Validator, + ExportSectionReader, FunctionBody, FunctionSectionReader, Payload, TypeSectionReader, Validator, }; use crate::{Error, Result}; @@ -19,12 +17,12 @@ pub struct ModuleReader<'a> { pub export_section: Option>, pub code_section: Option>, - pub table_section: Option>, - pub memory_section: Option>, - pub global_section: Option>, - pub element_section: Option>, - pub data_section: Option>, - pub import_section: Option>, + // pub table_section: Option>, + // pub memory_section: Option>, + // pub global_section: Option>, + // pub element_section: Option>, + // pub data_section: Option>, + // pub import_section: Option>, pub end_reached: bool, } @@ -34,14 +32,14 @@ impl Debug for ModuleReader<'_> { .field("version", &self.version) .field("type_section", &self.type_section) .field("function_section", &self.function_section) - .field("table_section", &self.table_section) - .field("memory_section", &self.memory_section) - .field("global_section", &self.global_section) - .field("element_section", &self.element_section) - .field("data_section", &self.data_section) .field("code_section", &self.code_section) - .field("import_section", &self.import_section) .field("export_section", &self.export_section) + // .field("table_section", &self.table_section) + // .field("memory_section", &self.memory_section) + // .field("global_section", &self.global_section) + // .field("element_section", &self.element_section) + // .field("data_section", &self.data_section) + // .field("import_section", &self.import_section) .finish() } } @@ -118,6 +116,10 @@ impl<'a> ModuleReader<'a> { } CodeSectionStart { count, range, .. } => { debug!("Found code section ({} functions)", count); + if self.code_section.is_some() { + return Error::other("Code section already found"); + } + validator.code_section_start(count, &range)?; self.code_section = Some(CodeSection::new()); } diff --git a/crates/tinywasm/src/runtime/types.rs b/crates/tinywasm/src/runtime/types.rs index f96c406..2a09fc4 100644 --- a/crates/tinywasm/src/runtime/types.rs +++ b/crates/tinywasm/src/runtime/types.rs @@ -1,8 +1,4 @@ -use alloc::{string::String, vec::Vec}; -use wasmparser::{FuncType, OperatorsIterator, ValType}; - -/// A WebAssembly Label -pub struct Label(Addr); +use alloc::string::String; /// A WebAssembly Address. /// These are indexes into the respective stores. @@ -15,29 +11,29 @@ pub type GlobalAddr = Addr; pub type ElmAddr = Addr; pub type DataAddr = Addr; pub type ExternAddr = Addr; +// additional internal addresses +pub type TypeAddr = Addr; +pub type LocalAddr = Addr; +pub type LabelAddr = 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 code: FuncAddr, -} -pub struct Func<'a> { - pub ty: FuncType, - pub locals: Vec, - pub body: Vec>, -} +// #[derive(Debug)] +// pub enum FuncInst { +// Host(HostFunc), +// Module(ModuleFunc), +// } +// #[derive(Debug)] +// pub struct HostFunc { +// pub ty: FuncType, +// pub hostcode: fn() -> (), +// } + +// pub struct Func<'a> { +// pub ty: FuncType, +// pub locals: Vec, +// pub body: Vec>, +// } /// A WebAssembly Export Instance. /// https://webassembly.github.io/spec/core/exec/runtime.html#export-instances -- cgit v1.3.1