From 2840c8ae978d7fe493c66d87a41754cfa4c9ac8b Mon Sep 17 00:00:00 2001 From: Able Date: Thu, 11 Nov 2021 15:30:45 -0600 Subject: [PATCH] wasm_exer --- .gitignore | 1 + Cargo.lock | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 10 +++ src/main.rs | 105 ++++++++++++++++++++++++ src/test.wat | 16 ++++ 5 files changed, 358 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs create mode 100644 src/test.wat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9a1d97d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,226 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ableos-wasm-loader" +version = "0.1.0" +dependencies = [ + "wabt", + "wasmi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cmake" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089" +dependencies = [ + "cc", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "libc" +version = "0.2.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "parity-wasm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + +[[package]] +name = "proc-macro2" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wabt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" +dependencies = [ + "serde", + "serde_derive", + "serde_json", + "wabt-sys", +] + +[[package]] +name = "wabt-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" +dependencies = [ + "cc", + "cmake", + "glob", +] + +[[package]] +name = "wasmi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca00c5147c319a8ec91ec1a0edbec31e566ce2c9cc93b3f9bb86a9efd0eb795d" +dependencies = [ + "downcast-rs", + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "165343ecd6c018fc09ebcae280752702c9a2ef3e6f8d02f1cfcbdb53ef6d7937" +dependencies = [ + "parity-wasm", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..32f233a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ableos-wasm-loader" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +wasmi="*" +wabt="*" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..bba0fbf --- /dev/null +++ b/src/main.rs @@ -0,0 +1,105 @@ +extern crate wabt; +extern crate wasmi; + +use wasmi::{ + Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, ModuleInstance, + RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, +}; + +pub const KILL: usize = 0; +pub const ADD_FUNC_INDEX: usize = 1; + +struct HostFunctions; +impl HostFunctions { + fn check_signature(&self, index: usize, signature: &Signature) -> bool { + let (params, ret_ty): (&[ValueType], Option) = match index { + ADD_FUNC_INDEX => (&[ValueType::I32, ValueType::I32], Some(ValueType::I32)), + _ => return false, + }; + signature.params() == params && signature.return_type() == ret_ty + } +} + +impl Externals for HostFunctions { + fn invoke_index( + &mut self, + index: usize, + args: RuntimeArgs, + ) -> Result, Trap> { + match index { + ADD_FUNC_INDEX => { + println!("you pe"); + let a: u32 = args.nth_checked(0)?; + let b: u32 = args.nth_checked(1)?; + let result = a + b; + + Ok(Some(RuntimeValue::I32(result as i32))) + } + _ => panic!("Unimplemented function at {}", index), + } + } +} +impl ModuleImportResolver for HostFunctions { + fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { + let index = match field_name { + "add" => ADD_FUNC_INDEX, + _ => { + return Err(Error::Instantiation(format!( + "Export {} not found", + field_name + ))) + } + }; + + if !self.check_signature(index, signature) { + return Err(Error::Instantiation(format!( + "Export {} has a bad signature", + field_name + ))); + } + + Ok(FuncInstance::alloc_host( + Signature::new(&[ValueType::I32, ValueType::I32][..], Some(ValueType::I32)), + index, + )) + } +} + +fn main() { + // Parse WAT (WebAssembly Text format) into wasm bytecode. + let wasm_binary = wabt::wat2wasm(include_str!("test.wat")); + + let wasm_binary = match wasm_binary { + Ok(abc) => abc, + Err(abc) => { + println!("{}", abc); + return; + } + }; + + // .expect("failed to parse wat"); + + // Load wasm binary and prepare it for instantiation. + let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); + + // Instantiate a module with empty imports and + // assert that there is no `start` function. + let instance = ModuleInstance::new(&module, &ImportsBuilder::default()) + .expect("failed to instantiate wasm module") + .assert_no_start(); + + // Finally, invoke the exported function "test" with no parameters + // and empty external function executor. + let result: i32 = instance + .invoke_export("main", &[], &mut HostFunctions) + // .with_resolver(&mut HostFunctions) + .expect("failed to execute export") + .unwrap() + .try_into() + .unwrap(); + + println!( + "{:?}", + result // .unwrap() + ); +} diff --git a/src/test.wat b/src/test.wat new file mode 100644 index 0000000..f70add2 --- /dev/null +++ b/src/test.wat @@ -0,0 +1,16 @@ +(module + (import "host" "add" (func $add (param i32 i32)(result i32))) + (func (export "main") (result i32) + (call $add (i32.const 123) (i32.const 456)) + (; i32.const 1337 ;) + ) +) + + + +(;; +(func $main (export "_start") + (; (call $print_greeting) ;) + return + ) +;;)