From 61170ba059533dce4f17a04c1761b6a4c3ddfed1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Feb 2019 11:55:38 -0800 Subject: [PATCH] Add a test for non-treelike behavior of stack We've recently found a bug in a WebAssembly library we've been working with where we're mapping WebAssembly to a tree-like IR internally. The way we parse into this representation, however, has a bug when the function isn't itself tree-like but rather exibits properties that exploit a stack machine. For example this isn't so straightforward to represent in a tree-like fashion: (import "" "a" (func $foo)) (import "" "b" (func $foo (result i32))) (func (result i32) call $b call $b call $a i32.xor) The extra `call $a` in the middle is valid `WebAssembly` but needs special treatment when converting to a more tree-like IR format. I figured it'd be good to ensure there's a spec test covering this case as we currently pass the suite of spec tests but still contain this bug! --- test/core/stack.wast | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/core/stack.wast b/test/core/stack.wast index d0c46955d3..5da5043c8e 100644 --- a/test/core/stack.wast +++ b/test/core/stack.wast @@ -125,12 +125,31 @@ end local.get $res ) + + (global $temp (mut i32) (i32.const 0)) + (func $add_one_to_global (result i32) + (local i32) + (global.set $temp (i32.add (i32.const 1) (global.get $temp))) + (global.get $temp) + ) + (func $add_one_to_global_and_drop + (drop (call $add_one_to_global)) + ) + (func (export "not-quite-a-tree") (result i32) + call $add_one_to_global + call $add_one_to_global + call $add_one_to_global_and_drop + i32.add + ) ) (assert_return (invoke "fac-expr" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-stack" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-mixed" (i64.const 25)) (i64.const 7034535277573963776)) +(assert_return (invoke "not-quite-a-tree") (i32.const 3)) +(assert_return (invoke "not-quite-a-tree") (i32.const 9)) + ;; Syntax of flat call_indirect