diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/cli/Cargo.toml | 2 | ||||
| -rw-r--r-- | crates/cli/src/bin.rs | 6 | ||||
| -rw-r--r-- | crates/parser/Cargo.toml | 5 | ||||
| -rw-r--r-- | crates/parser/src/conversion.rs | 32 | ||||
| -rw-r--r-- | crates/parser/src/lib.rs | 11 | ||||
| -rw-r--r-- | crates/parser/src/module.rs | 8 | ||||
| -rw-r--r-- | crates/tinywasm/Cargo.toml | 11 | ||||
| -rw-r--r-- | crates/tinywasm/src/error.rs | 25 | ||||
| -rw-r--r-- | crates/tinywasm/src/lib.rs | 12 | ||||
| -rw-r--r-- | crates/tinywasm/src/module.rs | 5 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/executer.rs | 4 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/value.rs | 10 | ||||
| -rw-r--r-- | crates/types/Cargo.toml | 7 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 12 |
14 files changed, 112 insertions, 38 deletions
diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index d34aeff..1f34a67 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -10,7 +10,7 @@ path="src/bin.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tinywasm={path="../tinywasm"} +tinywasm={path="../tinywasm", features=["std", "parser"]} argh="0.1" color-eyre={version="0.6", default-features=false} log="0.4" diff --git a/crates/cli/src/bin.rs b/crates/cli/src/bin.rs index 2e05f8a..f9c9f63 100644 --- a/crates/cli/src/bin.rs +++ b/crates/cli/src/bin.rs @@ -95,12 +95,16 @@ fn main() -> Result<()> { fn run(module: Module) -> Result<()> { let mut store = tinywasm::Store::default(); - let instance = module.instantiate(&mut store)?; let func = instance.get_typed_func::<(i32, i32), (i32,)>(&store, "add")?; let (res,) = func.call(&mut store, (2, 2))?; info!("{res:?}"); + // let func = instance.get_func(&store, "add")?; + // let params = vec![WasmValue::I32(2), WasmValue::I32(2)]; + // let res = func.call(&mut store, ¶ms)?; + // info!("{res:?}"); + Ok(()) } diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index e45d452..17c5557 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -7,9 +7,10 @@ edition="2021" # fork of wasmparser with no_std support, see https://github.com/bytecodealliance/wasmtime/issues/3495 # TODO: create dependency free parser wasmparser={version="0.100", package="wasmparser-nostd", default-features=false} -log="0.4" +log={version="0.4", optional=true} tinywasm-types={path="../types"} [features] -default=["std"] +default=["std", "logging"] +logging=["log"] std=[] diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index d08df9b..82ceddd 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -1,5 +1,6 @@ use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use tinywasm_types::{BlockArgs, Export, ExternalKind, FuncType, Instruction, MemArg, ValType}; +use wasmparser::{FuncValidator, ValidatorResources}; use crate::{module::CodeSection, Result}; @@ -24,23 +25,28 @@ pub(crate) fn convert_module_export(export: wasmparser::Export) -> Result<Export }) } -pub(crate) fn convert_module_code(func: wasmparser::FunctionBody) -> Result<CodeSection> { +pub(crate) fn convert_module_code( + func: wasmparser::FunctionBody, + mut validator: FuncValidator<ValidatorResources>, +) -> Result<CodeSection> { let locals_reader = func.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| convert_valtype(&l.1)), - ); + + for (i, local) in locals_reader.into_iter().enumerate() { + let local = local?; + for _ in 0..local.0 { + locals.push(convert_valtype(&local.1)); + } + validator.define_locals(i, local.0, local.1)?; + } if locals.len() != count as usize { return Err(crate::ParseError::Other("Invalid local index".to_string())); } let body_reader = func.get_operators_reader()?; - let body = process_operators(body_reader.into_iter())?; + let body = process_operators(body_reader.into_iter(), validator)?; Ok(CodeSection { locals: locals.into_boxed_slice(), @@ -106,12 +112,18 @@ pub(crate) fn convert_memarg(memarg: wasmparser::MemArg) -> MemArg { pub fn process_operators<'a>( ops: impl Iterator<Item = Result<wasmparser::Operator<'a>, wasmparser::BinaryReaderError>>, + mut validator: FuncValidator<ValidatorResources>, ) -> Result<Box<[Instruction]>> { let mut instructions = Vec::new(); + let mut offset = 0; for op in ops { + let op = op?; + validator.op(offset, &op)?; + offset += 1; + use wasmparser::Operator::*; - let res = match op? { + let res = match op { BrTable { targets } => { let def = targets.default(); let targets = targets @@ -303,5 +315,7 @@ pub fn process_operators<'a>( instructions.push(res); } + validator.finish(offset)?; + Ok(instructions.into_boxed_slice()) } diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 31e8cc8..343350a 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -5,6 +5,17 @@ mod std; extern crate alloc; +// log for logging (optional). +#[cfg(feature = "logging")] +#[allow(clippy::single_component_path_imports)] +use log; + +#[cfg(not(feature = "logging"))] +mod log { + macro_rules! debug ( ($($tt:tt)*) => {{}} ); + pub(crate) use debug; +} + mod conversion; mod error; mod module; diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 5bdbcd8..69bb894 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -1,6 +1,6 @@ +use crate::log::debug; use alloc::{boxed::Box, format, vec::Vec}; use core::fmt::Debug; -use log::debug; use tinywasm_types::{Export, FuncType, Instruction, ValType}; use wasmparser::{Payload, Validator}; @@ -124,9 +124,11 @@ impl ModuleReader { } CodeSectionEntry(function) => { debug!("Found code section entry"); - validator.code_section_entry(&function)?; + let v = validator.code_section_entry(&function)?; + let func_validator = v.into_validator(Default::default()); - self.code_section.push(conversion::convert_module_code(function)?); + self.code_section + .push(conversion::convert_module_code(function, func_validator)?); } ImportSection(_reader) => { return Err(ParseError::UnsupportedSection("Import section".into())); diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index ded786f..421ec37 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -9,12 +9,13 @@ path="src/lib.rs" crate-type=["cdylib", "rlib"] [dependencies] -log="0.4" -tinywasm-parser={path="../parser", default-features=false} +log={version="0.4", optional=true} +tinywasm-parser={path="../parser", default-features=false, optional=true} tinywasm-types={path="../types", default-features=false} - wasmparser={version="0.100", package="wasmparser-nostd", default-features=false} [features] -default=["std"] -std=["tinywasm-parser/std", "tinywasm-types/std"] +default=["std", "parser", "logging"] +logging=["log", "tinywasm-types/logging", "tinywasm-parser?/logging"] +std=["tinywasm-parser?/std", "tinywasm-types/std"] +parser=["tinywasm-parser"] diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index bc7028d..c186e46 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -1,10 +1,17 @@ use alloc::string::{String, ToString}; use core::fmt::Display; + +#[cfg(feature = "parser")] use tinywasm_parser::ParseError; #[derive(Debug)] pub enum Error { + #[cfg(feature = "parser")] ParseError(ParseError), + + #[cfg(feature = "std")] + Io(crate::std::io::Error), + UnsupportedFeature(String), Other(String), @@ -12,26 +19,25 @@ pub enum Error { StackUnderflow, BlockStackUnderflow, CallStackEmpty, - InvalidStore, - - #[cfg(feature = "std")] - Io(crate::std::io::Error), } impl Display for Error { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { + #[cfg(feature = "parser")] + Self::ParseError(err) => write!(f, "error parsing module: {:?}", err), + + #[cfg(feature = "std")] + Self::Io(err) => write!(f, "I/O error: {}", err), + + Self::Other(message) => write!(f, "unknown error: {}", message), + Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {}", feature), Self::FuncDidNotReturn => write!(f, "function did not return"), Self::BlockStackUnderflow => write!(f, "block stack underflow"), Self::StackUnderflow => write!(f, "stack underflow"), - Self::ParseError(err) => write!(f, "error parsing module: {:?}", err), - Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {}", feature), Self::CallStackEmpty => write!(f, "call stack empty"), - Self::Other(message) => write!(f, "unknown error: {}", message), Self::InvalidStore => write!(f, "invalid store"), - #[cfg(feature = "std")] - Self::Io(err) => write!(f, "I/O error: {}", err), } } } @@ -48,6 +54,7 @@ impl Error { } } +#[cfg(feature = "parser")] impl From<tinywasm_parser::ParseError> for Error { fn from(value: tinywasm_parser::ParseError) -> Self { Self::ParseError(value) diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 03e5cac..c09afb8 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -5,6 +5,17 @@ mod std; extern crate alloc; +// log for logging (optional). +#[cfg(feature = "logging")] +#[allow(clippy::single_component_path_imports)] +use log; + +#[cfg(not(feature = "logging"))] +pub(crate) mod log { + macro_rules! debug ( ($($tt:tt)*) => {{}} ); + pub(crate) use debug; +} + mod error; pub use error::*; @@ -23,6 +34,7 @@ pub use export::ExportInstance; pub mod func; pub use func::{FuncHandle, TypedFuncHandle}; +#[cfg(feature = "parser")] pub use tinywasm_parser as parser; pub use tinywasm_types::*; pub mod runtime; diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index 41ad860..740b4b7 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -14,20 +14,21 @@ impl From<TinyWasmModule> for Module { } impl Module { + #[cfg(feature = "parser")] pub fn parse_bytes(wasm: &[u8]) -> Result<Self> { let parser = tinywasm_parser::Parser::new(); let data = parser.parse_module_bytes(wasm)?; Ok(data.into()) } - #[cfg(feature = "std")] + #[cfg(all(feature = "parser", feature = "std"))] pub fn parse_file(path: impl AsRef<crate::std::path::Path> + Clone) -> Result<Self> { let parser = tinywasm_parser::Parser::new(); let data = parser.parse_module_file(path)?; Ok(data.into()) } - #[cfg(feature = "std")] + #[cfg(all(feature = "parser", feature = "std"))] pub fn parse_stream(stream: impl crate::std::io::Read) -> Result<Self> { let parser = tinywasm_parser::Parser::new(); let data = parser.parse_module_stream(stream)?; diff --git a/crates/tinywasm/src/runtime/executer.rs b/crates/tinywasm/src/runtime/executer.rs index 85a9823..f41ff89 100644 --- a/crates/tinywasm/src/runtime/executer.rs +++ b/crates/tinywasm/src/runtime/executer.rs @@ -1,9 +1,9 @@ use super::{Runtime, Stack}; -use crate::{Error, Result}; +use crate::{log::debug, Error, Result}; use alloc::vec; -use log::debug; use tinywasm_types::Instruction; +#[allow(dead_code)] enum BlockMarker { Top, Loop, diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index 534d245..fd497ce 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -1,11 +1,19 @@ +use core::fmt::Debug; + use tinywasm_types::{ValType, WasmValue}; /// A raw wasm value. /// This is the internal representation of all wasm values /// See [`WasmValue`] for the public representation. -#[derive(Debug, Clone, Copy, Default)] +#[derive(Clone, Copy, Default)] pub struct RawWasmValue(u64); +impl Debug for RawWasmValue { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "RawWasmValue({})", self.0) + } +} + impl RawWasmValue { pub fn attach_type(self, ty: ValType) -> WasmValue { match ty { diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index e7f6f92..082723f 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -5,9 +5,10 @@ edition="2021" [dependencies] log={version="0.4", optional=true} -rkyv={version="0.7", optional=true, default-features=false} +rkyv={version="0.7", optional=true, default-features=false, features=["size_32"]} [features] -default=["std"] -std=[] +default=["std", "logging"] +std=["rkyv/std"] serialize=["dep:rkyv", "dep:log"] +logging=["dep:log"] diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 875deaf..90c4f10 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -1,5 +1,17 @@ extern crate alloc; +// log for logging (optional). +// #[cfg(feature = "logging")] +// #[allow(unused_imports)] +// use log; + +// #[cfg(not(feature = "logging"))] +// #[macro_use] +// pub(crate) mod log { +// // macro_rules! debug ( ($($tt:tt)*) => {{}} ); +// // pub(crate) use debug; +// } + mod instructions; use core::fmt::Debug; |
