Embed a standalone WASM app

The WasmEdge Go SDK can embed standalone WebAssembly applications — ie a Rust application with a main() function compiled into WebAssembly.

Our demo Rust application reads from a file. Note that the WebAssembly program’s input and output data are now passed by the STDIN and STDOUT.

1. use std::env;
2. use std::fs::File;
3. use std::io::{self, BufRead};

5. fn main() {
6. // Get the argv.
7. let args: Vec<String> = env::args().collect();
8. if args.len() <= 1 {
9. println!("Rust: ERROR - No input file name.");
10. return;
11. }

13. // Open the file.
14. println!("Rust: Opening input file \"{}\"...", args[1]);
15. let file = match File::open(&args[1]) {
16. Err(why) => {
17. println!("Rust: ERROR - Open file \"{}\" failed: {}", args[1], why);
18. return;
19. },
20. Ok(file) => file,
21. };

23. // Read lines.
24. let reader = io::BufReader::new(file);
25. let mut texts:Vec<String> = Vec::new();
26. for line in reader.lines() {
27. if let Ok(text) = line {
28. texts.push(text);
29. }
30. }
31. println!("Rust: Read input file \"{}\" succeeded.", args[1]);

33. // Get stdin to print lines.
34. println!("Rust: Please input the line number to print the line of file.");
35. let stdin = io::stdin();
36. for line in stdin.lock().lines() {
37. let input = line.unwrap();
38. match input.parse::<usize>() {
39. Ok(n) => if n > 0 && n <= texts.len() {
40. println!("{}", texts[n - 1]);
41. } else {
42. println!("Rust: ERROR - Line \"{}\" is out of range.", n);
43. },
44. Err(e) => println!("Rust: ERROR - Input \"{}\" is not an integer: {}", input, e),
45. }
46. }
47. println!("Rust: Process end.");
48. }

Compile the application into WebAssembly.

$ cd rust_readfile $ cargo build --target wasm32-wasi # The output file will be target/wasm32-wasi/debug/rust_readfile.wasm

The Go source code to run the WebAssembly function in WasmEdge is as follows.

package main import ( "os" "github.com/second-state/WasmEdge-go/wasmedge" ) func main() { wasmedge.SetLogErrorLevel() var conf = wasmedge.NewConfigure(wasmedge.REFERENCE_TYPES) conf.AddConfig(wasmedge.WASI) var vm = wasmedge.NewVMWithConfig(conf) var wasi = vm.GetImportModule(wasmedge.WASI) wasi.InitWasi( os.Args[1:], // The args os.Environ(), // The envs []string{".:."}, // The mapping directories ) // Instantiate wasm. _start refers to the main() function vm.RunWasmFile(os.Args[1], "_start") vm.Release() conf.Release() }

Next, let’s build the Go application with the WasmEdge Go SDK.

go get github.com/second-state/WasmEdge-go/wasmedge@v0.10.0 go build

Run the Golang application.

`$ ./read_file rust_readfile/target/wasm32-wasi/debug/rust_readfile.wasm file.txt Rust: Opening input file "file.txt"... Rust: Read input file "file.txt" succeeded. Rust: Please input the line number to print the line of file. # Input "5" and press Enter. 5 # The output will be the 5th line offile.txt`: abcDEF_!@#$%^ # To terminate the program, send the EOF (Ctrl + D). ^D # The output will print the terminate message: Rust: Process end.

More examples can be found at the WasmEdge-go-examples GitHub repo.