mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-03-15 11:10:49 +00:00
Use macro + WAT to make gas injection unit tests more readable.
This commit is contained in:
parent
b5472bcd8f
commit
ed7f31ec20
585
src/gas.rs
585
src/gas.rs
@ -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)))
|
||||||
|
"#
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user