Tests
This commit is contained in:
parent
d0e13db6f2
commit
5e20cc28f8
|
@ -40,7 +40,7 @@
|
||||||
//! - Reserved immediates are ignored for `call_indirect`, `current_memory`, `grow_memory`.
|
//! - Reserved immediates are ignored for `call_indirect`, `current_memory`, `grow_memory`.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Target {
|
pub struct Target {
|
||||||
pub dst_pc: u32,
|
pub dst_pc: u32,
|
||||||
pub drop: u32,
|
pub drop: u32,
|
||||||
|
@ -48,7 +48,7 @@ pub struct Target {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)] // TODO: Remove
|
#[allow(unused)] // TODO: Remove
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
/// Push a local variable or an argument from the specified depth.
|
/// Push a local variable or an argument from the specified depth.
|
||||||
GetLocal(u32),
|
GetLocal(u32),
|
||||||
|
|
|
@ -109,19 +109,14 @@ impl Validator {
|
||||||
context.push_label(BlockFrameType::Function, result_ty, func_label)?;
|
context.push_label(BlockFrameType::Function, result_ty, func_label)?;
|
||||||
Validator::validate_function_block(&mut context, body.code().elements())?;
|
Validator::validate_function_block(&mut context, body.code().elements())?;
|
||||||
|
|
||||||
|
|
||||||
while !context.frame_stack.is_empty() {
|
while !context.frame_stack.is_empty() {
|
||||||
let branch_label = context.top_label()?.branch_label;
|
let branch_label = context.top_label()?.branch_label;
|
||||||
context.sink.resolve_label(branch_label);
|
context.sink.resolve_label(branch_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit explicit return.
|
|
||||||
// let (drop, keep) = context.drop_keep_return()?;
|
|
||||||
// TODO:
|
|
||||||
|
|
||||||
context.sink.emit(isa::Instruction::Return {
|
context.sink.emit(isa::Instruction::Return {
|
||||||
drop: 0,
|
drop: 0,
|
||||||
keep: 0,
|
keep: if result_ty == BlockType::NoResult { 0 } else { 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(context.into_code())
|
Ok(context.into_code())
|
||||||
|
|
|
@ -2,8 +2,11 @@ use super::validate_module;
|
||||||
use parity_wasm::builder::module;
|
use parity_wasm::builder::module;
|
||||||
use parity_wasm::elements::{
|
use parity_wasm::elements::{
|
||||||
External, GlobalEntry, GlobalType, ImportEntry, InitExpr, MemoryType,
|
External, GlobalEntry, GlobalType, ImportEntry, InitExpr, MemoryType,
|
||||||
Opcode, Opcodes, TableType, ValueType, BlockType
|
Opcode, Opcodes, TableType, ValueType, BlockType, deserialize_buffer,
|
||||||
|
Module,
|
||||||
};
|
};
|
||||||
|
use isa;
|
||||||
|
use wabt;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_is_valid() {
|
fn empty_is_valid() {
|
||||||
|
@ -299,3 +302,70 @@ fn if_else_with_return_type_validation() {
|
||||||
.build();
|
.build();
|
||||||
validate_module(m).unwrap();
|
validate_module(m).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile(wat: &str) -> Vec<isa::Instruction> {
|
||||||
|
let wasm = wabt::wat2wasm(wat).unwrap();
|
||||||
|
let module = deserialize_buffer::<Module>(&wasm).unwrap();
|
||||||
|
let validated_module = validate_module(module).unwrap();
|
||||||
|
let code = &validated_module.code_map[0];
|
||||||
|
code.code.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn explicit_return_no_value() {
|
||||||
|
let code = compile(r#"
|
||||||
|
(module
|
||||||
|
(func (export "call")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#);
|
||||||
|
assert_eq!(
|
||||||
|
code,
|
||||||
|
vec![
|
||||||
|
isa::Instruction::Return {
|
||||||
|
drop: 0,
|
||||||
|
keep: 0,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn explicit_return_with_value() {
|
||||||
|
let code = compile(r#"
|
||||||
|
(module
|
||||||
|
(func (export "call") (result i32)
|
||||||
|
i32.const 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#);
|
||||||
|
assert_eq!(
|
||||||
|
code,
|
||||||
|
vec![
|
||||||
|
isa::Instruction::I32Const(0),
|
||||||
|
isa::Instruction::Return {
|
||||||
|
drop: 0,
|
||||||
|
keep: 1,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn explicit_return_param() {
|
||||||
|
let code = compile(r#"
|
||||||
|
(module
|
||||||
|
(func (export "call") (param i32)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#);
|
||||||
|
assert_eq!(
|
||||||
|
code,
|
||||||
|
vec![
|
||||||
|
isa::Instruction::Return {
|
||||||
|
drop: 1,
|
||||||
|
keep: 0,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue