Fix use of locals
This commit is contained in:
136
src/tests.rs
136
src/tests.rs
@@ -159,6 +159,7 @@ fn large_function() {
|
||||
assert_eq!(
|
||||
{
|
||||
let translated = translate_wat(code);
|
||||
translated.disassemble();
|
||||
let out: u32 = unsafe { translated.execute_func(0, (5, 4, 3, 2, 1, 0)) };
|
||||
out
|
||||
},
|
||||
@@ -192,6 +193,7 @@ fn function_read_args_spill_to_stack() {
|
||||
assert_eq!(
|
||||
{
|
||||
let translated = translate_wat(code);
|
||||
translated.disassemble();
|
||||
let out: u32 = unsafe {
|
||||
translated.execute_func(0, (7u32, 6u32, 5u32, 4u32, 3u32, 2u32, 1u32, 0u32))
|
||||
};
|
||||
@@ -258,6 +260,140 @@ fn function_write_args_spill_to_stack() {
|
||||
11
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block() {
|
||||
let code = r#"
|
||||
(module
|
||||
(func (param i32) (param i32) (result i32)
|
||||
(block (result i32)
|
||||
get_local 0
|
||||
)
|
||||
)
|
||||
)
|
||||
"#;
|
||||
assert_eq!(execute_wat(code, 10, 20), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn br_block() {
|
||||
let code = r#"
|
||||
(module
|
||||
(func (param i32) (param i32) (result i32)
|
||||
get_local 1
|
||||
(block (result i32)
|
||||
get_local 0
|
||||
get_local 0
|
||||
br 0
|
||||
unreachable
|
||||
)
|
||||
i32.add
|
||||
)
|
||||
)
|
||||
"#;
|
||||
assert_eq!(execute_wat(code, 5, 7), 12);
|
||||
}
|
||||
|
||||
// Tests discarding values on the value stack, while
|
||||
// carrying over the result using a conditional branch.
|
||||
#[test]
|
||||
fn brif_block() {
|
||||
let code = r#"
|
||||
(module
|
||||
(func (param i32) (param i32) (result i32)
|
||||
get_local 1
|
||||
(block (result i32)
|
||||
get_local 0
|
||||
get_local 0
|
||||
br_if 0
|
||||
unreachable
|
||||
)
|
||||
i32.add
|
||||
)
|
||||
)
|
||||
"#;
|
||||
assert_eq!(execute_wat(code, 5, 7), 12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spec_loop() {
|
||||
let code = r#"
|
||||
(module
|
||||
(func
|
||||
(call $assert-return (call $as-binary-operand) (i32.const 12))
|
||||
(call $assert-return (call $break-bare) (i32.const 19))
|
||||
(call $assert-return (call $break-value) (i32.const 18))
|
||||
(call $assert-return (call $break-repeated) (i32.const 18))
|
||||
(call $assert-return (call $break-inner) (i32.const 0x7))
|
||||
)
|
||||
(func $dummy)
|
||||
(func $as-binary-operand (result i32)
|
||||
(i32.mul
|
||||
(loop (result i32) (call $dummy) (i32.const 3))
|
||||
(loop (result i32) (call $dummy) (i32.const 4))
|
||||
)
|
||||
)
|
||||
(func $break-bare (result i32)
|
||||
(block (loop (br 1) (br 0) (unreachable)))
|
||||
(block (loop (br_if 1 (i32.const 1)) (unreachable)))
|
||||
(i32.const 19)
|
||||
)
|
||||
(func $break-value (result i32)
|
||||
(block (result i32)
|
||||
(loop (result i32) (br 1 (i32.const 18)) (br 0) (i32.const 19))
|
||||
)
|
||||
)
|
||||
(func $break-repeated (result i32)
|
||||
(block (result i32)
|
||||
(loop (result i32)
|
||||
(br 1 (i32.const 18))
|
||||
(br 1 (i32.const 19))
|
||||
(drop (br_if 1 (i32.const 20) (i32.const 0)))
|
||||
(drop (br_if 1 (i32.const 20) (i32.const 1)))
|
||||
(br 1 (i32.const 21))
|
||||
(i32.const 21)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $break-inner (result i32)
|
||||
(local i32)
|
||||
(set_local 0 (i32.const 0))
|
||||
(set_local 0 (i32.add (get_local 0) (block (result i32) (loop (result i32) (block (result i32) (br 2 (i32.const 0x1)))))))
|
||||
(set_local 0 (i32.add (get_local 0) (block (result i32) (loop (result i32) (loop (result i32) (br 2 (i32.const 0x2)))))))
|
||||
(set_local 0 (i32.add (get_local 0) (block (result i32) (loop (result i32) (block (result i32) (loop (result i32) (br 1 (i32.const 0x4))))))))
|
||||
(get_local 0)
|
||||
)
|
||||
(func $assert-return (param i32) (param i32)
|
||||
(if (i32.eq (get_local 0) (get_local 1)) (then) (else (unreachable)))
|
||||
)
|
||||
)
|
||||
"#;
|
||||
|
||||
let translated = translate_wat(code);
|
||||
translated.disassemble();
|
||||
unsafe { translated.execute_func::<(), ()>(0, ()) }
|
||||
}
|
||||
|
||||
// Tests that br_if keeps values in the case if the branch
|
||||
// hasn't been taken.
|
||||
#[test]
|
||||
fn brif_block_passthru() {
|
||||
let code = r#"
|
||||
(module
|
||||
(func (param i32) (param i32) (result i32)
|
||||
(block (result i32)
|
||||
get_local 1
|
||||
get_local 0
|
||||
br_if 0
|
||||
get_local 1
|
||||
i32.add
|
||||
)
|
||||
)
|
||||
)
|
||||
"#;
|
||||
assert_eq!(execute_wat(code, 0, 3), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn literals() {
|
||||
let code = r#"
|
||||
|
||||
Reference in New Issue
Block a user