extern crate wain_exec;
extern crate wain_syntax_text;
extern crate wain_validate;
use std::io;
use std::process::exit;
use wain_exec::{DefaultImporter, Runtime, Value};
use wain_syntax_text::parse;
use wain_validate::validate;
const MODULE_ADD: &str = r#"
(module
(type (;0;) (func (param i32 i32) (result i32)))
(func $add (type 0) (param i32 i32) (result i32)
(local i32 i32 i32 i32 i32 i32)
global.get 0
local.set 2
i32.const 16
local.set 3
local.get 2
local.get 3
i32.sub
local.set 4
local.get 4
local.get 0
i32.store offset=12
local.get 4
local.get 1
i32.store offset=8
local.get 4
i32.load offset=12
local.set 5
local.get 4
i32.load offset=8
local.set 6
local.get 5
local.get 6
i32.add
local.set 7
local.get 7
return)
(table (;0;) 1 1 funcref)
(memory (;0;) 2)
(global (;0;) (mut i32) (i32.const 66560))
(export "memory" (memory 0))
(export "add" (func $add)))
"#;
fn main() {
let tree = match parse(MODULE_ADD) {
Ok(tree) => tree,
Err(err) => {
eprintln!("Parse failed: {}", err);
exit(1);
}
};
if let Err(err) = validate(&tree) {
eprintln!("This .wat file is invalid: {}", err);
exit(1);
}
let stdin = io::stdin();
let stdout = io::stdout();
let importer = DefaultImporter::with_stdio(stdin.lock(), stdout.lock());
let mut runtime = match Runtime::instantiate(&tree.module, importer) {
Ok(rt) => rt,
Err(err) => {
eprintln!("could not instantiate module: {}", err);
exit(1);
}
};
match runtime.invoke("add", &[Value::I32(10), Value::I32(32)]) {
Ok(ret) => {
if let Some(Value::I32(i)) = ret {
println!("10 + 32 = {}", i);
} else {
unreachable!();
}
}
Err(trap) => eprintln!("Execution was trapped: {}", trap),
}
}