Skip to content
This repository has been archived by the owner on Sep 12, 2023. It is now read-only.

Latest commit

 

History

History
154 lines (112 loc) · 3.84 KB

Tutorial_Wasm_Bindgen.md

File metadata and controls

154 lines (112 loc) · 3.84 KB

How to run wasm applications with wasmedge-core (Wasm-Bindgen and interpreter mode)

Environment Setup for Rust, Nodejs, and rustwasmc

$ sudo apt-get update
$ sudo apt-get -y upgrade
$ sudo apt install build-essential curl wget git vim libboost-all-dev

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env
$ cargo install cargo-wasi

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

$ export NVM_DIR="$HOME/.nvm"
$ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
$ [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

$ nvm install v14.2.0
$ nvm use v14.2.0

$ npm i -g rustwasmc

Example 1. Hello Application

Create a new rust library project

cargo new --lib hello
cd hello

Modify the cargo config file

Add the following to the Cargo.toml file.

[lib]
name = "hello"
path = "src/lib.rs"
crate-type =["cdylib"]

[dependencies]
wasm-bindgen = "=0.2.61"

Write Rust code

Below is the entire content of the src/lib.rs file.

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(s: String) -> String {
  let r = String::from("hello ");
  return r + &s;
}

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
    return a + b;
}

#[wasm_bindgen]
pub fn reverse(v: Vec<u8>) -> Vec<u8> {
    let mut r = v.clone();
    r.reverse();
    return r;
}

In addition to the above code, functions like the example below can deliberately parse incoming JSON string data. This is an additional say example that uses valid JSON instead of just plain string. Please note, in addition to the dependencies above, you will now also need to add serde_json = "1.0.53" to your Cargo.toml file for the following say_with_json demonstration to work.

use serde_json::json;
use wasm_bindgen::prelude::*;
use serde_json::{Result, Value};

#[wasm_bindgen]
pub fn say_with_json(s: String) -> String {
    let json_as_value: Value = serde_json::from_str(&s).unwrap();
    let first_word = String::from("Hello ");
    let concatenation = first_word + &serde_json::to_string(&json_as_value["name"]).unwrap();
    let response_object = json!({ "result": concatenation });
    return serde_json::to_string(&response_object).unwrap();
}

When given {"name": "Tim"} this say_with_json function returns Hello Tim wrapped in a response object (as valid JSON) like this {"ssvm_response": ["{\"result\": \"Hello Tim\"}"]}

Build the WASM bytecode with rustwasmc

rustwasmc build

After building, our target wasm file is located at pkg/hello_bg.wasm.

Install WasmEdge addon for your application

npm install wasmedge-core

or if you want to build from source:

export CXX=g++-9
npm install --build-from-source https://github.com/second-state/wasmedge-core

Use WasmEdge addon

After installing WasmEdge addon, we could now interact with hello_bg.wasm generated by wasm-pack in Node.js. Make sure you use the corresponding VM method to the rust return type.

  • Create a new folder at any path you want. (e.g. mkdir application)
  • Copy hello_bg.wasm into your application directory. (e.g. cp hello_gb.wasm <path_to_your_application_folder>)
  • Create js file main.js (or whatever you like) with the following content:
var wasmedge = require('wasmedge-core');
var vm = new wasmedge.VM("hello_bg.wasm");
var ret = vm.RunString("say", "world");
console.log(ret);

ret = vm.RunInt("add", 3, 4);
console.log(ret);

ret = vm.RunUint8Array("reverse", Uint8Array.from([1, 2, 3, 4, 5, 6]));
console.log(ret);

ret = vm.RunInt("add", 999, -111);
console.log(ret);

ret = vm.RunUint8Array("reverse", Uint8Array.from([60, 50, 40, 30, 20, 10]));
console.log(ret);

Execute and check results

$ node main.js

hello world
7
Uint8Array [ 6, 5, 4, 3, 2, 1 ]
888
Uint8Array [ 10, 20, 30, 40, 50, 60 ]