# How to run wasm applications with wasmedge-core (Wasm-Bindgen and interpreter mode) ## Environment Setup for Rust, Nodejs, and rustwasmc ```bash $ 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 ```bash cargo new --lib hello cd hello ``` ### Modify the cargo config file Add the following to the `Cargo.toml` file. ```toml [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. ```rust 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) -> Vec { 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. ```rust 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 ```bash rustwasmc build ``` After building, our target wasm file is located at `pkg/hello_bg.wasm`. ### Install WasmEdge addon for your application ```bash npm install wasmedge-core ``` or if you want to build from source: ```bash 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 `) - Create js file `main.js` (or whatever you like) with the following content: ```javascript 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 ```bash $ node main.js hello world 7 Uint8Array [ 6, 5, 4, 3, 2, 1 ] 888 Uint8Array [ 10, 20, 30, 40, 50, 60 ] ```