summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2023-12-02 23:50:14 +0100
committerHenry Gressmann <mail@henrygressmann.de>2023-12-02 23:50:14 +0100
commit7f72605405443482add128cb66b7d09e6bb59de9 (patch)
treee59314708468f1aed11fd218868d9fc18f480d3a
parent07a0404aff79a8598392cfa0eed8aea96122adf5 (diff)
feat: finish parser module, switch from tracing to log
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
-rw-r--r--Cargo.lock327
-rw-r--r--crates/cli/Cargo.toml4
-rw-r--r--crates/cli/bin.rs37
-rw-r--r--crates/cli/util.rs13
-rw-r--r--crates/parser/Cargo.toml2
-rw-r--r--crates/parser/src/conversion.rs178
-rw-r--r--crates/parser/src/error.rs1
-rw-r--r--crates/parser/src/lib.rs92
-rw-r--r--crates/parser/src/module.rs91
-rw-r--r--crates/tinywasm/Cargo.toml2
-rw-r--r--crates/tinywasm/src/lib.rs27
-rw-r--r--crates/tinywasm/src/module/reader.rs2
-rw-r--r--crates/tinywasm/src/naive/mod.rs108
-rw-r--r--crates/tinywasm/src/naive/module.rs92
-rw-r--r--crates/types/Cargo.toml2
-rw-r--r--crates/types/src/instructions.rs6
-rw-r--r--crates/types/src/lib.rs7
17 files changed, 562 insertions, 429 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9571d2b..ba2f313 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
+name = "aho-corasick"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "argh"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -64,6 +73,12 @@ dependencies = [
]
[[package]]
+name = "bitflags"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
+
+[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -106,6 +121,29 @@ dependencies = [
]
[[package]]
+name = "env_logger"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
+dependencies = [
+ "humantime",
+ "is-terminal",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "errno"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "eyre"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -122,6 +160,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
+name = "hermit-abi"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -134,6 +184,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590"
[[package]]
+name = "is-terminal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+dependencies = [
+ "hermit-abi",
+ "rustix",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -146,6 +207,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
+name = "linux-raw-sys"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
+
+[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -167,16 +234,6 @@ dependencies = [
]
[[package]]
-name = "nu-ansi-term"
-version = "0.46.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
-dependencies = [
- "overload",
- "winapi",
-]
-
-[[package]]
name = "object"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -192,12 +249,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
-name = "overload"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
-
-[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -210,6 +261,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
+name = "pretty_env_logger"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c"
+dependencies = [
+ "env_logger",
+ "log",
+]
+
+[[package]]
name = "proc-macro2"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -248,6 +309,35 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+
+[[package]]
name = "rkyv"
version = "0.7.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -276,6 +366,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
+name = "rustix"
+version = "0.38.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "seahash"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -311,12 +414,6 @@ dependencies = [
]
[[package]]
-name = "smallvec"
-version = "1.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
-
-[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -339,6 +436,15 @@ dependencies = [
]
[[package]]
+name = "termcolor"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
name = "thread_local"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -352,9 +458,9 @@ dependencies = [
name = "tinywasm"
version = "0.0.0"
dependencies = [
+ "log",
"tinywasm-parser",
"tinywasm-types",
- "tracing",
"wasmparser-nostd",
]
@@ -364,17 +470,17 @@ version = "0.0.0"
dependencies = [
"argh",
"color-eyre",
+ "log",
+ "pretty_env_logger",
"tinywasm",
- "tracing",
- "tracing-subscriber",
]
[[package]]
name = "tinywasm-parser"
version = "0.0.0"
dependencies = [
+ "log",
"tinywasm-types",
- "tracing",
"wasmparser-nostd",
]
@@ -382,8 +488,8 @@ dependencies = [
name = "tinywasm-types"
version = "0.0.0"
dependencies = [
+ "log",
"rkyv",
- "tracing",
]
[[package]]
@@ -393,22 +499,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
- "tracing-attributes",
"tracing-core",
]
[[package]]
-name = "tracing-attributes"
-version = "0.1.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.39",
-]
-
-[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -429,28 +523,14 @@ dependencies = [
]
[[package]]
-name = "tracing-log"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
-dependencies = [
- "log",
- "once_cell",
- "tracing-core",
-]
-
-[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
- "nu-ansi-term",
"sharded-slab",
- "smallvec",
"thread_local",
"tracing-core",
- "tracing-log",
]
[[package]]
@@ -491,7 +571,148 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
+name = "winapi-util"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml
index bfe0391..783ead2 100644
--- a/crates/cli/Cargo.toml
+++ b/crates/cli/Cargo.toml
@@ -13,5 +13,5 @@ path="bin.rs"
tinywasm={path="../tinywasm"}
argh="0.1"
color-eyre="0.6"
-tracing="0.1"
-tracing-subscriber="0.3"
+log="0.4"
+pretty_env_logger="0.5"
diff --git a/crates/cli/bin.rs b/crates/cli/bin.rs
index 2c554cd..9c6908d 100644
--- a/crates/cli/bin.rs
+++ b/crates/cli/bin.rs
@@ -2,9 +2,7 @@ use std::str::FromStr;
use argh::FromArgs;
use color_eyre::eyre::Result;
-use tinywasm::{self, WasmValue};
-use util::install_tracing;
-
+use tinywasm::{self};
mod util;
#[derive(FromArgs)]
@@ -12,6 +10,10 @@ mod util;
struct TinyWasmCli {
#[argh(subcommand)]
nested: TinyWasmSubcommand,
+
+ /// log level
+ #[argh(option, short = 'l', default = "\"info\".to_string()")]
+ log_level: String,
}
#[derive(FromArgs)]
@@ -22,7 +24,6 @@ enum TinyWasmSubcommand {
enum Engine {
Main,
- Naive,
}
impl FromStr for Engine {
@@ -30,7 +31,6 @@ impl FromStr for Engine {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
- "naive" => Ok(Self::Naive),
"main" => Ok(Self::Main),
_ => Err(format!("unknown engine: {}", s)),
}
@@ -52,16 +52,26 @@ struct Run {
fn main() -> Result<()> {
color_eyre::install()?;
- install_tracing(None);
let args: TinyWasmCli = argh::from_env();
+ let level = match args.log_level.as_str() {
+ "trace" => log::LevelFilter::Trace,
+ "debug" => log::LevelFilter::Debug,
+ "warn" => log::LevelFilter::Warn,
+ "error" => log::LevelFilter::Error,
+ "info" => log::LevelFilter::Info,
+ _ => log::LevelFilter::Info,
+ };
+
+ pretty_env_logger::formatted_builder()
+ .filter_level(level)
+ .init();
match args.nested {
TinyWasmSubcommand::Run(Run { wasm_file, engine }) => {
let wasm = std::fs::read(wasm_file)?;
match engine {
Engine::Main => run(&wasm),
- Engine::Naive => run_naive(&wasm),
}
}
}
@@ -78,16 +88,3 @@ fn run(wasm: &[u8]) -> Result<()> {
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::run(&mut module, "add", &args)?;
- println!("res: {:?}", res);
-
- let args = [WasmValue::I64(1), WasmValue::I64(2)];
- let res = tinywasm::naive::run(&mut module, "add_64", &args)?;
- println!("res: {:?}", res);
-
- Ok(())
-}
diff --git a/crates/cli/util.rs b/crates/cli/util.rs
index 2a8160a..8b13789 100644
--- a/crates/cli/util.rs
+++ b/crates/cli/util.rs
@@ -1,14 +1 @@
-pub fn install_tracing(log_level: Option<tracing::Level>) {
- use tracing_subscriber::filter::LevelFilter;
- use tracing_subscriber::prelude::*;
- tracing_subscriber::registry()
- .with(
- tracing_subscriber::fmt::layer()
- .compact()
- .with_filter(LevelFilter::from(
- log_level.unwrap_or(tracing::Level::DEBUG),
- )),
- )
- .init();
-}
diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml
index 590b90c..b187886 100644
--- a/crates/parser/Cargo.toml
+++ b/crates/parser/Cargo.toml
@@ -7,7 +7,7 @@ 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}
-tracing={version="0.1.38", default-features=false} # logging
+log="0.4.20"
tinywasm-types={path="../types"}
[features]
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index c75aaf1..ee30db9 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -1,18 +1,82 @@
-use alloc::{format, vec::Vec};
-use tinywasm_types::{BlockArgs, Instruction, MemArg, ValType};
+use alloc::{boxed::Box, format, string::ToString, vec::Vec};
+use tinywasm_types::{BlockArgs, Export, ExternalKind, FuncType, Instruction, MemArg, ValType};
-use crate::Result;
+use crate::{module::CodeSection, Result};
-fn convert_blocktype(blocktype: wasmparser::BlockType) -> BlockArgs {
+pub(crate) fn convert_module_export(export: wasmparser::Export) -> Result<Export> {
+ let kind = match export.kind {
+ wasmparser::ExternalKind::Func => ExternalKind::Func,
+ wasmparser::ExternalKind::Table => ExternalKind::Table,
+ wasmparser::ExternalKind::Memory => ExternalKind::Memory,
+ wasmparser::ExternalKind::Global => ExternalKind::Global,
+ wasmparser::ExternalKind::Tag => {
+ return Err(crate::ParseError::UnsupportedOperator(format!(
+ "Unsupported export kind: {:?}",
+ export.kind
+ )))
+ }
+ };
+
+ Ok(Export {
+ index: export.index,
+ name: Box::from(export.name),
+ kind,
+ })
+}
+
+pub(crate) fn convert_module_code(func: wasmparser::FunctionBody) -> 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)),
+ );
+
+ 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())?;
+
+ Ok(CodeSection {
+ locals: locals.into_boxed_slice(),
+ body,
+ })
+}
+
+pub(crate) fn convert_module_type(ty: wasmparser::Type) -> Result<FuncType> {
+ let wasmparser::Type::Func(ty) = ty;
+ let params = ty
+ .params()
+ .iter()
+ .map(|p| Ok(convert_valtype(p)))
+ .collect::<Result<Vec<ValType>>>()?
+ .into_boxed_slice();
+
+ let results = ty
+ .results()
+ .iter()
+ .map(|p| Ok(convert_valtype(p)))
+ .collect::<Result<Vec<ValType>>>()?
+ .into_boxed_slice();
+
+ Ok(FuncType { params, results })
+}
+
+pub(crate) fn convert_blocktype(blocktype: &wasmparser::BlockType) -> BlockArgs {
use wasmparser::BlockType::*;
match blocktype {
Empty => BlockArgs::Empty,
Type(ty) => BlockArgs::Type(convert_valtype(ty)),
- FuncType(ty) => BlockArgs::FuncType(ty),
+ FuncType(ty) => BlockArgs::FuncType(*ty),
}
}
-fn convert_valtype(valtype: wasmparser::ValType) -> ValType {
+pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType {
use wasmparser::ValType::*;
match valtype {
I32 => ValType::I32,
@@ -25,14 +89,38 @@ fn convert_valtype(valtype: wasmparser::ValType) -> ValType {
}
}
-fn convert_memarg(memarg: wasmparser::MemArg) -> MemArg {
+pub(crate) fn convert_memarg(memarg: wasmparser::MemArg) -> MemArg {
MemArg {
offset: memarg.offset,
align: memarg.align,
}
}
-pub fn process_operator(op: wasmparser::Operator<'_>) -> Result<Instruction> {
+pub fn process_operators<'a>(
+ ops: impl Iterator<Item = Result<wasmparser::Operator<'a>, wasmparser::BinaryReaderError>>,
+) -> Result<Box<[Instruction]>> {
+ let mut instructions = Vec::new();
+ for op in ops {
+ match op? {
+ wasmparser::Operator::BrTable { targets } => {
+ instructions.push(Instruction::BrTable(targets.default()));
+ instructions.extend(
+ targets
+ .targets()
+ .collect::<Result<Vec<u32>, wasmparser::BinaryReaderError>>()?
+ .into_iter()
+ .map(Instruction::Br),
+ );
+ }
+ op => instructions.push(process_operator(&op)?),
+ }
+ }
+
+ Ok(instructions.into_boxed_slice())
+}
+
+#[inline]
+pub(crate) fn process_operator(op: &wasmparser::Operator) -> Result<Instruction> {
use wasmparser::Operator::*;
let v = match op {
Unreachable => Instruction::Unreachable,
@@ -42,56 +130,48 @@ pub fn process_operator(op: wasmparser::Operator<'_>) -> Result<Instruction> {
If { blockty } => Instruction::If(convert_blocktype(blockty)),
Else => Instruction::Else,
End => Instruction::End,
- Br { relative_depth } => Instruction::Br(relative_depth),
- BrIf { relative_depth } => Instruction::BrIf(relative_depth),
- BrTable { targets } => {
- let default = targets.default();
- let targets = targets
- .targets()
- .map(|t| Ok(t?))
- .collect::<Result<Vec<u32>>>()?;
-
- Instruction::BrTable(targets, default)
- }
+ Br { relative_depth } => Instruction::Br(*relative_depth),
+ BrIf { relative_depth } => Instruction::BrIf(*relative_depth),
+ BrTable { targets } => Instruction::BrTable(targets.default()),
Return => Instruction::Return,
- Call { function_index } => Instruction::Call(function_index),
+ Call { function_index } => Instruction::Call(*function_index),
CallIndirect {
type_index,
table_index,
..
- } => Instruction::CallIndirect(type_index, table_index),
+ } => Instruction::CallIndirect(*type_index, *table_index),
Drop => Instruction::Drop,
Select => Instruction::Select,
- LocalGet { local_index } => Instruction::LocalGet(local_index),
- LocalSet { local_index } => Instruction::LocalSet(local_index),
- LocalTee { local_index } => Instruction::LocalTee(local_index),
- GlobalGet { global_index } => Instruction::GlobalGet(global_index),
- GlobalSet { global_index } => Instruction::GlobalSet(global_index),
+ LocalGet { local_index } => Instruction::LocalGet(*local_index),
+ LocalSet { local_index } => Instruction::LocalSet(*local_index),
+ LocalTee { local_index } => Instruction::LocalTee(*local_index),
+ GlobalGet { global_index } => Instruction::GlobalGet(*global_index),
+ GlobalSet { global_index } => Instruction::GlobalSet(*global_index),
MemorySize { .. } => Instruction::MemorySize,
MemoryGrow { .. } => Instruction::MemoryGrow,
- I32Load { memarg } => Instruction::I32Load(convert_memarg(memarg)),
- I64Load { memarg } => Instruction::I64Load(convert_memarg(memarg)),
- F32Load { memarg } => Instruction::F32Load(convert_memarg(memarg)),
- F64Load { memarg } => Instruction::F64Load(convert_memarg(memarg)),
- I32Load8S { memarg } => Instruction::I32Load8S(convert_memarg(memarg)),
- I32Load8U { memarg } => Instruction::I32Load8U(convert_memarg(memarg)),
- I32Load16S { memarg } => Instruction::I32Load16S(convert_memarg(memarg)),
- I32Load16U { memarg } => Instruction::I32Load16U(convert_memarg(memarg)),
- I64Load8S { memarg } => Instruction::I64Load8S(convert_memarg(memarg)),
- I64Load8U { memarg } => Instruction::I64Load8U(convert_memarg(memarg)),
- I64Load16S { memarg } => Instruction::I64Load16S(convert_memarg(memarg)),
- I64Load16U { memarg } => Instruction::I64Load16U(convert_memarg(memarg)),
- I64Load32S { memarg } => Instruction::I64Load32S(convert_memarg(memarg)),
- I64Load32U { memarg } => Instruction::I64Load32U(convert_memarg(memarg)),
- I32Store { memarg } => Instruction::I32Store(convert_memarg(memarg)),
- I64Store { memarg } => Instruction::I64Store(convert_memarg(memarg)),
- F32Store { memarg } => Instruction::F32Store(convert_memarg(memarg)),
- F64Store { memarg } => Instruction::F64Store(convert_memarg(memarg)),
- I32Store8 { memarg } => Instruction::I32Store8(convert_memarg(memarg)),
- I32Store16 { memarg } => Instruction::I32Store16(convert_memarg(memarg)),
- I64Store8 { memarg } => Instruction::I64Store8(convert_memarg(memarg)),
- I64Store16 { memarg } => Instruction::I64Store16(convert_memarg(memarg)),
- I64Store32 { memarg } => Instruction::I64Store32(convert_memarg(memarg)),
+ I32Load { memarg } => Instruction::I32Load(convert_memarg(*memarg)),
+ I64Load { memarg } => Instruction::I64Load(convert_memarg(*memarg)),
+ F32Load { memarg } => Instruction::F32Load(convert_memarg(*memarg)),
+ F64Load { memarg } => Instruction::F64Load(convert_memarg(*memarg)),
+ I32Load8S { memarg } => Instruction::I32Load8S(convert_memarg(*memarg)),
+ I32Load8U { memarg } => Instruction::I32Load8U(convert_memarg(*memarg)),
+ I32Load16S { memarg } => Instruction::I32Load16S(convert_memarg(*memarg)),
+ I32Load16U { memarg } => Instruction::I32Load16U(convert_memarg(*memarg)),
+ I64Load8S { memarg } => Instruction::I64Load8S(convert_memarg(*memarg)),
+ I64Load8U { memarg } => Instruction::I64Load8U(convert_memarg(*memarg)),
+ I64Load16S { memarg } => Instruction::I64Load16S(convert_memarg(*memarg)),
+ I64Load16U { memarg } => Instruction::I64Load16U(convert_memarg(*memarg)),
+ I64Load32S { memarg } => Instruction::I64Load32S(convert_memarg(*memarg)),
+ I64Load32U { memarg } => Instruction::I64Load32U(convert_memarg(*memarg)),
+ I32Store { memarg } => Instruction::I32Store(convert_memarg(*memarg)),
+ I64Store { memarg } => Instruction::I64Store(convert_memarg(*memarg)),
+ F32Store { memarg } => Instruction::F32Store(convert_memarg(*memarg)),
+ F64Store { memarg } => Instruction::F64Store(convert_memarg(*memarg)),
+ I32Store8 { memarg } => Instruction::I32Store8(convert_memarg(*memarg)),
+ I32Store16 { memarg } => Instruction::I32Store16(convert_memarg(*memarg)),
+ I64Store8 { memarg } => Instruction::I64Store8(convert_memarg(*memarg)),
+ I64Store16 { memarg } => Instruction::I64Store16(convert_memarg(*memarg)),
+ I64Store32 { memarg } => Instruction::I64Store32(convert_memarg(*memarg)),
I32Eqz => Instruction::I32Eqz,
I32Eq => Instruction::I32Eq,
I32Ne => Instruction::I32Ne,
diff --git a/crates/parser/src/error.rs b/crates/parser/src/error.rs
index c99fa01..ee217c7 100644
--- a/crates/parser/src/error.rs
+++ b/crates/parser/src/error.rs
@@ -2,6 +2,7 @@ use alloc::string::{String, ToString};
use wasmparser::Encoding;
pub enum ParseError {
+ InvalidType,
UnsupportedSection(String),
DuplicateSection(String),
EmptySection(String),
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index d2b6d9c..5b17fb8 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -9,49 +9,101 @@ extern crate std;
mod conversion;
mod error;
mod module;
+use alloc::vec::Vec;
pub use error::*;
use module::ModuleReader;
-use tinywasm_types::TinyWasmModule;
+use tinywasm_types::{Function, TinyWasmModule};
+use wasmparser::Validator;
pub struct Parser {}
impl Parser {
pub fn parse_module_bytes(wasm: &[u8]) -> Result<TinyWasmModule> {
- let reader = ModuleReader::new();
- reader.try_into()
- }
+ 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 Err(ParseError::EndNotReached);
+ }
- pub fn parse_module_file(file_name: &str) -> Result<TinyWasmModule> {
- let reader = ModuleReader::new();
reader.try_into()
}
#[cfg(feature = "std")]
- pub fn parse_module_stream(stream: impl std::io::Read) -> Result<TinyWasmModule> {
- let reader = ModuleReader::new();
- reader.try_into()
- }
+ pub fn parse_module_file(path: impl AsRef<crate::std::path::Path>) -> Result<TinyWasmModule> {
+ use alloc::format;
+ let f = crate::std::fs::File::open("log.txt").map_err(|e| {
+ ParseError::Other(format!("Error opening file {:?}: {}", path.as_ref(), e))
+ })?;
- pub fn read_module_bytes(bytes: &[u8]) -> Result<TinyWasmModule> {
- unimplemented!()
- }
- pub fn read_module_file(file_name: &str) -> Result<TinyWasmModule> {
- unimplemented!()
+ let mut reader = crate::std::io::BufReader::new(f);
+ Self::parse_module_stream(&mut reader)
}
+
#[cfg(feature = "std")]
- pub fn read_module_stream(stream: impl std::io::Read) -> Result<TinyWasmModule> {
- unimplemented!()
+ pub fn parse_module_stream(mut stream: impl std::io::Read) -> Result<TinyWasmModule> {
+ use alloc::format;
+
+ let mut validator = Validator::new();
+ let mut reader = ModuleReader::new();
+ let mut buffer = Vec::new();
+ let mut parser = wasmparser::Parser::new(0);
+ let mut eof = false;
+
+ loop {
+ match parser.parse(&buffer, eof)? {
+ wasmparser::Chunk::NeedMoreData(hint) => {
+ let len = buffer.len();
+ buffer.extend((0..hint).map(|_| 0u8));
+ let read_bytes = stream.read(&mut buffer[len..]).map_err(|e| {
+ ParseError::Other(format!("Error reading from stream: {}", e))
+ })?;
+ buffer.truncate(len + read_bytes);
+ eof = read_bytes == 0;
+ }
+ wasmparser::Chunk::Parsed { consumed, payload } => {
+ reader.process_payload(payload, &mut validator)?;
+ buffer.drain(..consumed);
+ if eof || reader.end_reached {
+ return reader.try_into();
+ }
+ }
+ };
+ }
}
}
-impl TryFrom<ModuleReader<'_>> for TinyWasmModule {
+impl TryFrom<ModuleReader> for TinyWasmModule {
type Error = ParseError;
- fn try_from(reader: ModuleReader<'_>) -> Result<Self> {
+ fn try_from(reader: ModuleReader) -> Result<Self> {
if !reader.end_reached {
return Err(ParseError::EndNotReached);
}
- unimplemented!()
+ let func_types = reader.function_section;
+ let funcs = reader
+ .code_section
+ .into_iter()
+ .zip(func_types)
+ .map(|(f, ty)| Function {
+ body: f.body,
+ locals: f.locals,
+ ty,
+ })
+ .collect::<Vec<_>>()
+ .into_boxed_slice();
+
+ Ok(TinyWasmModule {
+ version: reader.version,
+ start_func: reader.start_func,
+ types: reader.type_section.into_boxed_slice(),
+ funcs,
+ exports: reader.export_section.into_boxed_slice(),
+ })
}
}
diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs
index e2e1bde..268bad7 100644
--- a/crates/parser/src/module.rs
+++ b/crates/parser/src/module.rs
@@ -1,21 +1,26 @@
-use alloc::{format, vec::Vec};
+use alloc::{boxed::Box, format, vec::Vec};
use core::fmt::Debug;
-use tracing::debug;
-use wasmparser::{
- ExportSectionReader, FunctionBody, FunctionSectionReader, Payload, TypeSectionReader, Validator,
-};
+use log::debug;
+use tinywasm_types::{Export, FuncType, Instruction, ValType};
+use wasmparser::{Payload, Validator};
-use crate::{ParseError, Result};
+use crate::{conversion, ParseError, Result};
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct CodeSection {
+ pub locals: Box<[ValType]>,
+ pub body: Box<[Instruction]>,
+}
#[derive(Default)]
-pub struct ModuleReader<'a> {
+pub struct ModuleReader {
pub version: Option<u16>,
pub start_func: Option<u32>,
- pub type_section: Option<TypeSectionReader<'a>>,
- pub function_section: Option<FunctionSectionReader<'a>>,
- pub export_section: Option<ExportSectionReader<'a>>,
- pub code_section: Option<CodeSection<'a>>,
+ pub type_section: Vec<FuncType>,
+ pub function_section: Vec<u32>,
+ pub export_section: Vec<Export>,
+ pub code_section: Vec<CodeSection>,
// pub table_section: Option<TableSectionReader<'a>>,
// pub memory_section: Option<MemorySectionReader<'a>>,
@@ -26,8 +31,8 @@ pub struct ModuleReader<'a> {
pub end_reached: bool,
}
-impl Debug for ModuleReader<'_> {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+impl Debug for ModuleReader {
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_struct("ModuleReader")
.field("version", &self.version)
.field("type_section", &self.type_section)
@@ -44,16 +49,12 @@ impl Debug for ModuleReader<'_> {
}
}
-impl<'a> ModuleReader<'a> {
- pub fn new() -> ModuleReader<'a> {
+impl ModuleReader {
+ pub fn new() -> ModuleReader {
Self::default()
}
- pub fn process_payload(
- &mut self,
- payload: Payload<'a>,
- validator: &mut Validator,
- ) -> Result<()> {
+ pub fn process_payload(&mut self, payload: Payload, validator: &mut Validator) -> Result<()> {
use wasmparser::Payload::*;
match payload {
@@ -79,12 +80,18 @@ impl<'a> ModuleReader<'a> {
TypeSection(reader) => {
debug!("Found type section");
validator.type_section(&reader)?;
- self.type_section = Some(reader);
+ self.type_section = reader
+ .into_iter()
+ .map(|t| conversion::convert_module_type(t?))
+ .collect::<Result<Vec<FuncType>>>()?;
}
FunctionSection(reader) => {
debug!("Found function section");
validator.function_section(&reader)?;
- self.function_section = Some(reader);
+ self.function_section = reader
+ .into_iter()
+ .map(|f| Ok(f?))
+ .collect::<Result<Vec<_>>>()?;
}
TableSection(_reader) => {
return Err(ParseError::UnsupportedSection("Table section".into()));
@@ -118,22 +125,18 @@ impl<'a> ModuleReader<'a> {
}
CodeSectionStart { count, range, .. } => {
debug!("Found code section ({} functions)", count);
- if self.code_section.is_some() {
+ if !self.code_section.is_empty() {
return Err(ParseError::DuplicateSection("Code section".into()));
}
validator.code_section_start(count, &range)?;
- self.code_section = Some(CodeSection::new());
}
CodeSectionEntry(function) => {
debug!("Found code section entry");
validator.code_section_entry(&function)?;
- if let Some(code_section) = &mut self.code_section {
- code_section.functions.push(function);
- } else {
- return Err(ParseError::EmptySection("Code section".into()));
- }
+ self.code_section
+ .push(conversion::convert_module_code(function)?);
}
ImportSection(_reader) => {
return Err(ParseError::UnsupportedSection("Import section".into()));
@@ -145,7 +148,10 @@ impl<'a> ModuleReader<'a> {
ExportSection(reader) => {
debug!("Found export section");
validator.export_section(&reader)?;
- self.export_section = Some(reader);
+ self.export_section = reader
+ .into_iter()
+ .map(|e| conversion::convert_module_export(e?))
+ .collect::<Result<Vec<_>>>()?;
}
End(offset) => {
debug!("Reached end of module");
@@ -156,26 +162,17 @@ impl<'a> ModuleReader<'a> {
validator.end(offset)?;
self.end_reached = true;
}
- UnknownSection { .. } | _ => {
- return Err(ParseError::UnsupportedSection(format!("Unknown section")))
+ UnknownSection { .. } => {
+ return Err(ParseError::UnsupportedSection("Unknown section".into()))
+ }
+ section => {
+ return Err(ParseError::UnsupportedSection(format!(
+ "Unsupported section: {:?}",
+ section
+ )))
}
};
Ok(())
}
}
-
-/// A WebAssembly code section
-/// Can be cloned to read functions multiple times
-#[derive(Debug, Clone)]
-pub struct CodeSection<'a> {
- pub(crate) functions: Vec<FunctionBody<'a>>,
-}
-
-impl<'a> CodeSection<'a> {
- fn new() -> Self {
- Self {
- functions: Vec::new(),
- }
- }
-}
diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml
index 0bae290..db4b659 100644
--- a/crates/tinywasm/Cargo.toml
+++ b/crates/tinywasm/Cargo.toml
@@ -7,7 +7,7 @@ edition="2021"
path="src/lib.rs"
[dependencies]
-tracing={version="0.1.38", default-features=false} # logging
+log="0.4.20"
tinywasm-parser={path="../parser"}
tinywasm-types={path="../types"}
diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs
index c362526..da24d19 100644
--- a/crates/tinywasm/src/lib.rs
+++ b/crates/tinywasm/src/lib.rs
@@ -18,27 +18,24 @@ pub use module::ModuleInstance;
pub mod types;
pub use types::*;
-pub mod naive;
pub mod runtime;
#[cfg(test)]
mod tests {
- use crate::std::println;
- use crate::{error::Result, naive, WasmValue};
- #[test]
- fn naive_add() -> Result<()> {
- let wasm = include_bytes!("../../../examples/wasm/add.wasm");
- let mut module = naive::Module::new(wasm)?;
+ // #[test]
+ // fn naive_add() -> Result<()> {
+ // let wasm = include_bytes!("../../../examples/wasm/add.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::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);
+ // let args = [WasmValue::I64(1), WasmValue::I64(2)];
+ // let res = naive::run(&mut module, "add_64", &args)?;
+ // println!("res: {:?}", res);
- Ok(())
- }
+ // Ok(())
+ // }
}
diff --git a/crates/tinywasm/src/module/reader.rs b/crates/tinywasm/src/module/reader.rs
index 7bcface..062cf45 100644
--- a/crates/tinywasm/src/module/reader.rs
+++ b/crates/tinywasm/src/module/reader.rs
@@ -1,6 +1,6 @@
use alloc::{format, vec::Vec};
use core::fmt::Debug;
-use tracing::debug;
+use log::debug;
use wasmparser::{
ExportSectionReader, FunctionBody, FunctionSectionReader, Payload, TypeSectionReader, Validator,
};
diff --git a/crates/tinywasm/src/naive/mod.rs b/crates/tinywasm/src/naive/mod.rs
deleted file mode 100644
index e92bf7f..0000000
--- a/crates/tinywasm/src/naive/mod.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-use alloc::{format, string::ToString, vec, vec::Vec};
-use tracing::info;
-use wasmparser::Operator;
-
-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
- .exports
- .iter()
- .find(|e| e.name == func_name)
- .ok_or_else(|| Error::Other(format!("Function {} not found", func_name)))?;
-
- let func_type_index = module.functions[func.index as usize];
- let func_type = &module.types[func_type_index as usize];
-
- info!("func_type: {:#?}", func_type);
- let code = &mut module.code[func.index as usize];
- code.allow_memarg64(false);
-
- let mut locals = vec![];
- for ty in func_type.params() {
- locals.push(*ty);
- }
-
- let mut returns = vec![];
- for ty in func_type.results() {
- returns.push(*ty);
- }
-
- let locals_reader = code.get_locals_reader().unwrap();
- for local in locals_reader.into_iter() {
- let local = local.unwrap();
- if locals.len() != local.0 as usize {
- panic!("Invalid local index");
- }
- locals.push(local.1);
- }
-
- let mut local_values = vec![];
- let body = code.get_operators_reader().unwrap().into_iter();
- for (i, arg) in args.iter().enumerate() {
- // if !arg.is(locals[i]) {
- // return Error::other(&format!(
- // "Invalid argument type for {}, index {}: expected {:?}, got {:?}",
- // func_name,
- // i,
- // locals[i],
- // arg.type_of()
- // ));
- // }
-
- local_values.push(arg);
- }
-
- let mut stack: Vec<WasmValue> = vec![];
- for op in body {
- let op = op.unwrap();
- info!("op: {:#?}", op);
-
- match op {
- Operator::LocalGet { local_index } => {
- let local = locals.get(local_index as usize).unwrap();
- let val = local_values[local_index as usize];
- info!("local: {:#?}", local);
- stack.push(val.clone());
- }
- Operator::I64Add => {
- let a = stack.pop().unwrap();
- let b = stack.pop().unwrap();
- let (WasmValue::I64(a), WasmValue::I64(b)) = (a, b) else {
- panic!("Invalid type");
- };
- let c = WasmValue::I64(a + b);
- stack.push(c);
- }
- Operator::I32Add => {
- let a = stack.pop().unwrap();
- let b = stack.pop().unwrap();
- let (WasmValue::I32(a), WasmValue::I32(b)) = (a, b) else {
- panic!("Invalid type");
- };
- let c = WasmValue::I32(a + b);
- stack.push(c);
- }
- Operator::End => {
- info!("stack: {:#?}", stack);
- let res = returns
- .iter()
- .map(|ty| {
- let val = stack.pop()?;
- // (val.is(*ty)).then_some(val)
- Some(val)
- })
- .collect::<Option<Vec<_>>>()
- .ok_or_else(|| Error::Other("Invalid return type".to_string()))?;
-
- return Ok(res);
- }
- _ => {}
- }
- }
-
- Error::other("End not reached")
-}
diff --git a/crates/tinywasm/src/naive/module.rs b/crates/tinywasm/src/naive/module.rs
deleted file mode 100644
index 24f2d55..0000000
--- a/crates/tinywasm/src/naive/module.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-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/types/Cargo.toml b/crates/types/Cargo.toml
index fa2fc6e..e34c474 100644
--- a/crates/types/Cargo.toml
+++ b/crates/types/Cargo.toml
@@ -4,7 +4,7 @@ version="0.0.0"
edition="2021"
[dependencies]
-tracing={version="0.1.38", default-features=false} # logging
+log="0.4.20"
rkyv={version="0.7", optional=true, default-features=false}
[features]
diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs
index 993b260..dca99fe 100644
--- a/crates/types/src/instructions.rs
+++ b/crates/types/src/instructions.rs
@@ -1,5 +1,4 @@
use super::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr, ValType};
-use alloc::{format, vec::Vec};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BlockArgs {
@@ -9,7 +8,7 @@ pub enum BlockArgs {
}
/// Represents a memory immediate in a WebAssembly memory instruction.
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct MemArg {
pub align: u8,
pub offset: u64,
@@ -18,6 +17,7 @@ pub struct MemArg {
/// A WebAssembly Instruction
/// See https://webassembly.github.io/spec/core/binary/instructions.html
/// Currently includes all instructions from the MVP (1.0) spec
+#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Instruction {
// Control Instructions
// See https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions
@@ -30,7 +30,7 @@ pub enum Instruction {
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
+ BrTable(u32), // not to spec, has to be followed by multiple Br instructions with labels
Return,
Call(FuncAddr),
CallIndirect(TypeAddr, TableAddr),
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index e793b26..af5cf1a 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -7,9 +7,9 @@ pub struct TinyWasmModule {
pub version: Option<u16>,
pub start_func: Option<u32>,
- pub types: Option<Box<[FuncType]>>,
- pub funcs: Option<Box<[Function]>>,
- pub exports: Option<Box<[Export]>>,
+ pub types: Box<[FuncType]>,
+ pub funcs: Box<[Function]>,
+ pub exports: Box<[Export]>,
// pub tables: Option<TableType>,
// pub memories: Option<MemoryType>,
// pub globals: Option<GlobalType>,
@@ -98,6 +98,7 @@ pub struct FuncType {
/// A WebAssembly Function
pub struct Function {
+ pub ty: TypeAddr,
pub locals: Box<[ValType]>,
pub body: Box<[Instruction]>,
}