From 5e20cc28f804a901aa72937562912acbce1261ee Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Wed, 13 Jun 2018 12:05:20 +0300 Subject: [PATCH] Tests --- src/isa.rs | 4 +-- src/validation/func.rs | 7 +--- src/validation/tests.rs | 72 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/isa.rs b/src/isa.rs index 4c7f73a..7d82767 100644 --- a/src/isa.rs +++ b/src/isa.rs @@ -40,7 +40,7 @@ //! - Reserved immediates are ignored for `call_indirect`, `current_memory`, `grow_memory`. //! -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Target { pub dst_pc: u32, pub drop: u32, @@ -48,7 +48,7 @@ pub struct Target { } #[allow(unused)] // TODO: Remove -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Instruction { /// Push a local variable or an argument from the specified depth. GetLocal(u32), diff --git a/src/validation/func.rs b/src/validation/func.rs index c1eaed4..76137de 100644 --- a/src/validation/func.rs +++ b/src/validation/func.rs @@ -109,19 +109,14 @@ impl Validator { context.push_label(BlockFrameType::Function, result_ty, func_label)?; Validator::validate_function_block(&mut context, body.code().elements())?; - while !context.frame_stack.is_empty() { let branch_label = context.top_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 { drop: 0, - keep: 0, + keep: if result_ty == BlockType::NoResult { 0 } else { 1 }, }); Ok(context.into_code()) diff --git a/src/validation/tests.rs b/src/validation/tests.rs index 38ad0cc..834ff5c 100644 --- a/src/validation/tests.rs +++ b/src/validation/tests.rs @@ -2,8 +2,11 @@ use super::validate_module; use parity_wasm::builder::module; use parity_wasm::elements::{ External, GlobalEntry, GlobalType, ImportEntry, InitExpr, MemoryType, - Opcode, Opcodes, TableType, ValueType, BlockType + Opcode, Opcodes, TableType, ValueType, BlockType, deserialize_buffer, + Module, }; +use isa; +use wabt; #[test] fn empty_is_valid() { @@ -299,3 +302,70 @@ fn if_else_with_return_type_validation() { .build(); validate_module(m).unwrap(); } + +fn compile(wat: &str) -> Vec { + let wasm = wabt::wat2wasm(wat).unwrap(); + let module = deserialize_buffer::(&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, + } + ] + ) +}