diff --git a/Cargo.toml b/Cargo.toml index 01723b561..74a52b87b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -137,25 +137,45 @@ harness = false [[example]] name = "engine-jit" -path = "examples/engine_00_jit.rs" +path = "examples/engine_jit.rs" required-features = ["cranelift"] [[example]] name = "engine-native" -path = "examples/engine_01_native.rs" +path = "examples/engine_native.rs" required-features = ["cranelift"] [[example]] name = "engine-headless" -path = "examples/engine_02_headless.rs" +path = "examples/engine_headless.rs" required-features = ["cranelift"] [[example]] name = "cross-compilation" -path = "examples/engine_03_cross_compilation.rs" +path = "examples/engine_cross_compilation.rs" required-features = ["cranelift"] +[[example]] +name = "compiler-singlepass" +path = "examples/compiler_singlepass.rs" +required-features = ["singlepass"] + +[[example]] +name = "compiler-cranelift" +path = "examples/compiler_cranelift.rs" +required-features = ["cranelift"] + +[[example]] +name = "compiler-llvm" +path = "examples/compiler_llvm.rs" +required-features = ["llvm"] + [[example]] name = "exported-function" -path = "examples/exports_00_function.rs" -required-features = ["cranelift"] \ No newline at end of file +path = "examples/exports_function.rs" +required-features = ["cranelift"] + +[[example]] +name = "wasi" +path = "examples/wasi.rs" +required-features = ["cranelift", "wasi"] diff --git a/examples/README.md b/examples/README.md index ada110d48..d0ff41211 100644 --- a/examples/README.md +++ b/examples/README.md @@ -77,10 +77,54 @@ example. ``` + +### Compilers + +5. [**Singlepass Compiler**][compiler-singlepass], explains how to use + the [Singlepass compiler](https://github.com/wasmerio/wasmer-reborn/tree/master/lib/compiler-singlepass). + _Keywords_: engine, compiler, singlepass. + +
+ Execute the example + + ```shell + $ cargo run --example compiler-singlepass --release --features "singlepass" + ``` + +
+ +6. [**Cranelift Compiler**][compiler-cranelift], explains how to use + the [Cranelift compiler](https://github.com/wasmerio/wasmer-reborn/tree/master/lib/compiler-cranelift). + + _Keywords_: engine, compiler, cranelift. + +
+ Execute the example + + ```shell + $ cargo run --example compiler-cranelift --release --features "cranelift" + ``` + +
+ +7. [**LLVM Compiler**][compiler-llvm], explains how to use + the [LLVM compiler](https://github.com/wasmerio/wasmer-reborn/tree/master/lib/compiler-llvm). + + _Keywords_: engine, compiler, llvm. + +
+ Execute the example + + ```shell + $ cargo run --example compiler-llvm --release --features "llvm" + ``` + +
+ ### Exports -5. [**Exported function**][exported-function], explains how to get and +8. [**Exported function**][exported-function], explains how to get and how to call an exported function. They come in 2 flavors: dynamic, and “static”/native. The pros and cons are discussed briefly. @@ -95,9 +139,29 @@ example. +### Integrations -[engine-jit]: ./engine_00_jit.rs -[engine-native]: ./engine_01_native.rs -[engine-headless]: ./engine_02_headless.rs -[cross-compilation]: ./engine_03_cross_compilation.rs -[exported-function]: ./exports_00_function.rs +9. [**WASI integration**][wasi], explains how to get and + how to call an exported function. They come in 2 flavors: dynamic, + and “static”/native. The pros and cons are discussed briefly. + + _Keywords_: export, function, dynamic, static, native. + +
+ Execute the example + + ```shell + $ cargo run --example wasi --release --features "cranelift,wasi" + ``` + +
+ +[engine-jit]: ./engine_jit.rs +[engine-native]: ./engine_native.rs +[engine-headless]: ./engine_headless.rs +[compiler-singlepass]: ./compiler_singlepass.rs +[compiler-cranelift]: ./compiler_cranelift.rs +[compiler-llvm]: ./compiler_llvm.rs +[cross-compilation]: ./engine_cross_compilation.rs +[exported-function]: ./exports_function.rs +[integration-wasi]: ./wasi.rs diff --git a/examples/compiler_cranelift.rs b/examples/compiler_cranelift.rs new file mode 100644 index 000000000..2214ac489 --- /dev/null +++ b/examples/compiler_cranelift.rs @@ -0,0 +1,65 @@ +//! A Wasm module can be compiled with multiple compilers. +//! +//! This example illustrates how to use the Cranelift compiler. +//! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example compiler-cranelift --release --features "cranelift" +//! ``` +//! +//! Ready? + +use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler_cranelift::Cranelift; +use wasmer_engine_jit::JIT; + +fn main() -> Result<(), Box> { + // Let's declare the Wasm module with the text representation. + let wasm_bytes = wat2wasm( + r#" +(module + (type $sum_t (func (param i32 i32) (result i32))) + (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add) + (export "sum" (func $sum_f))) +"# + .as_bytes(), + )?; + + // Use Cranelift compiler with the default settings + let compiler = Cranelift::default(); + + // Create the store + let store = Store::new(&JIT::new(&compiler).engine()); + + println!("Compiling module..."); + // Let's compile the Wasm module. + let module = Module::new(&store, wasm_bytes)?; + + // Create an empty import object. + let import_object = imports! {}; + + println!("Instantiating module..."); + // Let's instantiate the Wasm module. + let instance = Instance::new(&module, &import_object)?; + + let sum = instance.exports.get_function("sum")?; + + println!("Calling `sum` function..."); + // Let's call the `sum` exported function. The parameters are a + // slice of `Value`s. The results are a boxed slice of `Value`s. + let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + + println!("Results: {:?}", results); + assert_eq!(results.to_vec(), vec![Value::I32(3)]); + + Ok(()) +} + +#[test] +fn test_exported_function() -> Result<(), Box> { + main() +} diff --git a/examples/compiler_llvm.rs b/examples/compiler_llvm.rs new file mode 100644 index 000000000..b35127947 --- /dev/null +++ b/examples/compiler_llvm.rs @@ -0,0 +1,65 @@ +//! A Wasm module can be compiled with multiple compilers. +//! +//! This example illustrates how to use the LLVM compiler. +//! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example compiler-llvm --release --features "llvm" +//! ``` +//! +//! Ready? + +use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler_llvm::LLVM; +use wasmer_engine_jit::JIT; + +fn main() -> Result<(), Box> { + // Let's declare the Wasm module with the text representation. + let wasm_bytes = wat2wasm( + r#" +(module + (type $sum_t (func (param i32 i32) (result i32))) + (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add) + (export "sum" (func $sum_f))) +"# + .as_bytes(), + )?; + + // Use LLVM compiler with the default settings + let compiler = LLVM::default(); + + // Create the store + let store = Store::new(&JIT::new(&compiler).engine()); + + println!("Compiling module..."); + // Let's compile the Wasm module. + let module = Module::new(&store, wasm_bytes)?; + + // Create an empty import object. + let import_object = imports! {}; + + println!("Instantiating module..."); + // Let's instantiate the Wasm module. + let instance = Instance::new(&module, &import_object)?; + + let sum = instance.exports.get_function("sum")?; + + println!("Calling `sum` function..."); + // Let's call the `sum` exported function. The parameters are a + // slice of `Value`s. The results are a boxed slice of `Value`s. + let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + + println!("Results: {:?}", results); + assert_eq!(results.to_vec(), vec![Value::I32(3)]); + + Ok(()) +} + +#[test] +fn test_exported_function() -> Result<(), Box> { + main() +} diff --git a/examples/compiler_singlepass.rs b/examples/compiler_singlepass.rs new file mode 100644 index 000000000..03cd596e1 --- /dev/null +++ b/examples/compiler_singlepass.rs @@ -0,0 +1,65 @@ +//! A Wasm module can be compiled with multiple compilers. +//! +//! This example illustrates how to use the Singlepass compiler. +//! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example compiler-singlepass --release --features "singlepass" +//! ``` +//! +//! Ready? + +use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler_singlepass::Singlepass; +use wasmer_engine_jit::JIT; + +fn main() -> Result<(), Box> { + // Let's declare the Wasm module with the text representation. + let wasm_bytes = wat2wasm( + r#" +(module + (type $sum_t (func (param i32 i32) (result i32))) + (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add) + (export "sum" (func $sum_f))) +"# + .as_bytes(), + )?; + + // Use Singlepass compiler with the default settings + let compiler = Singlepass::default(); + + // Create the store + let store = Store::new(&JIT::new(&compiler).engine()); + + println!("Compiling module..."); + // Let's compile the Wasm module. + let module = Module::new(&store, wasm_bytes)?; + + // Create an empty import object. + let import_object = imports! {}; + + println!("Instantiating module..."); + // Let's instantiate the Wasm module. + let instance = Instance::new(&module, &import_object)?; + + let sum = instance.exports.get_function("sum")?; + + println!("Calling `sum` function..."); + // Let's call the `sum` exported function. The parameters are a + // slice of `Value`s. The results are a boxed slice of `Value`s. + let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + + println!("Results: {:?}", results); + assert_eq!(results.to_vec(), vec![Value::I32(3)]); + + Ok(()) +} + +#[test] +fn test_exported_function() -> Result<(), Box> { + main() +} diff --git a/examples/engine_03_cross_compilation.rs b/examples/engine_cross_compilation.rs similarity index 89% rename from examples/engine_03_cross_compilation.rs rename to examples/engine_cross_compilation.rs index 120184b12..dbd1fd879 100644 --- a/examples/engine_03_cross_compilation.rs +++ b/examples/engine_cross_compilation.rs @@ -10,10 +10,15 @@ //! illustrates how the abstraction over the compiler is so powerful //! that it is possible to cross-compile a Wasm module. //! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example cross-compilation --release --features "cranelift" +//! ``` +//! //! Ready? use std::str::FromStr; -use std::sync::Arc; use wasmer::{wat2wasm, Module, RuntimeError, Store}; use wasmer_compiler::{CpuFeature, Target, Triple}; use wasmer_compiler_cranelift::Cranelift; @@ -59,6 +64,7 @@ fn main() -> Result<(), Box> { // // Let's build the target. let target = Target::new(triple, cpu_feature); + println!("Chosen target: {:?}", target); // Define the engine that will drive everything. // @@ -73,15 +79,17 @@ fn main() -> Result<(), Box> { // this information with the compiler. .target(target) // Get the engine. - .engine(), - ); + .engine(); // Create a store, that holds the engine. - let store = Store::new(&*engine); + let store = Store::new(&engine); + println!("Compiling module..."); // Let's compile the Wasm module. let _module = Module::new(&store, wasm_bytes)?; + println!("Module compiled successfully."); + // Congrats, the Wasm module is cross-compiled! // // What to do with that? It is possible to use an engine (probably diff --git a/examples/engine_02_headless.rs b/examples/engine_headless.rs similarity index 86% rename from examples/engine_02_headless.rs rename to examples/engine_headless.rs index 1e25f2b06..6e794399c 100644 --- a/examples/engine_02_headless.rs +++ b/examples/engine_headless.rs @@ -36,9 +36,14 @@ //! workflow, but keep in mind the compiler isn't required after the //! compilation step. //! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example engine-headless --release --features "cranelift" +//! ``` +//! //! Ready? -use std::sync::Arc; use tempfile::NamedTempFile; use wasmer::imports; use wasmer::wat2wasm; @@ -51,6 +56,7 @@ use wasmer_engine_native::Native; fn main() -> Result<(), Box> { // First step, let's compile the Wasm module and serialize it. + // Note: we need a compiler here. let serialized_module_file = { // Let's declare the Wasm module with the text representation. let wasm_bytes = wat2wasm( @@ -73,6 +79,7 @@ fn main() -> Result<(), Box> { // compile the Wasm module into executable code. let mut compiler_config = Cranelift::default(); + println!("Creating Native engine..."); // Define the engine that will drive everything. // // In this case, the engine is `wasmer_engine_native` which @@ -84,11 +91,13 @@ fn main() -> Result<(), Box> { let engine = Native::new(&mut compiler_config).engine(); // Create a store, that holds the engine. - let store = Store::new(&*engine); + let store = Store::new(&engine); + println!("Compiling module..."); // Let's compile the Wasm module. let module = Module::new(&store, wasm_bytes)?; + println!("Serializing module..."); // Here we go. Let's serialize the compiled Wasm module in a // file. let serialized_module_file = NamedTempFile::new()?; @@ -100,11 +109,12 @@ fn main() -> Result<(), Box> { // Second step, deserialize the compiled Wasm module, and execute // it, for example with Wasmer without a compiler. { - // Define a new store, with the same engine. - let mut compiler_config = Cranelift::default(); - let engine = Arc::new(Native::new(&mut compiler_config).engine()); - let store = Store::new(&*engine); + println!("Creating headless Native engine..."); + // We create a headless Native engine. + let engine = Native::headless().engine(); + let store = Store::new(&engine); + println!("Deserializing module..."); // Here we go. // // Deserialize the compiled Wasm module. This code is unsafe @@ -120,13 +130,16 @@ fn main() -> Result<(), Box> { // any imports, it's an empty object. let import_object = imports! {}; + println!("Instantiating module..."); // Let's instantiate the Wasm module. let instance = Instance::new(&module, &import_object)?; + println!("Calling `sum` function..."); // The Wasm module exports a function called `sum`. let sum = instance.exports.get_function("sum")?; let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + println!("Results: {:?}", results); assert_eq!(results.to_vec(), vec![Value::I32(3)]); } diff --git a/examples/engine_00_jit.rs b/examples/engine_jit.rs similarity index 86% rename from examples/engine_00_jit.rs rename to examples/engine_jit.rs index 7094bf74c..e49c13ea2 100644 --- a/examples/engine_00_jit.rs +++ b/examples/engine_jit.rs @@ -10,9 +10,14 @@ //! In the particular context of the JIT engine, the executable code //! is stored in memory. //! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example engine-jit --release --features "cranelift" +//! ``` +//! //! Ready? -use std::sync::Arc; use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; use wasmer_compiler_cranelift::Cranelift; use wasmer_engine_jit::JIT; @@ -39,6 +44,7 @@ fn main() -> Result<(), Box> { // compile the Wasm module into executable code. let mut compiler_config = Cranelift::default(); + println!("Creating JIT engine..."); // Define the engine that will drive everything. // // In this case, the engine is `wasmer_engine_jit` which roughly @@ -46,8 +52,9 @@ fn main() -> Result<(), Box> { let engine = JIT::new(&mut compiler_config).engine(); // Create a store, that holds the engine. - let store = Store::new(&*engine); + let store = Store::new(&engine); + println!("Compiling module..."); // Here we go. // // Let's compile the Wasm module. It is at this step that the Wasm @@ -63,13 +70,16 @@ fn main() -> Result<(), Box> { // any imports, it's an empty object. let import_object = imports! {}; + println!("Instantiating module..."); // And here we go again. Let's instantiate the Wasm module. let instance = Instance::new(&module, &import_object)?; + println!("Calling `sum` function..."); // The Wasm module exports a function called `sum`. let sum = instance.exports.get_function("sum")?; let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + println!("Results: {:?}", results); assert_eq!(results.to_vec(), vec![Value::I32(3)]); Ok(()) diff --git a/examples/engine_01_native.rs b/examples/engine_native.rs similarity index 86% rename from examples/engine_01_native.rs rename to examples/engine_native.rs index dbf5c83e1..da360f133 100644 --- a/examples/engine_01_native.rs +++ b/examples/engine_native.rs @@ -11,9 +11,14 @@ //! code is stored in a native object, more precisely in a dynamic //! library. //! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example engine-native --release --features "cranelift" +//! ``` +//! //! Ready? -use std::sync::Arc; use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; use wasmer_compiler_cranelift::Cranelift; use wasmer_engine_native::Native; @@ -40,6 +45,7 @@ fn main() -> Result<(), Box> { // compile the Wasm module into executable code. let mut compiler_config = Cranelift::default(); + println!("Creating Native engine..."); // Define the engine that will drive everything. // // In this case, the engine is `wasmer_engine_native` which means @@ -47,8 +53,9 @@ fn main() -> Result<(), Box> { let engine = Native::new(&mut compiler_config).engine(); // Create a store, that holds the engine. - let store = Store::new(&*engine); + let store = Store::new(&engine); + println!("Compiling module..."); // Here we go. // // Let's compile the Wasm module. It is at this step that the Wasm @@ -64,13 +71,16 @@ fn main() -> Result<(), Box> { // any imports, it's an empty object. let import_object = imports! {}; + println!("Instantiating module..."); // And here we go again. Let's instantiate the Wasm module. let instance = Instance::new(&module, &import_object)?; + println!("Calling `sum` function..."); // The Wasm module exports a function called `sum`. let sum = instance.exports.get_function("sum")?; let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + println!("Results: {:?}", results); assert_eq!(results.to_vec(), vec![Value::I32(3)]); Ok(()) diff --git a/examples/exports_00_function.rs b/examples/exports_function.rs similarity index 80% rename from examples/exports_00_function.rs rename to examples/exports_function.rs index d3c4f9c5f..dadd708d9 100644 --- a/examples/exports_00_function.rs +++ b/examples/exports_function.rs @@ -9,9 +9,14 @@ //! 2. Native function, where parameters and results are statically //! typed Rust values. //! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example exported-function --release --features "cranelift" +//! ``` +//! //! Ready? -use std::sync::Arc; use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; use wasmer_compiler_cranelift::Cranelift; use wasmer_engine_jit::JIT; @@ -31,21 +36,20 @@ fn main() -> Result<(), Box> { .as_bytes(), )?; - // Define a compiler configuration. - let mut compiler_config = Cranelift::default(); - - // Define the engine that will drive everything. - let engine = JIT::new(&mut compiler_config).engine(); - - // Create a store, that holds the engine. - let store = Store::new(&*engine); + // Create a Store. + // Note that we don't need to specify the engine/compiler if we want to use + // the default provided by Wasmer. + // You can use `Store::default()` for that. + let store = Store::new(&JIT::new(&Cranelift::default()).engine()); + println!("Compiling module..."); // Let's compile the Wasm module. let module = Module::new(&store, wasm_bytes)?; // Create an empty import object. let import_object = imports! {}; + println!("Instantiating module..."); // Let's instantiate the Wasm module. let instance = Instance::new(&module, &import_object)?; @@ -65,10 +69,12 @@ fn main() -> Result<(), Box> { // ``` let sum = instance.exports.get_function("sum")?; + println!("Calling `sum` function..."); // Let's call the `sum` exported function. The parameters are a // slice of `Value`s. The results are a boxed slice of `Value`s. let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + println!("Results: {:?}", results); assert_eq!(results.to_vec(), vec![Value::I32(3)]); // That was fun. But what if we can get rid of the `Value`s? Well, @@ -81,11 +87,13 @@ fn main() -> Result<(), Box> { // error will be raised. let sum = sum.native::<(i32, i32), i32>()?; + println!("Calling `sum` function (natively)..."); // Let's call the `sum` exported function. The parameters are // statically typed Rust values of type `i32` and `i32`. The // result, in this case particular case, in a unit of type `i32`. let result = sum.call(1, 2)?; + println!("Results: {:?}", result); assert_eq!(result, 3); // Much nicer, isn't it? diff --git a/examples/wasi.rs b/examples/wasi.rs new file mode 100644 index 000000000..680d2f4c0 --- /dev/null +++ b/examples/wasi.rs @@ -0,0 +1,68 @@ +//! Running a WASI compiled WebAssembly module with Wasmer. +//! +//! This example illustrates how to run WASI modules with +//! Wasmer. To run WASI we have to have to do mainly 3 steps: +//! +//! 1. Create a `WasiEnv` instance +//! 2. Attach the imports from the `WasiEnv` to a new instance +//! 3. Run the `WASI` module. +//! +//! You can run the example directly by executing in Wasmer root: +//! +//! ```bash +//! cargo run --example wasi --release --features "cranelift,wasi" +//! ``` +//! +//! Ready? + +use wasmer::{Instance, Module, Store}; +use wasmer_compiler_cranelift::Cranelift; +use wasmer_engine_jit::JIT; +use wasmer_wasi::WasiState; + +fn main() -> Result<(), Box> { + let wasm_path = format!( + "{}/tests/wasi-wast/wasi/unstable/hello.wasm", + std::env::var("CARGO_MANIFEST_DIR").unwrap() + ); + // Let's declare the Wasm module with the text representation. + let wasm_bytes = std::fs::read(wasm_path)?; + + // Create a Store. + // Note that we don't need to specify the engine/compiler if we want to use + // the default provided by Wasmer. + // You can use `Store::default()` for that. + let store = Store::new(&JIT::new(&Cranelift::default()).engine()); + + println!("Compiling module..."); + // Let's compile the Wasm module. + let module = Module::new(&store, wasm_bytes)?; + + println!("Creating `WasiEnv`..."); + // First, we create the `WasiEnv` + let mut wasi_env = WasiState::new("hello") + // .args(&["world"]) + // .env("KEY", "Value") + .finalize()?; + + println!("Instantiating module with WASI imports..."); + // Then, we get the import object related to our WASI + // and attach it to the Wasm instance. + let import_object = wasi_env.import_object(&module)?; + let instance = Instance::new(&module, &import_object)?; + + // WASI requires to explicitly set the memory for the `WasiEnv` + wasi_env.set_memory(instance.exports.get_memory("memory")?.clone()); + + println!("Call WASI `_start` function..."); + // And we just call the `_start` function! + let start = instance.exports.get_function("_start")?; + start.call(&[])?; + + Ok(()) +} + +#[test] +fn test_wasi() -> Result<(), Box> { + main() +} diff --git a/lib/compiler-cranelift/README.md b/lib/compiler-cranelift/README.md index 4db9f4e37..b1ef278e6 100644 --- a/lib/compiler-cranelift/README.md +++ b/lib/compiler-cranelift/README.md @@ -22,6 +22,8 @@ let compiler = Cranelift::new(); let store = Store::new(&JIT::new(&compiler).engine()); ``` +*Note: you can find a [full working example using Cranelift compiler here](https://github.com/wasmerio/wasmer-reborn/blob/test-examples/examples/compiler-cranelift.rs).* + ## When to use Cranelift We recommend using this compiler crate **only for development proposes**. diff --git a/lib/compiler-llvm/README.md b/lib/compiler-llvm/README.md index 4b79d5ebd..cc06ea272 100644 --- a/lib/compiler-llvm/README.md +++ b/lib/compiler-llvm/README.md @@ -22,6 +22,8 @@ let compiler = LLVM::new(); let store = Store::new(&JIT::new(&compiler).engine()); ``` +*Note: you can find a [full working example using LLVM compiler here](https://github.com/wasmerio/wasmer-reborn/blob/test-examples/examples/compiler-llvm.rs).* + ## When to use LLVM We recommend using LLVM as the default compiler when running WebAssembly diff --git a/lib/compiler-singlepass/README.md b/lib/compiler-singlepass/README.md index f582fd1ea..2e0307e9d 100644 --- a/lib/compiler-singlepass/README.md +++ b/lib/compiler-singlepass/README.md @@ -22,6 +22,8 @@ let compiler = Singlepass::new(); let store = Store::new(&JIT::new(&compiler).engine()); ``` +*Note: you can find a [full working example using Singlepass compiler here](https://github.com/wasmerio/wasmer-reborn/blob/test-examples/examples/compiler-singlepass.rs).* + ## When to use Singlepass Singlepass is designed to emit compiled code at linear time, as such diff --git a/lib/engine-jit/README.md b/lib/engine-jit/README.md index 1fbf28f80..46195db88 100644 --- a/lib/engine-jit/README.md +++ b/lib/engine-jit/README.md @@ -6,6 +6,8 @@ After the compiler process the result, the JIT pushes it into memory and links it's contents so it can be usable by the `wasmer` api. +*Note: you can find a [full working example using the JIT engine here](https://github.com/wasmerio/wasmer-reborn/blob/test-examples/examples/engine-jit.rs).* + ### Acknowledgments This project borrowed some of the code of the code memory and unwind tables from the [wasmtime-jit](https://crates.io/crates/wasmtime-jit), the code since then has evolved significantly. diff --git a/lib/engine-native/README.md b/lib/engine-native/README.md index 47c141df5..fa43bff8e 100644 --- a/lib/engine-native/README.md +++ b/lib/engine-native/README.md @@ -10,6 +10,8 @@ so it can be usable by the `wasmer` API. This allows Wasmer to achieve *blazing fast* native startup times. +*Note: you can find a [full working example using the JIT engine here](https://github.com/wasmerio/wasmer-reborn/blob/test-examples/examples/engine-jit.rs).* + ## Requirements The `wasmer-engine-native` crate requires a linker available on your diff --git a/lib/wasi/README.md b/lib/wasi/README.md index faf9534d1..3bd6f6e00 100644 --- a/lib/wasi/README.md +++ b/lib/wasi/README.md @@ -2,3 +2,5 @@ This is the `wasmer-wasi` crate. It provides the necessary imports to use WASI easily from Wasmer. + +*Note: you can find a [full working example using WASI here](https://github.com/wasmerio/wasmer-reborn/blob/test-examples/examples/wasi.rs).*