diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 87ef086902..52ea623b76 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -54,6 +54,7 @@ wasmtime-wast = { path = "../wast" } wasmtime-wasi = { path = "../wasi" } rayon = "1.1" file-per-thread-logger = "0.1.1" +wat = "1.0" [badges] maintenance = { status = "actively-developed" } diff --git a/crates/api/examples/gcd.rs b/crates/api/examples/gcd.rs index c15df5a53f..5d16bb1342 100644 --- a/crates/api/examples/gcd.rs +++ b/crates/api/examples/gcd.rs @@ -2,11 +2,40 @@ //! invoking its exported function. use anyhow::{format_err, Result}; -use std::fs::read; use wasmtime_api::*; +const WAT: &str = r#" +(module + (func $gcd (param i32 i32) (result i32) + (local i32) + block ;; label = @1 + block ;; label = @2 + local.get 0 + br_if 0 (;@2;) + local.get 1 + local.set 2 + br 1 (;@1;) + end + loop ;; label = @2 + local.get 1 + local.get 0 + local.tee 2 + i32.rem_u + local.set 0 + local.get 2 + local.set 1 + local.get 0 + br_if 0 (;@2;) + end + end + local.get 2 + ) + (export "gcd" (func $gcd)) +) +"#; + fn main() -> Result<()> { - let wasm = read("examples/gcd.wasm")?; + let wasm = wat::parse_str(WAT)?; // Instantiate engine and store. let engine = HostRef::new(Engine::default()); diff --git a/crates/api/examples/gcd.wasm b/crates/api/examples/gcd.wasm deleted file mode 100644 index 35a13435f9..0000000000 Binary files a/crates/api/examples/gcd.wasm and /dev/null differ diff --git a/crates/api/examples/hello.rs b/crates/api/examples/hello.rs index 4f367cdd70..2f517a3e86 100644 --- a/crates/api/examples/hello.rs +++ b/crates/api/examples/hello.rs @@ -1,11 +1,8 @@ //! Translation of hello example -extern crate alloc; - -use alloc::rc::Rc; use anyhow::{ensure, format_err, Context as _, Result}; use core::cell::Ref; -use std::fs::read; +use std::rc::Rc; use wasmtime_api::*; struct HelloCallback; @@ -19,25 +16,37 @@ impl Callable for HelloCallback { } fn main() -> Result<()> { - // Initialize. + // Configure the initial compilation environment, creating more global + // structures such as an `Engine` and a `Store`. println!("Initializing..."); let engine = HostRef::new(Engine::default()); let store = HostRef::new(Store::new(&engine)); - // Load binary. + // Next upload the `*.wasm` binary file, which in this case we're going to + // be parsing an inline text format into a binary. println!("Loading binary..."); - let binary = read("examples/hello.wasm")?; + let binary = wat::parse_str( + r#" + (module + (func $hello (import "" "hello")) + (func (export "run") (call $hello)) + ) + "#, + )?; - // Compile. + // Compiler the `*.wasm` binary into an in-memory instance of a `Module`. println!("Compiling module..."); let module = HostRef::new(Module::new(&store, &binary).context("> Error compiling module!")?); - // Create external print functions. + // Here we handle the imports of the module, which in this case is our + // `HelloCallback` type and its associated implementation of `Callback. println!("Creating callback..."); let hello_type = FuncType::new(Box::new([]), Box::new([])); let hello_func = HostRef::new(Func::new(&store, hello_type, Rc::new(HelloCallback))); - // Instantiate. + // Once we've got that all set up we can then move to the instantiation + // phase, pairing together a compiled module as well as a set of imports. + // Note that this is where the wasm `start` function, if any, would run. println!("Instantiating module..."); let imports = vec![hello_func.into()]; let instance = HostRef::new( @@ -45,24 +54,19 @@ fn main() -> Result<()> { .context("> Error instantiating module!")?, ); - // Extract export. + // Next we poke around a bit to extract the `run` function from the module. println!("Extracting export..."); let exports = Ref::map(instance.borrow(), |instance| instance.exports()); ensure!(!exports.is_empty(), "> Error accessing exports!"); let run_func = exports[0].func().context("> Error accessing exports!")?; - // Call. + // And last but not least we can call it! println!("Calling export..."); run_func .borrow() .call(&[]) .map_err(|e| format_err!("> Error calling function: {:?}", e))?; - // Shut down. - println!("Shutting down..."); - drop(store); - - // All done. println!("Done."); Ok(()) } diff --git a/crates/api/examples/hello.wasm b/crates/api/examples/hello.wasm deleted file mode 100644 index 2207c03eea..0000000000 Binary files a/crates/api/examples/hello.wasm and /dev/null differ diff --git a/crates/api/examples/hello.wat b/crates/api/examples/hello.wat deleted file mode 100644 index 1c56c55822..0000000000 --- a/crates/api/examples/hello.wat +++ /dev/null @@ -1,4 +0,0 @@ -(module - (func $hello (import "" "hello")) - (func (export "run") (call $hello)) -) diff --git a/crates/api/examples/memory.rs b/crates/api/examples/memory.rs index 6ca8f9c125..927a06f235 100644 --- a/crates/api/examples/memory.rs +++ b/crates/api/examples/memory.rs @@ -1,8 +1,7 @@ //! Translation of the memory example use anyhow::{bail, ensure, Context as _, Error}; -use core::cell::Ref; -use std::fs::read; +use std::cell::Ref; use wasmtime_api::*; fn get_export_memory(exports: &[Extern], i: usize) -> Result, Error> { @@ -69,7 +68,23 @@ fn main() -> Result<(), Error> { // Load binary. println!("Loading binary..."); - let binary = read("examples/memory.wasm")?; + let binary = wat::parse_str( + r#" + (module + (memory (export "memory") 2 3) + + (func (export "size") (result i32) (memory.size)) + (func (export "load") (param i32) (result i32) + (i32.load8_s (local.get 0)) + ) + (func (export "store") (param i32 i32) + (i32.store8 (local.get 0) (local.get 1)) + ) + + (data (i32.const 0x1000) "\01\02\03\04") + ) + "#, + )?; // Compile. println!("Compiling module..."); diff --git a/crates/api/examples/memory.wasm b/crates/api/examples/memory.wasm deleted file mode 100644 index 6f6518b187..0000000000 Binary files a/crates/api/examples/memory.wasm and /dev/null differ diff --git a/crates/api/examples/memory.wat b/crates/api/examples/memory.wat deleted file mode 100644 index 4cf43e2c7d..0000000000 --- a/crates/api/examples/memory.wat +++ /dev/null @@ -1,11 +0,0 @@ -(module - (memory (export "memory") 2 3) - - (func (export "size") (result i32) (memory.size)) - (func (export "load") (param i32) (result i32) (i32.load8_s (local.get 0))) - (func (export "store") (param i32 i32) - (i32.store8 (local.get 0) (local.get 1)) - ) - - (data (i32.const 0x1000) "\01\02\03\04") -) diff --git a/crates/api/examples/multi.rs b/crates/api/examples/multi.rs index e3d35c296e..53267a59dc 100644 --- a/crates/api/examples/multi.rs +++ b/crates/api/examples/multi.rs @@ -1,11 +1,8 @@ //! Translation of multi example -extern crate alloc; - -use alloc::rc::Rc; use anyhow::{ensure, format_err, Context as _, Result}; -use core::cell::Ref; -use std::fs::read; +use std::cell::Ref; +use std::rc::Rc; use wasmtime_api::*; struct Callback; @@ -21,6 +18,31 @@ impl Callable for Callback { } } +const WAT: &str = r#" +(module + (func $f (import "" "f") (param i32 i64) (result i64 i32)) + + (func $g (export "g") (param i32 i64) (result i64 i32) + (call $f (local.get 0) (local.get 1)) + ) + + (func $round_trip_many + (export "round_trip_many") + (param i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) + (result i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) + local.get 0 + local.get 1 + local.get 2 + local.get 3 + local.get 4 + local.get 5 + local.get 6 + local.get 7 + local.get 8 + local.get 9) +) +"#; + fn main() -> Result<()> { // Initialize. println!("Initializing..."); @@ -29,7 +51,7 @@ fn main() -> Result<()> { // Load binary. println!("Loading binary..."); - let binary = read("examples/multi.wasm")?; + let binary = wat::parse_str(WAT)?; // Compile. println!("Compiling module..."); diff --git a/crates/api/examples/multi.wasm b/crates/api/examples/multi.wasm deleted file mode 100644 index 9684f9fa1d..0000000000 Binary files a/crates/api/examples/multi.wasm and /dev/null differ diff --git a/crates/api/examples/multi.wat b/crates/api/examples/multi.wat deleted file mode 100644 index cacd95504a..0000000000 --- a/crates/api/examples/multi.wat +++ /dev/null @@ -1,22 +0,0 @@ -(module - (func $f (import "" "f") (param i32 i64) (result i64 i32)) - - (func $g (export "g") (param i32 i64) (result i64 i32) - (call $f (local.get 0) (local.get 1)) - ) - - (func $round_trip_many - (export "round_trip_many") - (param i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) - (result i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) - local.get 0 - local.get 1 - local.get 2 - local.get 3 - local.get 4 - local.get 5 - local.get 6 - local.get 7 - local.get 8 - local.get 9) -) diff --git a/crates/api/tests/import_calling_export.rs b/crates/api/tests/import_calling_export.rs index 55741eae59..de02454455 100644 --- a/crates/api/tests/import_calling_export.rs +++ b/crates/api/tests/import_calling_export.rs @@ -1,12 +1,20 @@ -extern crate alloc; - -use alloc::rc::Rc; -use core::cell::{Ref, RefCell}; -use std::fs::read; +use std::cell::{Ref, RefCell}; +use std::rc::Rc; use wasmtime_api::*; #[test] fn test_import_calling_export() { + const WAT: &str = r#" + (module + (type $t0 (func)) + (import "" "imp" (func $.imp (type $t0))) + (func $run call $.imp) + (func $other) + (export "run" (func $run)) + (export "other" (func $other)) + ) + "#; + struct Callback { pub other: RefCell>>, } @@ -26,13 +34,8 @@ fn test_import_calling_export() { let engine = HostRef::new(Engine::default()); let store = HostRef::new(Store::new(&engine)); - let module = HostRef::new( - Module::new( - &store, - &read("tests/import_calling_export.wasm").expect("failed to read wasm file"), - ) - .expect("failed to create module"), - ); + let wasm = wat::parse_str(WAT).unwrap(); + let module = HostRef::new(Module::new(&store, &wasm).expect("failed to create module")); let callback = Rc::new(Callback { other: RefCell::new(None), diff --git a/crates/api/tests/import_calling_export.wasm b/crates/api/tests/import_calling_export.wasm deleted file mode 100644 index 8f1f81100f..0000000000 Binary files a/crates/api/tests/import_calling_export.wasm and /dev/null differ diff --git a/crates/lightbeam/Cargo.toml b/crates/lightbeam/Cargo.toml index f62bacb2d5..b63d8154a5 100644 --- a/crates/lightbeam/Cargo.toml +++ b/crates/lightbeam/Cargo.toml @@ -30,6 +30,7 @@ more-asserts = "0.2.1" lazy_static = "1.2" wat = "1.0.2" quickcheck = "0.9.0" +anyhow = "1.0" [badges] maintenance = { status = "experimental" } diff --git a/crates/lightbeam/examples/test.rs b/crates/lightbeam/examples/test.rs index 6918d5948a..12d54193ae 100644 --- a/crates/lightbeam/examples/test.rs +++ b/crates/lightbeam/examples/test.rs @@ -1,34 +1,16 @@ use lightbeam::translate; -use std::fs::File; -use std::io; -use std::io::Read; -use std::path::Path; -fn read_to_end>(path: P) -> io::Result> { - let mut buffer = Vec::new(); - if path.as_ref() == Path::new("-") { - let stdin = io::stdin(); - let mut stdin = stdin.lock(); - stdin.read_to_end(&mut buffer)?; - } else { - let mut file = File::open(path)?; - file.read_to_end(&mut buffer)?; - } - Ok(buffer) -} +const WAT: &str = r#" +(module + (func (param i32) (param i32) (result i32) (i32.add (get_local 0) (get_local 1))) +) +"#; -fn maybe_main() -> Result<(), String> { - let data = read_to_end("test.wasm").map_err(|e| e.to_string())?; - let translated = translate(&data).map_err(|e| e.to_string())?; - let result: u32 = translated.execute_func(0, (5u32, 3u32)).unwrap(); +fn main() -> anyhow::Result<()> { + let data = wat::parse_str(WAT)?; + let translated = translate(&data)?; + let result: u32 = translated.execute_func(0, (5u32, 3u32))?; println!("f(5, 3) = {}", result); Ok(()) } - -fn main() { - match maybe_main() { - Ok(()) => (), - Err(e) => eprintln!("error: {}", e), - } -} diff --git a/crates/lightbeam/src/module.rs b/crates/lightbeam/src/module.rs index 2dc43de4ea..61636e8f02 100644 --- a/crates/lightbeam/src/module.rs +++ b/crates/lightbeam/src/module.rs @@ -9,6 +9,7 @@ use cranelift_codegen::{ }; use memoffset::offset_of; use more_asserts::assert_le; +use thiserror::Error; use wasmparser::{FuncType, MemoryType, ModuleReader, SectionCode, Type}; pub trait AsValueType { @@ -133,9 +134,11 @@ impl TranslatedModule { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)] pub enum ExecutionError { + #[error("function index out of bounds")] FuncIndexOutOfBounds, + #[error("type mismatch")] TypeMismatch, } diff --git a/crates/lightbeam/test.wasm b/crates/lightbeam/test.wasm deleted file mode 100644 index 1b132cf191..0000000000 Binary files a/crates/lightbeam/test.wasm and /dev/null differ diff --git a/crates/lightbeam/test.wat b/crates/lightbeam/test.wat deleted file mode 100644 index 2f59984430..0000000000 --- a/crates/lightbeam/test.wat +++ /dev/null @@ -1,3 +0,0 @@ -(module - (func (param i32) (param i32) (result i32) (i32.add (get_local 0) (get_local 1))) -)