Engines, Modules, Stores & Instances 😵
There are several stages to go through in the process of taking a .wasm file and loading it into executable code. This document explains the stages and the various objects involved at a high level.
Importing​
In Editor​
Wasmbox detects .wasm and .wat files in your project and imports them to create a WASM Asset and generated C# code.
At Runtime​
It is possible to load wasm or wat at runtime, without importing it in the editor, by using DynamicWasmAsset or even a custom implementation of IWasmAsset. All of these options produce something that can be used in the same way as an editor imported WASM Asset.
Runtime loading does not generate wrapper code.
Loading​
At runtime a WASM Asset must be loaded and configured before it can be called. This process is quite complicated, but Wasmbox includes helpers such as the SimpleWasmMonoBehaviour which handle most of the steps for you.
- An 
EngineConfigconfigures how the code will be compiled. - The 
EngineConfigis used to compile theWASM Assetinto aLoadedModule. - A 
Storeis created from theEngineConfig, to store all state. - A 
Linkeris created from theEngineConfig, to set what the WASM code can access. Store,Linker&LoadedModuleare used to create anInstance.- Functions can be called on the 
Instance.- Generated C# code can be used to make this easier.
 
 
Glossary​
LoadedModule​
A LoadedModule compiles the WASM code stored in a WASM Asset into machine code that can be run on this machine. This process can take a lot of time (100ms or more) the first time it is done, but after that it is cached and should be nearly instantaneous.
The editor importer can precompile WASM code in the editor, which significantly speeds up loading at runtime.
Store​
A WASM Instance has no state (i.e. memory), instead it is all contained within the Store. A Store may be shared between multiple Instances.
Linker​
By default WASM execution is completely "sandboxed", executing WASM code cannot access anything outside of the box. This makes it safe to run malicious code, and easy to ensure determinism. The Linker allows you to expose certain C# methods to WASM code, allowing it to call those methods. For example WASI features.
int Add(int a, int b)
{
    return a + b;
}
// Allow WASM to call `Add` as `myfunctions::add`
linker.DefineFunction("myfunctions", "add", Add);
Instance​
An Instance is the final step which allows you to call WASM code.
var add = instance.GetFunction<int, int, int>("Add");
var result = add(1, 2);
Debug.Assert(result == 3);
Generated Code​
An Instance is a low level API that is often not very convenient to use directly. The Wasmbox editor importer can generate code which "wraps" an Instance and makes it much more convenient (and efficient) to use.
using (var wrapper = new GeneratedWrapper(instance, store))
{
    var result = wrapper.Add(1, 2);
    Debug.Assert(result == 3);
}