diff options
Diffstat (limited to 'test/unit/test_poppy_validation.py')
-rw-r--r-- | test/unit/test_poppy_validation.py | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/test/unit/test_poppy_validation.py b/test/unit/test_poppy_validation.py new file mode 100644 index 000000000..3dc2907d8 --- /dev/null +++ b/test/unit/test_poppy_validation.py @@ -0,0 +1,203 @@ +import os + +from scripts.test import shared +from . import utils + + +class PoppyValidationTest(utils.BinaryenTestCase): + def check_invalid(self, module, error): + p = shared.run_process(shared.WASM_OPT + + ['--experimental-poppy', '--print', '-o', os.devnull], + input=module, check=False, capture_output=True) + self.assertIn(error, p.stderr) + self.assertIn('Fatal: error validating input', p.stderr) + self.assertNotEqual(p.returncode, 0) + + def check_valid(self, module): + p = shared.run_process(shared.WASM_OPT + + ['--experimental-poppy', '--print', '-o', os.devnull], + input=module, check=False, capture_output=True) + self.assertEqual(p.stderr, "") + self.assertEqual(p.returncode, 0) + + def test_top_level_pop(self): + module = ''' + (module + (func $foo (result i32) + (block (result i32) + (i32.const 0) + (i32.pop) + ) + ) + ) + ''' + self.check_invalid(module, "Unexpected top-level pop in block") + + def test_top_level_pop_fixed(self): + module = ''' + (module + (func $foo (result i32) + (block (result i32) + (i32.const 0) + ) + ) + ) + ''' + self.check_valid(module) + + def test_incompatible_type(self): + module = ''' + (module + (func $foo (result i32) + (f32.const 42) + (i32.const 42) + (i32.add + (i32.pop) + (i32.pop) + ) + ) + ) + ''' + self.check_invalid(module, "block element has incompatible type") + self.check_invalid(module, "required: (i32 i32), available: (f32 i32)") + + def test_incorrect_pop_type(self): + module = ''' + (module + (func $foo (result i32) + (i32.const 42) + (i32.const 42) + (i32.add + (i32.pop) + (f32.pop) + ) + ) + ) + ''' + self.check_invalid(module, "binary child types must be equal") + + def test_incompatible_type_fixed(self): + module = ''' + (module + (func $foo (result i32) + (i32.const 42) + (i32.const 42) + (i32.add + (i32.pop) + (i32.pop) + ) + ) + ) + ''' + self.check_valid(module) + + def test_incorrect_block_type(self): + module = ''' + (module + (func $foo (result i32) + (f32.const 42) + (nop) + ) + ) + ''' + self.check_invalid(module, "block contents should satisfy block type") + + def test_nonblock_body(self): + module = ''' + (module + (func $foo (result f32) + (f32.const 42) + ) + ) + ''' + self.check_invalid(module, "Function body must be a block") + + def test_nonpop_if_condition(self): + module = ''' + (module + (func $foo + (nop) + (i32.const 1) + (if + (i32.const 42) + (block) + ) + ) + ) + ''' + self.check_invalid(module, "Expected condition to be a Pop") + + def test_nonblock_if_true(self): + module = ''' + (module + (func $foo + (nop) + (i32.const 1) + (if + (i32.pop) + (nop) + ) + ) + ) + ''' + self.check_invalid(module, "Expected control flow child to be a block") + + def test_nonblock_if_false(self): + module = ''' + (module + (func $foo + (nop) + (i32.const 1) + (if + (i32.pop) + (block) + (nop) + ) + ) + ) + ''' + self.check_invalid(module, "Expected control flow child to be a block") + + def test_nonblock_if_fixed(self): + module = ''' + (module + (func $foo + (nop) + (i32.const 1) + (if + (i32.pop) + (block) + (block) + ) + ) + ) + ''' + self.check_valid(module) + + def test_nonblock_loop_body(self): + module = ''' + (module + (func $foo + (nop) + (loop + (nop) + ) + ) + ) + ''' + self.check_invalid(module, "Expected control flow child to be a block") + + def test_nonpop_child(self): + module = ''' + (module + (func $foo (result i32) + (i32.const 42) + (i32.const 5) + (i32.add + (i32.pop) + (i32.const -1) + ) + ) + ) + ''' + self.check_invalid(module, "Unexpected non-Pop child") |