bytecodealliance / wamr-rust-sdk

Apache License 2.0
29 stars 9 forks source link

wamr-rust-sdk

WAMR Rust SDK

Overview

WAMR Rust SDK provides Rust language bindings for WAMR. It is the wrapper of wasm_export.h but with Rust style. It is more convenient to use WAMR in Rust with this crate.

This crate contains API used to interact with Wasm modules. You can compile modules, instantiate modules, call their export functions, etc. Plus, as an embedded of Wasm, you can provide Wasm module functionality by creating host-defined functions.

WAMR Rust SDK includes a wamr-sys crate. It will search for the WAMR runtime source in the path ../... And then uses rust-bindgen durning the build process to make a .so.

This crate has similar concepts to the WebAssembly specification.

Core concepts

WASI concepts

WAMR private concepts

Examples

Example: to run a wasm32-wasi .wasm

wasm32-wasi is a most common target for Wasm. It means that the .wasm is compiled with cargo build --target wasm32-wasi or wasi-sdk/bin/clang --target wasm32-wasi.

Say there is a gcd_wasm32_wasi.wasm which includes a function named gcd. It returns the GCD of two parameters.

The rust code to call the function would be:

use wamr_rust_sdk::{
    runtime::Runtime, module::Module, instance::Instance, function::Function,
    value::WasmValue, RuntimeError
};
use std::path::PathBuf;

fn main() -> Result<(), RuntimeError> {
    let runtime = Runtime::new()?;

    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.push("resources/test");
    d.push("gcd_wasm32_wasi.wasm");

    let module = Module::from_file(&runtime, d.as_path())?;

    let instance = Instance::new(&runtime, &module, 1024 * 64)?;

    let function = Function::find_export_func(&instance, "gcd")?;

    let params: Vec<WasmValue> = vec![WasmValue::I32(9), WasmValue::I32(27)];
    let result = function.call(&instance, &params)?;
    assert_eq!(result, WasmValue::I32(9));

    Ok(())
}

Example: more configuration for runtime.

With more configuration, runtime is capable to run .wasm with variant features, like

Say there is an add_extra_wasm32_wasi.wasm. Its exported function, add(), requires an imported function, extra(), during the execution. The add() adds two parameters and the result of extra() . It is like a + b + extra().

The rust code to call the add function is like this:

use wamr_rust_sdk::{
    runtime::Runtime, module::Module, instance::Instance, function::Function,
    value::WasmValue, RuntimeError
};
use std::path::PathBuf;
use std::ffi::c_void;

extern "C" fn extra() -> i32 {
    100
}

fn main() -> Result<(), RuntimeError> {
    let runtime = Runtime::builder()
        .use_system_allocator()
        .register_host_function("extra", extra as *mut c_void)
        .build()?;

    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.push("resources/test");
    d.push("add_extra_wasm32_wasi.wasm");
    let module = Module::from_file(&runtime, d.as_path())?;

    let instance = Instance::new(&runtime, &module, 1024 * 64)?;

    let function = Function::find_export_func(&instance, "add")?;

    let params: Vec<WasmValue> = vec![WasmValue::I32(9), WasmValue::I32(27)];
    let result = function.call(&instance, &params)?;
    assert_eq!(result, WasmValue::I32(136));

    Ok(())
}