Use macro + WAT to make gas injection unit tests more readable.

This commit is contained in:
Jim Posen 2019-07-12 10:15:37 +02:00
parent b5472bcd8f
commit ed7f31ec20

View File

@ -587,136 +587,6 @@ mod tests {
self::wabt::wasm2wat(&binary).unwrap(); self::wabt::wasm2wat(&binary).unwrap();
} }
#[test]
fn simple() {
let module = builder::module()
.global()
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(1),
Call(0),
GetGlobal(0),
End
][..]
);
}
#[test]
fn nested() {
let module = builder::module()
.global()
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(6),
Call(0),
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
][..]
);
}
#[test]
fn ifelse() {
let module = builder::module()
.global()
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
If(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
Else,
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(3),
Call(0),
GetGlobal(0),
If(elements::BlockType::NoResult),
I32Const(3),
Call(0),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
Else,
I32Const(2),
Call(0),
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
][..]
);
}
#[test] #[test]
fn call_index() { fn call_index() {
let module = builder::module() let module = builder::module()
@ -775,7 +645,6 @@ mod tests {
); );
} }
#[test] #[test]
fn forbidden() { fn forbidden() {
let module = builder::module() let module = builder::module()
@ -802,225 +671,247 @@ mod tests {
} }
fn parse_wat(source: &str) -> elements::Module {
let module_bytes = wabt::Wat2Wasm::new()
.validate(false)
.convert(source)
.expect("failed to parse module");
elements::deserialize_buffer(module_bytes.as_ref())
.expect("failed to parse module")
}
macro_rules! test_gas_counter_injection {
(name = $name:ident; input = $input:expr; expected = $expected:expr) => {
#[test] #[test]
fn branch_innermost() { fn $name() {
let module = builder::module() let input_module = parse_wat($input);
.global() let expected_module = parse_wat($expected);
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
Drop,
Br(0),
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap(); let injected_module = inject_gas_counter(input_module, &Default::default())
.expect("inject_gas_counter call failed");
assert_eq!( let actual_func_body = get_function_body(&injected_module, 0)
get_function_body(&injected_module, 0).unwrap(), .expect("injected module must have a function body");
&vec![ let expected_func_body = get_function_body(&expected_module, 0)
I32Const(6), .expect("post-module must have a function body");
Call(0),
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
Drop,
Br(0),
I32Const(2),
Call(0),
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End
][..]
);
}
#[test] assert_eq!(actual_func_body, expected_func_body);
fn branch_outer_block() { }
let module = builder::module() }
.global() }
.value_type().i32()
.build() test_gas_counter_injection! {
.function() name = simple;
.signature().param().i32().build() input = r#"
.body() (module
.with_instructions(elements::Instructions::new( (func (result i32)
vec![ (get_global 0)))
GetGlobal(0), "#;
Block(elements::BlockType::NoResult), expected = r#"
GetGlobal(0), (module
If(elements::BlockType::NoResult), (func (result i32)
GetGlobal(0), (call 0 (i32.const 1))
GetGlobal(0), (get_global 0)))
Drop, "#
BrIf(1), }
End,
GetGlobal(0), test_gas_counter_injection! {
Drop, name = nested;
End, input = r#"
GetGlobal(0), (module
End, (func (result i32)
] (get_global 0)
)) (block
.build() (get_global 0)
.build() (get_global 0)
.build(); (get_global 0))
(get_global 0)))
let injected_module = inject_gas_counter(module, &Default::default()).unwrap(); "#;
expected = r#"
assert_eq!( (module
get_function_body(&injected_module, 0).unwrap(), (func (result i32)
&vec![ (call 0 (i32.const 6))
I32Const(5), (get_global 0)
Call(0), (block
GetGlobal(0), (get_global 0)
Block(elements::BlockType::NoResult), (get_global 0)
GetGlobal(0), (get_global 0))
If(elements::BlockType::NoResult), (get_global 0)))
I32Const(4), "#
Call(0), }
GetGlobal(0),
GetGlobal(0), test_gas_counter_injection! {
Drop, name = ifelse;
BrIf(1), input = r#"
End, (module
I32Const(2), (func (result i32)
Call(0), (get_global 0)
GetGlobal(0), (if
Drop, (then
End, (get_global 0)
GetGlobal(0), (get_global 0)
End, (get_global 0))
][..] (else
); (get_global 0)
} (get_global 0)))
(get_global 0)))
#[test] "#;
fn branch_outer_loop() { expected = r#"
let module = builder::module() (module
.global() (func (result i32)
.value_type().i32() (call 0 (i32.const 3))
.build() (get_global 0)
.function() (if
.signature().param().i32().build() (then
.body() (call 0 (i32.const 3))
.with_instructions(elements::Instructions::new( (get_global 0)
vec![ (get_global 0)
GetGlobal(0), (get_global 0))
Loop(elements::BlockType::NoResult), (else
GetGlobal(0), (call 0 (i32.const 2))
If(elements::BlockType::NoResult), (get_global 0)
GetGlobal(0), (get_global 0)))
BrIf(0), (get_global 0)))
Else, "#
GetGlobal(0), }
GetGlobal(0),
Drop, test_gas_counter_injection! {
BrIf(1), name = branch_innermost;
End, input = r#"
GetGlobal(0), (module
Drop, (func (result i32)
End, (get_global 0)
GetGlobal(0), (block
End, (get_global 0)
] (drop)
)) (br 0)
.build() (get_global 0)
.build() (drop))
.build(); (get_global 0)))
"#;
let injected_module = inject_gas_counter(module, &Default::default()).unwrap(); expected = r#"
(module
assert_eq!( (func (result i32)
get_function_body(&injected_module, 0).unwrap(), (call 0 (i32.const 6))
&vec![ (get_global 0)
I32Const(3), (block
Call(0), (get_global 0)
GetGlobal(0), (drop)
Loop(elements::BlockType::NoResult), (br 0)
I32Const(4), (call 0 (i32.const 2))
Call(0), (get_global 0)
GetGlobal(0), (drop))
If(elements::BlockType::NoResult), (get_global 0)))
I32Const(2), "#
Call(0), }
GetGlobal(0),
BrIf(0), test_gas_counter_injection! {
Else, name = branch_outer_block;
I32Const(4), input = r#"
Call(0), (module
GetGlobal(0), (func (result i32)
GetGlobal(0), (get_global 0)
Drop, (block
BrIf(1), (get_global 0)
End, (if
GetGlobal(0), (then
Drop, (get_global 0)
End, (get_global 0)
GetGlobal(0), (drop)
End, (br_if 1)))
][..] (get_global 0)
); (drop))
} (get_global 0)))
"#;
#[test] expected = r#"
fn return_from_func() { (module
let module = builder::module() (func (result i32)
.global() (call 0 (i32.const 5))
.value_type().i32() (get_global 0)
.build() (block
.function() (get_global 0)
.signature().param().i32().build() (if
.body() (then
.with_instructions(elements::Instructions::new( (call 0 (i32.const 4))
vec![ (get_global 0)
GetGlobal(0), (get_global 0)
If(elements::BlockType::NoResult), (drop)
Return, (br_if 1)))
End, (call 0 (i32.const 2))
GetGlobal(0), (get_global 0)
End, (drop))
] (get_global 0)))
)) "#
.build() }
.build()
.build(); test_gas_counter_injection! {
name = branch_outer_loop;
let injected_module = inject_gas_counter(module, &Default::default()).unwrap(); input = r#"
(module
assert_eq!( (func (result i32)
get_function_body(&injected_module, 0).unwrap(), (get_global 0)
&vec![ (loop
I32Const(2), (get_global 0)
Call(0), (if
GetGlobal(0), (then
If(elements::BlockType::NoResult), (get_global 0)
I32Const(1), (br_if 0))
Call(0), (else
Return, (get_global 0)
End, (get_global 0)
I32Const(1), (drop)
Call(0), (br_if 1)))
GetGlobal(0), (get_global 0)
End, (drop))
][..] (get_global 0)))
); "#;
expected = r#"
(module
(func (result i32)
(call 0 (i32.const 3))
(get_global 0)
(loop
(call 0 (i32.const 4))
(get_global 0)
(if
(then
(call 0 (i32.const 2))
(get_global 0)
(br_if 0))
(else
(call 0 (i32.const 4))
(get_global 0)
(get_global 0)
(drop)
(br_if 1)))
(get_global 0)
(drop))
(get_global 0)))
"#
}
test_gas_counter_injection! {
name = return_from_func;
input = r#"
(module
(func (result i32)
(get_global 0)
(if
(then
(return)))
(get_global 0)))
"#;
expected = r#"
(module
(func (result i32)
(call 0 (i32.const 2))
(get_global 0)
(if
(then
(call 0 (i32.const 1))
(return)))
(call 0 (i32.const 1))
(get_global 0)))
"#
} }
} }