summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock146
-rw-r--r--crates/cli/Cargo.toml2
-rw-r--r--crates/cli/src/bin.rs6
-rw-r--r--crates/parser/Cargo.toml5
-rw-r--r--crates/parser/src/conversion.rs32
-rw-r--r--crates/parser/src/lib.rs11
-rw-r--r--crates/parser/src/module.rs8
-rw-r--r--crates/tinywasm/Cargo.toml11
-rw-r--r--crates/tinywasm/src/error.rs25
-rw-r--r--crates/tinywasm/src/lib.rs12
-rw-r--r--crates/tinywasm/src/module.rs5
-rw-r--r--crates/tinywasm/src/runtime/executer.rs4
-rw-r--r--crates/tinywasm/src/runtime/value.rs10
-rw-r--r--crates/types/Cargo.toml7
-rw-r--r--crates/types/src/lib.rs12
15 files changed, 258 insertions, 38 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1456976..9b51193 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
+name = "ahash"
+version = "0.7.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -79,6 +90,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
+[[package]]
+name = "bytecheck"
+version = "0.6.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627"
+dependencies = [
+ "bytecheck_derive",
+ "ptr_meta",
+ "simdutf8",
+]
+
+[[package]]
+name = "bytecheck_derive"
+version = "0.6.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -140,12 +185,38 @@ dependencies = [
]
[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
+[[package]]
+name = "getrandom"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
name = "gimli"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
name = "hermit-abi"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -289,6 +360,12 @@ dependencies = [
]
[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
+[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -318,14 +395,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
+name = "rend"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd"
+dependencies = [
+ "bytecheck",
+]
+
+[[package]]
name = "rkyv"
version = "0.7.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58"
dependencies = [
+ "bitvec",
+ "bytecheck",
+ "hashbrown",
"ptr_meta",
+ "rend",
"rkyv_derive",
"seahash",
+ "tinyvec",
+ "uuid",
]
[[package]]
@@ -385,6 +477,12 @@ dependencies = [
]
[[package]]
+name = "simdutf8"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a"
+
+[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -407,6 +505,12 @@ dependencies = [
]
[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
name = "termcolor"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -416,6 +520,21 @@ dependencies = [
]
[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
name = "tinywasm"
version = "0.0.0"
dependencies = [
@@ -467,6 +586,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
+name = "uuid"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
name = "wasm-encoder"
version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -658,3 +795,12 @@ name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+
+[[package]]
+name = "wyz"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
+dependencies = [
+ "tap",
+]
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, &params)?;
+ // 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;