summaryrefslogtreecommitdiff
path: root/test/unit/test_poppy_validation.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/test_poppy_validation.py')
-rw-r--r--test/unit/test_poppy_validation.py203
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")