WebAssembly Micro Runtime (WAMR) is standalone WebAssembly (WASM) runtime with small footprint. It includes a few components:
- WebAssembly VM core
- WASM application programming API (code available, but compilation is depending on the app manager component)
- Dynamic WASM application management (Not available in github yet. It will be released soon)
Why should we use a WASM runtime out of browser? There are a few points which might be meaningful:
1. WASM is already the LLVM official backend target. That means WASM can run any programming languages which can be compiled to LLVM IR. It is a huge advantage comparing to those language bound runtimes like JS, Lua.
2. WASM is an open standard and the growing trend is so fast as it is supported by the whole web ecosystem
3. WASM is designed to be very friendly for compiling to native binary and gaining the native speed.
4. Potentially change the development practices. Imaging we can do both the WASM application development and validation in a browser, then just download the wasm binary code into the target device.
5. WASM can work without garbage collection. It can be designed to support execution determinics for the time sensitive requirement.
Features
=========================
- WASM interpreter (AOT is planned)
- Provide built-in Libc subset, support "side_module=1" EMCC compilation option
- Provide APIs for embedding runtime into production software
- Provide mechanism for exporting native APIs to WASM applications
- Support programming firmware apps in multi languages (C/C++/Java/Rust/Go/TypeScript etc.)
- App sandbox execution environment on embedded OS
- Pure asynchronized programming model
- Menu configuration for easy platform integration
- Support micro service and pub-sub event inter-app communication models
- Easy to extend to support remote FW application management from host or cloud
Architecture
=========================
The application manager component handles the packets that the platform recieved from external through any communication buses such as socket, serial port, PSI. A packet type can be either request, response or event. It will service the request with URI "/applet" and call the runtime glue layer interfaces for installing/uninstalling the application. For other URIs, it will filter the resource registeration table and router the request to internal queue of responsible application.
The WebAssembly runtime is the execution environment for WASM applications.
The messaging layer can suppor the API for WASM applications communicate to each other and also the host environment.
When Ahead of Time compilation is enabled, the WASM application can be either bytecode or compiled native binary.
You will get ```test.wasm``` which is the WASM app binary.
Run WASM app
========================
Assume you are using Linux, the command to run the test.wasm is
``` Bash
cd iwasm/products/linux/bin
./iwasm test.wasm
```
You will get output:
```
Hello world!
buf ptr: 0x000101ac
buf: 1234
```
If you would like to run test app on Zephyr, we have embedded test sample into its OS image. You need to execute
```
ninja run
```
Embed WAMR into software production
=====================================
WAMR can be built into a standalone executable which takes WASM application file name as input, and then execute it. To use it in the embedded environment, you should embed WAMR into your own software product. WASM provides a set of APIs for embedders code to load WASM module, instansiate module and invoke WASM function from native call.
if (!wasm_runtime_call_wasm(inst, env, func, 1, argv_buf) ) {
wasm_runtime_clear_exception(inst);
}
wasm_runtime_destory_exec_env(env);
wasm_runtime_deinstantiate(inst);
wasm_runtime_unload(module);
wasm_runtime_destroy();
```
WASM application library
========================
In general, there are 3 kinds of APIs for programming the WASM application:
- Built-in APIs: WAMR has already provided a minimal API set for developers.
- 3rd party APIs: Programmer can download include any 3rd party C source code, and added into their own WASM app source tree.
- Platform native APIs: The board vendors define these APIs during their making board firmware. They are provided WASM application to invoke like built-in and 3rd party APIs. In this way board vendors extend APIs which can make programmers develop more complicated WASM apps.
Built-in application library
---------------
Built-in APIs include Libc APIs, Base library, Extension library reference.
**Libc APIs**<br/>
It is the minimal Libc APIs like memory allocation and string copy etc.
The header files is ```lib/app-libs/libc/lib-base.h```. The API set is listed as below:
``` C
void *malloc(size_t size);
void *calloc(size_t n, size_t size);
void free(void *ptr);
int memcmp(const void *s1, const void *s2, size_t n);
char *strncpy(char *dest, const char *src, unsigned long n);
```
**Base library**<br/>
The basic support like communication, timers etc is already available. The header files is ```lib/app-libs/base/wasm-app.h```, it includes request and response APIs, event pub/sub APIs and timer APIs. Please be noted that they may not work if you have no corresponding framework to work with them.
void api_timer_restart(user_timer_t timer, int interval);
```
**Library extension reference**<br/>
Currently we provide the sensor APIs as one library extension sample. The header file ```lib/app-libs/extension/sensor/sensor.h```, the API set is listed as below:
WAMR provides the macro `EXPORT_WASM_API` to enable users to export native API to WASM application. WAMR implemented a base API for timer and messaging by using `EXPORT_WASM_API`. They can be reference point of extending your own library.
 **Security attention:** The WebAssembly application is supposed to access its own memory space, the integrator should carefully design the native function to ensure the memory safe. The native API to be exporte to WASM application must follow the rules:
- Only use 32 bits number for parameters
- Don’t passing data structure pointer (do data serialization instead)
- Do the pointer address conversion in native API
- Don’t passing function pointer as callback
Below is a sample of library extension. All invoke across WASM world and native world must be serialized and de-serialized, and native world must do boundary check for every incoming address from WASM world.
In the application source project, it includes the WAMR built-in APIs header file and platform extension header files.
Assume the board vendor extend the library which added a API called customized(). The WASM application would be like this:
``` C
#include <stdio.h>
#include "lib-export-dec.h" // provided by platform vendor
int main(int argc, char **argv)
{
int I;
char *buf = “abcd”;
customized(); // customized API provided by platform vendor
return i;
}
```
Comming soon...
========================
We are preparing the open source for application manager and related cool samples like inter-application communication, application life cycle management, 2D graphic demo and more. You will get updated soon.
Submit issues and request
=========================
[Click here to submit. Your feedback is always welcome!](https://github.com/intel/wasm-micro-runtime/issues/new)