Added switch spectest

This commit is contained in:
Syrus Akbary 2018-10-28 13:59:06 +01:00
parent b94049f949
commit f4ce2c72ba
4 changed files with 647 additions and 2 deletions

150
spectests/switch.wast Normal file
View File

@ -0,0 +1,150 @@
(module
;; Statement switch
(func (export "stmt") (param $i i32) (result i32)
(local $j i32)
(set_local $j (i32.const 100))
(block $switch
(block $7
(block $default
(block $6
(block $5
(block $4
(block $3
(block $2
(block $1
(block $0
(br_table $0 $1 $2 $3 $4 $5 $6 $7 $default
(get_local $i)
)
) ;; 0
(return (get_local $i))
) ;; 1
(nop)
;; fallthrough
) ;; 2
;; fallthrough
) ;; 3
(set_local $j (i32.sub (i32.const 0) (get_local $i)))
(br $switch)
) ;; 4
(br $switch)
) ;; 5
(set_local $j (i32.const 101))
(br $switch)
) ;; 6
(set_local $j (i32.const 101))
;; fallthrough
) ;; default
(set_local $j (i32.const 102))
) ;; 7
;; fallthrough
)
(return (get_local $j))
)
;; Expression switch
(func (export "expr") (param $i i64) (result i64)
(local $j i64)
(set_local $j (i64.const 100))
(return
(block $switch (result i64)
(block $7
(block $default
(block $4
(block $5
(block $6
(block $3
(block $2
(block $1
(block $0
(br_table $0 $1 $2 $3 $4 $5 $6 $7 $default
(i32.wrap/i64 (get_local $i))
)
) ;; 0
(return (get_local $i))
) ;; 1
(nop)
;; fallthrough
) ;; 2
;; fallthrough
) ;; 3
(br $switch (i64.sub (i64.const 0) (get_local $i)))
) ;; 6
(set_local $j (i64.const 101))
;; fallthrough
) ;; 4
;; fallthrough
) ;; 5
;; fallthrough
) ;; default
(br $switch (get_local $j))
) ;; 7
(i64.const -5)
)
)
)
;; Argument switch
(func (export "arg") (param $i i32) (result i32)
(return
(block $2 (result i32)
(i32.add (i32.const 10)
(block $1 (result i32)
(i32.add (i32.const 100)
(block $0 (result i32)
(i32.add (i32.const 1000)
(block $default (result i32)
(br_table $0 $1 $2 $default
(i32.mul (i32.const 2) (get_local $i))
(i32.and (i32.const 3) (get_local $i))
)
)
)
)
)
)
)
)
)
)
;; Corner cases
(func (export "corner") (result i32)
(block
(br_table 0 (i32.const 0))
)
(i32.const 1)
)
)
(assert_return (invoke "stmt" (i32.const 0)) (i32.const 0))
(assert_return (invoke "stmt" (i32.const 1)) (i32.const -1))
(assert_return (invoke "stmt" (i32.const 2)) (i32.const -2))
(assert_return (invoke "stmt" (i32.const 3)) (i32.const -3))
(assert_return (invoke "stmt" (i32.const 4)) (i32.const 100))
(assert_return (invoke "stmt" (i32.const 5)) (i32.const 101))
(assert_return (invoke "stmt" (i32.const 6)) (i32.const 102))
(assert_return (invoke "stmt" (i32.const 7)) (i32.const 100))
(assert_return (invoke "stmt" (i32.const -10)) (i32.const 102))
(assert_return (invoke "expr" (i64.const 0)) (i64.const 0))
(assert_return (invoke "expr" (i64.const 1)) (i64.const -1))
(assert_return (invoke "expr" (i64.const 2)) (i64.const -2))
(assert_return (invoke "expr" (i64.const 3)) (i64.const -3))
(assert_return (invoke "expr" (i64.const 6)) (i64.const 101))
(assert_return (invoke "expr" (i64.const 7)) (i64.const -5))
(assert_return (invoke "expr" (i64.const -10)) (i64.const 100))
(assert_return (invoke "arg" (i32.const 0)) (i32.const 110))
(assert_return (invoke "arg" (i32.const 1)) (i32.const 12))
(assert_return (invoke "arg" (i32.const 2)) (i32.const 4))
(assert_return (invoke "arg" (i32.const 3)) (i32.const 1116))
(assert_return (invoke "arg" (i32.const 4)) (i32.const 118))
(assert_return (invoke "arg" (i32.const 5)) (i32.const 20))
(assert_return (invoke "arg" (i32.const 6)) (i32.const 12))
(assert_return (invoke "arg" (i32.const 7)) (i32.const 1124))
(assert_return (invoke "arg" (i32.const 8)) (i32.const 126))
(assert_return (invoke "corner") (i32.const 1))
(assert_invalid (module (func (br_table 3 (i32.const 0)))) "unknown label")

View File

