Update the top-level README.md and embedding documentation. (#508)
* Update the top-level README.md and embedding documentation. wasmtime-api is now the primary external API crate, so recommend that instead of wasmtime-jit. Also, enable wasmtime-api's C API by default, so that it shows up on docs.rs, and to make it easier to use. And, add basic embedding documentation and link to it from the README.md. Credit to @yurydelendik for the content. * Use the new wasm-c-api URL. * Don't pass --features wasm-c-api, as it is now on by default.
This commit is contained in:
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -201,7 +201,7 @@ jobs:
|
|||||||
- run: $CENTOS cargo build --release --bin wasmtime --bin wasm2obj
|
- run: $CENTOS cargo build --release --bin wasmtime --bin wasm2obj
|
||||||
shell: bash
|
shell: bash
|
||||||
# Build `libwasmtime_api.so`
|
# Build `libwasmtime_api.so`
|
||||||
- run: $CENTOS cargo build --release --features wasm-c-api --manifest-path wasmtime-api/Cargo.toml
|
- run: $CENTOS cargo build --release --manifest-path wasmtime-api/Cargo.toml
|
||||||
shell: bash
|
shell: bash
|
||||||
# Test what we just built
|
# Test what we just built
|
||||||
- run: $CENTOS cargo test --release --all --exclude lightbeam --exclude wasmtime-wasi-c --exclude wasmtime-py --exclude wasmtime-api
|
- run: $CENTOS cargo test --release --all --exclude lightbeam --exclude wasmtime-wasi-c --exclude wasmtime-py --exclude wasmtime-api
|
||||||
|
|||||||
30
README.md
30
README.md
@@ -35,34 +35,24 @@ of ongoing research.
|
|||||||
Additional goals for Wasmtime include:
|
Additional goals for Wasmtime include:
|
||||||
- Support a variety of host APIs (not just WASI), with fast calling sequences,
|
- Support a variety of host APIs (not just WASI), with fast calling sequences,
|
||||||
and develop proposals for additional API modules to be part of WASI.
|
and develop proposals for additional API modules to be part of WASI.
|
||||||
- Implement the [proposed WebAssembly C API].
|
- Facilitate development and testing around the [Cranelift] and [Lightbeam] JITs,
|
||||||
- Facilitate testing, experimentation, and development around the [Cranelift] and
|
and other WebAssembly execution strategies.
|
||||||
[Lightbeam] JITs.
|
|
||||||
- Develop a native ABI used for compiling WebAssembly suitable for use in both
|
- Develop a native ABI used for compiling WebAssembly suitable for use in both
|
||||||
JIT and AOT to native object files.
|
JIT and AOT to native object files.
|
||||||
|
|
||||||
[proposed WebAssembly C API]: https://github.com/rossberg/wasm-c-api
|
|
||||||
[Cranelift]: https://github.com/CraneStation/cranelift
|
[Cranelift]: https://github.com/CraneStation/cranelift
|
||||||
[Lightbeam]: https://github.com/CraneStation/lightbeam
|
[Lightbeam]: https://github.com/CraneStation/wasmtime/tree/master/lightbeam
|
||||||
|
|
||||||
#### Including Wasmtime in your project
|
#### Including Wasmtime in your project
|
||||||
Wasmtime exposes an API for JIT compilation through the `wasmtime-jit` subcrate, which depends on `wasmtime-environ` and `wasmtime-runtime` for the ABI and runtime support respectively. However, this API is not documented and subject to change. Please use at your own risk!
|
|
||||||
|
|
||||||
Build the individual crates as such:
|
Wasmtime exposes an API for embedding as a library through the `wasmtime-api` subcrate,
|
||||||
|
which contains both a [high-level and safe Rust API], as well as a C-compatible API
|
||||||
|
compatible with the [proposed WebAssembly C API].
|
||||||
|
|
||||||
```
|
For more information, see the [Rust API embedding chapter] of the Wasmtime documentation.
|
||||||
cargo build --package wasmtime-jit
|
|
||||||
```
|
|
||||||
|
|
||||||
Wasmtime does not currently publish these crates on crates.io. They may be included as a git dependency, like this:
|
[high-level and safe Rust API]: https://docs.rs/wasmtime-api/
|
||||||
|
[proposed WebAssembly C API]: https://github.com/WebAssembly/wasm-c-api
|
||||||
```toml
|
[Rust API embedding chapter]: https://cranestation.github.io/wasmtime/embed-rust.html
|
||||||
[dependencies]
|
|
||||||
wasmtime-environ = { git = "https://github.com/CraneStation/wasmtime", rev = "somecommithash" }
|
|
||||||
wasmtime-runtime = { git = "https://github.com/CraneStation/wasmtime", rev = "somecommithash" }
|
|
||||||
wasmtime-jit = { git = "https://github.com/CraneStation/wasmtime", rev = "somecommithash" }
|
|
||||||
```
|
|
||||||
|
|
||||||
All three crates must be specified as dependencies for `wasmtime-jit` to build correctly, at the moment.
|
|
||||||
|
|
||||||
It's Wasmtime.
|
It's Wasmtime.
|
||||||
|
|||||||
@@ -1,3 +1,99 @@
|
|||||||
# Embedding Wasmtime in Rust
|
# Embedding Wasmtime in Rust
|
||||||
|
|
||||||
... more coming soon
|
This document shows how to embed Wasmtime using the Rust API, and run a simple
|
||||||
|
wasm program.
|
||||||
|
|
||||||
|
# Create some wasm
|
||||||
|
|
||||||
|
Let's create a simple WebAssembly file with a single exported function that returns an integer:
|
||||||
|
|
||||||
|
```wat
|
||||||
|
(;; wat2wasm hello.wat -o $WASM_FILES/hello.wasm ;;)
|
||||||
|
(module
|
||||||
|
(func (export "answer") (result i32)
|
||||||
|
i32.const 42
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
# Create rust project
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cargo new --bin wasmtime_hello
|
||||||
|
$ cd wasmtime_hello
|
||||||
|
$ cp $WASM_FILES/hello.wasm .
|
||||||
|
```
|
||||||
|
|
||||||
|
We will be using the wasmtime engine/API to run the wasm file, so we will add the dependency to `Cargo.toml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[dependencies]
|
||||||
|
wasmtime-api = { git = "https://github.com/CraneStation/wasmtime" }
|
||||||
|
```
|
||||||
|
|
||||||
|
It is time to add code to the `src/main.rs`. First, the engine and storage need to be activated:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use wasmtime_api::*;
|
||||||
|
|
||||||
|
let engine = HostRef::new(Engine::default());
|
||||||
|
let store = HostRef::new(Store::new(&engine));
|
||||||
|
```
|
||||||
|
|
||||||
|
The `HostRef` will be used a lot -- it is a "convenience" object to store and refer an object between the host and
|
||||||
|
the embedded environments.
|
||||||
|
|
||||||
|
The `hello.wasm` can be read from the file system and provided to the `Module` object constructor as `&[u8]`:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::fs::read;
|
||||||
|
|
||||||
|
let hello_wasm = read("hello.wasm").expect("wasm file");
|
||||||
|
|
||||||
|
let module = HostRef::new(Module::new(&store, &hello_wasm).expect("wasm module"));
|
||||||
|
```
|
||||||
|
|
||||||
|
The module instance can now be created. Normally, you would provide exports, but in this case, there is none required:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let instance = Instance::new(&store, &module, &[]).expect("wasm instance");
|
||||||
|
```
|
||||||
|
|
||||||
|
Everything is set. If a WebAssembly module has a start function -- it was run.
|
||||||
|
The instance's exports can be used at this point. This wasm file has only one export, so we can index it directly:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let answer_fn = instance.exports()[0].func().expect("answer function");
|
||||||
|
```
|
||||||
|
|
||||||
|
The exported function can be called using the `call` method. Remember that in most of the cases,
|
||||||
|
a `HostRef<_>` object will be returned, so `borrow()` or `borrow_mut()` method has to be used to refer the
|
||||||
|
specific object. The exported "answer" function accepts no parameters and returns a single `i32` value.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let result = answer_fn.borrow().call(&[]).expect("success");
|
||||||
|
println!("Answer: {}", result[0].i32());
|
||||||
|
```
|
||||||
|
|
||||||
|
The names of the WebAssembly module's imports and exports can be discovered by means of module's corresponding methods.
|
||||||
|
|
||||||
|
# src/main.rs
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::fs::read;
|
||||||
|
use wasmtime_api::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let engine = HostRef::new(Engine::default());
|
||||||
|
let store = HostRef::new(Store::new(&engine));
|
||||||
|
|
||||||
|
let wasm = read("hello.wasm").expect("wasm file");
|
||||||
|
|
||||||
|
let module = HostRef::new(Module::new(&store, &wasm).expect("wasm module"));
|
||||||
|
let instance = Instance::new(&store, &module, &[]).expect("wasm instance");
|
||||||
|
|
||||||
|
let answer_fn = instance.exports()[0].func().expect("answer function");
|
||||||
|
let result = answer_fn.borrow().call(&[]).expect("success");
|
||||||
|
println!("Answer: {}", result[0].i32());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ hashbrown = { version = "0.6.0", optional = true }
|
|||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = ["cranelift-codegen/std", "cranelift-wasm/std", "wasmtime-environ/std", "wasmparser/std"]
|
std = ["cranelift-codegen/std", "cranelift-wasm/std", "wasmtime-environ/std", "wasmparser/std"]
|
||||||
wasm-c-api = []
|
|
||||||
core = ["hashbrown/nightly", "cranelift-codegen/core", "cranelift-wasm/core", "wasmtime-environ/core", "wasmparser/core"]
|
core = ["hashbrown/nightly", "cranelift-codegen/core", "cranelift-wasm/core", "wasmtime-environ/core", "wasmparser/core"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ WASM_CC_LIBS = $(error unsupported C++)
|
|||||||
|
|
||||||
# Compiler config
|
# Compiler config
|
||||||
ifeq (${WASMTIME_API_MODE},release)
|
ifeq (${WASMTIME_API_MODE},release)
|
||||||
CARGO_BUILD_FLAGS = --features "wasm-c-api" --release
|
CARGO_BUILD_FLAGS = --release
|
||||||
else
|
else
|
||||||
CARGO_BUILD_FLAGS = --features "wasm-c-api"
|
CARGO_BUILD_FLAGS =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (${C_COMP},clang)
|
ifeq (${C_COMP},clang)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ mod trap;
|
|||||||
mod types;
|
mod types;
|
||||||
mod values;
|
mod values;
|
||||||
|
|
||||||
#[cfg(feature = "wasm-c-api")]
|
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|||||||
Reference in New Issue
Block a user