This example illustrates the basics of using Wasmer through a "Hello World"-like project.
In this example we will be building a "Hello World"-like project. WebAssembly only supports passing integers and floats directly right now, thus to keep it simple we will be writing a host application that calls the add_one function of a guest Wasm module, which adds 1 to the value passed as a parameter, and returns the result.
The goal here is to show you the basics of using Wasmer, we'll focus on the steps required to get an instance out of a Wasm module.
First we are going to want to initialize a new project. To do this we can navigate to our project folder, or create one. In this example, we will create a new project. Lets create it and navigate to it:
The final code for this example can be found on GitHub.
This should generate two important files for us, Cargo.toml and src/main.rs. The Cargo.toml is a file that describes your project and its dependencies. The src/main.rs is the entry point for your project, and contains the fn main() { .. } that is run when the project is executed.
We then modify the Cargo.toml to add the Wasmer dependencies as shown below:
Wasmer C API includes two header files: wasm.h and wasmer_wasm.h. The first one provides the standard Wasm C API while the second one adds some useful functions like wat2wasm and many others.
Now that we have everything set up, let's go ahead and try it out!
Loading the Wasm module
The first step will be to load the Wasm module we want to use. This is done by having its contents loaded as bytes:
Here we are using the text representation of the Wasm module. Wasmer wants to have a binary representation of the module so we have to use wat2wasm to do the translation.
The next step will be to compile the module. To do this, we'll need two things: the Wasm module as bytes and a Store.
The Store is a representation of the actual state of the module: it represents the state of every entities in the module during its lifecycle. It also holds the engine which is what will be used to actually compile the module.
Here is how we can create the store and compile the module:
let store =Store::default();let module =Module::new(&store, wasm_bytes)?;
We are creating a store using the default settings provided by Wasmer. In some cases, you may want to use a specific engine or compiler. Here is how you would do:
let engine = JIT::new(&Cranelift::default()).engine();let store =Store::new(&engine);let module =Module::new(&store, wasm_bytes)?;
We created a store with the JIT engine and the Cranelift compiler with its default configuration. These are good defaults but it will be a good thing to adapt this configuration to your needs.
We are now close to having the module run in our Rust host.
The last step will be to create an Instance out of the Wasm module. As for the previous step, here we need more than just the compiled module: we also need to define imports.
In fact, Wasm modules can define entities they need to work properly. These are called imports. In this example we don't need any of them but we still need to define an empty set and use it to instantiate the module:
let import_object =imports! {};let instance =Instance::new(&module, &import_object)?;