@ -15,7 +15,7 @@ static ENV_VAR: &str = "WASM_GENERATE_SPECTESTS";
static BANNER: &str = "// Rust test file autogenerated with cargo build (src/build_spectests.rs).
// Please do NOT modify it by hand, as it will be reseted on next build.\n";
const TESTS: [&str; 25] = [
const TESTS: [&str; 26] = [
"spectests/address.wast",
"spectests/align.wast",
"spectests/block.wast",
@ -40,6 +40,7 @@ const TESTS: [&str; 25] = [
"spectests/labels.wast",
"spectests/memory.wast",
"spectests/set_local.wast",
"spectests/switch.wast",
"spectests/types.wast",
];
@ -384,7 +385,8 @@ fn wast_to_rust(wast_filepath: &str) -> String {
// panic!("SOULD MODIFY {:?} {:?}", should_modify, rust_test_filepath);
if should_modify || true {
if true {
// should_modify
let mut generator = WastTestGenerator::new(&path);
generator.consume();
let generated_script = generator.finalize();

View File

@ -27,4 +27,5 @@ mod i64_;
mod labels;
mod memory;
mod set_local;
mod switch;
mod types;

492
src/spectests/switch.rs Normal file
View File

@ -0,0 +1,492 @@
// Rust test file autogenerated with cargo build (src/build_spectests.rs).
// Please do NOT modify it by hand, as it will be reseted on next build.
// Test based on spectests/switch.wast
#![allow(
warnings,
dead_code
)]
use crate::webassembly::{instantiate, compile, ImportObject, ResultObject, VmCtx, Export};
use super::_common::spectest_importobject;
use wabt::wat2wasm;
// Line 1
fn create_module_1() -> ResultObject {
let module_str = "(module
(type (;0;) (func (param i32) (result i32)))
(type (;1;) (func (param i64) (result i64)))
(type (;2;) (func (result i32)))
(func (;0;) (type 0) (param i32) (result i32)
(local i32)
i32.const 100
set_local 1
block ;; label = @1
block ;; label = @2
block ;; label = @3
block ;; label = @4
block ;; label = @5
block ;; label = @6
block ;; label = @7
block ;; label = @8
block ;; label = @9
block ;; label = @10
get_local 0
br_table 0 (;@10;) 1 (;@9;) 2 (;@8;) 3 (;@7;) 4 (;@6;) 5 (;@5;) 6 (;@4;) 8 (;@2;) 7 (;@3;)
end
get_local 0
return
end
nop
end
end
i32.const 0
get_local 0
i32.sub
set_local 1
br 5 (;@1;)
end
br 4 (;@1;)
end
i32.const 101
set_local 1
br 3 (;@1;)
end
i32.const 101
set_local 1
end
i32.const 102
set_local 1
end
end
get_local 1
return)
(func (;1;) (type 1) (param i64) (result i64)
(local i64)
i64.const 100
set_local 1
block (result i64) ;; label = @1
block ;; label = @2
block ;; label = @3
block ;; label = @4
block ;; label = @5
block ;; label = @6
block ;; label = @7
block ;; label = @8
block ;; label = @9
block ;; label = @10
get_local 0
i32.wrap/i64
br_table 0 (;@10;) 1 (;@9;) 2 (;@8;) 3 (;@7;) 6 (;@4;) 5 (;@5;) 4 (;@6;) 8 (;@2;) 7 (;@3;)
end
get_local 0
return
end
nop
end
end
i64.const 0
get_local 0
i64.sub
br 5 (;@1;)
end
i64.const 101
set_local 1
end
end
end
get_local 1
br 1 (;@1;)
end
i64.const -5
end
return)
(func (;2;) (type 0) (param i32) (result i32)
block (result i32) ;; label = @1
i32.const 10
block (result i32) ;; label = @2
i32.const 100
block (result i32) ;; label = @3
i32.const 1000
block (result i32) ;; label = @4
i32.const 2
get_local 0
i32.mul
i32.const 3
get_local 0
i32.and
br_table 1 (;@3;) 2 (;@2;) 3 (;@1;) 0 (;@4;)
end
i32.add
end
i32.add
end
i32.add
end
return)
(func (;3;) (type 2) (result i32)
block ;; label = @1
i32.const 0
br_table 0 (;@1;)
end
i32.const 1)
(export \"stmt\" (func 0))
(export \"expr\" (func 1))
(export \"arg\" (func 2))
(export \"corner\" (func 3)))
";
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated")
}
// Line 120
fn l120_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l120_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(0 as i32, &vm_context);
assert_eq!(result, 0 as i32);
}
// Line 121
fn l121_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l121_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(1 as i32, &vm_context);
assert_eq!(result, -1 as i32);
}
// Line 122
fn l122_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l122_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(2 as i32, &vm_context);
assert_eq!(result, -2 as i32);
}
// Line 123
fn l123_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l123_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(3 as i32, &vm_context);
assert_eq!(result, -3 as i32);
}
// Line 124
fn l124_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l124_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(4 as i32, &vm_context);
assert_eq!(result, 100 as i32);
}
// Line 125
fn l125_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l125_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(5 as i32, &vm_context);
assert_eq!(result, 101 as i32);
}
// Line 126
fn l126_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l126_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(6 as i32, &vm_context);
assert_eq!(result, 102 as i32);
}
// Line 127
fn l127_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l127_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(7 as i32, &vm_context);
assert_eq!(result, 100 as i32);
}
// Line 128
fn l128_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l128_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("stmt") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(-10 as i32, &vm_context);
assert_eq!(result, 102 as i32);
}
// Line 130
fn l130_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l130_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(0 as i64, &vm_context);
assert_eq!(result, 0 as i64);
}
// Line 131
fn l131_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l131_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(1 as i64, &vm_context);
assert_eq!(result, -1 as i64);
}
// Line 132
fn l132_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l132_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(2 as i64, &vm_context);
assert_eq!(result, -2 as i64);
}
// Line 133
fn l133_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l133_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(3 as i64, &vm_context);
assert_eq!(result, -3 as i64);
}
// Line 134
fn l134_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l134_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(6 as i64, &vm_context);
assert_eq!(result, 101 as i64);
}
// Line 135
fn l135_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l135_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(7 as i64, &vm_context);
assert_eq!(result, -5 as i64);
}
// Line 136
fn l136_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l136_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("expr") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(-10 as i64, &vm_context);
assert_eq!(result, 100 as i64);
}
// Line 138
fn l138_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l138_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(0 as i32, &vm_context);
assert_eq!(result, 110 as i32);
}
// Line 139
fn l139_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l139_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(1 as i32, &vm_context);
assert_eq!(result, 12 as i32);
}
// Line 140
fn l140_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l140_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(2 as i32, &vm_context);
assert_eq!(result, 4 as i32);
}
// Line 141
fn l141_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l141_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(3 as i32, &vm_context);
assert_eq!(result, 1116 as i32);
}
// Line 142
fn l142_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l142_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(4 as i32, &vm_context);
assert_eq!(result, 118 as i32);
}
// Line 143
fn l143_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l143_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(5 as i32, &vm_context);
assert_eq!(result, 20 as i32);
}
// Line 144
fn l144_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l144_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(6 as i32, &vm_context);
assert_eq!(result, 12 as i32);
}
// Line 145
fn l145_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l145_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(7 as i32, &vm_context);
assert_eq!(result, 1124 as i32);
}
// Line 146
fn l146_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l146_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("arg") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(8 as i32, &vm_context);
assert_eq!(result, 126 as i32);
}
// Line 148
fn l148_assert_return_invoke(result_object: &ResultObject, vm_context: &VmCtx) {
println!("Executing function {}", "l148_assert_return_invoke");
let func_index = match result_object.module.info.exports.get("corner") {
Some(&Export::Function(index)) => index,
_ => panic!("Function not found"),
};
let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(result_object.instance, func_index);
let result = invoke_fn(&vm_context);
assert_eq!(result, 1 as i32);
}
// Line 150
#[test]
fn l150_assert_invalid() {
let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 10, 9, 1, 7, 0, 65, 0, 14, 0, 3, 11];
let compilation = compile(wasm_binary.to_vec());
assert!(compilation.is_err(), "WASM should not compile as is invalid");
}
#[test]
fn test_module_1() {
let result_object = create_module_1();
let vm_context = result_object.instance.generate_context();
// We group the calls together
l120_assert_return_invoke(&result_object, &vm_context);
l121_assert_return_invoke(&result_object, &vm_context);
l122_assert_return_invoke(&result_object, &vm_context);
l123_assert_return_invoke(&result_object, &vm_context);
l124_assert_return_invoke(&result_object, &vm_context);
l125_assert_return_invoke(&result_object, &vm_context);
l126_assert_return_invoke(&result_object, &vm_context);
l127_assert_return_invoke(&result_object, &vm_context);
l128_assert_return_invoke(&result_object, &vm_context);
l130_assert_return_invoke(&result_object, &vm_context);
l131_assert_return_invoke(&result_object, &vm_context);
l132_assert_return_invoke(&result_object, &vm_context);
l133_assert_return_invoke(&result_object, &vm_context);
l134_assert_return_invoke(&result_object, &vm_context);
l135_assert_return_invoke(&result_object, &vm_context);
l136_assert_return_invoke(&result_object, &vm_context);
l138_assert_return_invoke(&result_object, &vm_context);
l139_assert_return_invoke(&result_object, &vm_context);
l140_assert_return_invoke(&result_object, &vm_context);
l141_assert_return_invoke(&result_object, &vm_context);
l142_assert_return_invoke(&result_object, &vm_context);
l143_assert_return_invoke(&result_object, &vm_context);
l144_assert_return_invoke(&result_object, &vm_context);
l145_assert_return_invoke(&result_object, &vm_context);
l146_assert_return_invoke(&result_object, &vm_context);
l148_assert_return_invoke(&result_object, &vm_context);
}