| --- |
| permalink: /docs/executing-wasm |
| --- |
| |
| # Executing WebAssembly in Teaclave |
| |
| Teaclave integrates WebAssembly Micro Runtime as an executor, which can |
| interpret WebAssembly bytecode in a sandboxed environment. Theoretically, source |
| code written in any language which can be compiled to WebAssembly should also be |
| executable in Teaclave. However, in order to be more secure, Teaclave cannot |
| provide interfaces such as syscalls to legacy applications, so the source code |
| should: |
| |
| 1. Be self-contained: not depending on libraries which are not provided by |
| Teaclave, including standard libraries. |
| 2. Contains no syscall: no system call-related code. |
| 3. Implement required interface: exporting an `int entrypoint(int argc, char* |
| argv[])` function which is compatible with Teaclave WAMR calling convention |
| (see examples for more details). |
| |
| Currently, [Teaclave file system APIs](../sdk/payload/wasm) are supported. We |
| also provide examples for compiling and executing from source code of various |
| languages. |
| |
| ::: tip NOTE |
| In current Teaclave client SDK, when passing arguments to the registered |
| function, each `(key, value)` pair is converted into two string pointers in |
| `argv` and you should expect `argc` is as twice as the actual number of |
| arguments. The calling convention is subject to further changes. |
| ::: |
| |
| |
| ## From C |
| |
| `clang` supporting `wasm32` can be used for compiling Teaclave-compatible WASM |
| bytecode. Remember to add following options while compiling: |
| |
| ```sh |
| --target=wasm32 \ |
| -nostdlib \ |
| -Wl,--no-entry \ |
| -Wl,--export-all, \ |
| -Wl,--allow-undefined |
| ``` |
| |
| You can also use `clang` provided by |
| [wasi-sdk](https://github.com/WebAssembly/wasi-sdk), and the option |
| `--target=wasm32` is not needed for this version. We also provide an [example |
| payload written in |
| C](https://github.com/apache/incubator-teaclave/tree/master/examples/python/wasm_c_millionaire_problem_payload). |
| |
| Alternatively, C and C++ code can be compiled with [zig](https://ziglang.org): |
| |
| ```sh |
| zig cc -Os --target=wasm32-freestanding -shared -o example.wasm example.c |
| zig c++ -Os --target=wasm32-freestanding -shared -o example.wasm example.cpp |
| ``` |
| |
| ## From Rust |
| |
| First of all, your cargo should support `wasm32` target and `wasm-gc` is |
| required to reduce the size of generated binary. You can easily run the |
| following commands to install dependencies: |
| |
| ```sh |
| rustup target add wasm32-unknown-unknown |
| cargo install wasm-gc |
| ``` |
| |
| There should be an exported `entrypoint` function in the source code, so you can |
| simply use `cargo` to create a new library and generate it with `cargo build |
| --target wasm32-unknown-unknown`. Please also add `crate-type = ["cdylib"]` in |
| the `[lib]` section into your `Cargo.toml` file to let cargo generate WASM file. |
| To reduce the size of WASM file, run: |
| |
| ```sh |
| cargo build --target wasm32-unknown-unknown --release |
| wasm-gc target/wasm32-unknown-unknown/release/[WASM FILENAME] |
| ``` |
| |
| For detailed optimization options and function signature, please refer to the |
| [example payload](https://github.com/apache/incubator-teaclave/tree/master/examples/python/wasm_rust_psi_payload). |
| |
| ## References |
| |
| - [Compiling Rust to WebAssembly: A Simple Example](https://depth-first.com/articles/2020/06/29/compiling-rust-to-webassembly-a-simple-example/) |