2018-08-20 03:07:30 +03:00
|
|
|
extern crate parity_wasm;
|
|
|
|
extern crate tempfile;
|
|
|
|
extern crate wasm_bindgen_wasm_interpreter;
|
|
|
|
|
|
|
|
use std::fs;
|
|
|
|
use std::process::Command;
|
|
|
|
|
|
|
|
use wasm_bindgen_wasm_interpreter::Interpreter;
|
|
|
|
|
|
|
|
fn interpret(wat: &str, name: &str, result: Option<&[u32]>) {
|
|
|
|
let input = tempfile::NamedTempFile::new().unwrap();
|
|
|
|
let output = tempfile::NamedTempFile::new().unwrap();
|
|
|
|
fs::write(input.path(), wat).unwrap();
|
|
|
|
let status = Command::new("wat2wasm")
|
|
|
|
.arg(input.path())
|
2018-09-26 18:26:00 +03:00
|
|
|
.arg("-o")
|
|
|
|
.arg(output.path())
|
2018-08-20 03:07:30 +03:00
|
|
|
.status()
|
|
|
|
.unwrap();
|
|
|
|
println!("status: {}", status);
|
|
|
|
assert!(status.success());
|
|
|
|
let module = parity_wasm::deserialize_file(output.path()).unwrap();
|
|
|
|
let mut i = Interpreter::new(&module);
|
2019-01-11 21:26:45 +03:00
|
|
|
assert_eq!(i.interpret_descriptor(name, &module), result);
|
2018-08-20 03:07:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn smoke() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
|
|
|
|
(func $foo)
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[]));
|
|
|
|
interpret(wat, "bar", None);
|
|
|
|
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
|
|
|
(func $foo
|
|
|
|
i32.const 1
|
|
|
|
call $__wbindgen_describe
|
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn locals() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
|
|
|
(func $foo
|
|
|
|
(local i32)
|
|
|
|
i32.const 2
|
2019-01-11 21:26:45 +03:00
|
|
|
local.set 0
|
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
call $__wbindgen_describe
|
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[2]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn globals() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
2019-01-11 21:26:45 +03:00
|
|
|
(global (mut i32) (i32.const 0))
|
2018-08-20 03:07:30 +03:00
|
|
|
|
|
|
|
(func $foo
|
|
|
|
(local i32)
|
2019-01-11 21:26:45 +03:00
|
|
|
global.get 0
|
|
|
|
local.set 0
|
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
call $__wbindgen_describe
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
|
|
|
global.set 0
|
2018-08-20 03:07:30 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[256]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn arithmetic() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
|
|
|
(func $foo
|
|
|
|
i32.const 1
|
|
|
|
i32.const 2
|
|
|
|
i32.add
|
|
|
|
call $__wbindgen_describe
|
|
|
|
i32.const 2
|
|
|
|
i32.const 1
|
|
|
|
i32.sub
|
|
|
|
call $__wbindgen_describe
|
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[3, 1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn return_early() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
|
|
|
(func $foo
|
|
|
|
i32.const 1
|
|
|
|
i32.const 2
|
|
|
|
call $__wbindgen_describe
|
|
|
|
return
|
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[2]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn loads_and_stores() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
2019-01-11 21:26:45 +03:00
|
|
|
(global (mut i32) (i32.const 0))
|
2018-08-20 03:07:30 +03:00
|
|
|
(memory 1)
|
|
|
|
|
|
|
|
(func $foo
|
|
|
|
(local i32)
|
|
|
|
|
|
|
|
;; decrement the stack pointer, setting our local to the
|
|
|
|
;; lowest address of our stack
|
2019-01-11 21:26:45 +03:00
|
|
|
global.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.const 16
|
|
|
|
i32.sub
|
2019-01-11 21:26:45 +03:00
|
|
|
local.set 0
|
|
|
|
local.get 0
|
|
|
|
global.set 0
|
2018-08-20 03:07:30 +03:00
|
|
|
|
|
|
|
;; store 1 at fp+0
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.const 1
|
|
|
|
i32.store offset=0
|
|
|
|
|
|
|
|
;; store 2 at fp+4
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.const 2
|
|
|
|
i32.store offset=4
|
|
|
|
|
|
|
|
;; store 3 at fp+8
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.const 3
|
|
|
|
i32.store offset=8
|
|
|
|
|
|
|
|
;; load fp+0 and call
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.load offset=0
|
|
|
|
call $__wbindgen_describe
|
|
|
|
|
|
|
|
;; load fp+4 and call
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.load offset=4
|
|
|
|
call $__wbindgen_describe
|
|
|
|
|
|
|
|
;; load fp+8 and call
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.load offset=8
|
|
|
|
call $__wbindgen_describe
|
|
|
|
|
|
|
|
;; increment our stack pointer
|
2019-01-11 21:26:45 +03:00
|
|
|
local.get 0
|
2018-08-20 03:07:30 +03:00
|
|
|
i32.const 16
|
|
|
|
i32.add
|
2019-01-11 21:26:45 +03:00
|
|
|
global.set 0
|
2018-08-20 03:07:30 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[1, 2, 3]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn calling_functions() {
|
|
|
|
let wat = r#"
|
|
|
|
(module
|
|
|
|
(import "__wbindgen_placeholder__" "__wbindgen_describe"
|
|
|
|
(func $__wbindgen_describe (param i32)))
|
|
|
|
|
|
|
|
(global i32 (i32.const 0))
|
|
|
|
(memory 1)
|
|
|
|
|
|
|
|
(func $foo
|
|
|
|
call $bar
|
|
|
|
)
|
|
|
|
|
|
|
|
(func $bar
|
|
|
|
i32.const 0
|
|
|
|
call $__wbindgen_describe
|
|
|
|
)
|
|
|
|
|
|
|
|
(export "foo" (func $foo))
|
|
|
|
)
|
|
|
|
"#;
|
|
|
|
interpret(wat, "foo", Some(&[0]));
|
|
|
|
}
|