summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/cli/bin.rs2
-rw-r--r--crates/tinywasm/src/error.rs10
-rw-r--r--crates/tinywasm/src/module/data.rs68
-rw-r--r--crates/tinywasm/src/module/instructions.rs399
-rw-r--r--crates/tinywasm/src/module/mod.rs89
-rw-r--r--crates/tinywasm/src/module/reader.rs32
-rw-r--r--crates/tinywasm/src/runtime/types.rs46
7 files changed, 557 insertions, 89 deletions
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<Self> {
+ 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::<Result<Vec<Instruction>>>()?;
+
+ 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<str>,
+ /// 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<u16>,
+ pub start_func: Option<u32>,
+
+ pub types: Box<[FuncType]>,
+ pub functions: Box<[Function]>,
+ pub exports: Box<[Export]>,
+ // pub tables: Option<TableType>,
+ // pub memories: Option<MemoryType>,
+ // pub globals: Option<GlobalType>,
+ // pub elements: Option<ElementSectionReader<'a>>,
+ // pub imports: Option<ImportSectionReader<'a>>,
+ // pub data_segments: Option<DataSectionReader<'a>>,
+}
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>, 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<wasmparser::Operator<'_>> for Instruction {
+ type Error = crate::Error;
+
+ fn try_from(value: wasmparser::Operator<'_>) -> Result<Self> {
+ 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::<Result<Vec<u32>>>()?;
+
+ 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<Module<'data>> {
+ pub fn from_bytes(wasm: &'data [u8]) -> Result<Module<'data>> {
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<ModuleInstance<'m, 'data>>
- where
- 'm: 'data,
- {
- let i = ModuleInstance::new(store, &self)?;
+ ) -> Result<ModuleInstance<'data>> {
+ 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<FuncAddr>,
pub(crate) types: Vec<FuncType>,
- pub(crate) func_addrs: Vec<FuncAddr>,
+ // pub(crate) func_addrs: Vec<FuncAddr>,
// pub table_addrs: Vec<TableAddr>,
// pub mem_addrs: Vec<MemAddr>,
// pub global_addrs: Vec<GlobalAddr>,
@@ -66,36 +60,39 @@ pub struct ModuleInstance<'m, 'data> {
pub(crate) exports: Vec<Export<'data>>,
}
-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<ModuleFunc> {
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<ModuleFunc> {
- 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<Self> {
+ pub fn new(store: &'data mut Store<'data>, module: &Module<'data>) -> Result<Self> {
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::<Result<Vec<_>>>()
- })
- .transpose()?
- .unwrap_or_default();
+ // let func_addrs = module
+ // .data
+ // .function_section
+ // .as_ref()
+ // .map(|s| {
+ // s.clone()
+ // .into_iter()
+ // .map(|f| Ok(f?))
+ // .collect::<Result<Vec<_>>>()
+ // })
+ // .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<ExportSectionReader<'a>>,
pub code_section: Option<CodeSection<'a>>,
- pub table_section: Option<TableSectionReader<'a>>,
- pub memory_section: Option<MemorySectionReader<'a>>,
- pub global_section: Option<GlobalSectionReader<'a>>,
- pub element_section: Option<ElementSectionReader<'a>>,
- pub data_section: Option<DataSectionReader<'a>>,
- pub import_section: Option<ImportSectionReader<'a>>,
+ // pub table_section: Option<TableSectionReader<'a>>,
+ // pub memory_section: Option<MemorySectionReader<'a>>,
+ // pub global_section: Option<GlobalSectionReader<'a>>,
+ // pub element_section: Option<ElementSectionReader<'a>>,
+ // pub data_section: Option<DataSectionReader<'a>>,
+ // pub import_section: Option<ImportSectionReader<'a>>,
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<ValType>,
- pub body: Vec<OperatorsIterator<'a>>,
-}
+// #[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<ValType>,
+// pub body: Vec<OperatorsIterator<'a>>,
+// }
/// A WebAssembly Export Instance.
/// https://webassembly.github.io/spec/core/exec/runtime.html#export-instances