From 6d1acce9d484cdeb13c1e7bdbbc70fac6e0b4bd1 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Thu, 19 May 2016 11:29:47 +0200 Subject: [PATCH 1/2] More tests --- ml-proto/host/format.ml | 3 +- ml-proto/runtests.py | 7 +- ml-proto/test/block.wast | 77 ++++++--- ml-proto/test/br.wast | 248 ++++++++++++++++++++++++++++ ml-proto/test/loop.wast | 227 ++++++++++++++++++++++++++ ml-proto/test/return.wast | 287 +++++++++++++++++++++++++++++++++ ml-proto/test/unreachable.wast | 24 ++- 7 files changed, 843 insertions(+), 30 deletions(-) create mode 100644 ml-proto/test/br.wast create mode 100644 ml-proto/test/loop.wast create mode 100644 ml-proto/test/return.wast diff --git a/ml-proto/host/format.ml b/ml-proto/host/format.ml index 5443d2591c..8961d23c0b 100644 --- a/ml-proto/host/format.ml +++ b/ml-proto/host/format.ml @@ -195,8 +195,9 @@ let rec expr e = match e.it with | Nop -> "nop", [] | Unreachable -> "unreachable", [] + | Block ([], {it = Loop e; _}) -> "loop", [expr e] | Block (es, e) -> "block", list expr (es @ [e]) - | Loop e -> "loop", [expr e] + | Loop e -> assert false | Break (x, eo) -> "br " ^ var x, opt expr eo | BreakIf (x, eo, e) -> "br_if " ^ var x, opt expr eo @ [expr e] | BreakTable (xs, x, eo, e) -> diff --git a/ml-proto/runtests.py b/ml-proto/runtests.py index 78787ec183..66e790913d 100755 --- a/ml-proto/runtests.py +++ b/ml-proto/runtests.py @@ -18,8 +18,11 @@ class RunTests(unittest.TestCase): def _runCommand(self, command, logPath = None, expectedExitCode = 0): out = None if logPath is None else file(logPath, 'w+') - exitCode = subprocess.call(command, shell=True, stdout=out, stderr=subprocess.STDOUT) - self.assertEqual(expectedExitCode, exitCode, "test runner failed with exit code %i, expected %i" % (exitCode, expectedExitCode)) + try: + exitCode = subprocess.call(command, shell=True, stdout=out, stderr=subprocess.STDOUT) + self.assertEqual(expectedExitCode, exitCode, "test runner failed with exit code %i, expected %i" % (exitCode, expectedExitCode)) + except: + print(("# Failure running %s") % command) if logPath is not None: out.close() diff --git a/ml-proto/test/block.wast b/ml-proto/test/block.wast index 4eca40aa43..c09de3635d 100644 --- a/ml-proto/test/block.wast +++ b/ml-proto/test/block.wast @@ -46,43 +46,62 @@ (f32.gt (block (call $nop) (f32.const 3)) (block (call $nop) (f32.const 3))) ) - (func "br-bare" (result i32) + (func "break-bare" (result i32) (block (br 0) (unreachable)) + (block (br_if 0 (i32.const 1)) (unreachable)) + (block (br_table 0 (i32.const 0)) (unreachable)) + (block (br_table 0 0 0 (i32.const 1)) (unreachable)) (i32.const 19) ) - (func "br-value" (result i32) + (func "break-value" (result i32) (block (br 0 (i32.const 18)) (i32.const 19)) ) - (func "br-repeated" (result i32) + (func "break-repeated" (result i32) (block (br 0 (i32.const 18)) (br 0 (i32.const 19)) - (br 0 (i32.const 20)) + (br_if 0 (i32.const 20) (i32.const 0)) + (br_if 0 (i32.const 20) (i32.const 1)) + (br 0 (i32.const 21)) + (br_table 0 (i32.const 22) (i32.const 4)) + (br_table 0 0 0 (i32.const 23) (i32.const 1)) (i32.const 21) ) ) - (func "br-inner" (result i32) - (block - (block (br 1 (i32.const 22))) - (block (br 0)) - (i32.const 21) - ) + (func "break-inner" (result i32) + (local i32) + (set_local 0 (i32.const 0)) + (set_local 0 (i32.add (get_local 0) (block (block (br 1 (i32.const 0x1)))))) + (set_local 0 (i32.add (get_local 0) (block (block (br 0)) (i32.const 0x2)))) + (set_local 0 (i32.add (get_local 0) (block (i32.ctz (br 0 (i32.const 0x4)))))) + (set_local 0 (i32.add (get_local 0) (block (i32.ctz (block (br 1 (i32.const 0x8))))))) + (get_local 0) ) - (func "drop-inner" (result i32) + (func "drop-mid" (result i32) (block (call $fx) (i32.const 7) (call $nop) (i32.const 8)) ) (func "drop-last" (block (call $nop) (call $fx) (nop) (i32.const 8)) ) - (func "drop-br-void" + (func "drop-break-void" (block (br 0 (nop))) (block (br 0 (call $nop))) - ) - (func "drop-br-value" - (block (br 0 (i32.const 8))) - ) - (func "drop-br-value-heterogeneous" + (block (br_if 0 (nop) (i32.const 0))) + (block (br_if 0 (nop) (i32.const 1))) + (block (br_if 0 (call $nop) (i32.const 0))) + (block (br_if 0 (call $nop) (i32.const 1))) + (block (br_table 0 (nop) (i32.const 3))) + (block (br_table 0 0 0 (nop) (i32.const 2))) + ) + (func "drop-break-value" + (block (br 0 (i32.const 12))) + (block (br_if 0 (i32.const 11) (i32.const 0))) + (block (br_if 0 (i32.const 10) (i32.const 1))) + (block (br_table 0 (i32.const 9) (i32.const 5))) + (block (br_table 0 0 0 (i32.const 8) (i32.const 1))) + ) + (func "drop-break-value-heterogeneous" (block (br 0 (i32.const 8)) (br 0 (f64.const 8)) (br 0 (f32.const 8))) (block (br 0 (i32.const 8)) (br 0) (br 0 (f64.const 8))) (block (br 0 (i32.const 8)) (br 0 (call $nop)) (br 0 (f64.const 8))) @@ -117,16 +136,16 @@ (assert_return (invoke "test-operand") (i32.const 0)) (assert_return (invoke "compare-operand") (i32.const 0)) -(assert_return (invoke "br-bare") (i32.const 19)) -(assert_return (invoke "br-value") (i32.const 18)) -(assert_return (invoke "br-repeated") (i32.const 18)) -(assert_return (invoke "br-inner") (i32.const 22)) +(assert_return (invoke "break-bare") (i32.const 19)) +(assert_return (invoke "break-value") (i32.const 18)) +(assert_return (invoke "break-repeated") (i32.const 18)) +(assert_return (invoke "break-inner") (i32.const 0xf)) -(assert_return (invoke "drop-inner") (i32.const 8)) +(assert_return (invoke "drop-mid") (i32.const 8)) (assert_return (invoke "drop-last")) -(assert_return (invoke "drop-br-void")) -(assert_return (invoke "drop-br-value")) -(assert_return (invoke "drop-br-value-heterogeneous")) +(assert_return (invoke "drop-break-void")) +(assert_return (invoke "drop-break-value")) +(assert_return (invoke "drop-break-value-heterogeneous")) (assert_return (invoke "effects") (i32.const 1)) @@ -162,4 +181,12 @@ (module (func (result i32) (block (block (br 1 (i64.const 1))) (br 0 (i32.const 1))))) "type mismatch" ) +(assert_invalid + (module (func (result i32) (block (br 0)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (i32.ctz (block (br 0))))) + "type mismatch" +) diff --git a/ml-proto/test/br.wast b/ml-proto/test/br.wast new file mode 100644 index 0000000000..f2b3585546 --- /dev/null +++ b/ml-proto/test/br.wast @@ -0,0 +1,248 @@ +;; Test `br` operator + +(module + (func "type-i32" (block (i32.ctz (br 0)))) + (func "type-i64" (block (i64.ctz (br 0)))) + (func "type-f32" (block (f32.neg (br 0)))) + (func "type-f64" (block (f64.neg (br 0)))) + + (func "block-first" + (block (br 0) (i32.const 2)) + ) + (func "block-mid" + (block (i32.const 1) (br 0) (i32.const 2)) + ) + (func "block-last" + (block (nop) (i32.const 1) (br 0)) + ) + (func "block-value" (result i32) + (block (nop) (i32.const 1) (br 0 (i32.const 2))) + ) + + (func "loop-first" (result i32) + (loop (br 1 (i32.const 3)) (i32.const 2)) + ) + (func "loop-mid" (result i32) + (loop (i32.const 1) (br 1 (i32.const 4)) (i32.const 2)) + ) + (func "loop-last" (result i32) + (loop (nop) (i32.const 1) (br 1 (i32.const 5))) + ) + + (func "br-value" (result i32) + (block (br 0 (br 0 (i32.const 9)))) + ) + + (func "br_if-cond" + (block (br_if 0 (br 0))) + ) + (func "br_if-value" (result i32) + (block (br_if 0 (br 0 (i32.const 8)) (i32.const 1)) (i32.const 7)) + ) + (func "br_if-value-cond" (result i32) + (block (br_if 0 (i32.const 6) (br 0 (i32.const 9))) (i32.const 7)) + ) + + (func "br_table-index" + (block (br_table 0 0 0 (br 0))) + ) + (func "br_table-value" (result i32) + (block (br_table 0 0 0 (br 0 (i32.const 10)) (i32.const 1)) (i32.const 7)) + ) + (func "br_table-value-index" (result i32) + (block (br_table 0 0 (i32.const 6) (br 0 (i32.const 11))) (i32.const 7)) + ) + + (func "return-value" (result i64) + (block (return (br 0 (i64.const 7)))) + ) + + (func "if-cond" (result i32) + (block (if (br 0 (i32.const 2)) (i32.const 0) (i32.const 1))) + ) + (func "if-then" (param i32 i32) (result i32) + (block (if (get_local 0) (br 1 (i32.const 3)) (get_local 1))) + ) + (func "if-else" (param i32 i32) (result i32) + (block (if (get_local 0) (get_local 1) (br 1 (i32.const 4)))) + ) + + (func "select-first" (param i32 i32) (result i32) + (block (select (br 0 (i32.const 5)) (get_local 0) (get_local 1))) + ) + (func "select-second" (param i32 i32) (result i32) + (block (select (get_local 0) (br 0 (i32.const 6)) (get_local 1))) + ) + (func "select-cond" (result i32) + (block (select (i32.const 0) (i32.const 1) (br 0 (i32.const 7)))) + ) + + (func $f (param i32 i32 i32) (result i32) (i32.const -1)) + (func "call-first" (result i32) + (block (call $f (br 0 (i32.const 12)) (i32.const 2) (i32.const 3))) + ) + (func "call-mid" (result i32) + (block (call $f (i32.const 1) (br 0 (i32.const 13)) (i32.const 3))) + ) + (func "call-last" (result i32) + (block (call $f (i32.const 1) (i32.const 2) (br 0 (i32.const 14)))) + ) + + (import "spectest" "print" (param i32 i32 i32)) + (func "call_import-first" + (block (call_import 0 (br 0) (i32.const 2) (i32.const 3))) + ) + (func "call_import-mid" + (block (call_import 0 (i32.const 1) (br 0) (i32.const 3))) + ) + (func "call_import-last" + (block (call_import 0 (i32.const 1) (i32.const 2) (br 0))) + ) + + (type $sig (func (param i32 i32 i32) (result i32))) + (table $f) + (func "call_indirect-func" (result i32) + (block (call_indirect $sig (br 0 (i32.const 20)) (i32.const 1) (i32.const 2) (i32.const 3))) + ) + (func "call_indirect-first" (result i32) + (block (call_indirect $sig (i32.const 0) (br 0 (i32.const 21)) (i32.const 2) (i32.const 3))) + ) + (func "call_indirect-mid" (result i32) + (block (call_indirect $sig (i32.const 0) (i32.const 1) (br 0 (i32.const 22)) (i32.const 3))) + ) + (func "call_indirect-last" (result i32) + (block (call_indirect $sig (i32.const 0) (i32.const 1) (i32.const 2) (br 0 (i32.const 23)))) + ) + + (func "set_local-value" (result i32) (local f32) + (block (set_local 0 (br 0 (i32.const 17))) (i32.const -1)) + ) + + (memory 1) + (func "load-address" (result f32) + (block (f32.load (br 0 (f32.const 1.7)))) + ) + (func "loadN-address" (result i64) + (block (i64.load8_s (br 0 (i64.const 30)))) + ) + + (func "store-address" (result i32) + (block (f64.store (br 0 (i32.const 30)) (f64.const 7)) (i32.const -1)) + ) + (func "store-value" (result i32) + (block (i64.store (i32.const 2) (br 0 (i32.const 31))) (i32.const -1)) + ) + + (func "storeN-address" (result i32) + (block (i32.store8 (br 0 (i32.const 32)) (i32.const 7)) (i32.const -1)) + ) + (func "storeN-value" (result i32) + (block (i64.store16 (i32.const 2) (br 0 (i32.const 33))) (i32.const -1)) + ) + + (func "unary-operand" (result f32) + (block (f32.neg (br 0 (f32.const 3.4)))) + ) + + (func "binary-left" (result i32) + (block (i32.add (br 0 (i32.const 3)) (i32.const 10))) + ) + (func "binary-right" (result i64) + (block (i64.sub (i64.const 10) (br 0 (i64.const 45)))) + ) + + (func "test-operand" (result i32) + (block (i32.eqz (br 0 (i32.const 44)))) + ) + + (func "compare-left" (result i32) + (block (f64.le (br 0 (i32.const 43)) (f64.const 10))) + ) + (func "compare-right" (result i32) + (block (f32.ne (f32.const 10) (br 0 (i32.const 42)))) + ) + + (func "convert-operand" (result i32) + (block (i32.wrap/i64 (br 0 (i32.const 41)))) + ) + + (func "grow_memory-size" (result i32) + (block (grow_memory (br 0 (i32.const 40)))) + ) +) + +(assert_return (invoke "type-i32")) +(assert_return (invoke "type-i64")) +(assert_return (invoke "type-f32")) +(assert_return (invoke "type-f64")) + +(assert_return (invoke "block-first")) +(assert_return (invoke "block-mid")) +(assert_return (invoke "block-last")) +(assert_return (invoke "block-value") (i32.const 2)) + +(assert_return (invoke "loop-first") (i32.const 3)) +(assert_return (invoke "loop-mid") (i32.const 4)) +(assert_return (invoke "loop-last") (i32.const 5)) + +(assert_return (invoke "br-value") (i32.const 9)) + +(assert_return (invoke "br_if-cond")) +(assert_return (invoke "br_if-value") (i32.const 8)) +(assert_return (invoke "br_if-value-cond") (i32.const 9)) + +(assert_return (invoke "br_table-index")) +(assert_return (invoke "br_table-value") (i32.const 10)) +(assert_return (invoke "br_table-value-index") (i32.const 11)) + +(assert_return (invoke "return-value") (i64.const 7)) + +(assert_return (invoke "if-cond") (i32.const 2)) +(assert_return (invoke "if-then" (i32.const 1) (i32.const 6)) (i32.const 3)) +(assert_return (invoke "if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) +(assert_return (invoke "if-else" (i32.const 0) (i32.const 6)) (i32.const 4)) +(assert_return (invoke "if-else" (i32.const 1) (i32.const 6)) (i32.const 6)) + +(assert_return (invoke "select-first" (i32.const 0) (i32.const 6)) (i32.const 5)) +(assert_return (invoke "select-first" (i32.const 1) (i32.const 6)) (i32.const 5)) +(assert_return (invoke "select-second" (i32.const 0) (i32.const 6)) (i32.const 6)) +(assert_return (invoke "select-second" (i32.const 1) (i32.const 6)) (i32.const 6)) +(assert_return (invoke "select-cond") (i32.const 7)) + +(assert_return (invoke "call-first") (i32.const 12)) +(assert_return (invoke "call-mid") (i32.const 13)) +(assert_return (invoke "call-last") (i32.const 14)) + +(assert_return (invoke "call_import-first")) +(assert_return (invoke "call_import-mid")) +(assert_return (invoke "call_import-last")) + +(assert_return (invoke "call_indirect-func") (i32.const 20)) +(assert_return (invoke "call_indirect-first") (i32.const 21)) +(assert_return (invoke "call_indirect-mid") (i32.const 22)) +(assert_return (invoke "call_indirect-last") (i32.const 23)) + +(assert_return (invoke "set_local-value") (i32.const 17)) + +(assert_return (invoke "load-address") (f32.const 1.7)) +(assert_return (invoke "loadN-address") (i64.const 30)) + +(assert_return (invoke "store-address") (i32.const 30)) +(assert_return (invoke "store-value") (i32.const 31)) +(assert_return (invoke "storeN-address") (i32.const 32)) +(assert_return (invoke "storeN-value") (i32.const 33)) + +(assert_return (invoke "unary-operand") (f32.const 3.4)) + +(assert_return (invoke "binary-left") (i32.const 3)) +(assert_return (invoke "binary-right") (i64.const 45)) + +(assert_return (invoke "test-operand") (i32.const 44)) + +(assert_return (invoke "compare-left") (i32.const 43)) +(assert_return (invoke "compare-right") (i32.const 42)) + +(assert_return (invoke "convert-operand") (i32.const 41)) + +(assert_return (invoke "grow_memory-size") (i32.const 40)) + diff --git a/ml-proto/test/loop.wast b/ml-proto/test/loop.wast new file mode 100644 index 0000000000..02c9e0bf04 --- /dev/null +++ b/ml-proto/test/loop.wast @@ -0,0 +1,227 @@ +;; Test `loop` opcode + +(module + (func "empty" + (loop) + (loop $l) + ) + + (func "singular" (result i32) + (loop (nop)) + (loop (i32.const 7)) + ) + + (func $nop) + (func "multi" (result i32) + (loop (call $nop) (call $nop) (call $nop) (call $nop)) + (loop (call $nop) (call $nop) (call $nop) (i32.const 8)) + ) + + (func "nested" (result i32) + (loop (loop (call $nop) (block) (nop)) (loop (call $nop) (i32.const 9))) + ) + + (func "deep" (result i32) + (loop (block (loop (block (loop (block (loop (block (loop (block + (loop (block (loop (block (loop (block (loop (block (loop (block + (loop (block (loop (block (loop (block (loop (block (loop (block + (loop (block (loop (block (loop (block (loop (block (loop (block + (loop (block (loop (block (loop (call $nop) (i32.const 150)))))) + )))))))))) + )))))))))) + )))))))))) + )))))))))) + ) + + (func "unary-operand" (result i32) + (i32.ctz (loop (call $nop) (i32.const 13))) + ) + (func "binary-operand" (result i32) + (i32.mul (loop (call $nop) (i32.const 3)) (loop (call $nop) (i32.const 4))) + ) + (func "test-operand" (result i32) + (i32.eqz (loop (call $nop) (i32.const 13))) + ) + (func "compare-operand" (result i32) + (f32.gt (loop (call $nop) (f32.const 3)) (loop (call $nop) (f32.const 3))) + ) + + (func "break-bare" (result i32) + (loop (br 1) (br 0) (unreachable)) + (loop (br_if 1 (i32.const 1)) (unreachable)) + (loop (br_table 1 (i32.const 0)) (unreachable)) + (loop (br_table 1 1 1 (i32.const 1)) (unreachable)) + (i32.const 19) + ) + (func "break-value" (result i32) + (loop (br 1 (i32.const 18)) (br 0) (i32.const 19)) + ) + (func "break-repeated" (result i32) + (loop + (br 1 (i32.const 18)) + (br 1 (i32.const 19)) + (br_if 1 (i32.const 20) (i32.const 0)) + (br_if 1 (i32.const 20) (i32.const 1)) + (br 1 (i32.const 21)) + (br_table 1 (i32.const 22) (i32.const 0)) + (br_table 1 1 1 (i32.const 23) (i32.const 1)) + (i32.const 21) + ) + ) + (func "break-inner" (result i32) + (local i32) + (set_local 0 (i32.const 0)) + (set_local 0 (i32.add (get_local 0) (loop (block (br 2 (i32.const 0x1)))))) + (set_local 0 (i32.add (get_local 0) (loop (loop (br 3 (i32.const 0x2)))))) + (set_local 0 (i32.add (get_local 0) (loop (loop (br 1 (i32.const 0x4)))))) + (set_local 0 (i32.add (get_local 0) (loop (i32.ctz (br 1 (i32.const 0x8)))))) + (set_local 0 (i32.add (get_local 0) (loop (i32.ctz (loop (br 3 (i32.const 0x10))))))) + (get_local 0) + ) + (func "cont-inner" (result i32) + (local i32) + (set_local 0 (i32.const 0)) + (set_local 0 (i32.add (get_local 0) (loop (loop (br 2))))) + (set_local 0 (i32.add (get_local 0) (loop (i32.ctz (br 0))))) + (set_local 0 (i32.add (get_local 0) (loop (i32.ctz (loop (br 2)))))) + (get_local 0) + ) + + ;; TODO: tests of actual looping + + (func "drop-mid" (result i32) + (loop (call $fx) (i32.const 7) (call $nop) (i32.const 8)) + ) + (func "drop-last" + (loop (call $nop) (call $fx) (nop) (i32.const 8)) + ) + (func "drop-break-void" + (loop (br 1 (nop))) + (loop (br 1 (call $nop))) + (loop (br_if 1 (nop) (i32.const 0))) + (loop (br_if 1 (nop) (i32.const 1))) + (loop (br_if 1 (call $nop) (i32.const 0))) + (loop (br_if 1 (call $nop) (i32.const 1))) + (loop (br_table 1 (nop) (i32.const 3))) + (loop (br_table 1 1 1 (nop) (i32.const 1))) + ) + (func "drop-break-value" + (loop (br 1 (i32.const 8))) + (loop (br_if 1 (i32.const 11) (i32.const 0))) + (loop (br_if 1 (i32.const 10) (i32.const 1))) + (loop (br_table 1 (i32.const 9) (i32.const 5))) + (loop (br_table 1 1 1 (i32.const 8) (i32.const 1))) + ) + (func "drop-cont-void" + (loop (br 0 (nop))) + (loop (br 0 (call $nop))) + (loop (br_if 0 (nop) (i32.const 0))) + (loop (br_if 0 (nop) (i32.const 1))) + (loop (br_if 0 (call $nop) (i32.const 0))) + (loop (br_if 0 (call $nop) (i32.const 1))) + (loop (br_table 0 (nop) (i32.const 3))) + (loop (br_table 0 1 1 (nop) (i32.const 1))) + ) + (func "drop-cont-value" + (loop (br 0 (i32.const 8))) + (loop (br_if 0 (i32.const 11) (i32.const 0))) + (loop (br_if 0 (i32.const 10) (i32.const 1))) + (loop (br_table 0 (i32.const 9) (i32.const 5))) + (loop (br_table 0 0 1 (i32.const 8) (i32.const 1))) + ) + (func "drop-break-value-heterogeneous" + (loop (br 1 (i32.const 8)) (br 1 (f64.const 8)) (br 1 (f32.const 8))) + (loop (br 1 (i32.const 8)) (br 1) (br 1 (f64.const 8))) + (loop (br 1 (i32.const 8)) (br 1) (br 1 (f32.const 8)) (i64.const 3)) + (loop (br 1) (br 1 (i32.const 8)) (br 1 (f64.const 8))) + (loop (br 1) (br 1 (i32.const 8)) (br 1 (f32.const 8)) (i64.const 3)) + (loop (loop (br 1) (br 3 (i32.const 8))) (br 1 (f32.const 8)) (block (br 2 (f64.const 7))) (i64.const 3)) + ) + (func "drop-cont-value-heterogeneous" + (loop (br 0 (i32.const 8)) (br 0 (f64.const 8)) (br 1 (f32.const 8))) + (loop (br 0 (i32.const 8)) (br 0) (br 0 (f64.const 8))) + (loop (br 0 (i32.const 8)) (br 0) (br 0 (f32.const 8)) (i64.const 3)) + (loop (br 0) (br 0 (i32.const 8)) (br 0 (f64.const 8))) + (loop (br 0) (br 0 (i32.const 8)) (br 0 (f32.const 8)) (i64.const 3)) + (loop (loop (br 1) (br 2 (i32.const 8))) (br 0 (f32.const 8)) (block (br 1 (f64.const 7))) (i64.const 3)) + ) + + (func "effects" $fx (result i32) + (local i32) + (loop + (set_local 0 (i32.const 1)) + (set_local 0 (i32.mul (get_local 0) (i32.const 3))) + (set_local 0 (i32.sub (get_local 0) (i32.const 5))) + (set_local 0 (i32.mul (get_local 0) (i32.const 7))) + (br 1) + (set_local 0 (i32.mul (get_local 0) (i32.const 100))) + ) + (i32.eq (get_local 0) (i32.const -14)) + ) +) + +(assert_return (invoke "empty")) +(assert_return (invoke "singular") (i32.const 7)) +(assert_return (invoke "multi") (i32.const 8)) +(assert_return (invoke "nested") (i32.const 9)) +(assert_return (invoke "deep") (i32.const 150)) + +(assert_return (invoke "unary-operand") (i32.const 0)) +(assert_return (invoke "binary-operand") (i32.const 12)) +(assert_return (invoke "test-operand") (i32.const 0)) +(assert_return (invoke "compare-operand") (i32.const 0)) + +(assert_return (invoke "break-bare") (i32.const 19)) +(assert_return (invoke "break-value") (i32.const 18)) +(assert_return (invoke "break-repeated") (i32.const 18)) +(assert_return (invoke "break-inner") (i32.const 0x1f)) + +(assert_return (invoke "drop-mid") (i32.const 8)) +(assert_return (invoke "drop-last")) +(assert_return (invoke "drop-break-void")) +(assert_return (invoke "drop-break-value")) +(assert_return (invoke "drop-break-value-heterogeneous")) + +(assert_return (invoke "effects") (i32.const 1)) + +(assert_invalid + (module (func (result i32) (loop))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (nop)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (f32.const 0)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (br 1) (i32.const 1)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (br 1 (i32.const 1)) (nop)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (br 1 (i64.const 1)) (i32.const 1)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (br 1 (i64.const 1)) (br 1 (i32.const 1))))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (loop (br 3 (i64.const 1))) (br 1 (i32.const 1))))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (loop (br 1)))) + "type mismatch" +) +(assert_invalid + (module (func (result i32) (i32.ctz (loop (br 1))))) + "type mismatch" +) + diff --git a/ml-proto/test/return.wast b/ml-proto/test/return.wast new file mode 100644 index 0000000000..1539f0b31d --- /dev/null +++ b/ml-proto/test/return.wast @@ -0,0 +1,287 @@ +;; Test `return` operator + +(module + (func "type-i32" (i32.ctz (return))) + (func "type-i64" (i64.ctz (return))) + (func "type-f32" (f32.neg (return))) + (func "type-f64" (f64.neg (return))) + + (func "nullary" (return)) + (func "unary" (result f64) (return (f64.const 3.1))) + + (func "first" (result i32) + (return (i32.const 1)) (i32.const 2) + ) + (func "mid" (result i32) + (i32.const 1) (return (i32.const 2)) (i32.const 3) + ) + (func "last" + (nop) (i32.const 1) (return) + ) + (func "value" (result i32) + (nop) (i32.const 1) (return (i32.const 3)) + ) + + (func "block-first" + (block (return) (i32.const 2)) + ) + (func "block-mid" + (block (i32.const 1) (return) (i32.const 2)) + ) + (func "block-last" + (block (nop) (i32.const 1) (return)) + ) + (func "block-value" (result i32) + (block (nop) (i32.const 1) (return (i32.const 2))) + ) + + (func "loop-first" (result i32) + (loop (return (i32.const 3)) (i32.const 2)) + ) + (func "loop-mid" (result i32) + (loop (i32.const 1) (return (i32.const 4)) (i32.const 2)) + ) + (func "loop-last" (result i32) + (loop (nop) (i32.const 1) (return (i32.const 5))) + ) + + (func "br-value" (result i32) + (block (br 0 (return (i32.const 9)))) + ) + + (func "br_if-cond" + (block (br_if 0 (return))) + ) + (func "br_if-value" (result i32) + (block (br_if 0 (return (i32.const 8)) (i32.const 1)) (i32.const 7)) + ) + (func "br_if-value-cond" (result i32) + (block (br_if 0 (i32.const 6) (return (i32.const 9))) (i32.const 7)) + ) + + (func "br_table-index" (result i64) + (block (br_table 0 0 0 (return (i64.const 9)))) (i64.const -1) + ) + (func "br_table-value" (result i32) + (block (br_table 0 0 0 (return (i32.const 10)) (i32.const 1)) (i32.const 7)) + ) + (func "br_table-value-index" (result i32) + (block (br_table 0 0 (i32.const 6) (return (i32.const 11))) (i32.const 7)) + ) + + (func "return-value" (result i64) + (return (return (i64.const 7))) + ) + + (func "if-cond" (result i32) + (if (return (i32.const 2)) (i32.const 0) (i32.const 1)) + ) + (func "if-then" (param i32 i32) (result i32) + (if (get_local 0) (return (i32.const 3)) (get_local 1)) + ) + (func "if-else" (param i32 i32) (result i32) + (if (get_local 0) (get_local 1) (return (i32.const 4))) + ) + + (func "select-first" (param i32 i32) (result i32) + (select (return (i32.const 5)) (get_local 0) (get_local 1)) + ) + (func "select-second" (param i32 i32) (result i32) + (select (get_local 0) (return (i32.const 6)) (get_local 1)) + ) + (func "select-cond" (result i32) + (select (i32.const 0) (i32.const 1) (return (i32.const 7))) + ) + + (func $f (param i32 i32 i32) (result i32) (i32.const -1)) + (func "call-first" (result i32) + (call $f (return (i32.const 12)) (i32.const 2) (i32.const 3)) + ) + (func "call-mid" (result i32) + (call $f (i32.const 1) (return (i32.const 13)) (i32.const 3)) + ) + (func "call-last" (result i32) + (call $f (i32.const 1) (i32.const 2) (return (i32.const 14))) + ) + + (import "spectest" "print" (param i32 i32 i32)) + (func "call_import-first" + (call_import 0 (return) (i32.const 2) (i32.const 3)) + ) + (func "call_import-mid" + (call_import 0 (i32.const 1) (return) (i32.const 3)) + ) + (func "call_import-last" + (call_import 0 (i32.const 1) (i32.const 2) (return)) + ) + + (type $sig (func (param i32 i32 i32) (result i32))) + (table $f) + (func "call_indirect-func" (result i32) + (call_indirect $sig (return (i32.const 20)) (i32.const 1) (i32.const 2) (i32.const 3)) + ) + (func "call_indirect-first" (result i32) + (call_indirect $sig (i32.const 0) (return (i32.const 21)) (i32.const 2) (i32.const 3)) + ) + (func "call_indirect-mid" (result i32) + (call_indirect $sig (i32.const 0) (i32.const 1) (return (i32.const 22)) (i32.const 3)) + ) + (func "call_indirect-last" (result i32) + (call_indirect $sig (i32.const 0) (i32.const 1) (i32.const 2) (return (i32.const 23))) + ) + + (func "set_local-value" (result i32) (local f32) + (set_local 0 (return (i32.const 17))) (i32.const -1) + ) + + (memory 1) + (func "load-address" (result f32) + (f32.load (return (f32.const 1.7))) + ) + (func "loadN-address" (result i64) + (i64.load8_s (return (i64.const 30))) + ) + + (func "store-address" (result i32) + (f64.store (return (i32.const 30)) (f64.const 7)) (i32.const -1) + ) + (func "store-value" (result i32) + (i64.store (i32.const 2) (return (i32.const 31))) (i32.const -1) + ) + + (func "storeN-address" (result i32) + (i32.store8 (return (i32.const 32)) (i32.const 7)) (i32.const -1) + ) + (func "storeN-value" (result i32) + (i64.store16 (i32.const 2) (return (i32.const 33))) (i32.const -1) + ) + + (func "unary-operand" (result f32) + (f32.neg (return (f32.const 3.4))) + ) + + (func "binary-left" (result i32) + (i32.add (return (i32.const 3)) (i32.const 10)) + ) + (func "binary-right" (result i64) + (i64.sub (i64.const 10) (return (i64.const 45))) + ) + + (func "test-operand" (result i32) + (i32.eqz (return (i32.const 44))) + ) + + (func "compare-left" (result i32) + (f64.le (return (i32.const 43)) (f64.const 10)) + ) + (func "compare-right" (result i32) + (f32.ne (f32.const 10) (return (i32.const 42))) + ) + + (func "convert-operand" (result i32) + (i32.wrap/i64 (return (i32.const 41))) + ) + + (func "grow_memory-size" (result i32) + (grow_memory (return (i32.const 40))) + ) +) + +(assert_return (invoke "type-i32")) +(assert_return (invoke "type-i64")) +(assert_return (invoke "type-f32")) +(assert_return (invoke "type-f64")) + +(assert_return (invoke "nullary")) +(assert_return (invoke "unary") (f64.const 3.1)) + +(assert_invalid + (module (func (result f64) (return))) + "type mismatch" +) + +(assert_invalid + (module (func (result f64) (return (i64.const 1)))) + "type mismatch" +) + +(assert_invalid + (module (func (result f64) (return (f32.const 1)))) + "type mismatch" +) + +(assert_return (invoke "first") (i32.const 1)) +(assert_return (invoke "mid") (i32.const 2)) +(assert_return (invoke "last")) +(assert_return (invoke "value") (i32.const 3)) + +(assert_return (invoke "block-first")) +(assert_return (invoke "block-mid")) +(assert_return (invoke "block-last")) +(assert_return (invoke "block-value") (i32.const 2)) + +(assert_return (invoke "loop-first") (i32.const 3)) +(assert_return (invoke "loop-mid") (i32.const 4)) +(assert_return (invoke "loop-last") (i32.const 5)) + +(assert_return (invoke "br-value") (i32.const 9)) + +(assert_return (invoke "br_if-cond")) +(assert_return (invoke "br_if-value") (i32.const 8)) +(assert_return (invoke "br_if-value-cond") (i32.const 9)) + +(assert_return (invoke "br_table-index") (i64.const 9)) +(assert_return (invoke "br_table-value") (i32.const 10)) +(assert_return (invoke "br_table-value-index") (i32.const 11)) + +(assert_return (invoke "return-value") (i64.const 7)) + +(assert_return (invoke "if-cond") (i32.const 2)) +(assert_return (invoke "if-then" (i32.const 1) (i32.const 6)) (i32.const 3)) +(assert_return (invoke "if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) +(assert_return (invoke "if-else" (i32.const 0) (i32.const 6)) (i32.const 4)) +(assert_return (invoke "if-else" (i32.const 1) (i32.const 6)) (i32.const 6)) + +(assert_return (invoke "select-first" (i32.const 0) (i32.const 6)) (i32.const 5)) +(assert_return (invoke "select-first" (i32.const 1) (i32.const 6)) (i32.const 5)) +(assert_return (invoke "select-second" (i32.const 0) (i32.const 6)) (i32.const 6)) +(assert_return (invoke "select-second" (i32.const 1) (i32.const 6)) (i32.const 6)) +(assert_return (invoke "select-cond") (i32.const 7)) + +(assert_return (invoke "call-first") (i32.const 12)) +(assert_return (invoke "call-mid") (i32.const 13)) +(assert_return (invoke "call-last") (i32.const 14)) + +(assert_return (invoke "call_import-first")) +(assert_return (invoke "call_import-mid")) +(assert_return (invoke "call_import-last")) + +(assert_return (invoke "call_indirect-func") (i32.const 20)) +(assert_return (invoke "call_indirect-first") (i32.const 21)) +(assert_return (invoke "call_indirect-mid") (i32.const 22)) +(assert_return (invoke "call_indirect-last") (i32.const 23)) + +(assert_return (invoke "set_local-value") (i32.const 17)) + +(assert_return (invoke "load-address") (f32.const 1.7)) +(assert_return (invoke "loadN-address") (i64.const 30)) + +(assert_return (invoke "store-address") (i32.const 30)) +(assert_return (invoke "store-value") (i32.const 31)) +(assert_return (invoke "storeN-address") (i32.const 32)) +(assert_return (invoke "storeN-value") (i32.const 33)) + +(assert_return (invoke "unary-operand") (f32.const 3.4)) + +(assert_return (invoke "binary-left") (i32.const 3)) +(assert_return (invoke "binary-right") (i64.const 45)) + +(assert_return (invoke "test-operand") (i32.const 44)) + +(assert_return (invoke "compare-left") (i32.const 43)) +(assert_return (invoke "compare-right") (i32.const 42)) + +(assert_return (invoke "convert-operand") (i32.const 41)) + +(assert_return (invoke "grow_memory-size") (i32.const 40)) + diff --git a/ml-proto/test/unreachable.wast b/ml-proto/test/unreachable.wast index 73247a5494..064d5a087b 100644 --- a/ml-proto/test/unreachable.wast +++ b/ml-proto/test/unreachable.wast @@ -6,6 +6,19 @@ (func "type-f32" (result f64) (unreachable)) (func "type-f64" (result f64) (unreachable)) + (func "first" (result i32) + (unreachable) (i32.const -1) + ) + (func "mid" (result i32) + (f32.const 1) (unreachable) (i32.const -1) + ) + (func "last" + (i64.const 8) (unreachable) + ) + (func "value" (result i32) + (i64.const 8) (unreachable) + ) + (func "block-first" (result i32) (block (unreachable) (i32.const 2)) ) @@ -38,6 +51,7 @@ (func "br-value" (result i32) (block (br 0 (unreachable))) ) + (func "br_if-cond" (block (br_if 0 (unreachable))) ) @@ -47,6 +61,7 @@ (func "br_if-value-cond" (result i32) (block (br_if 0 (i32.const 6) (unreachable)) (i32.const 7)) ) + (func "br_table-index" (block (br_table 0 0 0 (unreachable))) ) @@ -180,6 +195,11 @@ (assert_trap (invoke "type-f32") "unreachable") (assert_trap (invoke "type-f64") "unreachable") +(assert_trap (invoke "first") "unreachable") +(assert_trap (invoke "mid") "unreachable") +(assert_trap (invoke "last") "unreachable") +(assert_trap (invoke "value") "unreachable") + (assert_trap (invoke "block-first") "unreachable") (assert_trap (invoke "block-mid") "unreachable") (assert_trap (invoke "block-last") "unreachable") @@ -201,6 +221,8 @@ (assert_trap (invoke "br_table-value") "unreachable") (assert_trap (invoke "br_table-value-index") "unreachable") +(assert_trap (invoke "return-value") "unreachable") + (assert_trap (invoke "if-cond") "unreachable") (assert_trap (invoke "if-then" (i32.const 1) (i32.const 6)) "unreachable") (assert_return (invoke "if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) @@ -213,8 +235,6 @@ (assert_trap (invoke "select-second" (i32.const 1) (i32.const 6)) "unreachable") (assert_trap (invoke "select-cond") "unreachable") -(assert_trap (invoke "return-value") "unreachable") - (assert_trap (invoke "call-first") "unreachable") (assert_trap (invoke "call-mid") "unreachable") (assert_trap (invoke "call-last") "unreachable") From 748f9daa44534dad4099f822095e9c117ef2772e Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Fri, 20 May 2016 16:07:36 +0200 Subject: [PATCH 2/2] Some actual looping --- ml-proto/test/loop.wast | 77 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/ml-proto/test/loop.wast b/ml-proto/test/loop.wast index 02c9e0bf04..e4c6581eaf 100644 --- a/ml-proto/test/loop.wast +++ b/ml-proto/test/loop.wast @@ -87,8 +87,6 @@ (get_local 0) ) - ;; TODO: tests of actual looping - (func "drop-mid" (result i32) (loop (call $fx) (i32.const 7) (call $nop) (i32.const 8)) ) @@ -158,6 +156,50 @@ ) (i32.eq (get_local 0) (i32.const -14)) ) + + (func "while" (param i64) (result i64) + (local i64) + (set_local 1 (i64.const 1)) + (loop + (br_if 1 (i64.eqz (get_local 0))) + (set_local 1 (i64.mul (get_local 0) (get_local 1))) + (set_local 0 (i64.sub (get_local 0) (i64.const 1))) + (br 0) + ) + (get_local 1) + ) + + (func "for" (param i64) (result i64) + (local i64 i64) + (set_local 1 (i64.const 1)) + (set_local 2 (i64.const 2)) + (loop + (br_if 1 (i64.gt_u (get_local 2) (get_local 0))) + (set_local 1 (i64.mul (get_local 1) (get_local 2))) + (set_local 2 (i64.add (get_local 2) (i64.const 1))) + (br 0) + ) + (get_local 1) + ) + + (func "nesting" (param f32 f32) (result f32) + (local f32 f32) + (loop + (br_if 1 (f32.eq (get_local 0) (f32.const 0))) + (set_local 2 (get_local 1)) + (loop + (br_if 1 (f32.eq (get_local 2) (f32.const 0))) + (br_if 3 (f32.lt (get_local 2) (f32.const 0))) + (set_local 3 (f32.add (get_local 3) (get_local 2))) + (set_local 2 (f32.sub (get_local 2) (f32.const 2))) + (br 0) + ) + (set_local 3 (f32.div (get_local 3) (get_local 0))) + (set_local 0 (f32.sub (get_local 0) (f32.const 1))) + (br 0) + ) + (get_local 3) + ) ) (assert_return (invoke "empty")) @@ -184,6 +226,37 @@ (assert_return (invoke "effects") (i32.const 1)) +(assert_return (invoke "while" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "while" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "while" (i64.const 2)) (i64.const 2)) +(assert_return (invoke "while" (i64.const 3)) (i64.const 6)) +(assert_return (invoke "while" (i64.const 5)) (i64.const 120)) +(assert_return (invoke "while" (i64.const 20)) (i64.const 2432902008176640000)) + +(assert_return (invoke "for" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "for" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "for" (i64.const 2)) (i64.const 2)) +(assert_return (invoke "for" (i64.const 3)) (i64.const 6)) +(assert_return (invoke "for" (i64.const 5)) (i64.const 120)) +(assert_return (invoke "for" (i64.const 20)) (i64.const 2432902008176640000)) + +(assert_return (invoke "nesting" (f32.const 0) (f32.const 7)) (f32.const 0)) +(assert_return (invoke "nesting" (f32.const 7) (f32.const 0)) (f32.const 0)) +(assert_return (invoke "nesting" (f32.const 1) (f32.const 1)) (f32.const 1)) +(assert_return (invoke "nesting" (f32.const 1) (f32.const 2)) (f32.const 2)) +(assert_return (invoke "nesting" (f32.const 1) (f32.const 3)) (f32.const 4)) +(assert_return (invoke "nesting" (f32.const 1) (f32.const 4)) (f32.const 6)) +(assert_return (invoke "nesting" (f32.const 1) (f32.const 100)) (f32.const 2550)) +(assert_return (invoke "nesting" (f32.const 1) (f32.const 101)) (f32.const 2601)) +(assert_return (invoke "nesting" (f32.const 2) (f32.const 1)) (f32.const 1)) +(assert_return (invoke "nesting" (f32.const 3) (f32.const 1)) (f32.const 1)) +(assert_return (invoke "nesting" (f32.const 10) (f32.const 1)) (f32.const 1)) +(assert_return (invoke "nesting" (f32.const 2) (f32.const 2)) (f32.const 3)) +(assert_return (invoke "nesting" (f32.const 2) (f32.const 3)) (f32.const 4)) +(assert_return (invoke "nesting" (f32.const 7) (f32.const 4)) (f32.const 10.3095235825)) +(assert_return (invoke "nesting" (f32.const 7) (f32.const 100)) (f32.const 4381.54785156)) +(assert_return (invoke "nesting" (f32.const 7) (f32.const 101)) (f32.const 2601)) + (assert_invalid (module (func (result i32) (loop))) "type mismatch"