From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../wasm/spec/function-references/br_if.wast.js | 886 +++++++++ .../function-references/br_on_non_null.wast.js | 101 ++ .../spec/function-references/br_on_null.wast.js | 94 + .../wasm/spec/function-references/call_ref.wast.js | 275 +++ .../wasm/spec/function-references/directives.txt | 1 + .../wasm/spec/function-references/func.wast.js | 1240 +++++++++++++ .../wasm/spec/function-references/global.wast.js | 796 ++++++++ .../function-references/harness/directives.txt | 1 + .../spec/function-references/harness/harness.js | 448 +++++ .../tests/wasm/spec/function-references/if.wast.js | 1911 ++++++++++++++++++++ .../spec/function-references/local_get.wast.js | 279 +++ .../wasm/spec/function-references/ref.wast.js | 110 ++ .../function-references/ref_as_non_null.wast.js | 71 + .../wasm/spec/function-references/ref_func.wast.js | 156 ++ .../function-references/return_call_ref.wast.js | 460 +++++ .../function-references/unreached-valid.wast.js | 109 ++ 16 files changed, 6938 insertions(+) create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/br_if.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/br_on_non_null.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/br_on_null.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/call_ref.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/directives.txt create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/func.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/global.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/harness/directives.txt create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/harness/harness.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/if.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/local_get.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/ref.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/ref_as_non_null.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/ref_func.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/return_call_ref.wast.js create mode 100644 js/src/jit-test/tests/wasm/spec/function-references/unreached-valid.wast.js (limited to 'js/src/jit-test/tests/wasm/spec/function-references') diff --git a/js/src/jit-test/tests/wasm/spec/function-references/br_if.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/br_if.wast.js new file mode 100644 index 0000000000..511ee003fb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/br_if.wast.js @@ -0,0 +1,886 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/br_if.wast + +// ./test/core/br_if.wast:3 +let $0 = instantiate(`(module + (func $$dummy) + + (func (export "type-i32") + (block (drop (i32.ctz (br_if 0 (i32.const 0) (i32.const 1))))) + ) + (func (export "type-i64") + (block (drop (i64.ctz (br_if 0 (i64.const 0) (i32.const 1))))) + ) + (func (export "type-f32") + (block (drop (f32.neg (br_if 0 (f32.const 0) (i32.const 1))))) + ) + (func (export "type-f64") + (block (drop (f64.neg (br_if 0 (f64.const 0) (i32.const 1))))) + ) + + (func (export "type-i32-value") (result i32) + (block (result i32) (i32.ctz (br_if 0 (i32.const 1) (i32.const 1)))) + ) + (func (export "type-i64-value") (result i64) + (block (result i64) (i64.ctz (br_if 0 (i64.const 2) (i32.const 1)))) + ) + (func (export "type-f32-value") (result f32) + (block (result f32) (f32.neg (br_if 0 (f32.const 3) (i32.const 1)))) + ) + (func (export "type-f64-value") (result f64) + (block (result f64) (f64.neg (br_if 0 (f64.const 4) (i32.const 1)))) + ) + + (func (export "as-block-first") (param i32) (result i32) + (block (br_if 0 (local.get 0)) (return (i32.const 2))) (i32.const 3) + ) + (func (export "as-block-mid") (param i32) (result i32) + (block (call $$dummy) (br_if 0 (local.get 0)) (return (i32.const 2))) + (i32.const 3) + ) + (func (export "as-block-last") (param i32) + (block (call $$dummy) (call $$dummy) (br_if 0 (local.get 0))) + ) + (func (export "as-block-first-value") (param i32) (result i32) + (block (result i32) + (drop (br_if 0 (i32.const 10) (local.get 0))) (return (i32.const 11)) + ) + ) + (func (export "as-block-mid-value") (param i32) (result i32) + (block (result i32) + (call $$dummy) + (drop (br_if 0 (i32.const 20) (local.get 0))) + (return (i32.const 21)) + ) + ) + (func (export "as-block-last-value") (param i32) (result i32) + (block (result i32) + (call $$dummy) (call $$dummy) (br_if 0 (i32.const 11) (local.get 0)) + ) + ) + + (func (export "as-loop-first") (param i32) (result i32) + (block (loop (br_if 1 (local.get 0)) (return (i32.const 2)))) (i32.const 3) + ) + (func (export "as-loop-mid") (param i32) (result i32) + (block (loop (call $$dummy) (br_if 1 (local.get 0)) (return (i32.const 2)))) + (i32.const 4) + ) + (func (export "as-loop-last") (param i32) + (loop (call $$dummy) (br_if 1 (local.get 0))) + ) + + (func (export "as-br-value") (result i32) + (block (result i32) (br 0 (br_if 0 (i32.const 1) (i32.const 2)))) + ) + + (func (export "as-br_if-cond") + (block (br_if 0 (br_if 0 (i32.const 1) (i32.const 1)))) + ) + (func (export "as-br_if-value") (result i32) + (block (result i32) + (drop (br_if 0 (br_if 0 (i32.const 1) (i32.const 2)) (i32.const 3))) + (i32.const 4) + ) + ) + (func (export "as-br_if-value-cond") (param i32) (result i32) + (block (result i32) + (drop (br_if 0 (i32.const 2) (br_if 0 (i32.const 1) (local.get 0)))) + (i32.const 4) + ) + ) + + (func (export "as-br_table-index") + (block (br_table 0 0 0 (br_if 0 (i32.const 1) (i32.const 2)))) + ) + (func (export "as-br_table-value") (result i32) + (block (result i32) + (br_table 0 0 0 (br_if 0 (i32.const 1) (i32.const 2)) (i32.const 3)) (i32.const 4) + ) + ) + (func (export "as-br_table-value-index") (result i32) + (block (result i32) + (br_table 0 0 (i32.const 2) (br_if 0 (i32.const 1) (i32.const 3))) (i32.const 4) + ) + ) + (func (export "as-return-value") (result i64) + (block (result i64) (return (br_if 0 (i64.const 1) (i32.const 2)))) + ) + + (func (export "as-if-cond") (param i32) (result i32) + (block (result i32) + (if (result i32) + (br_if 0 (i32.const 1) (local.get 0)) + (then (i32.const 2)) + (else (i32.const 3)) + ) + ) + ) + (func (export "as-if-then") (param i32 i32) + (block + (if (local.get 0) (then (br_if 1 (local.get 1))) (else (call $$dummy))) + ) + ) + (func (export "as-if-else") (param i32 i32) + (block + (if (local.get 0) (then (call $$dummy)) (else (br_if 1 (local.get 1)))) + ) + ) + + (func (export "as-select-first") (param i32) (result i32) + (block (result i32) + (select (br_if 0 (i32.const 3) (i32.const 10)) (i32.const 2) (local.get 0)) + ) + ) + (func (export "as-select-second") (param i32) (result i32) + (block (result i32) + (select (i32.const 1) (br_if 0 (i32.const 3) (i32.const 10)) (local.get 0)) + ) + ) + (func (export "as-select-cond") (result i32) + (block (result i32) + (select (i32.const 1) (i32.const 2) (br_if 0 (i32.const 3) (i32.const 10))) + ) + ) + + (func $$f (param i32 i32 i32) (result i32) (i32.const -1)) + (func (export "as-call-first") (result i32) + (block (result i32) + (call $$f + (br_if 0 (i32.const 12) (i32.const 1)) (i32.const 2) (i32.const 3) + ) + ) + ) + (func (export "as-call-mid") (result i32) + (block (result i32) + (call $$f + (i32.const 1) (br_if 0 (i32.const 13) (i32.const 1)) (i32.const 3) + ) + ) + ) + (func (export "as-call-last") (result i32) + (block (result i32) + (call $$f + (i32.const 1) (i32.const 2) (br_if 0 (i32.const 14) (i32.const 1)) + ) + ) + ) + + (func $$func (param i32 i32 i32) (result i32) (local.get 0)) + (type $$check (func (param i32 i32 i32) (result i32))) + (table funcref (elem $$func)) + (func (export "as-call_indirect-func") (result i32) + (block (result i32) + (call_indirect (type $$check) + (br_if 0 (i32.const 4) (i32.const 10)) + (i32.const 1) (i32.const 2) (i32.const 0) + ) + ) + ) + + (func (export "as-call_indirect-first") (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 1) (br_if 0 (i32.const 4) (i32.const 10)) (i32.const 2) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-mid") (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 1) (i32.const 2) (br_if 0 (i32.const 4) (i32.const 10)) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-last") (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 1) (i32.const 2) (i32.const 3) (br_if 0 (i32.const 4) (i32.const 10)) + ) + ) + ) + + (func (export "as-local.set-value") (param i32) (result i32) + (local i32) + (block (result i32) + (local.set 0 (br_if 0 (i32.const 17) (local.get 0))) + (i32.const -1) + ) + ) + (func (export "as-local.tee-value") (param i32) (result i32) + (block (result i32) + (local.tee 0 (br_if 0 (i32.const 1) (local.get 0))) + (return (i32.const -1)) + ) + ) + (global $$a (mut i32) (i32.const 10)) + (func (export "as-global.set-value") (param i32) (result i32) + (block (result i32) + (global.set $$a (br_if 0 (i32.const 1) (local.get 0))) + (return (i32.const -1)) + ) + ) + + (memory 1) + (func (export "as-load-address") (result i32) + (block (result i32) (i32.load (br_if 0 (i32.const 1) (i32.const 1)))) + ) + (func (export "as-loadN-address") (result i32) + (block (result i32) (i32.load8_s (br_if 0 (i32.const 30) (i32.const 1)))) + ) + + (func (export "as-store-address") (result i32) + (block (result i32) + (i32.store (br_if 0 (i32.const 30) (i32.const 1)) (i32.const 7)) (i32.const -1) + ) + ) + (func (export "as-store-value") (result i32) + (block (result i32) + (i32.store (i32.const 2) (br_if 0 (i32.const 31) (i32.const 1))) (i32.const -1) + ) + ) + + (func (export "as-storeN-address") (result i32) + (block (result i32) + (i32.store8 (br_if 0 (i32.const 32) (i32.const 1)) (i32.const 7)) (i32.const -1) + ) + ) + (func (export "as-storeN-value") (result i32) + (block (result i32) + (i32.store16 (i32.const 2) (br_if 0 (i32.const 33) (i32.const 1))) (i32.const -1) + ) + ) + + (func (export "as-unary-operand") (result f64) + (block (result f64) (f64.neg (br_if 0 (f64.const 1.0) (i32.const 1)))) + ) + (func (export "as-binary-left") (result i32) + (block (result i32) (i32.add (br_if 0 (i32.const 1) (i32.const 1)) (i32.const 10))) + ) + (func (export "as-binary-right") (result i32) + (block (result i32) (i32.sub (i32.const 10) (br_if 0 (i32.const 1) (i32.const 1)))) + ) + (func (export "as-test-operand") (result i32) + (block (result i32) (i32.eqz (br_if 0 (i32.const 0) (i32.const 1)))) + ) + (func (export "as-compare-left") (result i32) + (block (result i32) (i32.le_u (br_if 0 (i32.const 1) (i32.const 1)) (i32.const 10))) + ) + (func (export "as-compare-right") (result i32) + (block (result i32) (i32.ne (i32.const 10) (br_if 0 (i32.const 1) (i32.const 42)))) + ) + + (func (export "as-memory.grow-size") (result i32) + (block (result i32) (memory.grow (br_if 0 (i32.const 1) (i32.const 1)))) + ) + + (func (export "nested-block-value") (param i32) (result i32) + (i32.add + (i32.const 1) + (block (result i32) + (drop (i32.const 2)) + (i32.add + (i32.const 4) + (block (result i32) + (drop (br_if 1 (i32.const 8) (local.get 0))) + (i32.const 16) + ) + ) + ) + ) + ) + + (func (export "nested-br-value") (param i32) (result i32) + (i32.add + (i32.const 1) + (block (result i32) + (drop (i32.const 2)) + (br 0 + (block (result i32) + (drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 4) + ) + ) + (i32.const 16) + ) + ) + ) + + (func (export "nested-br_if-value") (param i32) (result i32) + (i32.add + (i32.const 1) + (block (result i32) + (drop (i32.const 2)) + (drop (br_if 0 + (block (result i32) + (drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 4) + ) + (i32.const 1) + )) + (i32.const 16) + ) + ) + ) + + (func (export "nested-br_if-value-cond") (param i32) (result i32) + (i32.add + (i32.const 1) + (block (result i32) + (drop (i32.const 2)) + (drop (br_if 0 + (i32.const 4) + (block (result i32) + (drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 1) + ) + )) + (i32.const 16) + ) + ) + ) + + (func (export "nested-br_table-value") (param i32) (result i32) + (i32.add + (i32.const 1) + (block (result i32) + (drop (i32.const 2)) + (br_table 0 + (block (result i32) + (drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 4) + ) + (i32.const 1) + ) + (i32.const 16) + ) + ) + ) + + (func (export "nested-br_table-value-index") (param i32) (result i32) + (i32.add + (i32.const 1) + (block (result i32) + (drop (i32.const 2)) + (br_table 0 + (i32.const 4) + (block (result i32) + (drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 1) + ) + ) + (i32.const 16) + ) + ) + ) + +)`); + +// ./test/core/br_if.wast:372 +assert_return(() => invoke($0, `type-i32`, []), []); + +// ./test/core/br_if.wast:373 +assert_return(() => invoke($0, `type-i64`, []), []); + +// ./test/core/br_if.wast:374 +assert_return(() => invoke($0, `type-f32`, []), []); + +// ./test/core/br_if.wast:375 +assert_return(() => invoke($0, `type-f64`, []), []); + +// ./test/core/br_if.wast:377 +assert_return(() => invoke($0, `type-i32-value`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:378 +assert_return(() => invoke($0, `type-i64-value`, []), [value("i64", 2n)]); + +// ./test/core/br_if.wast:379 +assert_return(() => invoke($0, `type-f32-value`, []), [value("f32", 3)]); + +// ./test/core/br_if.wast:380 +assert_return(() => invoke($0, `type-f64-value`, []), [value("f64", 4)]); + +// ./test/core/br_if.wast:382 +assert_return(() => invoke($0, `as-block-first`, [0]), [value("i32", 2)]); + +// ./test/core/br_if.wast:383 +assert_return(() => invoke($0, `as-block-first`, [1]), [value("i32", 3)]); + +// ./test/core/br_if.wast:384 +assert_return(() => invoke($0, `as-block-mid`, [0]), [value("i32", 2)]); + +// ./test/core/br_if.wast:385 +assert_return(() => invoke($0, `as-block-mid`, [1]), [value("i32", 3)]); + +// ./test/core/br_if.wast:386 +assert_return(() => invoke($0, `as-block-last`, [0]), []); + +// ./test/core/br_if.wast:387 +assert_return(() => invoke($0, `as-block-last`, [1]), []); + +// ./test/core/br_if.wast:389 +assert_return(() => invoke($0, `as-block-first-value`, [0]), [value("i32", 11)]); + +// ./test/core/br_if.wast:390 +assert_return(() => invoke($0, `as-block-first-value`, [1]), [value("i32", 10)]); + +// ./test/core/br_if.wast:391 +assert_return(() => invoke($0, `as-block-mid-value`, [0]), [value("i32", 21)]); + +// ./test/core/br_if.wast:392 +assert_return(() => invoke($0, `as-block-mid-value`, [1]), [value("i32", 20)]); + +// ./test/core/br_if.wast:393 +assert_return(() => invoke($0, `as-block-last-value`, [0]), [value("i32", 11)]); + +// ./test/core/br_if.wast:394 +assert_return(() => invoke($0, `as-block-last-value`, [1]), [value("i32", 11)]); + +// ./test/core/br_if.wast:396 +assert_return(() => invoke($0, `as-loop-first`, [0]), [value("i32", 2)]); + +// ./test/core/br_if.wast:397 +assert_return(() => invoke($0, `as-loop-first`, [1]), [value("i32", 3)]); + +// ./test/core/br_if.wast:398 +assert_return(() => invoke($0, `as-loop-mid`, [0]), [value("i32", 2)]); + +// ./test/core/br_if.wast:399 +assert_return(() => invoke($0, `as-loop-mid`, [1]), [value("i32", 4)]); + +// ./test/core/br_if.wast:400 +assert_return(() => invoke($0, `as-loop-last`, [0]), []); + +// ./test/core/br_if.wast:401 +assert_return(() => invoke($0, `as-loop-last`, [1]), []); + +// ./test/core/br_if.wast:403 +assert_return(() => invoke($0, `as-br-value`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:405 +assert_return(() => invoke($0, `as-br_if-cond`, []), []); + +// ./test/core/br_if.wast:406 +assert_return(() => invoke($0, `as-br_if-value`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:407 +assert_return(() => invoke($0, `as-br_if-value-cond`, [0]), [value("i32", 2)]); + +// ./test/core/br_if.wast:408 +assert_return(() => invoke($0, `as-br_if-value-cond`, [1]), [value("i32", 1)]); + +// ./test/core/br_if.wast:410 +assert_return(() => invoke($0, `as-br_table-index`, []), []); + +// ./test/core/br_if.wast:411 +assert_return(() => invoke($0, `as-br_table-value`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:412 +assert_return(() => invoke($0, `as-br_table-value-index`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:414 +assert_return(() => invoke($0, `as-return-value`, []), [value("i64", 1n)]); + +// ./test/core/br_if.wast:416 +assert_return(() => invoke($0, `as-if-cond`, [0]), [value("i32", 2)]); + +// ./test/core/br_if.wast:417 +assert_return(() => invoke($0, `as-if-cond`, [1]), [value("i32", 1)]); + +// ./test/core/br_if.wast:418 +assert_return(() => invoke($0, `as-if-then`, [0, 0]), []); + +// ./test/core/br_if.wast:419 +assert_return(() => invoke($0, `as-if-then`, [4, 0]), []); + +// ./test/core/br_if.wast:420 +assert_return(() => invoke($0, `as-if-then`, [0, 1]), []); + +// ./test/core/br_if.wast:421 +assert_return(() => invoke($0, `as-if-then`, [4, 1]), []); + +// ./test/core/br_if.wast:422 +assert_return(() => invoke($0, `as-if-else`, [0, 0]), []); + +// ./test/core/br_if.wast:423 +assert_return(() => invoke($0, `as-if-else`, [3, 0]), []); + +// ./test/core/br_if.wast:424 +assert_return(() => invoke($0, `as-if-else`, [0, 1]), []); + +// ./test/core/br_if.wast:425 +assert_return(() => invoke($0, `as-if-else`, [3, 1]), []); + +// ./test/core/br_if.wast:427 +assert_return(() => invoke($0, `as-select-first`, [0]), [value("i32", 3)]); + +// ./test/core/br_if.wast:428 +assert_return(() => invoke($0, `as-select-first`, [1]), [value("i32", 3)]); + +// ./test/core/br_if.wast:429 +assert_return(() => invoke($0, `as-select-second`, [0]), [value("i32", 3)]); + +// ./test/core/br_if.wast:430 +assert_return(() => invoke($0, `as-select-second`, [1]), [value("i32", 3)]); + +// ./test/core/br_if.wast:431 +assert_return(() => invoke($0, `as-select-cond`, []), [value("i32", 3)]); + +// ./test/core/br_if.wast:433 +assert_return(() => invoke($0, `as-call-first`, []), [value("i32", 12)]); + +// ./test/core/br_if.wast:434 +assert_return(() => invoke($0, `as-call-mid`, []), [value("i32", 13)]); + +// ./test/core/br_if.wast:435 +assert_return(() => invoke($0, `as-call-last`, []), [value("i32", 14)]); + +// ./test/core/br_if.wast:437 +assert_return(() => invoke($0, `as-call_indirect-func`, []), [value("i32", 4)]); + +// ./test/core/br_if.wast:438 +assert_return(() => invoke($0, `as-call_indirect-first`, []), [value("i32", 4)]); + +// ./test/core/br_if.wast:439 +assert_return(() => invoke($0, `as-call_indirect-mid`, []), [value("i32", 4)]); + +// ./test/core/br_if.wast:440 +assert_return(() => invoke($0, `as-call_indirect-last`, []), [value("i32", 4)]); + +// ./test/core/br_if.wast:442 +assert_return(() => invoke($0, `as-local.set-value`, [0]), [value("i32", -1)]); + +// ./test/core/br_if.wast:443 +assert_return(() => invoke($0, `as-local.set-value`, [1]), [value("i32", 17)]); + +// ./test/core/br_if.wast:445 +assert_return(() => invoke($0, `as-local.tee-value`, [0]), [value("i32", -1)]); + +// ./test/core/br_if.wast:446 +assert_return(() => invoke($0, `as-local.tee-value`, [1]), [value("i32", 1)]); + +// ./test/core/br_if.wast:448 +assert_return(() => invoke($0, `as-global.set-value`, [0]), [value("i32", -1)]); + +// ./test/core/br_if.wast:449 +assert_return(() => invoke($0, `as-global.set-value`, [1]), [value("i32", 1)]); + +// ./test/core/br_if.wast:451 +assert_return(() => invoke($0, `as-load-address`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:452 +assert_return(() => invoke($0, `as-loadN-address`, []), [value("i32", 30)]); + +// ./test/core/br_if.wast:454 +assert_return(() => invoke($0, `as-store-address`, []), [value("i32", 30)]); + +// ./test/core/br_if.wast:455 +assert_return(() => invoke($0, `as-store-value`, []), [value("i32", 31)]); + +// ./test/core/br_if.wast:456 +assert_return(() => invoke($0, `as-storeN-address`, []), [value("i32", 32)]); + +// ./test/core/br_if.wast:457 +assert_return(() => invoke($0, `as-storeN-value`, []), [value("i32", 33)]); + +// ./test/core/br_if.wast:459 +assert_return(() => invoke($0, `as-unary-operand`, []), [value("f64", 1)]); + +// ./test/core/br_if.wast:460 +assert_return(() => invoke($0, `as-binary-left`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:461 +assert_return(() => invoke($0, `as-binary-right`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:462 +assert_return(() => invoke($0, `as-test-operand`, []), [value("i32", 0)]); + +// ./test/core/br_if.wast:463 +assert_return(() => invoke($0, `as-compare-left`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:464 +assert_return(() => invoke($0, `as-compare-right`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:465 +assert_return(() => invoke($0, `as-memory.grow-size`, []), [value("i32", 1)]); + +// ./test/core/br_if.wast:467 +assert_return(() => invoke($0, `nested-block-value`, [0]), [value("i32", 21)]); + +// ./test/core/br_if.wast:468 +assert_return(() => invoke($0, `nested-block-value`, [1]), [value("i32", 9)]); + +// ./test/core/br_if.wast:469 +assert_return(() => invoke($0, `nested-br-value`, [0]), [value("i32", 5)]); + +// ./test/core/br_if.wast:470 +assert_return(() => invoke($0, `nested-br-value`, [1]), [value("i32", 9)]); + +// ./test/core/br_if.wast:471 +assert_return(() => invoke($0, `nested-br_if-value`, [0]), [value("i32", 5)]); + +// ./test/core/br_if.wast:472 +assert_return(() => invoke($0, `nested-br_if-value`, [1]), [value("i32", 9)]); + +// ./test/core/br_if.wast:473 +assert_return(() => invoke($0, `nested-br_if-value-cond`, [0]), [value("i32", 5)]); + +// ./test/core/br_if.wast:474 +assert_return(() => invoke($0, `nested-br_if-value-cond`, [1]), [value("i32", 9)]); + +// ./test/core/br_if.wast:475 +assert_return(() => invoke($0, `nested-br_table-value`, [0]), [value("i32", 5)]); + +// ./test/core/br_if.wast:476 +assert_return(() => invoke($0, `nested-br_table-value`, [1]), [value("i32", 9)]); + +// ./test/core/br_if.wast:477 +assert_return(() => invoke($0, `nested-br_table-value-index`, [0]), [value("i32", 5)]); + +// ./test/core/br_if.wast:478 +assert_return(() => invoke($0, `nested-br_table-value-index`, [1]), [value("i32", 9)]); + +// ./test/core/br_if.wast:480 +assert_invalid( + () => instantiate(`(module (func $$type-false-i32 (block (i32.ctz (br_if 0 (i32.const 0))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:484 +assert_invalid( + () => instantiate(`(module (func $$type-false-i64 (block (i64.ctz (br_if 0 (i32.const 0))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:488 +assert_invalid( + () => instantiate(`(module (func $$type-false-f32 (block (f32.neg (br_if 0 (i32.const 0))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:492 +assert_invalid( + () => instantiate(`(module (func $$type-false-f64 (block (f64.neg (br_if 0 (i32.const 0))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:497 +assert_invalid( + () => instantiate(`(module (func $$type-true-i32 (block (i32.ctz (br_if 0 (i32.const 1))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:501 +assert_invalid( + () => instantiate(`(module (func $$type-true-i64 (block (i64.ctz (br_if 0 (i64.const 1))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:505 +assert_invalid( + () => instantiate(`(module (func $$type-true-f32 (block (f32.neg (br_if 0 (f32.const 1))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:509 +assert_invalid( + () => instantiate(`(module (func $$type-true-f64 (block (f64.neg (br_if 0 (i64.const 1))))))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:514 +assert_invalid( + () => instantiate(`(module (func $$type-false-arg-void-vs-num (result i32) + (block (result i32) (br_if 0 (i32.const 0)) (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:520 +assert_invalid( + () => instantiate(`(module (func $$type-true-arg-void-vs-num (result i32) + (block (result i32) (br_if 0 (i32.const 1)) (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:526 +assert_invalid( + () => instantiate(`(module (func $$type-false-arg-num-vs-void + (block (br_if 0 (i32.const 0) (i32.const 0))) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:532 +assert_invalid( + () => instantiate(`(module (func $$type-true-arg-num-vs-void + (block (br_if 0 (i32.const 0) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:539 +assert_invalid( + () => instantiate(`(module (func $$type-false-arg-void-vs-num (result i32) + (block (result i32) (br_if 0 (nop) (i32.const 0)) (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:545 +assert_invalid( + () => instantiate(`(module (func $$type-true-arg-void-vs-num (result i32) + (block (result i32) (br_if 0 (nop) (i32.const 1)) (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:551 +assert_invalid( + () => instantiate(`(module (func $$type-false-arg-num-vs-num (result i32) + (block (result i32) + (drop (br_if 0 (i64.const 1) (i32.const 0))) (i32.const 1) + ) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:559 +assert_invalid( + () => instantiate(`(module (func $$type-true-arg-num-vs-num (result i32) + (block (result i32) + (drop (br_if 0 (i64.const 1) (i32.const 0))) (i32.const 1) + ) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:568 +assert_invalid( + () => instantiate(`(module (func $$type-cond-empty-vs-i32 + (block (br_if 0)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:574 +assert_invalid( + () => instantiate(`(module (func $$type-cond-void-vs-i32 + (block (br_if 0 (nop))) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:580 +assert_invalid( + () => instantiate(`(module (func $$type-cond-num-vs-i32 + (block (br_if 0 (i64.const 0))) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:586 +assert_invalid( + () => instantiate(`(module (func $$type-arg-cond-void-vs-i32 (result i32) + (block (result i32) (br_if 0 (i32.const 0) (nop)) (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:592 +assert_invalid( + () => instantiate(`(module (func $$type-arg-void-vs-num-nested (result i32) + (block (result i32) (i32.const 0) (block (br_if 1 (i32.const 1)))) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:598 +assert_invalid( + () => instantiate(`(module (func $$type-arg-cond-num-vs-i32 (result i32) + (block (result i32) (br_if 0 (i32.const 0) (i64.const 0)) (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/br_if.wast:605 +assert_invalid( + () => instantiate(`(module + (func $$type-1st-cond-empty-in-then + (block + (i32.const 0) (i32.const 0) + (if (result i32) (then (br_if 0))) + ) + (i32.eqz) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/br_if.wast:617 +assert_invalid( + () => instantiate(`(module + (func $$type-2nd-cond-empty-in-then + (block + (i32.const 0) (i32.const 0) + (if (result i32) (then (br_if 0 (i32.const 1)))) + ) + (i32.eqz) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/br_if.wast:629 +assert_invalid( + () => instantiate(`(module + (func $$type-1st-cond-empty-in-return + (block (result i32) + (return (br_if 0)) + ) + (i32.eqz) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/br_if.wast:640 +assert_invalid( + () => instantiate(`(module + (func $$type-2nd-cond-empty-in-return + (block (result i32) + (return (br_if 0 (i32.const 1))) + ) + (i32.eqz) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/br_if.wast:653 +assert_invalid( + () => instantiate(`(module (func $$unbound-label (br_if 1 (i32.const 1))))`), + `unknown label`, +); + +// ./test/core/br_if.wast:657 +assert_invalid( + () => instantiate(`(module (func $$unbound-nested-label (block (block (br_if 5 (i32.const 1))))))`), + `unknown label`, +); + +// ./test/core/br_if.wast:661 +assert_invalid( + () => instantiate(`(module (func $$large-label (br_if 0x10000001 (i32.const 1))))`), + `unknown label`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/br_on_non_null.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/br_on_non_null.wast.js new file mode 100644 index 0000000000..16a778a8e4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/br_on_non_null.wast.js @@ -0,0 +1,101 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/br_on_non_null.wast + +// ./test/core/br_on_non_null.wast:1 +let $0 = instantiate(`(module + (type $$t (func (result i32))) + + (func $$nn (param $$r (ref $$t)) (result i32) + (call_ref $$t + (block $$l (result (ref $$t)) + (br_on_non_null $$l (local.get $$r)) + (return (i32.const -1)) + ) + ) + ) + (func $$n (param $$r (ref null $$t)) (result i32) + (call_ref $$t + (block $$l (result (ref $$t)) + (br_on_non_null $$l (local.get $$r)) + (return (i32.const -1)) + ) + ) + ) + + (elem func $$f) + (func $$f (result i32) (i32.const 7)) + + (func (export "nullable-null") (result i32) (call $$n (ref.null $$t))) + (func (export "nonnullable-f") (result i32) (call $$nn (ref.func $$f))) + (func (export "nullable-f") (result i32) (call $$n (ref.func $$f))) + + (func (export "unreachable") (result i32) + (block $$l (result (ref $$t)) + (br_on_non_null $$l (unreachable)) + (return (i32.const -1)) + ) + (call_ref $$t) + ) +)`); + +// ./test/core/br_on_non_null.wast:37 +assert_trap(() => invoke($0, `unreachable`, []), `unreachable`); + +// ./test/core/br_on_non_null.wast:39 +assert_return(() => invoke($0, `nullable-null`, []), [value("i32", -1)]); + +// ./test/core/br_on_non_null.wast:40 +assert_return(() => invoke($0, `nonnullable-f`, []), [value("i32", 7)]); + +// ./test/core/br_on_non_null.wast:41 +assert_return(() => invoke($0, `nullable-f`, []), [value("i32", 7)]); + +// ./test/core/br_on_non_null.wast:43 +let $1 = instantiate(`(module + (type $$t (func)) + (func (param $$r (ref null $$t)) (drop (block (result (ref $$t)) (br_on_non_null 0 (local.get $$r)) (unreachable)))) + (func (param $$r (ref null func)) (drop (block (result (ref func)) (br_on_non_null 0 (local.get $$r)) (unreachable)))) + (func (param $$r (ref null extern)) (drop (block (result (ref extern)) (br_on_non_null 0 (local.get $$r)) (unreachable)))) +)`); + +// ./test/core/br_on_non_null.wast:51 +let $2 = instantiate(`(module + (type $$t (func (param i32) (result i32))) + (elem func $$f) + (func $$f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0))) + + (func $$a (param $$n i32) (param $$r (ref null $$t)) (result i32) + (call_ref $$t + (block $$l (result i32 (ref $$t)) + (return (br_on_non_null $$l (local.get $$n) (local.get $$r))) + ) + ) + ) + + (func (export "args-null") (param $$n i32) (result i32) + (call $$a (local.get $$n) (ref.null $$t)) + ) + (func (export "args-f") (param $$n i32) (result i32) + (call $$a (local.get $$n) (ref.func $$f)) + ) +)`); + +// ./test/core/br_on_non_null.wast:72 +assert_return(() => invoke($2, `args-null`, [3]), [value("i32", 3)]); + +// ./test/core/br_on_non_null.wast:73 +assert_return(() => invoke($2, `args-f`, [3]), [value("i32", 9)]); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/br_on_null.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/br_on_null.wast.js new file mode 100644 index 0000000000..3335e22930 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/br_on_null.wast.js @@ -0,0 +1,94 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/br_on_null.wast + +// ./test/core/br_on_null.wast:1 +let $0 = instantiate(`(module + (type $$t (func (result i32))) + + (func $$nn (param $$r (ref $$t)) (result i32) + (block $$l + (return (call_ref $$t (br_on_null $$l (local.get $$r)))) + ) + (i32.const -1) + ) + (func $$n (param $$r (ref null $$t)) (result i32) + (block $$l + (return (call_ref $$t (br_on_null $$l (local.get $$r)))) + ) + (i32.const -1) + ) + + (elem func $$f) + (func $$f (result i32) (i32.const 7)) + + (func (export "nullable-null") (result i32) (call $$n (ref.null $$t))) + (func (export "nonnullable-f") (result i32) (call $$nn (ref.func $$f))) + (func (export "nullable-f") (result i32) (call $$n (ref.func $$f))) + + (func (export "unreachable") (result i32) + (block $$l + (return (call_ref $$t (br_on_null $$l (unreachable)))) + ) + (i32.const -1) + ) +)`); + +// ./test/core/br_on_null.wast:32 +assert_trap(() => invoke($0, `unreachable`, []), `unreachable`); + +// ./test/core/br_on_null.wast:34 +assert_return(() => invoke($0, `nullable-null`, []), [value("i32", -1)]); + +// ./test/core/br_on_null.wast:35 +assert_return(() => invoke($0, `nonnullable-f`, []), [value("i32", 7)]); + +// ./test/core/br_on_null.wast:36 +assert_return(() => invoke($0, `nullable-f`, []), [value("i32", 7)]); + +// ./test/core/br_on_null.wast:38 +let $1 = instantiate(`(module + (type $$t (func)) + (func (param $$r (ref null $$t)) (drop (br_on_null 0 (local.get $$r)))) + (func (param $$r (ref null func)) (drop (br_on_null 0 (local.get $$r)))) + (func (param $$r (ref null extern)) (drop (br_on_null 0 (local.get $$r)))) +)`); + +// ./test/core/br_on_null.wast:46 +let $2 = instantiate(`(module + (type $$t (func (param i32) (result i32))) + (elem func $$f) + (func $$f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0))) + + (func $$a (param $$n i32) (param $$r (ref null $$t)) (result i32) + (block $$l (result i32) + (return (call_ref $$t (br_on_null $$l (local.get $$n) (local.get $$r)))) + ) + ) + + (func (export "args-null") (param $$n i32) (result i32) + (call $$a (local.get $$n) (ref.null $$t)) + ) + (func (export "args-f") (param $$n i32) (result i32) + (call $$a (local.get $$n) (ref.func $$f)) + ) +)`); + +// ./test/core/br_on_null.wast:65 +assert_return(() => invoke($2, `args-null`, [3]), [value("i32", 3)]); + +// ./test/core/br_on_null.wast:66 +assert_return(() => invoke($2, `args-f`, [3]), [value("i32", 9)]); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/call_ref.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/call_ref.wast.js new file mode 100644 index 0000000000..4b430e1dae --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/call_ref.wast.js @@ -0,0 +1,275 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/call_ref.wast + +// ./test/core/call_ref.wast:1 +let $0 = instantiate(`(module + (type $$ii (func (param i32) (result i32))) + + (func $$apply (param $$f (ref $$ii)) (param $$x i32) (result i32) + (call_ref $$ii (local.get $$x) (local.get $$f)) + ) + + (func $$f (type $$ii) (i32.mul (local.get 0) (local.get 0))) + (func $$g (type $$ii) (i32.sub (i32.const 0) (local.get 0))) + + (elem declare func $$f $$g) + + (func (export "run") (param $$x i32) (result i32) + (local $$rf (ref null $$ii)) + (local $$rg (ref null $$ii)) + (local.set $$rf (ref.func $$f)) + (local.set $$rg (ref.func $$g)) + (call_ref $$ii (call_ref $$ii (local.get $$x) (local.get $$rf)) (local.get $$rg)) + ) + + (func (export "null") (result i32) + (call_ref $$ii (i32.const 1) (ref.null $$ii)) + ) + + ;; Recursion + + (type $$ll (func (param i64) (result i64))) + (type $$lll (func (param i64 i64) (result i64))) + + (elem declare func $$fac) + (global $$fac (ref $$ll) (ref.func $$fac)) + + (func $$fac (export "fac") (type $$ll) + (if (result i64) (i64.eqz (local.get 0)) + (then (i64.const 1)) + (else + (i64.mul + (local.get 0) + (call_ref $$ll (i64.sub (local.get 0) (i64.const 1)) (global.get $$fac)) + ) + ) + ) + ) + + (elem declare func $$fac-acc) + (global $$fac-acc (ref $$lll) (ref.func $$fac-acc)) + + (func $$fac-acc (export "fac-acc") (type $$lll) + (if (result i64) (i64.eqz (local.get 0)) + (then (local.get 1)) + (else + (call_ref $$lll + (i64.sub (local.get 0) (i64.const 1)) + (i64.mul (local.get 0) (local.get 1)) + (global.get $$fac-acc) + ) + ) + ) + ) + + (elem declare func $$fib) + (global $$fib (ref $$ll) (ref.func $$fib)) + + (func $$fib (export "fib") (type $$ll) + (if (result i64) (i64.le_u (local.get 0) (i64.const 1)) + (then (i64.const 1)) + (else + (i64.add + (call_ref $$ll (i64.sub (local.get 0) (i64.const 2)) (global.get $$fib)) + (call_ref $$ll (i64.sub (local.get 0) (i64.const 1)) (global.get $$fib)) + ) + ) + ) + ) + + (elem declare func $$even $$odd) + (global $$even (ref $$ll) (ref.func $$even)) + (global $$odd (ref $$ll) (ref.func $$odd)) + + (func $$even (export "even") (type $$ll) + (if (result i64) (i64.eqz (local.get 0)) + (then (i64.const 44)) + (else (call_ref $$ll (i64.sub (local.get 0) (i64.const 1)) (global.get $$odd))) + ) + ) + (func $$odd (export "odd") (type $$ll) + (if (result i64) (i64.eqz (local.get 0)) + (then (i64.const 99)) + (else (call_ref $$ll (i64.sub (local.get 0) (i64.const 1)) (global.get $$even))) + ) + ) +)`); + +// ./test/core/call_ref.wast:94 +assert_return(() => invoke($0, `run`, [0]), [value("i32", 0)]); + +// ./test/core/call_ref.wast:95 +assert_return(() => invoke($0, `run`, [3]), [value("i32", -9)]); + +// ./test/core/call_ref.wast:97 +assert_trap(() => invoke($0, `null`, []), `null function`); + +// ./test/core/call_ref.wast:99 +assert_return(() => invoke($0, `fac`, [0n]), [value("i64", 1n)]); + +// ./test/core/call_ref.wast:100 +assert_return(() => invoke($0, `fac`, [1n]), [value("i64", 1n)]); + +// ./test/core/call_ref.wast:101 +assert_return(() => invoke($0, `fac`, [5n]), [value("i64", 120n)]); + +// ./test/core/call_ref.wast:102 +assert_return(() => invoke($0, `fac`, [25n]), [value("i64", 7034535277573963776n)]); + +// ./test/core/call_ref.wast:103 +assert_return(() => invoke($0, `fac-acc`, [0n, 1n]), [value("i64", 1n)]); + +// ./test/core/call_ref.wast:104 +assert_return(() => invoke($0, `fac-acc`, [1n, 1n]), [value("i64", 1n)]); + +// ./test/core/call_ref.wast:105 +assert_return(() => invoke($0, `fac-acc`, [5n, 1n]), [value("i64", 120n)]); + +// ./test/core/call_ref.wast:106 +assert_return(() => invoke($0, `fac-acc`, [25n, 1n]), [value("i64", 7034535277573963776n)]); + +// ./test/core/call_ref.wast:111 +assert_return(() => invoke($0, `fib`, [0n]), [value("i64", 1n)]); + +// ./test/core/call_ref.wast:112 +assert_return(() => invoke($0, `fib`, [1n]), [value("i64", 1n)]); + +// ./test/core/call_ref.wast:113 +assert_return(() => invoke($0, `fib`, [2n]), [value("i64", 2n)]); + +// ./test/core/call_ref.wast:114 +assert_return(() => invoke($0, `fib`, [5n]), [value("i64", 8n)]); + +// ./test/core/call_ref.wast:115 +assert_return(() => invoke($0, `fib`, [20n]), [value("i64", 10946n)]); + +// ./test/core/call_ref.wast:117 +assert_return(() => invoke($0, `even`, [0n]), [value("i64", 44n)]); + +// ./test/core/call_ref.wast:118 +assert_return(() => invoke($0, `even`, [1n]), [value("i64", 99n)]); + +// ./test/core/call_ref.wast:119 +assert_return(() => invoke($0, `even`, [100n]), [value("i64", 44n)]); + +// ./test/core/call_ref.wast:120 +assert_return(() => invoke($0, `even`, [77n]), [value("i64", 99n)]); + +// ./test/core/call_ref.wast:121 +assert_return(() => invoke($0, `odd`, [0n]), [value("i64", 99n)]); + +// ./test/core/call_ref.wast:122 +assert_return(() => invoke($0, `odd`, [1n]), [value("i64", 44n)]); + +// ./test/core/call_ref.wast:123 +assert_return(() => invoke($0, `odd`, [200n]), [value("i64", 99n)]); + +// ./test/core/call_ref.wast:124 +assert_return(() => invoke($0, `odd`, [77n]), [value("i64", 44n)]); + +// ./test/core/call_ref.wast:129 +let $1 = instantiate(`(module + (type $$t (func)) + (func (export "unreachable") (result i32) + (unreachable) + (call_ref $$t) + ) +)`); + +// ./test/core/call_ref.wast:136 +assert_trap(() => invoke($1, `unreachable`, []), `unreachable`); + +// ./test/core/call_ref.wast:138 +let $2 = instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (ref.func $$f) + (call_ref $$t) + ) +)`); + +// ./test/core/call_ref.wast:149 +assert_trap(() => invoke($2, `unreachable`, []), `unreachable`); + +// ./test/core/call_ref.wast:151 +let $3 = instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (i32.const 0) + (ref.func $$f) + (call_ref $$t) + (drop) + (i32.const 0) + ) +)`); + +// ./test/core/call_ref.wast:165 +assert_trap(() => invoke($3, `unreachable`, []), `unreachable`); + +// ./test/core/call_ref.wast:167 +assert_invalid( + () => instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (i64.const 0) + (ref.func $$f) + (call_ref $$t) + ) + )`), + `type mismatch`, +); + +// ./test/core/call_ref.wast:183 +assert_invalid( + () => instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (ref.func $$f) + (call_ref $$t) + (drop) + (i64.const 0) + ) + )`), + `type mismatch`, +); + +// ./test/core/call_ref.wast:200 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (func $$f (param $$r externref) + (call_ref $$t (local.get $$r)) + ) + )`), + `type mismatch`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/directives.txt b/js/src/jit-test/tests/wasm/spec/function-references/directives.txt new file mode 100644 index 0000000000..bb76560525 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-compiler=optimizing; test-also=--wasm-compiler=baseline; test-also=--wasm-test-serialization; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemorySupported(); local-include:harness/harness.js; --wasm-function-references; skip-if: !wasmFunctionReferencesEnabled() \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/function-references/func.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/func.wast.js new file mode 100644 index 0000000000..8521cbbd18 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/func.wast.js @@ -0,0 +1,1240 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/func.wast + +// ./test/core/func.wast:3 +let $0 = instantiate(`(module + ;; Auxiliary definition + (type $$sig (func)) + (func $$dummy) + + ;; Syntax + + (func) + (func (export "f")) + (func $$f) + (func $$h (export "g")) + + (func (local)) + (func (local) (local)) + (func (local i32)) + (func (local $$x i32)) + (func (local i32 f64 i64)) + (func (local i32) (local f64)) + (func (local i32 f32) (local $$x i64) (local) (local i32 f64)) + + (func (param)) + (func (param) (param)) + (func (param i32)) + (func (param $$x i32)) + (func (param i32 f64 i64)) + (func (param i32) (param f64)) + (func (param i32 f32) (param $$x i64) (param) (param i32 f64)) + + (func (result)) + (func (result) (result)) + (func (result i32) (unreachable)) + (func (result i32 f64 f32) (unreachable)) + (func (result i32) (result f64) (unreachable)) + (func (result i32 f32) (result i64) (result) (result i32 f64) (unreachable)) + + (type $$sig-1 (func)) + (type $$sig-2 (func (result i32))) + (type $$sig-3 (func (param $$x i32))) + (type $$sig-4 (func (param i32 f64 i32) (result i32))) + + (func (export "type-use-1") (type $$sig-1)) + (func (export "type-use-2") (type $$sig-2) (i32.const 0)) + (func (export "type-use-3") (type $$sig-3)) + (func (export "type-use-4") (type $$sig-4) (i32.const 0)) + (func (export "type-use-5") (type $$sig-2) (result i32) (i32.const 0)) + (func (export "type-use-6") (type $$sig-3) (param i32)) + (func (export "type-use-7") + (type $$sig-4) (param i32) (param f64 i32) (result i32) (i32.const 0) + ) + + (func (type $$sig)) + (func (type $$forward)) ;; forward reference + + (func $$complex + (param i32 f32) (param $$x i64) (param) (param i32) + (result) (result i32) (result) (result i64 i32) + (local f32) (local $$y i32) (local i64 i32) (local) (local f64 i32) + (unreachable) (unreachable) + ) + (func $$complex-sig + (type $$sig) + (local f32) (local $$y i32) (local i64 i32) (local) (local f64 i32) + (unreachable) (unreachable) + ) + + (type $$forward (func)) + + ;; Typing of locals + + (func (export "local-first-i32") (result i32) (local i32 i32) (local.get 0)) + (func (export "local-first-i64") (result i64) (local i64 i64) (local.get 0)) + (func (export "local-first-f32") (result f32) (local f32 f32) (local.get 0)) + (func (export "local-first-f64") (result f64) (local f64 f64) (local.get 0)) + (func (export "local-second-i32") (result i32) (local i32 i32) (local.get 1)) + (func (export "local-second-i64") (result i64) (local i64 i64) (local.get 1)) + (func (export "local-second-f32") (result f32) (local f32 f32) (local.get 1)) + (func (export "local-second-f64") (result f64) (local f64 f64) (local.get 1)) + (func (export "local-mixed") (result f64) + (local f32) (local $$x i32) (local i64 i32) (local) (local f64 i32) + (drop (f32.neg (local.get 0))) + (drop (i32.eqz (local.get 1))) + (drop (i64.eqz (local.get 2))) + (drop (i32.eqz (local.get 3))) + (drop (f64.neg (local.get 4))) + (drop (i32.eqz (local.get 5))) + (local.get 4) + ) + + ;; Typing of parameters + + (func (export "param-first-i32") (param i32 i32) (result i32) (local.get 0)) + (func (export "param-first-i64") (param i64 i64) (result i64) (local.get 0)) + (func (export "param-first-f32") (param f32 f32) (result f32) (local.get 0)) + (func (export "param-first-f64") (param f64 f64) (result f64) (local.get 0)) + (func (export "param-second-i32") (param i32 i32) (result i32) (local.get 1)) + (func (export "param-second-i64") (param i64 i64) (result i64) (local.get 1)) + (func (export "param-second-f32") (param f32 f32) (result f32) (local.get 1)) + (func (export "param-second-f64") (param f64 f64) (result f64) (local.get 1)) + (func (export "param-mixed") (param f32 i32) (param) (param $$x i64) (param i32 f64 i32) + (result f64) + (drop (f32.neg (local.get 0))) + (drop (i32.eqz (local.get 1))) + (drop (i64.eqz (local.get 2))) + (drop (i32.eqz (local.get 3))) + (drop (f64.neg (local.get 4))) + (drop (i32.eqz (local.get 5))) + (local.get 4) + ) + + ;; Typing of results + + (func (export "empty")) + (func (export "value-void") (call $$dummy)) + (func (export "value-i32") (result i32) (i32.const 77)) + (func (export "value-i64") (result i64) (i64.const 7777)) + (func (export "value-f32") (result f32) (f32.const 77.7)) + (func (export "value-f64") (result f64) (f64.const 77.77)) + (func (export "value-i32-f64") (result i32 f64) (i32.const 77) (f64.const 7)) + (func (export "value-i32-i32-i32") (result i32 i32 i32) + (i32.const 1) (i32.const 2) (i32.const 3) + ) + (func (export "value-block-void") (block (call $$dummy) (call $$dummy))) + (func (export "value-block-i32") (result i32) + (block (result i32) (call $$dummy) (i32.const 77)) + ) + (func (export "value-block-i32-i64") (result i32 i64) + (block (result i32 i64) (call $$dummy) (i32.const 1) (i64.const 2)) + ) + + (func (export "return-empty") (return)) + (func (export "return-i32") (result i32) (return (i32.const 78))) + (func (export "return-i64") (result i64) (return (i64.const 7878))) + (func (export "return-f32") (result f32) (return (f32.const 78.7))) + (func (export "return-f64") (result f64) (return (f64.const 78.78))) + (func (export "return-i32-f64") (result i32 f64) + (return (i32.const 78) (f64.const 78.78)) + ) + (func (export "return-i32-i32-i32") (result i32 i32 i32) + (return (i32.const 1) (i32.const 2) (i32.const 3)) + ) + (func (export "return-block-i32") (result i32) + (return (block (result i32) (call $$dummy) (i32.const 77))) + ) + (func (export "return-block-i32-i64") (result i32 i64) + (return (block (result i32 i64) (call $$dummy) (i32.const 1) (i64.const 2))) + ) + + (func (export "break-empty") (br 0)) + (func (export "break-i32") (result i32) (br 0 (i32.const 79))) + (func (export "break-i64") (result i64) (br 0 (i64.const 7979))) + (func (export "break-f32") (result f32) (br 0 (f32.const 79.9))) + (func (export "break-f64") (result f64) (br 0 (f64.const 79.79))) + (func (export "break-i32-f64") (result i32 f64) + (br 0 (i32.const 79) (f64.const 79.79)) + ) + (func (export "break-i32-i32-i32") (result i32 i32 i32) + (br 0 (i32.const 1) (i32.const 2) (i32.const 3)) + ) + (func (export "break-block-i32") (result i32) + (br 0 (block (result i32) (call $$dummy) (i32.const 77))) + ) + (func (export "break-block-i32-i64") (result i32 i64) + (br 0 (block (result i32 i64) (call $$dummy) (i32.const 1) (i64.const 2))) + ) + + (func (export "break-br_if-empty") (param i32) + (br_if 0 (local.get 0)) + ) + (func (export "break-br_if-num") (param i32) (result i32) + (drop (br_if 0 (i32.const 50) (local.get 0))) (i32.const 51) + ) + (func (export "break-br_if-num-num") (param i32) (result i32 i64) + (drop (drop (br_if 0 (i32.const 50) (i64.const 51) (local.get 0)))) + (i32.const 51) (i64.const 52) + ) + + (func (export "break-br_table-empty") (param i32) + (br_table 0 0 0 (local.get 0)) + ) + (func (export "break-br_table-num") (param i32) (result i32) + (br_table 0 0 (i32.const 50) (local.get 0)) (i32.const 51) + ) + (func (export "break-br_table-num-num") (param i32) (result f32 i64) + (br_table 0 0 (f32.const 50) (i64.const 51) (local.get 0)) + (f32.const 51) (i64.const 52) + ) + (func (export "break-br_table-nested-empty") (param i32) + (block (br_table 0 1 0 (local.get 0))) + ) + (func (export "break-br_table-nested-num") (param i32) (result i32) + (i32.add + (block (result i32) + (br_table 0 1 0 (i32.const 50) (local.get 0)) (i32.const 51) + ) + (i32.const 2) + ) + ) + (func (export "break-br_table-nested-num-num") (param i32) (result i32 i32) + (i32.add + (block (result i32 i32) + (br_table 0 1 0 (i32.const 50) (i32.const 51) (local.get 0)) + (i32.const 51) (i32.const -3) + ) + ) + (i32.const 52) + ) + + ;; Large signatures + + (func (export "large-sig") + (param i32 i64 f32 f32 i32 f64 f32 i32 i32 i32 f32 f64 f64 f64 i32 i32 f32) + (result f64 f32 i32 i32 i32 i64 f32 i32 i32 f32 f64 f64 i32 f32 i32 f64) + (local.get 5) + (local.get 2) + (local.get 0) + (local.get 8) + (local.get 7) + (local.get 1) + (local.get 3) + (local.get 9) + (local.get 4) + (local.get 6) + (local.get 13) + (local.get 11) + (local.get 15) + (local.get 16) + (local.get 14) + (local.get 12) + ) + + ;; Default initialization of locals + + (func (export "init-local-i32") (result i32) (local i32) (local.get 0)) + (func (export "init-local-i64") (result i64) (local i64) (local.get 0)) + (func (export "init-local-f32") (result f32) (local f32) (local.get 0)) + (func (export "init-local-f64") (result f64) (local f64) (local.get 0)) +)`); + +// ./test/core/func.wast:241 +assert_return(() => invoke($0, `type-use-1`, []), []); + +// ./test/core/func.wast:242 +assert_return(() => invoke($0, `type-use-2`, []), [value("i32", 0)]); + +// ./test/core/func.wast:243 +assert_return(() => invoke($0, `type-use-3`, [1]), []); + +// ./test/core/func.wast:244 +assert_return(() => invoke($0, `type-use-4`, [1, value("f64", 1), 1]), [value("i32", 0)]); + +// ./test/core/func.wast:248 +assert_return(() => invoke($0, `type-use-5`, []), [value("i32", 0)]); + +// ./test/core/func.wast:249 +assert_return(() => invoke($0, `type-use-6`, [1]), []); + +// ./test/core/func.wast:250 +assert_return(() => invoke($0, `type-use-7`, [1, value("f64", 1), 1]), [value("i32", 0)]); + +// ./test/core/func.wast:255 +assert_return(() => invoke($0, `local-first-i32`, []), [value("i32", 0)]); + +// ./test/core/func.wast:256 +assert_return(() => invoke($0, `local-first-i64`, []), [value("i64", 0n)]); + +// ./test/core/func.wast:257 +assert_return(() => invoke($0, `local-first-f32`, []), [value("f32", 0)]); + +// ./test/core/func.wast:258 +assert_return(() => invoke($0, `local-first-f64`, []), [value("f64", 0)]); + +// ./test/core/func.wast:259 +assert_return(() => invoke($0, `local-second-i32`, []), [value("i32", 0)]); + +// ./test/core/func.wast:260 +assert_return(() => invoke($0, `local-second-i64`, []), [value("i64", 0n)]); + +// ./test/core/func.wast:261 +assert_return(() => invoke($0, `local-second-f32`, []), [value("f32", 0)]); + +// ./test/core/func.wast:262 +assert_return(() => invoke($0, `local-second-f64`, []), [value("f64", 0)]); + +// ./test/core/func.wast:263 +assert_return(() => invoke($0, `local-mixed`, []), [value("f64", 0)]); + +// ./test/core/func.wast:265 +assert_return(() => invoke($0, `param-first-i32`, [2, 3]), [value("i32", 2)]); + +// ./test/core/func.wast:268 +assert_return(() => invoke($0, `param-first-i64`, [2n, 3n]), [value("i64", 2n)]); + +// ./test/core/func.wast:271 +assert_return( + () => invoke($0, `param-first-f32`, [value("f32", 2), value("f32", 3)]), + [value("f32", 2)], +); + +// ./test/core/func.wast:274 +assert_return( + () => invoke($0, `param-first-f64`, [value("f64", 2), value("f64", 3)]), + [value("f64", 2)], +); + +// ./test/core/func.wast:277 +assert_return(() => invoke($0, `param-second-i32`, [2, 3]), [value("i32", 3)]); + +// ./test/core/func.wast:280 +assert_return(() => invoke($0, `param-second-i64`, [2n, 3n]), [value("i64", 3n)]); + +// ./test/core/func.wast:283 +assert_return( + () => invoke($0, `param-second-f32`, [value("f32", 2), value("f32", 3)]), + [value("f32", 3)], +); + +// ./test/core/func.wast:286 +assert_return( + () => invoke($0, `param-second-f64`, [value("f64", 2), value("f64", 3)]), + [value("f64", 3)], +); + +// ./test/core/func.wast:290 +assert_return( + () => invoke($0, `param-mixed`, [value("f32", 1), 2, 3n, 4, value("f64", 5.5), 6]), + [value("f64", 5.5)], +); + +// ./test/core/func.wast:298 +assert_return(() => invoke($0, `empty`, []), []); + +// ./test/core/func.wast:299 +assert_return(() => invoke($0, `value-void`, []), []); + +// ./test/core/func.wast:300 +assert_return(() => invoke($0, `value-i32`, []), [value("i32", 77)]); + +// ./test/core/func.wast:301 +assert_return(() => invoke($0, `value-i64`, []), [value("i64", 7777n)]); + +// ./test/core/func.wast:302 +assert_return(() => invoke($0, `value-f32`, []), [value("f32", 77.7)]); + +// ./test/core/func.wast:303 +assert_return(() => invoke($0, `value-f64`, []), [value("f64", 77.77)]); + +// ./test/core/func.wast:304 +assert_return(() => invoke($0, `value-i32-f64`, []), [value("i32", 77), value("f64", 7)]); + +// ./test/core/func.wast:305 +assert_return( + () => invoke($0, `value-i32-i32-i32`, []), + [value("i32", 1), value("i32", 2), value("i32", 3)], +); + +// ./test/core/func.wast:308 +assert_return(() => invoke($0, `value-block-void`, []), []); + +// ./test/core/func.wast:309 +assert_return(() => invoke($0, `value-block-i32`, []), [value("i32", 77)]); + +// ./test/core/func.wast:310 +assert_return(() => invoke($0, `value-block-i32-i64`, []), [value("i32", 1), value("i64", 2n)]); + +// ./test/core/func.wast:312 +assert_return(() => invoke($0, `return-empty`, []), []); + +// ./test/core/func.wast:313 +assert_return(() => invoke($0, `return-i32`, []), [value("i32", 78)]); + +// ./test/core/func.wast:314 +assert_return(() => invoke($0, `return-i64`, []), [value("i64", 7878n)]); + +// ./test/core/func.wast:315 +assert_return(() => invoke($0, `return-f32`, []), [value("f32", 78.7)]); + +// ./test/core/func.wast:316 +assert_return(() => invoke($0, `return-f64`, []), [value("f64", 78.78)]); + +// ./test/core/func.wast:317 +assert_return(() => invoke($0, `return-i32-f64`, []), [value("i32", 78), value("f64", 78.78)]); + +// ./test/core/func.wast:318 +assert_return( + () => invoke($0, `return-i32-i32-i32`, []), + [value("i32", 1), value("i32", 2), value("i32", 3)], +); + +// ./test/core/func.wast:321 +assert_return(() => invoke($0, `return-block-i32`, []), [value("i32", 77)]); + +// ./test/core/func.wast:322 +assert_return(() => invoke($0, `return-block-i32-i64`, []), [value("i32", 1), value("i64", 2n)]); + +// ./test/core/func.wast:324 +assert_return(() => invoke($0, `break-empty`, []), []); + +// ./test/core/func.wast:325 +assert_return(() => invoke($0, `break-i32`, []), [value("i32", 79)]); + +// ./test/core/func.wast:326 +assert_return(() => invoke($0, `break-i64`, []), [value("i64", 7979n)]); + +// ./test/core/func.wast:327 +assert_return(() => invoke($0, `break-f32`, []), [value("f32", 79.9)]); + +// ./test/core/func.wast:328 +assert_return(() => invoke($0, `break-f64`, []), [value("f64", 79.79)]); + +// ./test/core/func.wast:329 +assert_return(() => invoke($0, `break-i32-f64`, []), [value("i32", 79), value("f64", 79.79)]); + +// ./test/core/func.wast:330 +assert_return( + () => invoke($0, `break-i32-i32-i32`, []), + [value("i32", 1), value("i32", 2), value("i32", 3)], +); + +// ./test/core/func.wast:333 +assert_return(() => invoke($0, `break-block-i32`, []), [value("i32", 77)]); + +// ./test/core/func.wast:334 +assert_return(() => invoke($0, `break-block-i32-i64`, []), [value("i32", 1), value("i64", 2n)]); + +// ./test/core/func.wast:336 +assert_return(() => invoke($0, `break-br_if-empty`, [0]), []); + +// ./test/core/func.wast:337 +assert_return(() => invoke($0, `break-br_if-empty`, [2]), []); + +// ./test/core/func.wast:338 +assert_return(() => invoke($0, `break-br_if-num`, [0]), [value("i32", 51)]); + +// ./test/core/func.wast:339 +assert_return(() => invoke($0, `break-br_if-num`, [1]), [value("i32", 50)]); + +// ./test/core/func.wast:340 +assert_return(() => invoke($0, `break-br_if-num-num`, [0]), [value("i32", 51), value("i64", 52n)]); + +// ./test/core/func.wast:343 +assert_return(() => invoke($0, `break-br_if-num-num`, [1]), [value("i32", 50), value("i64", 51n)]); + +// ./test/core/func.wast:347 +assert_return(() => invoke($0, `break-br_table-empty`, [0]), []); + +// ./test/core/func.wast:348 +assert_return(() => invoke($0, `break-br_table-empty`, [1]), []); + +// ./test/core/func.wast:349 +assert_return(() => invoke($0, `break-br_table-empty`, [5]), []); + +// ./test/core/func.wast:350 +assert_return(() => invoke($0, `break-br_table-empty`, [-1]), []); + +// ./test/core/func.wast:351 +assert_return(() => invoke($0, `break-br_table-num`, [0]), [value("i32", 50)]); + +// ./test/core/func.wast:352 +assert_return(() => invoke($0, `break-br_table-num`, [1]), [value("i32", 50)]); + +// ./test/core/func.wast:353 +assert_return(() => invoke($0, `break-br_table-num`, [10]), [value("i32", 50)]); + +// ./test/core/func.wast:354 +assert_return(() => invoke($0, `break-br_table-num`, [-100]), [value("i32", 50)]); + +// ./test/core/func.wast:355 +assert_return(() => invoke($0, `break-br_table-num-num`, [0]), [value("f32", 50), value("i64", 51n)]); + +// ./test/core/func.wast:358 +assert_return(() => invoke($0, `break-br_table-num-num`, [1]), [value("f32", 50), value("i64", 51n)]); + +// ./test/core/func.wast:361 +assert_return(() => invoke($0, `break-br_table-num-num`, [10]), [value("f32", 50), value("i64", 51n)]); + +// ./test/core/func.wast:364 +assert_return(() => invoke($0, `break-br_table-num-num`, [-100]), [value("f32", 50), value("i64", 51n)]); + +// ./test/core/func.wast:367 +assert_return(() => invoke($0, `break-br_table-nested-empty`, [0]), []); + +// ./test/core/func.wast:368 +assert_return(() => invoke($0, `break-br_table-nested-empty`, [1]), []); + +// ./test/core/func.wast:369 +assert_return(() => invoke($0, `break-br_table-nested-empty`, [3]), []); + +// ./test/core/func.wast:370 +assert_return(() => invoke($0, `break-br_table-nested-empty`, [-2]), []); + +// ./test/core/func.wast:371 +assert_return(() => invoke($0, `break-br_table-nested-num`, [0]), [value("i32", 52)]); + +// ./test/core/func.wast:374 +assert_return(() => invoke($0, `break-br_table-nested-num`, [1]), [value("i32", 50)]); + +// ./test/core/func.wast:377 +assert_return(() => invoke($0, `break-br_table-nested-num`, [2]), [value("i32", 52)]); + +// ./test/core/func.wast:380 +assert_return(() => invoke($0, `break-br_table-nested-num`, [-3]), [value("i32", 52)]); + +// ./test/core/func.wast:383 +assert_return( + () => invoke($0, `break-br_table-nested-num-num`, [0]), + [value("i32", 101), value("i32", 52)], +); + +// ./test/core/func.wast:387 +assert_return( + () => invoke($0, `break-br_table-nested-num-num`, [1]), + [value("i32", 50), value("i32", 51)], +); + +// ./test/core/func.wast:391 +assert_return( + () => invoke($0, `break-br_table-nested-num-num`, [2]), + [value("i32", 101), value("i32", 52)], +); + +// ./test/core/func.wast:395 +assert_return( + () => invoke($0, `break-br_table-nested-num-num`, [-3]), + [value("i32", 101), value("i32", 52)], +); + +// ./test/core/func.wast:400 +assert_return( + () => invoke($0, `large-sig`, [ + 0, + 1n, + value("f32", 2), + value("f32", 3), + 4, + value("f64", 5), + value("f32", 6), + 7, + 8, + 9, + value("f32", 10), + value("f64", 11), + value("f64", 12), + value("f64", 13), + 14, + 15, + value("f32", 16), + ]), + [ + value("f64", 5), + value("f32", 2), + value("i32", 0), + value("i32", 8), + value("i32", 7), + value("i64", 1n), + value("f32", 3), + value("i32", 9), + value("i32", 4), + value("f32", 6), + value("f64", 13), + value("f64", 11), + value("i32", 15), + value("f32", 16), + value("i32", 14), + value("f64", 12), + ], +); + +// ./test/core/func.wast:414 +assert_return(() => invoke($0, `init-local-i32`, []), [value("i32", 0)]); + +// ./test/core/func.wast:415 +assert_return(() => invoke($0, `init-local-i64`, []), [value("i64", 0n)]); + +// ./test/core/func.wast:416 +assert_return(() => invoke($0, `init-local-f32`, []), [value("f32", 0)]); + +// ./test/core/func.wast:417 +assert_return(() => invoke($0, `init-local-f64`, []), [value("f64", 0)]); + +// ./test/core/func.wast:422 +let $1 = instantiate(`(module + (func $$f (result f64) (f64.const 0)) ;; adds implicit type definition + (func $$g (param i32)) ;; reuses explicit type definition + (type $$t (func (param i32))) + + (func $$i32->void (type 0)) ;; (param i32) + (func $$void->f64 (type 1) (f64.const 0)) ;; (result f64) + (func $$check + (call $$i32->void (i32.const 0)) + (drop (call $$void->f64)) + ) +)`); + +// ./test/core/func.wast:435 +assert_invalid( + () => instantiate(`(module + (func $$f (result f64) (f64.const 0)) ;; adds implicit type definition + (func $$g (param i32)) ;; reuses explicit type definition + (func $$h (result f64) (f64.const 1)) ;; reuses implicit type definition + (type $$t (func (param i32))) + + (func (type 2)) ;; does not exist + )`), + `unknown type`, +); + +// ./test/core/func.wast:447 +assert_malformed( + () => instantiate(`(func $$f (result f64) (f64.const 0)) (func $$g (param i32)) (func $$h (result f64) (f64.const 1)) (type $$t (func (param i32))) (func (type 2) (param i32)) `), + `unknown type`, +); + +// ./test/core/func.wast:459 +let $2 = instantiate(`(module + (type $$proc (func (result i32))) + (type $$sig (func (param i32) (result i32))) + + (func (export "f") (type $$sig) + (local $$var i32) + (local.get $$var) + ) + + (func $$g (type $$sig) + (local $$var i32) + (local.get $$var) + ) + (func (export "g") (type $$sig) + (call $$g (local.get 0)) + ) + + (func (export "p") (type $$proc) + (local $$var i32) + (local.set 0 (i32.const 42)) + (local.get $$var) + ) +)`); + +// ./test/core/func.wast:483 +assert_return(() => invoke($2, `f`, [42]), [value("i32", 0)]); + +// ./test/core/func.wast:484 +assert_return(() => invoke($2, `g`, [42]), [value("i32", 0)]); + +// ./test/core/func.wast:485 +assert_return(() => invoke($2, `p`, []), [value("i32", 42)]); + +// ./test/core/func.wast:488 +let $3 = instantiate(`(module + (type $$sig (func)) + + (func $$empty-sig-1) ;; should be assigned type $$sig + (func $$complex-sig-1 (param f64 i64 f64 i64 f64 i64 f32 i32)) + (func $$empty-sig-2) ;; should be assigned type $$sig + (func $$complex-sig-2 (param f64 i64 f64 i64 f64 i64 f32 i32)) + (func $$complex-sig-3 (param f64 i64 f64 i64 f64 i64 f32 i32)) + (func $$complex-sig-4 (param i64 i64 f64 i64 f64 i64 f32 i32)) + (func $$complex-sig-5 (param i64 i64 f64 i64 f64 i64 f32 i32)) + + (type $$empty-sig-duplicate (func)) + (type $$complex-sig-duplicate (func (param i64 i64 f64 i64 f64 i64 f32 i32))) + (table funcref + (elem + $$complex-sig-3 $$empty-sig-2 $$complex-sig-1 $$complex-sig-3 $$empty-sig-1 + $$complex-sig-4 $$complex-sig-5 + ) + ) + + (func (export "signature-explicit-reused") + (call_indirect (type $$sig) (i32.const 1)) + (call_indirect (type $$sig) (i32.const 4)) + ) + + (func (export "signature-implicit-reused") + ;; The implicit index 3 in this test depends on the function and + ;; type definitions, and may need adapting if they change. + (call_indirect (type 3) + (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) + (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) + (i32.const 0) + ) + (call_indirect (type 3) + (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) + (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) + (i32.const 2) + ) + (call_indirect (type 3) + (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) + (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) + (i32.const 3) + ) + ) + + (func (export "signature-explicit-duplicate") + (call_indirect (type $$empty-sig-duplicate) (i32.const 1)) + ) + + (func (export "signature-implicit-duplicate") + (call_indirect (type $$complex-sig-duplicate) + (i64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) + (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) + (i32.const 5) + ) + (call_indirect (type $$complex-sig-duplicate) + (i64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) + (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) + (i32.const 6) + ) + ) +)`); + +// ./test/core/func.wast:551 +assert_return(() => invoke($3, `signature-explicit-reused`, []), []); + +// ./test/core/func.wast:552 +assert_return(() => invoke($3, `signature-implicit-reused`, []), []); + +// ./test/core/func.wast:553 +assert_return(() => invoke($3, `signature-explicit-duplicate`, []), []); + +// ./test/core/func.wast:554 +assert_return(() => invoke($3, `signature-implicit-duplicate`, []), []); + +// ./test/core/func.wast:559 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (type $$sig) (result i32) (param i32) (i32.const 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:566 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (param i32) (type $$sig) (result i32) (i32.const 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:573 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (param i32) (result i32) (type $$sig) (i32.const 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:580 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (result i32) (type $$sig) (param i32) (i32.const 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:587 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (result i32) (param i32) (type $$sig) (i32.const 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:594 +assert_malformed( + () => instantiate(`(func (result i32) (param i32) (i32.const 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:601 +assert_malformed( + () => instantiate(`(type $$sig (func)) (func (type $$sig) (result i32) (i32.const 0)) `), + `inline function type`, +); + +// ./test/core/func.wast:608 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (type $$sig) (result i32) (i32.const 0)) `), + `inline function type`, +); + +// ./test/core/func.wast:615 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (type $$sig) (param i32) (i32.const 0)) `), + `inline function type`, +); + +// ./test/core/func.wast:622 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32 i32) (result i32))) (func (type $$sig) (param i32) (result i32) (unreachable)) `), + `inline function type`, +); + +// ./test/core/func.wast:630 +assert_invalid(() => instantiate(`(module (func $$g (type 4)))`), `unknown type`); + +// ./test/core/func.wast:634 +assert_invalid( + () => instantiate(`(module + (func $$f (drop (ref.func $$g))) + (func $$g (type 4)) + (elem declare func $$g) + )`), + `unknown type`, +); + +// ./test/core/func.wast:646 +assert_invalid( + () => instantiate(`(module (func $$type-local-num-vs-num (result i64) (local i32) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/func.wast:650 +assert_invalid( + () => instantiate(`(module (func $$type-local-num-vs-num (local f32) (i32.eqz (local.get 0))))`), + `type mismatch`, +); + +// ./test/core/func.wast:654 +assert_invalid( + () => instantiate(`(module (func $$type-local-num-vs-num (local f64 i64) (f64.neg (local.get 1))))`), + `type mismatch`, +); + +// ./test/core/func.wast:659 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (func $$type-local-uninitialized (local $$x (ref $$t)) (drop (local.get $$x))) + )`), + `uninitialized local`, +); + +// ./test/core/func.wast:670 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num (param i32) (result i64) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/func.wast:674 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num (param f32) (i32.eqz (local.get 0))))`), + `type mismatch`, +); + +// ./test/core/func.wast:678 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num (param f64 i64) (f64.neg (local.get 1))))`), + `type mismatch`, +); + +// ./test/core/func.wast:686 +assert_invalid( + () => instantiate(`(module (func $$type-empty-i32 (result i32)))`), + `type mismatch`, +); + +// ./test/core/func.wast:690 +assert_invalid( + () => instantiate(`(module (func $$type-empty-i64 (result i64)))`), + `type mismatch`, +); + +// ./test/core/func.wast:694 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f32 (result f32)))`), + `type mismatch`, +); + +// ./test/core/func.wast:698 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f64 (result f64)))`), + `type mismatch`, +); + +// ./test/core/func.wast:702 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f64-i32 (result f64 i32)))`), + `type mismatch`, +); + +// ./test/core/func.wast:707 +assert_invalid( + () => instantiate(`(module (func $$type-value-void-vs-num (result i32) + (nop) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:713 +assert_invalid( + () => instantiate(`(module (func $$type-value-void-vs-nums (result i32 i32) + (nop) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:719 +assert_invalid( + () => instantiate(`(module (func $$type-value-num-vs-void + (i32.const 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:725 +assert_invalid( + () => instantiate(`(module (func $$type-value-nums-vs-void + (i32.const 0) (i64.const 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:731 +assert_invalid( + () => instantiate(`(module (func $$type-value-num-vs-num (result i32) + (f32.const 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:737 +assert_invalid( + () => instantiate(`(module (func $$type-value-num-vs-nums (result f32 f32) + (f32.const 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:743 +assert_invalid( + () => instantiate(`(module (func $$type-value-nums-vs-num (result f32) + (f32.const 0) (f32.const 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:750 +assert_invalid( + () => instantiate(`(module (func $$type-return-last-empty-vs-num (result i32) + (return) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:756 +assert_invalid( + () => instantiate(`(module (func $$type-return-last-empty-vs-nums (result i32 i32) + (return) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:762 +assert_invalid( + () => instantiate(`(module (func $$type-return-last-void-vs-num (result i32) + (return (nop)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:768 +assert_invalid( + () => instantiate(`(module (func $$type-return-last-void-vs-nums (result i32 i64) + (return (nop)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:774 +assert_invalid( + () => instantiate(`(module (func $$type-return-last-num-vs-num (result i32) + (return (i64.const 0)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:780 +assert_invalid( + () => instantiate(`(module (func $$type-return-last-num-vs-nums (result i64 i64) + (return (i64.const 0)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:787 +assert_invalid( + () => instantiate(`(module (func $$type-return-empty-vs-num (result i32) + (return) (i32.const 1) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:793 +assert_invalid( + () => instantiate(`(module (func $$type-return-empty-vs-nums (result i32 i32) + (return) (i32.const 1) (i32.const 2) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:799 +assert_invalid( + () => instantiate(`(module (func $$type-return-partial-vs-nums (result i32 i32) + (i32.const 1) (return) (i32.const 2) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:805 +assert_invalid( + () => instantiate(`(module (func $$type-return-void-vs-num (result i32) + (return (nop)) (i32.const 1) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:811 +assert_invalid( + () => instantiate(`(module (func $$type-return-void-vs-nums (result i32 i32) + (return (nop)) (i32.const 1) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:817 +assert_invalid( + () => instantiate(`(module (func $$type-return-num-vs-num (result i32) + (return (i64.const 1)) (i32.const 1) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:823 +assert_invalid( + () => instantiate(`(module (func $$type-return-num-vs-nums (result i32 i32) + (return (i64.const 1)) (i32.const 1) (i32.const 2) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:829 +assert_invalid( + () => instantiate(`(module (func $$type-return-first-num-vs-num (result i32) + (return (i64.const 1)) (return (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:835 +assert_invalid( + () => instantiate(`(module (func $$type-return-first-num-vs-nums (result i32 i32) + (return (i32.const 1)) (return (i32.const 1) (i32.const 2)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:842 +assert_invalid( + () => instantiate(`(module (func $$type-break-last-void-vs-num (result i32) + (br 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:848 +assert_invalid( + () => instantiate(`(module (func $$type-break-last-void-vs-nums (result i32 i32) + (br 0) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:854 +assert_invalid( + () => instantiate(`(module (func $$type-break-last-num-vs-num (result i32) + (br 0 (f32.const 0)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:860 +assert_invalid( + () => instantiate(`(module (func $$type-break-last-num-vs-nums (result i32 i32) + (br 0 (i32.const 0)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:866 +assert_invalid( + () => instantiate(`(module (func $$type-break-void-vs-num (result i32) + (br 0) (i32.const 1) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:872 +assert_invalid( + () => instantiate(`(module (func $$type-break-void-vs-nums (result i32 i32) + (br 0) (i32.const 1) (i32.const 2) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:878 +assert_invalid( + () => instantiate(`(module (func $$type-break-num-vs-num (result i32) + (br 0 (i64.const 1)) (i32.const 1) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:884 +assert_invalid( + () => instantiate(`(module (func $$type-break-num-vs-nums (result i32 i32) + (br 0 (i32.const 1)) (i32.const 1) (i32.const 2) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:890 +assert_invalid( + () => instantiate(`(module (func $$type-break-first-num-vs-num (result i32) + (br 0 (i64.const 1)) (br 0 (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:897 +assert_invalid( + () => instantiate(`(module (func $$type-break-nested-empty-vs-num (result i32) + (block (br 1)) (br 0 (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:903 +assert_invalid( + () => instantiate(`(module (func $$type-break-nested-empty-vs-nums (result i32 i32) + (block (br 1)) (br 0 (i32.const 1) (i32.const 2)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:909 +assert_invalid( + () => instantiate(`(module (func $$type-break-nested-void-vs-num (result i32) + (block (br 1 (nop))) (br 0 (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:915 +assert_invalid( + () => instantiate(`(module (func $$type-break-nested-void-vs-nums (result i32 i32) + (block (br 1 (nop))) (br 0 (i32.const 1) (i32.const 2)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:921 +assert_invalid( + () => instantiate(`(module (func $$type-break-nested-num-vs-num (result i32) + (block (br 1 (i64.const 1))) (br 0 (i32.const 1)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:927 +assert_invalid( + () => instantiate(`(module (func $$type-break-nested-num-vs-nums (result i32 i32) + (block (result i32) (br 1 (i32.const 1))) (br 0 (i32.const 1) (i32.const 2)) + ))`), + `type mismatch`, +); + +// ./test/core/func.wast:937 +assert_malformed(() => instantiate(`(func (nop) (local i32)) `), `unexpected token`); + +// ./test/core/func.wast:941 +assert_malformed(() => instantiate(`(func (nop) (param i32)) `), `unexpected token`); + +// ./test/core/func.wast:945 +assert_malformed(() => instantiate(`(func (nop) (result i32)) `), `unexpected token`); + +// ./test/core/func.wast:949 +assert_malformed(() => instantiate(`(func (local i32) (param i32)) `), `unexpected token`); + +// ./test/core/func.wast:953 +assert_malformed( + () => instantiate(`(func (local i32) (result i32) (local.get 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:957 +assert_malformed( + () => instantiate(`(func (result i32) (param i32) (local.get 0)) `), + `unexpected token`, +); + +// ./test/core/func.wast:964 +assert_malformed(() => instantiate(`(func $$foo) (func $$foo) `), `duplicate func`); + +// ./test/core/func.wast:968 +assert_malformed( + () => instantiate(`(import "" "" (func $$foo)) (func $$foo) `), + `duplicate func`, +); + +// ./test/core/func.wast:972 +assert_malformed( + () => instantiate(`(import "" "" (func $$foo)) (import "" "" (func $$foo)) `), + `duplicate func`, +); + +// ./test/core/func.wast:977 +assert_malformed( + () => instantiate(`(func (param $$foo i32) (param $$foo i32)) `), + `duplicate local`, +); + +// ./test/core/func.wast:981 +assert_malformed( + () => instantiate(`(func (param $$foo i32) (local $$foo i32)) `), + `duplicate local`, +); + +// ./test/core/func.wast:985 +assert_malformed( + () => instantiate(`(func (local $$foo i32) (local $$foo i32)) `), + `duplicate local`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/global.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/global.wast.js new file mode 100644 index 0000000000..de27027554 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/global.wast.js @@ -0,0 +1,796 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/global.wast + +// ./test/core/global.wast:3 +let $0 = instantiate(`(module + (global (import "spectest" "global_i32") i32) + (global (import "spectest" "global_i64") i64) + + (global $$a i32 (i32.const -2)) + (global (;3;) f32 (f32.const -3)) + (global (;4;) f64 (f64.const -4)) + (global $$b i64 (i64.const -5)) + + (global $$x (mut i32) (i32.const -12)) + (global (;7;) (mut f32) (f32.const -13)) + (global (;8;) (mut f64) (f64.const -14)) + (global $$y (mut i64) (i64.const -15)) + + (global $$z1 i32 (global.get 0)) + (global $$z2 i64 (global.get 1)) + + (global $$r externref (ref.null extern)) + (global $$mr (mut externref) (ref.null extern)) + (global funcref (ref.null func)) + + (func (export "get-a") (result i32) (global.get $$a)) + (func (export "get-b") (result i64) (global.get $$b)) + (func (export "get-r") (result externref) (global.get $$r)) + (func (export "get-mr") (result externref) (global.get $$mr)) + (func (export "get-x") (result i32) (global.get $$x)) + (func (export "get-y") (result i64) (global.get $$y)) + (func (export "get-z1") (result i32) (global.get $$z1)) + (func (export "get-z2") (result i64) (global.get $$z2)) + (func (export "set-x") (param i32) (global.set $$x (local.get 0))) + (func (export "set-y") (param i64) (global.set $$y (local.get 0))) + (func (export "set-mr") (param externref) (global.set $$mr (local.get 0))) + + (func (export "get-3") (result f32) (global.get 3)) + (func (export "get-4") (result f64) (global.get 4)) + (func (export "get-7") (result f32) (global.get 7)) + (func (export "get-8") (result f64) (global.get 8)) + (func (export "set-7") (param f32) (global.set 7 (local.get 0))) + (func (export "set-8") (param f64) (global.set 8 (local.get 0))) + + ;; As the argument of control constructs and instructions + + (memory 1) + + (func $$dummy) + + (func (export "as-select-first") (result i32) + (select (global.get $$x) (i32.const 2) (i32.const 3)) + ) + (func (export "as-select-mid") (result i32) + (select (i32.const 2) (global.get $$x) (i32.const 3)) + ) + (func (export "as-select-last") (result i32) + (select (i32.const 2) (i32.const 3) (global.get $$x)) + ) + + (func (export "as-loop-first") (result i32) + (loop (result i32) + (global.get $$x) (call $$dummy) (call $$dummy) + ) + ) + (func (export "as-loop-mid") (result i32) + (loop (result i32) + (call $$dummy) (global.get $$x) (call $$dummy) + ) + ) + (func (export "as-loop-last") (result i32) + (loop (result i32) + (call $$dummy) (call $$dummy) (global.get $$x) + ) + ) + + (func (export "as-if-condition") (result i32) + (if (result i32) (global.get $$x) + (then (call $$dummy) (i32.const 2)) + (else (call $$dummy) (i32.const 3)) + ) + ) + (func (export "as-if-then") (result i32) + (if (result i32) (i32.const 1) + (then (global.get $$x)) (else (i32.const 2)) + ) + ) + (func (export "as-if-else") (result i32) + (if (result i32) (i32.const 0) + (then (i32.const 2)) (else (global.get $$x)) + ) + ) + + (func (export "as-br_if-first") (result i32) + (block (result i32) + (br_if 0 (global.get $$x) (i32.const 2)) + (return (i32.const 3)) + ) + ) + (func (export "as-br_if-last") (result i32) + (block (result i32) + (br_if 0 (i32.const 2) (global.get $$x)) + (return (i32.const 3)) + ) + ) + + (func (export "as-br_table-first") (result i32) + (block (result i32) + (global.get $$x) (i32.const 2) (br_table 0 0) + ) + ) + (func (export "as-br_table-last") (result i32) + (block (result i32) + (i32.const 2) (global.get $$x) (br_table 0 0) + ) + ) + + (func $$func (param i32 i32) (result i32) (local.get 0)) + (type $$check (func (param i32 i32) (result i32))) + (table funcref (elem $$func)) + (func (export "as-call_indirect-first") (result i32) + (block (result i32) + (call_indirect (type $$check) + (global.get $$x) (i32.const 2) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-mid") (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 2) (global.get $$x) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-last") (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 2) (i32.const 0) (global.get $$x) + ) + ) + ) + + (func (export "as-store-first") + (global.get $$x) (i32.const 1) (i32.store) + ) + (func (export "as-store-last") + (i32.const 0) (global.get $$x) (i32.store) + ) + (func (export "as-load-operand") (result i32) + (i32.load (global.get $$x)) + ) + (func (export "as-memory.grow-value") (result i32) + (memory.grow (global.get $$x)) + ) + + (func $$f (param i32) (result i32) (local.get 0)) + (func (export "as-call-value") (result i32) + (call $$f (global.get $$x)) + ) + + (func (export "as-return-value") (result i32) + (global.get $$x) (return) + ) + (func (export "as-drop-operand") + (drop (global.get $$x)) + ) + (func (export "as-br-value") (result i32) + (block (result i32) (br 0 (global.get $$x))) + ) + + (func (export "as-local.set-value") (param i32) (result i32) + (local.set 0 (global.get $$x)) + (local.get 0) + ) + (func (export "as-local.tee-value") (param i32) (result i32) + (local.tee 0 (global.get $$x)) + ) + (func (export "as-global.set-value") (result i32) + (global.set $$x (global.get $$x)) + (global.get $$x) + ) + + (func (export "as-unary-operand") (result i32) + (i32.eqz (global.get $$x)) + ) + (func (export "as-binary-operand") (result i32) + (i32.mul + (global.get $$x) (global.get $$x) + ) + ) + (func (export "as-compare-operand") (result i32) + (i32.gt_u + (global.get 0) (i32.const 1) + ) + ) +)`); + +// ./test/core/global.wast:196 +assert_return(() => invoke($0, `get-a`, []), [value("i32", -2)]); + +// ./test/core/global.wast:197 +assert_return(() => invoke($0, `get-b`, []), [value("i64", -5n)]); + +// ./test/core/global.wast:198 +assert_return(() => invoke($0, `get-r`, []), [value('externref', null)]); + +// ./test/core/global.wast:199 +assert_return(() => invoke($0, `get-mr`, []), [value('externref', null)]); + +// ./test/core/global.wast:200 +assert_return(() => invoke($0, `get-x`, []), [value("i32", -12)]); + +// ./test/core/global.wast:201 +assert_return(() => invoke($0, `get-y`, []), [value("i64", -15n)]); + +// ./test/core/global.wast:202 +assert_return(() => invoke($0, `get-z1`, []), [value("i32", 666)]); + +// ./test/core/global.wast:203 +assert_return(() => invoke($0, `get-z2`, []), [value("i64", 666n)]); + +// ./test/core/global.wast:205 +assert_return(() => invoke($0, `get-3`, []), [value("f32", -3)]); + +// ./test/core/global.wast:206 +assert_return(() => invoke($0, `get-4`, []), [value("f64", -4)]); + +// ./test/core/global.wast:207 +assert_return(() => invoke($0, `get-7`, []), [value("f32", -13)]); + +// ./test/core/global.wast:208 +assert_return(() => invoke($0, `get-8`, []), [value("f64", -14)]); + +// ./test/core/global.wast:210 +assert_return(() => invoke($0, `set-x`, [6]), []); + +// ./test/core/global.wast:211 +assert_return(() => invoke($0, `set-y`, [7n]), []); + +// ./test/core/global.wast:213 +assert_return(() => invoke($0, `set-7`, [value("f32", 8)]), []); + +// ./test/core/global.wast:214 +assert_return(() => invoke($0, `set-8`, [value("f64", 9)]), []); + +// ./test/core/global.wast:216 +assert_return(() => invoke($0, `get-x`, []), [value("i32", 6)]); + +// ./test/core/global.wast:217 +assert_return(() => invoke($0, `get-y`, []), [value("i64", 7n)]); + +// ./test/core/global.wast:218 +assert_return(() => invoke($0, `get-7`, []), [value("f32", 8)]); + +// ./test/core/global.wast:219 +assert_return(() => invoke($0, `get-8`, []), [value("f64", 9)]); + +// ./test/core/global.wast:221 +assert_return(() => invoke($0, `set-7`, [value("f32", 8)]), []); + +// ./test/core/global.wast:222 +assert_return(() => invoke($0, `set-8`, [value("f64", 9)]), []); + +// ./test/core/global.wast:223 +assert_return(() => invoke($0, `set-mr`, [externref(10)]), []); + +// ./test/core/global.wast:225 +assert_return(() => invoke($0, `get-x`, []), [value("i32", 6)]); + +// ./test/core/global.wast:226 +assert_return(() => invoke($0, `get-y`, []), [value("i64", 7n)]); + +// ./test/core/global.wast:227 +assert_return(() => invoke($0, `get-7`, []), [value("f32", 8)]); + +// ./test/core/global.wast:228 +assert_return(() => invoke($0, `get-8`, []), [value("f64", 9)]); + +// ./test/core/global.wast:229 +assert_return(() => invoke($0, `get-mr`, []), [new ExternRefResult(10)]); + +// ./test/core/global.wast:231 +assert_return(() => invoke($0, `as-select-first`, []), [value("i32", 6)]); + +// ./test/core/global.wast:232 +assert_return(() => invoke($0, `as-select-mid`, []), [value("i32", 2)]); + +// ./test/core/global.wast:233 +assert_return(() => invoke($0, `as-select-last`, []), [value("i32", 2)]); + +// ./test/core/global.wast:235 +assert_return(() => invoke($0, `as-loop-first`, []), [value("i32", 6)]); + +// ./test/core/global.wast:236 +assert_return(() => invoke($0, `as-loop-mid`, []), [value("i32", 6)]); + +// ./test/core/global.wast:237 +assert_return(() => invoke($0, `as-loop-last`, []), [value("i32", 6)]); + +// ./test/core/global.wast:239 +assert_return(() => invoke($0, `as-if-condition`, []), [value("i32", 2)]); + +// ./test/core/global.wast:240 +assert_return(() => invoke($0, `as-if-then`, []), [value("i32", 6)]); + +// ./test/core/global.wast:241 +assert_return(() => invoke($0, `as-if-else`, []), [value("i32", 6)]); + +// ./test/core/global.wast:243 +assert_return(() => invoke($0, `as-br_if-first`, []), [value("i32", 6)]); + +// ./test/core/global.wast:244 +assert_return(() => invoke($0, `as-br_if-last`, []), [value("i32", 2)]); + +// ./test/core/global.wast:246 +assert_return(() => invoke($0, `as-br_table-first`, []), [value("i32", 6)]); + +// ./test/core/global.wast:247 +assert_return(() => invoke($0, `as-br_table-last`, []), [value("i32", 2)]); + +// ./test/core/global.wast:249 +assert_return(() => invoke($0, `as-call_indirect-first`, []), [value("i32", 6)]); + +// ./test/core/global.wast:250 +assert_return(() => invoke($0, `as-call_indirect-mid`, []), [value("i32", 2)]); + +// ./test/core/global.wast:251 +assert_trap(() => invoke($0, `as-call_indirect-last`, []), `undefined element`); + +// ./test/core/global.wast:253 +assert_return(() => invoke($0, `as-store-first`, []), []); + +// ./test/core/global.wast:254 +assert_return(() => invoke($0, `as-store-last`, []), []); + +// ./test/core/global.wast:255 +assert_return(() => invoke($0, `as-load-operand`, []), [value("i32", 1)]); + +// ./test/core/global.wast:256 +assert_return(() => invoke($0, `as-memory.grow-value`, []), [value("i32", 1)]); + +// ./test/core/global.wast:258 +assert_return(() => invoke($0, `as-call-value`, []), [value("i32", 6)]); + +// ./test/core/global.wast:260 +assert_return(() => invoke($0, `as-return-value`, []), [value("i32", 6)]); + +// ./test/core/global.wast:261 +assert_return(() => invoke($0, `as-drop-operand`, []), []); + +// ./test/core/global.wast:262 +assert_return(() => invoke($0, `as-br-value`, []), [value("i32", 6)]); + +// ./test/core/global.wast:264 +assert_return(() => invoke($0, `as-local.set-value`, [1]), [value("i32", 6)]); + +// ./test/core/global.wast:265 +assert_return(() => invoke($0, `as-local.tee-value`, [1]), [value("i32", 6)]); + +// ./test/core/global.wast:266 +assert_return(() => invoke($0, `as-global.set-value`, []), [value("i32", 6)]); + +// ./test/core/global.wast:268 +assert_return(() => invoke($0, `as-unary-operand`, []), [value("i32", 0)]); + +// ./test/core/global.wast:269 +assert_return(() => invoke($0, `as-binary-operand`, []), [value("i32", 36)]); + +// ./test/core/global.wast:270 +assert_return(() => invoke($0, `as-compare-operand`, []), [value("i32", 1)]); + +// ./test/core/global.wast:272 +assert_invalid( + () => instantiate(`(module (global f32 (f32.const 0)) (func (global.set 0 (f32.const 1))))`), + `immutable global`, +); + +// ./test/core/global.wast:277 +assert_invalid( + () => instantiate(`(module (import "spectest" "global_i32" (global i32)) (func (global.set 0 (i32.const 1))))`), + `immutable global`, +); + +// ./test/core/global.wast:283 +let $1 = instantiate(`(module (global (mut f32) (f32.const 0)) (export "a" (global 0)))`); + +// ./test/core/global.wast:284 +let $2 = instantiate(`(module (global (export "a") (mut f32) (f32.const 0)))`); + +// ./test/core/global.wast:286 +assert_invalid( + () => instantiate(`(module (global f32 (f32.neg (f32.const 0))))`), + `constant expression required`, +); + +// ./test/core/global.wast:291 +assert_invalid( + () => instantiate(`(module (global f32 (local.get 0)))`), + `constant expression required`, +); + +// ./test/core/global.wast:296 +assert_invalid( + () => instantiate(`(module (global f32 (f32.neg (f32.const 1))))`), + `constant expression required`, +); + +// ./test/core/global.wast:301 +assert_invalid( + () => instantiate(`(module (global i32 (i32.const 0) (nop)))`), + `constant expression required`, +); + +// ./test/core/global.wast:306 +assert_invalid( + () => instantiate(`(module (global i32 (i32.ctz (i32.const 0))))`), + `constant expression required`, +); + +// ./test/core/global.wast:311 +assert_invalid( + () => instantiate(`(module (global i32 (nop)))`), + `constant expression required`, +); + +// ./test/core/global.wast:316 +assert_invalid(() => instantiate(`(module (global i32 (f32.const 0)))`), `type mismatch`); + +// ./test/core/global.wast:321 +assert_invalid( + () => instantiate(`(module (global i32 (i32.const 0) (i32.const 0)))`), + `type mismatch`, +); + +// ./test/core/global.wast:326 +assert_invalid( + () => instantiate(`(module (global i32 (;empty instruction sequence;)))`), + `type mismatch`, +); + +// ./test/core/global.wast:331 +assert_invalid( + () => instantiate(`(module (global (import "" "") externref) (global funcref (global.get 0)))`), + `type mismatch`, +); + +// ./test/core/global.wast:336 +assert_invalid( + () => instantiate(`(module (global (import "test" "global-i32") i32) (global i32 (global.get 0) (global.get 0)))`), + `type mismatch`, +); + +// ./test/core/global.wast:341 +assert_invalid( + () => instantiate(`(module (global (import "test" "global-i32") i32) (global i32 (i32.const 0) (global.get 0)))`), + `type mismatch`, +); + +// ./test/core/global.wast:346 +assert_invalid( + () => instantiate(`(module (global i32 (global.get 0)))`), + `unknown global`, +); + +// ./test/core/global.wast:351 +assert_invalid( + () => instantiate(`(module (global i32 (global.get 1)) (global i32 (i32.const 0)))`), + `unknown global`, +); + +// ./test/core/global.wast:356 +assert_invalid( + () => instantiate(`(module (global (import "test" "global-i32") i32) (global i32 (global.get 2)))`), + `unknown global`, +); + +// ./test/core/global.wast:361 +assert_invalid( + () => instantiate(`(module (global (import "test" "global-mut-i32") (mut i32)) (global i32 (global.get 0)))`), + `constant expression required`, +); + +// ./test/core/global.wast:366 +let $3 = instantiate(`(module + (import "spectest" "global_i32" (global i32)) +)`); + +// ./test/core/global.wast:369 +assert_malformed( + () => instantiate(`(module binary + "\\00asm" "\\01\\00\\00\\00" + "\\02\\98\\80\\80\\80\\00" ;; import section + "\\01" ;; length 1 + "\\08\\73\\70\\65\\63\\74\\65\\73\\74" ;; "spectest" + "\\0a\\67\\6c\\6f\\62\\61\\6c\\5f\\69\\33\\32" ;; "global_i32" + "\\03" ;; GlobalImport + "\\7f" ;; i32 + "\\02" ;; malformed mutability + )`), + `malformed mutability`, +); + +// ./test/core/global.wast:382 +assert_malformed( + () => instantiate(`(module binary + "\\00asm" "\\01\\00\\00\\00" + "\\02\\98\\80\\80\\80\\00" ;; import section + "\\01" ;; length 1 + "\\08\\73\\70\\65\\63\\74\\65\\73\\74" ;; "spectest" + "\\0a\\67\\6c\\6f\\62\\61\\6c\\5f\\69\\33\\32" ;; "global_i32" + "\\03" ;; GlobalImport + "\\7f" ;; i32 + "\\ff" ;; malformed mutability + )`), + `malformed mutability`, +); + +// ./test/core/global.wast:396 +let $4 = instantiate(`(module + (global i32 (i32.const 0)) +)`); + +// ./test/core/global.wast:399 +assert_malformed( + () => instantiate(`(module binary + "\\00asm" "\\01\\00\\00\\00" + "\\06\\86\\80\\80\\80\\00" ;; global section + "\\01" ;; length 1 + "\\7f" ;; i32 + "\\02" ;; malformed mutability + "\\41\\00" ;; i32.const 0 + "\\0b" ;; end + )`), + `malformed mutability`, +); + +// ./test/core/global.wast:411 +assert_malformed( + () => instantiate(`(module binary + "\\00asm" "\\01\\00\\00\\00" + "\\06\\86\\80\\80\\80\\00" ;; global section + "\\01" ;; length 1 + "\\7f" ;; i32 + "\\ff" ;; malformed mutability + "\\41\\00" ;; i32.const 0 + "\\0b" ;; end + )`), + `malformed mutability`, +); + +// ./test/core/global.wast:425 +assert_invalid( + () => instantiate(`(module (func (result i32) (global.get 0)))`), + `unknown global`, +); + +// ./test/core/global.wast:430 +assert_invalid( + () => instantiate(`(module + (global i32 (i32.const 0)) + (func (result i32) (global.get 1)) + )`), + `unknown global`, +); + +// ./test/core/global.wast:438 +assert_invalid( + () => instantiate(`(module + (import "spectest" "global_i32" (global i32)) + (func (result i32) (global.get 1)) + )`), + `unknown global`, +); + +// ./test/core/global.wast:446 +assert_invalid( + () => instantiate(`(module + (import "spectest" "global_i32" (global i32)) + (global i32 (i32.const 0)) + (func (result i32) (global.get 2)) + )`), + `unknown global`, +); + +// ./test/core/global.wast:456 +assert_invalid( + () => instantiate(`(module (func (i32.const 0) (global.set 0)))`), + `unknown global`, +); + +// ./test/core/global.wast:461 +assert_invalid( + () => instantiate(`(module + (global i32 (i32.const 0)) + (func (i32.const 0) (global.set 1)) + )`), + `unknown global`, +); + +// ./test/core/global.wast:469 +assert_invalid( + () => instantiate(`(module + (import "spectest" "global_i32" (global i32)) + (func (i32.const 0) (global.set 1)) + )`), + `unknown global`, +); + +// ./test/core/global.wast:477 +assert_invalid( + () => instantiate(`(module + (import "spectest" "global_i32" (global i32)) + (global i32 (i32.const 0)) + (func (i32.const 0) (global.set 2)) + )`), + `unknown global`, +); + +// ./test/core/global.wast:487 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty + (global.set $$x) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:496 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-block + (i32.const 0) + (block (global.set $$x)) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:506 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-loop + (i32.const 0) + (loop (global.set $$x)) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:516 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-then + (i32.const 0) (i32.const 0) + (if (then (global.set $$x))) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:526 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-else + (i32.const 0) (i32.const 0) + (if (result i32) (then (i32.const 0)) (else (global.set $$x))) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:536 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-br + (i32.const 0) + (block (br 0 (global.set $$x))) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:546 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-br_if + (i32.const 0) + (block (br_if 0 (global.set $$x))) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:556 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-br_table + (i32.const 0) + (block (br_table 0 (global.set $$x))) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:566 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-return + (return (global.set $$x)) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:575 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-select + (select (global.set $$x) (i32.const 1) (i32.const 2)) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:584 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-global.set-value-empty-in-call + (call 1 (global.set $$x)) + ) + (func (param i32) (result i32) (local.get 0)) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:594 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$f (param i32) (result i32) (local.get 0)) + (type $$sig (func (param i32) (result i32))) + (table funcref (elem $$f)) + (func $$type-global.set-value-empty-in-call_indirect + (block (result i32) + (call_indirect (type $$sig) + (global.set $$x) (i32.const 0) + ) + ) + ) + )`), + `type mismatch`, +); + +// ./test/core/global.wast:613 +assert_malformed( + () => instantiate(`(global $$foo i32 (i32.const 0)) (global $$foo i32 (i32.const 0)) `), + `duplicate global`, +); + +// ./test/core/global.wast:617 +assert_malformed( + () => instantiate(`(import "" "" (global $$foo i32)) (global $$foo i32 (i32.const 0)) `), + `duplicate global`, +); + +// ./test/core/global.wast:621 +assert_malformed( + () => instantiate(`(import "" "" (global $$foo i32)) (import "" "" (global $$foo i32)) `), + `duplicate global`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/function-references/harness/directives.txt new file mode 100644 index 0000000000..d41243abbb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/harness/directives.txt @@ -0,0 +1 @@ +|jit-test| skip-if: true \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/function-references/harness/harness.js b/js/src/jit-test/tests/wasm/spec/function-references/harness/harness.js new file mode 100644 index 0000000000..a96781e8ed --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/harness/harness.js @@ -0,0 +1,448 @@ +"use strict"; + +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +if (!wasmIsSupported()) { + quit(); +} + +function bytes(type, bytes) { + var typedBuffer = new Uint8Array(bytes); + return wasmGlobalFromArrayBuffer(type, typedBuffer.buffer); +} +function value(type, value) { + return new WebAssembly.Global({ + value: type, + mutable: false, + }, value); +} + +function i8x16(elements) { + let typedBuffer = new Uint8Array(elements); + return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer); +} +function i16x8(elements) { + let typedBuffer = new Uint16Array(elements); + return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer); +} +function i32x4(elements) { + let typedBuffer = new Uint32Array(elements); + return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer); +} +function i64x2(elements) { + let typedBuffer = new BigUint64Array(elements); + return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer); +} +function f32x4(elements) { + let typedBuffer = new Float32Array(elements); + return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer); +} +function f64x2(elements) { + let typedBuffer = new Float64Array(elements); + return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer); +} + +function either(...arr) { + return new EitherVariants(arr); +} + +class F32x4Pattern { + constructor(x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } +} + +class F64x2Pattern { + constructor(x, y) { + this.x = x; + this.y = y; + } +} + +class RefWithType { + constructor(type) { + this.type = type; + } + + formatExpected() { + return `RefWithType(${this.type})`; + } + + test(refGlobal) { + try { + new WebAssembly.Global({value: this.type}, refGlobal.value); + return true; + } catch (err) { + assertEq(err instanceof TypeError, true, `wrong type of error when creating global: ${err}`); + assertEq(!!err.message.match(/can only pass/), true, `wrong type of error when creating global: ${err}`); + return false; + } + } +} + +// ref.extern values created by spec tests will be JS objects of the form +// { [externsym]: }. Other externref values are possible to observe +// if extern.convert_any is used. +let externsym = Symbol("externref"); +function externref(s) { + return { [externsym]: s }; +} +function is_externref(x) { + return (x !== null && externsym in x) ? 1 : 0; +} +function is_funcref(x) { + return typeof x === "function" ? 1 : 0; +} +function eq_externref(x, y) { + return x === y ? 1 : 0; +} +function eq_funcref(x, y) { + return x === y ? 1 : 0; +} + +class ExternRefResult { + constructor(n) { + this.n = n; + } + + formatExpected() { + return `ref.extern ${this.n}`; + } + + test(global) { + // the global's value can either be an externref or just a plain old JS number + let result = global.value; + if (typeof global.value === "object" && externsym in global.value) { + result = global.value[externsym]; + } + return result === this.n; + } +} + +// ref.host values created by spectests will be whatever the JS API does to +// convert the given value to anyref. It should implicitly be like any.convert_extern. +function hostref(v) { + if (!wasmGcEnabled()) { + throw new Error("ref.host only works when wasm GC is enabled"); + } + + const { internalizeNum } = new WebAssembly.Instance( + new WebAssembly.Module(wasmTextToBinary(`(module + (func (import "test" "coerce") (param i32) (result anyref)) + (func (export "internalizeNum") (param i32) (result anyref) + (call 0 (local.get 0)) + ) + )`)), + { "test": { "coerce": x => x } }, + ).exports; + return internalizeNum(v); +} + +class HostRefResult { + constructor(n) { + this.n = n; + } + + formatExpected() { + return `ref.host ${this.n}`; + } + + test(externrefGlobal) { + assertEq(externsym in externrefGlobal.value, true, `HostRefResult only works with externref inputs`); + return externrefGlobal.value[externsym] === this.n; + } +} + +let spectest = { + externref: externref, + is_externref: is_externref, + is_funcref: is_funcref, + eq_externref: eq_externref, + eq_funcref: eq_funcref, + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_i64: 666n, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({ + initial: 10, + maximum: 20, + element: "anyfunc", + }), + memory: new WebAssembly.Memory({ initial: 1, maximum: 2 }), +}; + +let linkage = { + spectest, +}; + +function getInstance(instanceish) { + if (typeof instanceish === "string") { + assertEq( + instanceish in linkage, + true, + `'${instanceish}'' must be registered`, + ); + return linkage[instanceish]; + } + return instanceish; +} + +function instantiate(source) { + let bytecode = wasmTextToBinary(source); + let module = new WebAssembly.Module(bytecode); + let instance = new WebAssembly.Instance(module, linkage); + return instance.exports; +} + +function register(instanceish, name) { + linkage[name] = getInstance(instanceish); +} + +function invoke(instanceish, field, params) { + let func = getInstance(instanceish)[field]; + assertEq(func instanceof Function, true, "expected a function"); + return wasmLosslessInvoke(func, ...params); +} + +function get(instanceish, field) { + let global = getInstance(instanceish)[field]; + assertEq( + global instanceof WebAssembly.Global, + true, + "expected a WebAssembly.Global", + ); + return global; +} + +function assert_trap(thunk, message) { + try { + thunk(); + throw new Error("expected trap"); + } catch (err) { + if (err instanceof WebAssembly.RuntimeError) { + return; + } + throw err; + } +} + +let StackOverflow; +try { + (function f() { + 1 + f(); + })(); +} catch (e) { + StackOverflow = e.constructor; +} +function assert_exhaustion(thunk, message) { + try { + thunk(); + assertEq("normal return", "exhaustion"); + } catch (err) { + assertEq( + err instanceof StackOverflow, + true, + "expected exhaustion", + ); + } +} + +function assert_invalid(thunk, message) { + try { + thunk(); + assertEq("valid module", "invalid module"); + } catch (err) { + assertEq( + err instanceof WebAssembly.LinkError || + err instanceof WebAssembly.CompileError, + true, + "expected an invalid module", + ); + } +} + +function assert_unlinkable(thunk, message) { + try { + thunk(); + assertEq(true, false, "expected an unlinkable module"); + } catch (err) { + assertEq( + err instanceof WebAssembly.LinkError || + err instanceof WebAssembly.CompileError, + true, + "expected an unlinkable module", + ); + } +} + +function assert_malformed(thunk, message) { + try { + thunk(); + assertEq("valid module", "malformed module"); + } catch (err) { + assertEq( + err instanceof TypeError || + err instanceof SyntaxError || + err instanceof WebAssembly.CompileError || + err instanceof WebAssembly.LinkError, + true, + `expected a malformed module`, + ); + } +} + +function assert_exception(thunk) { + let thrown = false; + try { + thunk(); + } catch (err) { + thrown = true; + } + assertEq(thrown, true, "expected an exception to be thrown"); +} + +function assert_return(thunk, expected) { + let results = thunk(); + + if (results === undefined) { + results = []; + } else if (!Array.isArray(results)) { + results = [results]; + } + if (!Array.isArray(expected)) { + expected = [expected]; + } + + if (!compareResults(results, expected)) { + let got = results.map((x) => formatResult(x)).join(", "); + let wanted = expected.map((x) => formatExpected(x)).join(", "); + assertEq( + `[${got}]`, + `[${wanted}]`, + ); + assertEq(true, false, `${got} !== ${wanted}`); + } +} + +function formatResult(result) { + if (typeof (result) === "object") { + return wasmGlobalToString(result); + } else { + return `${result}`; + } +} + +function formatExpected(expected) { + if ( + expected === `f32_canonical_nan` || + expected === `f32_arithmetic_nan` || + expected === `f64_canonical_nan` || + expected === `f64_arithmetic_nan` + ) { + return expected; + } else if (expected instanceof F32x4Pattern) { + return `f32x4(${formatExpected(expected.x)}, ${ + formatExpected(expected.y) + }, ${formatExpected(expected.z)}, ${formatExpected(expected.w)})`; + } else if (expected instanceof F64x2Pattern) { + return `f64x2(${formatExpected(expected.x)}, ${ + formatExpected(expected.y) + })`; + } else if (expected instanceof EitherVariants) { + return expected.formatExpected(); + } else if (expected instanceof RefWithType) { + return expected.formatExpected(); + } else if (expected instanceof ExternRefResult) { + return expected.formatExpected(); + } else if (expected instanceof HostRefResult) { + return expected.formatExpected(); + } else if (typeof (expected) === "object") { + return wasmGlobalToString(expected); + } else { + throw new Error("unknown expected result"); + } +} + +class EitherVariants { + constructor(arr) { + this.arr = arr; + } + matches(v) { + return this.arr.some((e) => compareResult(v, e)); + } + formatExpected() { + return `either(${this.arr.map(formatExpected).join(", ")})`; + } +} + +function compareResults(results, expected) { + if (results.length !== expected.length) { + return false; + } + for (let i in results) { + if (expected[i] instanceof EitherVariants) { + return expected[i].matches(results[i]); + } + if (!compareResult(results[i], expected[i])) { + return false; + } + } + return true; +} + +function compareResult(result, expected) { + if ( + expected === `canonical_nan` || + expected === `arithmetic_nan` + ) { + return wasmGlobalIsNaN(result, expected); + } else if (expected === null) { + return result.value === null; + } else if (expected instanceof F32x4Pattern) { + return compareResult( + wasmGlobalExtractLane(result, "f32x4", 0), + expected.x, + ) && + compareResult(wasmGlobalExtractLane(result, "f32x4", 1), expected.y) && + compareResult(wasmGlobalExtractLane(result, "f32x4", 2), expected.z) && + compareResult(wasmGlobalExtractLane(result, "f32x4", 3), expected.w); + } else if (expected instanceof F64x2Pattern) { + return compareResult( + wasmGlobalExtractLane(result, "f64x2", 0), + expected.x, + ) && + compareResult(wasmGlobalExtractLane(result, "f64x2", 1), expected.y); + } else if (expected instanceof RefWithType) { + return expected.test(result); + } else if (expected instanceof ExternRefResult) { + return expected.test(result); + } else if (expected instanceof HostRefResult) { + return expected.test(result); + } else if (typeof (expected) === "object") { + return wasmGlobalsEqual(result, expected); + } else { + throw new Error("unknown expected result"); + } +} diff --git a/js/src/jit-test/tests/wasm/spec/function-references/if.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/if.wast.js new file mode 100644 index 0000000000..ada0bd224a --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/if.wast.js @@ -0,0 +1,1911 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/if.wast + +// ./test/core/if.wast:3 +let $0 = instantiate(`(module + ;; Auxiliary definition + (memory 1) + + (func $$dummy) + + (func (export "empty") (param i32) + (if (local.get 0) (then)) + (if (local.get 0) (then) (else)) + (if $$l (local.get 0) (then)) + (if $$l (local.get 0) (then) (else)) + ) + + (func (export "singular") (param i32) (result i32) + (if (local.get 0) (then (nop))) + (if (local.get 0) (then (nop)) (else (nop))) + (if (result i32) (local.get 0) (then (i32.const 7)) (else (i32.const 8))) + ) + + (func (export "multi") (param i32) (result i32 i32) + (if (local.get 0) (then (call $$dummy) (call $$dummy) (call $$dummy))) + (if (local.get 0) (then) (else (call $$dummy) (call $$dummy) (call $$dummy))) + (if (result i32) (local.get 0) + (then (call $$dummy) (call $$dummy) (i32.const 8) (call $$dummy)) + (else (call $$dummy) (call $$dummy) (i32.const 9) (call $$dummy)) + ) + (if (result i32 i64 i32) (local.get 0) + (then + (call $$dummy) (call $$dummy) (i32.const 1) (call $$dummy) + (call $$dummy) (call $$dummy) (i64.const 2) (call $$dummy) + (call $$dummy) (call $$dummy) (i32.const 3) (call $$dummy) + ) + (else + (call $$dummy) (call $$dummy) (i32.const -1) (call $$dummy) + (call $$dummy) (call $$dummy) (i64.const -2) (call $$dummy) + (call $$dummy) (call $$dummy) (i32.const -3) (call $$dummy) + ) + ) + (drop) (drop) + ) + + (func (export "nested") (param i32 i32) (result i32) + (if (result i32) (local.get 0) + (then + (if (local.get 1) (then (call $$dummy) (block) (nop))) + (if (local.get 1) (then) (else (call $$dummy) (block) (nop))) + (if (result i32) (local.get 1) + (then (call $$dummy) (i32.const 9)) + (else (call $$dummy) (i32.const 10)) + ) + ) + (else + (if (local.get 1) (then (call $$dummy) (block) (nop))) + (if (local.get 1) (then) (else (call $$dummy) (block) (nop))) + (if (result i32) (local.get 1) + (then (call $$dummy) (i32.const 10)) + (else (call $$dummy) (i32.const 11)) + ) + ) + ) + ) + + (func (export "as-select-first") (param i32) (result i32) + (select + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 2) (i32.const 3) + ) + ) + (func (export "as-select-mid") (param i32) (result i32) + (select + (i32.const 2) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 3) + ) + ) + (func (export "as-select-last") (param i32) (result i32) + (select + (i32.const 2) (i32.const 3) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + ) + ) + + (func (export "as-loop-first") (param i32) (result i32) + (loop (result i32) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (call $$dummy) (call $$dummy) + ) + ) + (func (export "as-loop-mid") (param i32) (result i32) + (loop (result i32) + (call $$dummy) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (call $$dummy) + ) + ) + (func (export "as-loop-last") (param i32) (result i32) + (loop (result i32) + (call $$dummy) (call $$dummy) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + ) + ) + + (func (export "as-if-condition") (param i32) (result i32) + (if (result i32) + (if (result i32) (local.get 0) + (then (i32.const 1)) (else (i32.const 0)) + ) + (then (call $$dummy) (i32.const 2)) + (else (call $$dummy) (i32.const 3)) + ) + ) + + (func (export "as-br_if-first") (param i32) (result i32) + (block (result i32) + (br_if 0 + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 2) + ) + (return (i32.const 3)) + ) + ) + (func (export "as-br_if-last") (param i32) (result i32) + (block (result i32) + (br_if 0 + (i32.const 2) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + ) + (return (i32.const 3)) + ) + ) + + (func (export "as-br_table-first") (param i32) (result i32) + (block (result i32) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 2) + (br_table 0 0) + ) + ) + (func (export "as-br_table-last") (param i32) (result i32) + (block (result i32) + (i32.const 2) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (br_table 0 0) + ) + ) + + (func $$func (param i32 i32) (result i32) (local.get 0)) + (type $$check (func (param i32 i32) (result i32))) + (table funcref (elem $$func)) + (func (export "as-call_indirect-first") (param i32) (result i32) + (block (result i32) + (call_indirect (type $$check) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 2) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-mid") (param i32) (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 2) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-last") (param i32) (result i32) + (block (result i32) + (call_indirect (type $$check) + (i32.const 2) (i32.const 0) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + ) + ) + ) + + (func (export "as-store-first") (param i32) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.const 2) + (i32.store) + ) + (func (export "as-store-last") (param i32) + (i32.const 2) + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 1)) + (else (call $$dummy) (i32.const 0)) + ) + (i32.store) + ) + + (func (export "as-memory.grow-value") (param i32) (result i32) + (memory.grow + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) + ) + + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "as-call-value") (param i32) (result i32) + (call $$f + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) + ) + (func (export "as-return-value") (param i32) (result i32) + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0))) + (return) + ) + (func (export "as-drop-operand") (param i32) + (drop + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) + ) + (func (export "as-br-value") (param i32) (result i32) + (block (result i32) + (br 0 + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) + ) + ) + (func (export "as-local.set-value") (param i32) (result i32) + (local i32) + (local.set 0 + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) + (local.get 0) + ) + (func (export "as-local.tee-value") (param i32) (result i32) + (local.tee 0 + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) + ) + (global $$a (mut i32) (i32.const 10)) + (func (export "as-global.set-value") (param i32) (result i32) + (global.set $$a + (if (result i32) (local.get 0) + (then (i32.const 1)) + (else (i32.const 0)) + ) + ) (global.get $$a) + ) + (func (export "as-load-operand") (param i32) (result i32) + (i32.load + (if (result i32) (local.get 0) + (then (i32.const 11)) + (else (i32.const 10)) + ) + ) + ) + + (func (export "as-unary-operand") (param i32) (result i32) + (i32.ctz + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 13)) + (else (call $$dummy) (i32.const -13)) + ) + ) + ) + (func (export "as-binary-operand") (param i32 i32) (result i32) + (i32.mul + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 3)) + (else (call $$dummy) (i32.const -3)) + ) + (if (result i32) (local.get 1) + (then (call $$dummy) (i32.const 4)) + (else (call $$dummy) (i32.const -5)) + ) + ) + ) + (func (export "as-test-operand") (param i32) (result i32) + (i32.eqz + (if (result i32) (local.get 0) + (then (call $$dummy) (i32.const 13)) + (else (call $$dummy) (i32.const 0)) + ) + ) + ) + (func (export "as-compare-operand") (param i32 i32) (result i32) + (f32.gt + (if (result f32) (local.get 0) + (then (call $$dummy) (f32.const 3)) + (else (call $$dummy) (f32.const -3)) + ) + (if (result f32) (local.get 1) + (then (call $$dummy) (f32.const 4)) + (else (call $$dummy) (f32.const -4)) + ) + ) + ) + (func (export "as-binary-operands") (param i32) (result i32) + (i32.mul + (if (result i32 i32) (local.get 0) + (then (call $$dummy) (i32.const 3) (call $$dummy) (i32.const 4)) + (else (call $$dummy) (i32.const 3) (call $$dummy) (i32.const -4)) + ) + ) + ) + (func (export "as-compare-operands") (param i32) (result i32) + (f32.gt + (if (result f32 f32) (local.get 0) + (then (call $$dummy) (f32.const 3) (call $$dummy) (f32.const 3)) + (else (call $$dummy) (f32.const -2) (call $$dummy) (f32.const -3)) + ) + ) + ) + (func (export "as-mixed-operands") (param i32) (result i32) + (if (result i32 i32) (local.get 0) + (then (call $$dummy) (i32.const 3) (call $$dummy) (i32.const 4)) + (else (call $$dummy) (i32.const -3) (call $$dummy) (i32.const -4)) + ) + (i32.const 5) + (i32.add) + (i32.mul) + ) + + (func (export "break-bare") (result i32) + (if (i32.const 1) (then (br 0) (unreachable))) + (if (i32.const 1) (then (br 0) (unreachable)) (else (unreachable))) + (if (i32.const 0) (then (unreachable)) (else (br 0) (unreachable))) + (if (i32.const 1) (then (br_if 0 (i32.const 1)) (unreachable))) + (if (i32.const 1) (then (br_if 0 (i32.const 1)) (unreachable)) (else (unreachable))) + (if (i32.const 0) (then (unreachable)) (else (br_if 0 (i32.const 1)) (unreachable))) + (if (i32.const 1) (then (br_table 0 (i32.const 0)) (unreachable))) + (if (i32.const 1) (then (br_table 0 (i32.const 0)) (unreachable)) (else (unreachable))) + (if (i32.const 0) (then (unreachable)) (else (br_table 0 (i32.const 0)) (unreachable))) + (i32.const 19) + ) + + (func (export "break-value") (param i32) (result i32) + (if (result i32) (local.get 0) + (then (br 0 (i32.const 18)) (i32.const 19)) + (else (br 0 (i32.const 21)) (i32.const 20)) + ) + ) + (func (export "break-multi-value") (param i32) (result i32 i32 i64) + (if (result i32 i32 i64) (local.get 0) + (then + (br 0 (i32.const 18) (i32.const -18) (i64.const 18)) + (i32.const 19) (i32.const -19) (i64.const 19) + ) + (else + (br 0 (i32.const -18) (i32.const 18) (i64.const -18)) + (i32.const -19) (i32.const 19) (i64.const -19) + ) + ) + ) + + (func (export "param") (param i32) (result i32) + (i32.const 1) + (if (param i32) (result i32) (local.get 0) + (then (i32.const 2) (i32.add)) + (else (i32.const -2) (i32.add)) + ) + ) + (func (export "params") (param i32) (result i32) + (i32.const 1) + (i32.const 2) + (if (param i32 i32) (result i32) (local.get 0) + (then (i32.add)) + (else (i32.sub)) + ) + ) + (func (export "params-id") (param i32) (result i32) + (i32.const 1) + (i32.const 2) + (if (param i32 i32) (result i32 i32) (local.get 0) (then)) + (i32.add) + ) + (func (export "param-break") (param i32) (result i32) + (i32.const 1) + (if (param i32) (result i32) (local.get 0) + (then (i32.const 2) (i32.add) (br 0)) + (else (i32.const -2) (i32.add) (br 0)) + ) + ) + (func (export "params-break") (param i32) (result i32) + (i32.const 1) + (i32.const 2) + (if (param i32 i32) (result i32) (local.get 0) + (then (i32.add) (br 0)) + (else (i32.sub) (br 0)) + ) + ) + (func (export "params-id-break") (param i32) (result i32) + (i32.const 1) + (i32.const 2) + (if (param i32 i32) (result i32 i32) (local.get 0) (then (br 0))) + (i32.add) + ) + + (func (export "effects") (param i32) (result i32) + (local i32) + (if + (block (result i32) (local.set 1 (i32.const 1)) (local.get 0)) + (then + (local.set 1 (i32.mul (local.get 1) (i32.const 3))) + (local.set 1 (i32.sub (local.get 1) (i32.const 5))) + (local.set 1 (i32.mul (local.get 1) (i32.const 7))) + (br 0) + (local.set 1 (i32.mul (local.get 1) (i32.const 100))) + ) + (else + (local.set 1 (i32.mul (local.get 1) (i32.const 5))) + (local.set 1 (i32.sub (local.get 1) (i32.const 7))) + (local.set 1 (i32.mul (local.get 1) (i32.const 3))) + (br 0) + (local.set 1 (i32.mul (local.get 1) (i32.const 1000))) + ) + ) + (local.get 1) + ) + + ;; Examples + + (func $$add64_u_with_carry (export "add64_u_with_carry") + (param $$i i64) (param $$j i64) (param $$c i32) (result i64 i32) + (local $$k i64) + (local.set $$k + (i64.add + (i64.add (local.get $$i) (local.get $$j)) + (i64.extend_i32_u (local.get $$c)) + ) + ) + (return (local.get $$k) (i64.lt_u (local.get $$k) (local.get $$i))) + ) + + (func $$add64_u_saturated (export "add64_u_saturated") + (param i64 i64) (result i64) + (call $$add64_u_with_carry (local.get 0) (local.get 1) (i32.const 0)) + (if (param i64) (result i64) + (then (drop) (i64.const -1)) + ) + ) + + ;; Block signature syntax + + (type $$block-sig-1 (func)) + (type $$block-sig-2 (func (result i32))) + (type $$block-sig-3 (func (param $$x i32))) + (type $$block-sig-4 (func (param i32 f64 i32) (result i32 f64 i32))) + + (func (export "type-use") + (if (type $$block-sig-1) (i32.const 1) (then)) + (if (type $$block-sig-2) (i32.const 1) + (then (i32.const 0)) (else (i32.const 2)) + ) + (if (type $$block-sig-3) (i32.const 1) (then (drop)) (else (drop))) + (i32.const 0) (f64.const 0) (i32.const 0) + (if (type $$block-sig-4) (i32.const 1) (then)) + (drop) (drop) (drop) + (if (type $$block-sig-2) (result i32) (i32.const 1) + (then (i32.const 0)) (else (i32.const 2)) + ) + (if (type $$block-sig-3) (param i32) (i32.const 1) + (then (drop)) (else (drop)) + ) + (i32.const 0) (f64.const 0) (i32.const 0) + (if (type $$block-sig-4) + (param i32) (param f64 i32) (result i32 f64) (result i32) + (i32.const 1) (then) + ) + (drop) (drop) (drop) + ) +)`); + +// ./test/core/if.wast:529 +assert_return(() => invoke($0, `empty`, [0]), []); + +// ./test/core/if.wast:530 +assert_return(() => invoke($0, `empty`, [1]), []); + +// ./test/core/if.wast:531 +assert_return(() => invoke($0, `empty`, [100]), []); + +// ./test/core/if.wast:532 +assert_return(() => invoke($0, `empty`, [-2]), []); + +// ./test/core/if.wast:534 +assert_return(() => invoke($0, `singular`, [0]), [value("i32", 8)]); + +// ./test/core/if.wast:535 +assert_return(() => invoke($0, `singular`, [1]), [value("i32", 7)]); + +// ./test/core/if.wast:536 +assert_return(() => invoke($0, `singular`, [10]), [value("i32", 7)]); + +// ./test/core/if.wast:537 +assert_return(() => invoke($0, `singular`, [-10]), [value("i32", 7)]); + +// ./test/core/if.wast:539 +assert_return(() => invoke($0, `multi`, [0]), [value("i32", 9), value("i32", -1)]); + +// ./test/core/if.wast:540 +assert_return(() => invoke($0, `multi`, [1]), [value("i32", 8), value("i32", 1)]); + +// ./test/core/if.wast:541 +assert_return(() => invoke($0, `multi`, [13]), [value("i32", 8), value("i32", 1)]); + +// ./test/core/if.wast:542 +assert_return(() => invoke($0, `multi`, [-5]), [value("i32", 8), value("i32", 1)]); + +// ./test/core/if.wast:544 +assert_return(() => invoke($0, `nested`, [0, 0]), [value("i32", 11)]); + +// ./test/core/if.wast:545 +assert_return(() => invoke($0, `nested`, [1, 0]), [value("i32", 10)]); + +// ./test/core/if.wast:546 +assert_return(() => invoke($0, `nested`, [0, 1]), [value("i32", 10)]); + +// ./test/core/if.wast:547 +assert_return(() => invoke($0, `nested`, [3, 2]), [value("i32", 9)]); + +// ./test/core/if.wast:548 +assert_return(() => invoke($0, `nested`, [0, -100]), [value("i32", 10)]); + +// ./test/core/if.wast:549 +assert_return(() => invoke($0, `nested`, [10, 10]), [value("i32", 9)]); + +// ./test/core/if.wast:550 +assert_return(() => invoke($0, `nested`, [0, -1]), [value("i32", 10)]); + +// ./test/core/if.wast:551 +assert_return(() => invoke($0, `nested`, [-111, -2]), [value("i32", 9)]); + +// ./test/core/if.wast:553 +assert_return(() => invoke($0, `as-select-first`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:554 +assert_return(() => invoke($0, `as-select-first`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:555 +assert_return(() => invoke($0, `as-select-mid`, [0]), [value("i32", 2)]); + +// ./test/core/if.wast:556 +assert_return(() => invoke($0, `as-select-mid`, [1]), [value("i32", 2)]); + +// ./test/core/if.wast:557 +assert_return(() => invoke($0, `as-select-last`, [0]), [value("i32", 3)]); + +// ./test/core/if.wast:558 +assert_return(() => invoke($0, `as-select-last`, [1]), [value("i32", 2)]); + +// ./test/core/if.wast:560 +assert_return(() => invoke($0, `as-loop-first`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:561 +assert_return(() => invoke($0, `as-loop-first`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:562 +assert_return(() => invoke($0, `as-loop-mid`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:563 +assert_return(() => invoke($0, `as-loop-mid`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:564 +assert_return(() => invoke($0, `as-loop-last`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:565 +assert_return(() => invoke($0, `as-loop-last`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:567 +assert_return(() => invoke($0, `as-if-condition`, [0]), [value("i32", 3)]); + +// ./test/core/if.wast:568 +assert_return(() => invoke($0, `as-if-condition`, [1]), [value("i32", 2)]); + +// ./test/core/if.wast:570 +assert_return(() => invoke($0, `as-br_if-first`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:571 +assert_return(() => invoke($0, `as-br_if-first`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:572 +assert_return(() => invoke($0, `as-br_if-last`, [0]), [value("i32", 3)]); + +// ./test/core/if.wast:573 +assert_return(() => invoke($0, `as-br_if-last`, [1]), [value("i32", 2)]); + +// ./test/core/if.wast:575 +assert_return(() => invoke($0, `as-br_table-first`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:576 +assert_return(() => invoke($0, `as-br_table-first`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:577 +assert_return(() => invoke($0, `as-br_table-last`, [0]), [value("i32", 2)]); + +// ./test/core/if.wast:578 +assert_return(() => invoke($0, `as-br_table-last`, [1]), [value("i32", 2)]); + +// ./test/core/if.wast:580 +assert_return(() => invoke($0, `as-call_indirect-first`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:581 +assert_return(() => invoke($0, `as-call_indirect-first`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:582 +assert_return(() => invoke($0, `as-call_indirect-mid`, [0]), [value("i32", 2)]); + +// ./test/core/if.wast:583 +assert_return(() => invoke($0, `as-call_indirect-mid`, [1]), [value("i32", 2)]); + +// ./test/core/if.wast:584 +assert_return(() => invoke($0, `as-call_indirect-last`, [0]), [value("i32", 2)]); + +// ./test/core/if.wast:585 +assert_trap(() => invoke($0, `as-call_indirect-last`, [1]), `undefined element`); + +// ./test/core/if.wast:587 +assert_return(() => invoke($0, `as-store-first`, [0]), []); + +// ./test/core/if.wast:588 +assert_return(() => invoke($0, `as-store-first`, [1]), []); + +// ./test/core/if.wast:589 +assert_return(() => invoke($0, `as-store-last`, [0]), []); + +// ./test/core/if.wast:590 +assert_return(() => invoke($0, `as-store-last`, [1]), []); + +// ./test/core/if.wast:592 +assert_return(() => invoke($0, `as-memory.grow-value`, [0]), [value("i32", 1)]); + +// ./test/core/if.wast:593 +assert_return(() => invoke($0, `as-memory.grow-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:595 +assert_return(() => invoke($0, `as-call-value`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:596 +assert_return(() => invoke($0, `as-call-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:598 +assert_return(() => invoke($0, `as-return-value`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:599 +assert_return(() => invoke($0, `as-return-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:601 +assert_return(() => invoke($0, `as-drop-operand`, [0]), []); + +// ./test/core/if.wast:602 +assert_return(() => invoke($0, `as-drop-operand`, [1]), []); + +// ./test/core/if.wast:604 +assert_return(() => invoke($0, `as-br-value`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:605 +assert_return(() => invoke($0, `as-br-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:607 +assert_return(() => invoke($0, `as-local.set-value`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:608 +assert_return(() => invoke($0, `as-local.set-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:610 +assert_return(() => invoke($0, `as-local.tee-value`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:611 +assert_return(() => invoke($0, `as-local.tee-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:613 +assert_return(() => invoke($0, `as-global.set-value`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:614 +assert_return(() => invoke($0, `as-global.set-value`, [1]), [value("i32", 1)]); + +// ./test/core/if.wast:616 +assert_return(() => invoke($0, `as-load-operand`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:617 +assert_return(() => invoke($0, `as-load-operand`, [1]), [value("i32", 0)]); + +// ./test/core/if.wast:619 +assert_return(() => invoke($0, `as-unary-operand`, [0]), [value("i32", 0)]); + +// ./test/core/if.wast:620 +assert_return(() => invoke($0, `as-unary-operand`, [1]), [value("i32", 0)]); + +// ./test/core/if.wast:621 +assert_return(() => invoke($0, `as-unary-operand`, [-1]), [value("i32", 0)]); + +// ./test/core/if.wast:623 +assert_return(() => invoke($0, `as-binary-operand`, [0, 0]), [value("i32", 15)]); + +// ./test/core/if.wast:624 +assert_return(() => invoke($0, `as-binary-operand`, [0, 1]), [value("i32", -12)]); + +// ./test/core/if.wast:625 +assert_return(() => invoke($0, `as-binary-operand`, [1, 0]), [value("i32", -15)]); + +// ./test/core/if.wast:626 +assert_return(() => invoke($0, `as-binary-operand`, [1, 1]), [value("i32", 12)]); + +// ./test/core/if.wast:628 +assert_return(() => invoke($0, `as-test-operand`, [0]), [value("i32", 1)]); + +// ./test/core/if.wast:629 +assert_return(() => invoke($0, `as-test-operand`, [1]), [value("i32", 0)]); + +// ./test/core/if.wast:631 +assert_return(() => invoke($0, `as-compare-operand`, [0, 0]), [value("i32", 1)]); + +// ./test/core/if.wast:632 +assert_return(() => invoke($0, `as-compare-operand`, [0, 1]), [value("i32", 0)]); + +// ./test/core/if.wast:633 +assert_return(() => invoke($0, `as-compare-operand`, [1, 0]), [value("i32", 1)]); + +// ./test/core/if.wast:634 +assert_return(() => invoke($0, `as-compare-operand`, [1, 1]), [value("i32", 0)]); + +// ./test/core/if.wast:636 +assert_return(() => invoke($0, `as-binary-operands`, [0]), [value("i32", -12)]); + +// ./test/core/if.wast:637 +assert_return(() => invoke($0, `as-binary-operands`, [1]), [value("i32", 12)]); + +// ./test/core/if.wast:639 +assert_return(() => invoke($0, `as-compare-operands`, [0]), [value("i32", 1)]); + +// ./test/core/if.wast:640 +assert_return(() => invoke($0, `as-compare-operands`, [1]), [value("i32", 0)]); + +// ./test/core/if.wast:642 +assert_return(() => invoke($0, `as-mixed-operands`, [0]), [value("i32", -3)]); + +// ./test/core/if.wast:643 +assert_return(() => invoke($0, `as-mixed-operands`, [1]), [value("i32", 27)]); + +// ./test/core/if.wast:645 +assert_return(() => invoke($0, `break-bare`, []), [value("i32", 19)]); + +// ./test/core/if.wast:646 +assert_return(() => invoke($0, `break-value`, [1]), [value("i32", 18)]); + +// ./test/core/if.wast:647 +assert_return(() => invoke($0, `break-value`, [0]), [value("i32", 21)]); + +// ./test/core/if.wast:648 +assert_return( + () => invoke($0, `break-multi-value`, [0]), + [value("i32", -18), value("i32", 18), value("i64", -18n)], +); + +// ./test/core/if.wast:651 +assert_return( + () => invoke($0, `break-multi-value`, [1]), + [value("i32", 18), value("i32", -18), value("i64", 18n)], +); + +// ./test/core/if.wast:655 +assert_return(() => invoke($0, `param`, [0]), [value("i32", -1)]); + +// ./test/core/if.wast:656 +assert_return(() => invoke($0, `param`, [1]), [value("i32", 3)]); + +// ./test/core/if.wast:657 +assert_return(() => invoke($0, `params`, [0]), [value("i32", -1)]); + +// ./test/core/if.wast:658 +assert_return(() => invoke($0, `params`, [1]), [value("i32", 3)]); + +// ./test/core/if.wast:659 +assert_return(() => invoke($0, `params-id`, [0]), [value("i32", 3)]); + +// ./test/core/if.wast:660 +assert_return(() => invoke($0, `params-id`, [1]), [value("i32", 3)]); + +// ./test/core/if.wast:661 +assert_return(() => invoke($0, `param-break`, [0]), [value("i32", -1)]); + +// ./test/core/if.wast:662 +assert_return(() => invoke($0, `param-break`, [1]), [value("i32", 3)]); + +// ./test/core/if.wast:663 +assert_return(() => invoke($0, `params-break`, [0]), [value("i32", -1)]); + +// ./test/core/if.wast:664 +assert_return(() => invoke($0, `params-break`, [1]), [value("i32", 3)]); + +// ./test/core/if.wast:665 +assert_return(() => invoke($0, `params-id-break`, [0]), [value("i32", 3)]); + +// ./test/core/if.wast:666 +assert_return(() => invoke($0, `params-id-break`, [1]), [value("i32", 3)]); + +// ./test/core/if.wast:668 +assert_return(() => invoke($0, `effects`, [1]), [value("i32", -14)]); + +// ./test/core/if.wast:669 +assert_return(() => invoke($0, `effects`, [0]), [value("i32", -6)]); + +// ./test/core/if.wast:671 +assert_return(() => invoke($0, `add64_u_with_carry`, [0n, 0n, 0]), [value("i64", 0n), value("i32", 0)]); + +// ./test/core/if.wast:675 +assert_return( + () => invoke($0, `add64_u_with_carry`, [100n, 124n, 0]), + [value("i64", 224n), value("i32", 0)], +); + +// ./test/core/if.wast:679 +assert_return( + () => invoke($0, `add64_u_with_carry`, [-1n, 0n, 0]), + [value("i64", -1n), value("i32", 0)], +); + +// ./test/core/if.wast:683 +assert_return(() => invoke($0, `add64_u_with_carry`, [-1n, 1n, 0]), [value("i64", 0n), value("i32", 1)]); + +// ./test/core/if.wast:687 +assert_return( + () => invoke($0, `add64_u_with_carry`, [-1n, -1n, 0]), + [value("i64", -2n), value("i32", 1)], +); + +// ./test/core/if.wast:691 +assert_return(() => invoke($0, `add64_u_with_carry`, [-1n, 0n, 1]), [value("i64", 0n), value("i32", 1)]); + +// ./test/core/if.wast:695 +assert_return(() => invoke($0, `add64_u_with_carry`, [-1n, 1n, 1]), [value("i64", 1n), value("i32", 1)]); + +// ./test/core/if.wast:699 +assert_return( + () => invoke($0, `add64_u_with_carry`, [ + -9223372036854775808n, + -9223372036854775808n, + 0, + ]), + [value("i64", 0n), value("i32", 1)], +); + +// ./test/core/if.wast:704 +assert_return(() => invoke($0, `add64_u_saturated`, [0n, 0n]), [value("i64", 0n)]); + +// ./test/core/if.wast:707 +assert_return(() => invoke($0, `add64_u_saturated`, [1230n, 23n]), [value("i64", 1253n)]); + +// ./test/core/if.wast:710 +assert_return(() => invoke($0, `add64_u_saturated`, [-1n, 0n]), [value("i64", -1n)]); + +// ./test/core/if.wast:713 +assert_return(() => invoke($0, `add64_u_saturated`, [-1n, 1n]), [value("i64", -1n)]); + +// ./test/core/if.wast:716 +assert_return(() => invoke($0, `add64_u_saturated`, [-1n, -1n]), [value("i64", -1n)]); + +// ./test/core/if.wast:719 +assert_return( + () => invoke($0, `add64_u_saturated`, [-9223372036854775808n, -9223372036854775808n]), + [value("i64", -1n)], +); + +// ./test/core/if.wast:723 +assert_return(() => invoke($0, `type-use`, []), []); + +// ./test/core/if.wast:725 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 0) (if (type $$sig) (result i32) (param i32) (i32.const 1) (then)) ) `), + `unexpected token`, +); + +// ./test/core/if.wast:734 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 0) (if (param i32) (type $$sig) (result i32) (i32.const 1) (then)) ) `), + `unexpected token`, +); + +// ./test/core/if.wast:743 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 0) (if (param i32) (result i32) (type $$sig) (i32.const 1) (then)) ) `), + `unexpected token`, +); + +// ./test/core/if.wast:752 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 0) (if (result i32) (type $$sig) (param i32) (i32.const 1) (then)) ) `), + `unexpected token`, +); + +// ./test/core/if.wast:761 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 0) (if (result i32) (param i32) (type $$sig) (i32.const 1) (then)) ) `), + `unexpected token`, +); + +// ./test/core/if.wast:770 +assert_malformed( + () => instantiate(`(func (i32.const 0) (if (result i32) (param i32) (i32.const 1) (then))) `), + `unexpected token`, +); + +// ./test/core/if.wast:777 +assert_malformed( + () => instantiate(`(func (i32.const 0) (i32.const 1) (if (param $$x i32) (then (drop)) (else (drop))) ) `), + `unexpected token`, +); + +// ./test/core/if.wast:785 +assert_malformed( + () => instantiate(`(type $$sig (func)) (func (i32.const 1) (if (type $$sig) (result i32) (then (i32.const 0)) (else (i32.const 2))) (unreachable) ) `), + `inline function type`, +); + +// ./test/core/if.wast:795 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 1) (if (type $$sig) (result i32) (then (i32.const 0)) (else (i32.const 2))) (unreachable) ) `), + `inline function type`, +); + +// ./test/core/if.wast:805 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32) (result i32))) (func (i32.const 0) (i32.const 1) (if (type $$sig) (param i32) (then (drop)) (else (drop))) (unreachable) ) `), + `inline function type`, +); + +// ./test/core/if.wast:815 +assert_malformed( + () => instantiate(`(type $$sig (func (param i32 i32) (result i32))) (func (i32.const 0) (i32.const 1) (if (type $$sig) (param i32) (result i32) (then)) (unreachable) ) `), + `inline function type`, +); + +// ./test/core/if.wast:825 +assert_invalid( + () => instantiate(`(module + (type $$sig (func)) + (func (i32.const 1) (if (type $$sig) (i32.const 0) (then))) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:833 +assert_invalid( + () => instantiate(`(module (func $$type-empty-i32 (result i32) (if (i32.const 0) (then))))`), + `type mismatch`, +); + +// ./test/core/if.wast:837 +assert_invalid( + () => instantiate(`(module (func $$type-empty-i64 (result i64) (if (i32.const 0) (then))))`), + `type mismatch`, +); + +// ./test/core/if.wast:841 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f32 (result f32) (if (i32.const 0) (then))))`), + `type mismatch`, +); + +// ./test/core/if.wast:845 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f64 (result f64) (if (i32.const 0) (then))))`), + `type mismatch`, +); + +// ./test/core/if.wast:850 +assert_invalid( + () => instantiate(`(module (func $$type-empty-i32 (result i32) (if (i32.const 0) (then) (else))))`), + `type mismatch`, +); + +// ./test/core/if.wast:854 +assert_invalid( + () => instantiate(`(module (func $$type-empty-i64 (result i64) (if (i32.const 0) (then) (else))))`), + `type mismatch`, +); + +// ./test/core/if.wast:858 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f32 (result f32) (if (i32.const 0) (then) (else))))`), + `type mismatch`, +); + +// ./test/core/if.wast:862 +assert_invalid( + () => instantiate(`(module (func $$type-empty-f64 (result f64) (if (i32.const 0) (then) (else))))`), + `type mismatch`, +); + +// ./test/core/if.wast:867 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-num-vs-void + (if (i32.const 1) (then (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:873 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-num-vs-void-else + (if (i32.const 1) (then (i32.const 1)) (else)) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:879 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-num-vs-void + (if (i32.const 1) (then) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:885 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-num-vs-void + (if (i32.const 1) (then (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:892 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-nums-vs-void + (if (i32.const 1) (then (i32.const 1) (i32.const 2))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:898 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-nums-vs-void-else + (if (i32.const 1) (then (i32.const 1) (i32.const 2)) (else)) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:904 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-nums-vs-void + (if (i32.const 1) (then) (else (i32.const 1) (i32.const 2))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:910 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-nums-vs-void + (if (i32.const 1) (then (i32.const 1) (i32.const 2)) (else (i32.const 2) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:917 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-empty-vs-num (result i32) + (if (result i32) (i32.const 1) (then) (else (i32.const 0))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:923 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-empty-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 0)) (else)) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:929 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-empty-vs-num (result i32) + (if (result i32) (i32.const 1) (then) (else)) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:936 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-empty-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then) (else (i32.const 0) (i32.const 2))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:942 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-empty-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 0) (i32.const 1)) (else)) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:948 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-empty-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then) (else)) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:955 +assert_invalid( + () => instantiate(`(module (func $$type-no-else-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:961 +assert_invalid( + () => instantiate(`(module (func $$type-no-else-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 1) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:968 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-void-vs-num (result i32) + (if (result i32) (i32.const 1) (then (nop)) (else (i32.const 0))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:974 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-void-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 0)) (else (nop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:980 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-void-vs-num (result i32) + (if (result i32) (i32.const 1) (then (nop)) (else (nop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:987 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (nop)) (else (i32.const 0) (i32.const 0))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:993 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 0) (i32.const 0)) (else (nop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:999 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (nop)) (else (nop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1006 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-num-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i64.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1012 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-num-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 1)) (else (i64.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1018 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-num-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i64.const 1)) (else (i64.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1025 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-num-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 1)) (else (i32.const 1) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1031 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-num-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 1) (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1037 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-num-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1044 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-partial-vs-nums (result i32 i32) + (i32.const 0) + (if (result i32 i32) (i32.const 1) (then (i32.const 1)) (else (i32.const 1) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1051 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-partial-vs-nums (result i32 i32) + (i32.const 0) + (if (result i32 i32) (i32.const 1) (then (i32.const 1) (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1058 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-partial-vs-nums (result i32 i32) + (i32.const 0) + (if (result i32 i32) (i32.const 1) (then (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1066 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-nums-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 1) (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1072 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-nums-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 1)) (else (i32.const 1) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1078 +assert_invalid( + () => instantiate(`(module (func $$type-both-value-nums-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 1) (i32.const 1)) (else (i32.const 1) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1085 +assert_invalid( + () => instantiate(`(module (func $$type-both-different-value-num-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i64.const 1)) (else (f64.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1091 +assert_invalid( + () => instantiate(`(module (func $$type-both-different-value-nums-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 1) (i32.const 1) (i32.const 1)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1098 +assert_invalid( + () => instantiate(`(module (func $$type-then-value-unreached-select (result i32) + (if (result i64) + (i32.const 0) + (then (select (unreachable) (unreachable) (unreachable))) + (else (i64.const 0)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1108 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-unreached-select (result i32) + (if (result i64) + (i32.const 1) + (then (i64.const 0)) + (else (select (unreachable) (unreachable) (unreachable))) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1118 +assert_invalid( + () => instantiate(`(module (func $$type-else-value-unreached-select (result i32) + (if (result i64) + (i32.const 1) + (then (select (unreachable) (unreachable) (unreachable))) + (else (select (unreachable) (unreachable) (unreachable))) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1129 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-last-void-vs-num (result i32) + (if (result i32) (i32.const 1) (then (br 0)) (else (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1135 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-last-void-vs-num (result i32) + (if (result i32) (i32.const 1) (then (i32.const 1)) (else (br 0))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1141 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-last-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (br 0)) (else (i32.const 1) (i32.const 1))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1147 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-last-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) (then (i32.const 1) (i32.const 1)) (else (br 0))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1154 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-empty-vs-num (result i32) + (if (result i32) (i32.const 1) + (then (br 0) (i32.const 1)) + (else (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1163 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-empty-vs-num (result i32) + (if (result i32) (i32.const 1) + (then (i32.const 1)) + (else (br 0) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1172 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-empty-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) + (then (br 0) (i32.const 1) (i32.const 1)) + (else (i32.const 1) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1181 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-empty-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) + (then (i32.const 1) (i32.const 1)) + (else (br 0) (i32.const 1) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1191 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-void-vs-num (result i32) + (if (result i32) (i32.const 1) + (then (br 0 (nop)) (i32.const 1)) + (else (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1200 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-void-vs-num (result i32) + (if (result i32) (i32.const 1) + (then (i32.const 1)) + (else (br 0 (nop)) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1209 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) + (then (br 0 (nop)) (i32.const 1) (i32.const 1)) + (else (i32.const 1) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1218 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-void-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) + (then (i32.const 1) (i32.const 1)) + (else (br 0 (nop)) (i32.const 1) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1228 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-num-vs-num (result i32) + (if (result i32) (i32.const 1) + (then (br 0 (i64.const 1)) (i32.const 1)) + (else (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1237 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-num-vs-num (result i32) + (if (result i32) (i32.const 1) + (then (i32.const 1)) + (else (br 0 (i64.const 1)) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1246 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-num-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) + (then (br 0 (i64.const 1)) (i32.const 1) (i32.const 1)) + (else (i32.const 1) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1255 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-num-vs-nums (result i32 i32) + (if (result i32 i32) (i32.const 1) + (then (i32.const 1) (i32.const 1)) + (else (br 0 (i64.const 1)) (i32.const 1) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1264 +assert_invalid( + () => instantiate(`(module (func $$type-then-break-partial-vs-nums (result i32 i32) + (i32.const 1) + (if (result i32 i32) (i32.const 1) + (then (br 0 (i64.const 1)) (i32.const 1)) + (else (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1274 +assert_invalid( + () => instantiate(`(module (func $$type-else-break-partial-vs-nums (result i32 i32) + (i32.const 1) + (if (result i32 i32) (i32.const 1) + (then (i32.const 1)) + (else (br 0 (i64.const 1)) (i32.const 1)) + ) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1285 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty + (if (then)) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1293 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-block + (i32.const 0) + (block (if (then))) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1302 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-loop + (i32.const 0) + (loop (if (then))) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1311 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-then + (i32.const 0) (i32.const 0) + (if (then (if (then)))) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1320 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-else + (i32.const 0) (i32.const 0) + (if (result i32) (then (i32.const 0)) (else (if (then)) (i32.const 0))) + (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1330 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-br + (i32.const 0) + (block (br 0 (if(then))) (drop)) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1339 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-br_if + (i32.const 0) + (block (br_if 0 (if(then)) (i32.const 1)) (drop)) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1348 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-br_table + (i32.const 0) + (block (br_table 0 (if(then))) (drop)) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1357 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-return + (return (if(then))) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1365 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-select + (select (if(then)) (i32.const 1) (i32.const 2)) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1373 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-call + (call 1 (if(then))) (drop) + ) + (func (param i32) (result i32) (local.get 0)) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1382 +assert_invalid( + () => instantiate(`(module + (func $$f (param i32) (result i32) (local.get 0)) + (type $$sig (func (param i32) (result i32))) + (table funcref (elem $$f)) + (func $$type-condition-empty-in-call_indirect + (block (result i32) + (call_indirect (type $$sig) + (if(then)) (i32.const 0) + ) + (drop) + ) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1398 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-local.set + (local i32) + (local.set 0 (if(then))) (local.get 0) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1407 +assert_invalid( + () => instantiate(`(module + (func $$type-condition-empty-in-local.tee + (local i32) + (local.tee 0 (if(then))) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1416 +assert_invalid( + () => instantiate(`(module + (global $$x (mut i32) (i32.const 0)) + (func $$type-condition-empty-in-global.set + (global.set $$x (if(then))) (global.get $$x) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1425 +assert_invalid( + () => instantiate(`(module + (memory 0) + (func $$type-condition-empty-in-memory.grow + (memory.grow (if(then))) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1434 +assert_invalid( + () => instantiate(`(module + (memory 0) + (func $$type-condition-empty-in-load + (i32.load (if(then))) (drop) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1443 +assert_invalid( + () => instantiate(`(module + (memory 1) + (func $$type-condition-empty-in-store + (i32.store (if(then)) (i32.const 1)) + ) + )`), + `type mismatch`, +); + +// ./test/core/if.wast:1453 +assert_invalid( + () => instantiate(`(module (func $$type-param-void-vs-num + (if (param i32) (i32.const 1) (then (drop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1459 +assert_invalid( + () => instantiate(`(module (func $$type-param-void-vs-nums + (if (param i32 f64) (i32.const 1) (then (drop) (drop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1465 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num + (f32.const 0) (if (param i32) (i32.const 1) (then (drop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1471 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-nums + (f32.const 0) (if (param f32 i32) (i32.const 1) (then (drop) (drop))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1477 +assert_invalid( + () => instantiate(`(module (func $$type-param-nested-void-vs-num + (block (if (param i32) (i32.const 1) (then (drop)))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1483 +assert_invalid( + () => instantiate(`(module (func $$type-param-void-vs-nums + (block (if (param i32 f64) (i32.const 1) (then (drop) (drop)))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1489 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num + (block (f32.const 0) (if (param i32) (i32.const 1) (then (drop)))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1495 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-nums + (block (f32.const 0) (if (param f32 i32) (i32.const 1) (then (drop) (drop)))) + ))`), + `type mismatch`, +); + +// ./test/core/if.wast:1502 +assert_malformed( + () => instantiate(`(func (param i32) (result i32) if (param $$x i32) end) `), + `unexpected token`, +); + +// ./test/core/if.wast:1506 +assert_malformed( + () => instantiate(`(func (param i32) (result i32) (if (param $$x i32) (then))) `), + `unexpected token`, +); + +// ./test/core/if.wast:1511 +assert_malformed(() => instantiate(`(func i32.const 0 if end $$l) `), `mismatching label`); + +// ./test/core/if.wast:1515 +assert_malformed( + () => instantiate(`(func i32.const 0 if $$a end $$l) `), + `mismatching label`, +); + +// ./test/core/if.wast:1519 +assert_malformed( + () => instantiate(`(func i32.const 0 if else $$l end) `), + `mismatching label`, +); + +// ./test/core/if.wast:1523 +assert_malformed( + () => instantiate(`(func i32.const 0 if $$a else $$l end) `), + `mismatching label`, +); + +// ./test/core/if.wast:1527 +assert_malformed( + () => instantiate(`(func i32.const 0 if else end $$l) `), + `mismatching label`, +); + +// ./test/core/if.wast:1531 +assert_malformed( + () => instantiate(`(func i32.const 0 if else $$l end $$l) `), + `mismatching label`, +); + +// ./test/core/if.wast:1535 +assert_malformed( + () => instantiate(`(func i32.const 0 if else $$l1 end $$l2) `), + `mismatching label`, +); + +// ./test/core/if.wast:1539 +assert_malformed( + () => instantiate(`(func i32.const 0 if $$a else end $$l) `), + `mismatching label`, +); + +// ./test/core/if.wast:1543 +assert_malformed( + () => instantiate(`(func i32.const 0 if $$a else $$a end $$l) `), + `mismatching label`, +); + +// ./test/core/if.wast:1547 +assert_malformed( + () => instantiate(`(func i32.const 0 if $$a else $$l end $$l) `), + `mismatching label`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/local_get.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/local_get.wast.js new file mode 100644 index 0000000000..c51b00bd31 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/local_get.wast.js @@ -0,0 +1,279 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/local_get.wast + +// ./test/core/local_get.wast:3 +let $0 = instantiate(`(module + ;; Typing + + (func (export "type-local-i32") (result i32) (local i32) (local.get 0)) + (func (export "type-local-i64") (result i64) (local i64) (local.get 0)) + (func (export "type-local-f32") (result f32) (local f32) (local.get 0)) + (func (export "type-local-f64") (result f64) (local f64) (local.get 0)) + + (func (export "type-param-i32") (param i32) (result i32) (local.get 0)) + (func (export "type-param-i64") (param i64) (result i64) (local.get 0)) + (func (export "type-param-f32") (param f32) (result f32) (local.get 0)) + (func (export "type-param-f64") (param f64) (result f64) (local.get 0)) + + (func (export "type-mixed") (param i64 f32 f64 i32 i32) + (local f32 i64 i64 f64) + (drop (i64.eqz (local.get 0))) + (drop (f32.neg (local.get 1))) + (drop (f64.neg (local.get 2))) + (drop (i32.eqz (local.get 3))) + (drop (i32.eqz (local.get 4))) + (drop (f32.neg (local.get 5))) + (drop (i64.eqz (local.get 6))) + (drop (i64.eqz (local.get 7))) + (drop (f64.neg (local.get 8))) + ) + + ;; Reading + + (func (export "read") (param i64 f32 f64 i32 i32) (result f64) + (local f32 i64 i64 f64) + (local.set 5 (f32.const 5.5)) + (local.set 6 (i64.const 6)) + (local.set 8 (f64.const 8)) + (f64.add + (f64.convert_i64_u (local.get 0)) + (f64.add + (f64.promote_f32 (local.get 1)) + (f64.add + (local.get 2) + (f64.add + (f64.convert_i32_u (local.get 3)) + (f64.add + (f64.convert_i32_s (local.get 4)) + (f64.add + (f64.promote_f32 (local.get 5)) + (f64.add + (f64.convert_i64_u (local.get 6)) + (f64.add + (f64.convert_i64_u (local.get 7)) + (local.get 8) + ) + ) + ) + ) + ) + ) + ) + ) + ) + + ;; As parameter of control constructs and instructions + + (func (export "as-block-value") (param i32) (result i32) + (block (result i32) (local.get 0)) + ) + (func (export "as-loop-value") (param i32) (result i32) + (loop (result i32) (local.get 0)) + ) + (func (export "as-br-value") (param i32) (result i32) + (block (result i32) (br 0 (local.get 0))) + ) + (func (export "as-br_if-value") (param i32) (result i32) + (block $$l0 (result i32) (br_if $$l0 (local.get 0) (i32.const 1))) + ) + + (func (export "as-br_if-value-cond") (param i32) (result i32) + (block (result i32) + (br_if 0 (local.get 0) (local.get 0)) + ) + ) + (func (export "as-br_table-value") (param i32) (result i32) + (block + (block + (block + (br_table 0 1 2 (local.get 0)) + (return (i32.const 0)) + ) + (return (i32.const 1)) + ) + (return (i32.const 2)) + ) + (i32.const 3) + ) + + (func (export "as-return-value") (param i32) (result i32) + (return (local.get 0)) + ) + + (func (export "as-if-then") (param i32) (result i32) + (if (result i32) (local.get 0) (then (local.get 0)) (else (i32.const 0))) + ) + (func (export "as-if-else") (param i32) (result i32) + (if (result i32) (local.get 0) (then (i32.const 1)) (else (local.get 0))) + ) +)`); + +// ./test/core/local_get.wast:109 +assert_return(() => invoke($0, `type-local-i32`, []), [value("i32", 0)]); + +// ./test/core/local_get.wast:110 +assert_return(() => invoke($0, `type-local-i64`, []), [value("i64", 0n)]); + +// ./test/core/local_get.wast:111 +assert_return(() => invoke($0, `type-local-f32`, []), [value("f32", 0)]); + +// ./test/core/local_get.wast:112 +assert_return(() => invoke($0, `type-local-f64`, []), [value("f64", 0)]); + +// ./test/core/local_get.wast:114 +assert_return(() => invoke($0, `type-param-i32`, [2]), [value("i32", 2)]); + +// ./test/core/local_get.wast:115 +assert_return(() => invoke($0, `type-param-i64`, [3n]), [value("i64", 3n)]); + +// ./test/core/local_get.wast:116 +assert_return(() => invoke($0, `type-param-f32`, [value("f32", 4.4)]), [value("f32", 4.4)]); + +// ./test/core/local_get.wast:117 +assert_return(() => invoke($0, `type-param-f64`, [value("f64", 5.5)]), [value("f64", 5.5)]); + +// ./test/core/local_get.wast:119 +assert_return(() => invoke($0, `as-block-value`, [6]), [value("i32", 6)]); + +// ./test/core/local_get.wast:120 +assert_return(() => invoke($0, `as-loop-value`, [7]), [value("i32", 7)]); + +// ./test/core/local_get.wast:122 +assert_return(() => invoke($0, `as-br-value`, [8]), [value("i32", 8)]); + +// ./test/core/local_get.wast:123 +assert_return(() => invoke($0, `as-br_if-value`, [9]), [value("i32", 9)]); + +// ./test/core/local_get.wast:124 +assert_return(() => invoke($0, `as-br_if-value-cond`, [10]), [value("i32", 10)]); + +// ./test/core/local_get.wast:125 +assert_return(() => invoke($0, `as-br_table-value`, [1]), [value("i32", 2)]); + +// ./test/core/local_get.wast:127 +assert_return(() => invoke($0, `as-return-value`, [0]), [value("i32", 0)]); + +// ./test/core/local_get.wast:129 +assert_return(() => invoke($0, `as-if-then`, [1]), [value("i32", 1)]); + +// ./test/core/local_get.wast:130 +assert_return(() => invoke($0, `as-if-else`, [0]), [value("i32", 0)]); + +// ./test/core/local_get.wast:132 +assert_return(() => invoke($0, `type-mixed`, [1n, value("f32", 2.2), value("f64", 3.3), 4, 5]), []); + +// ./test/core/local_get.wast:138 +assert_return( + () => invoke($0, `read`, [1n, value("f32", 2), value("f64", 3.3), 4, 5]), + [value("f64", 34.8)], +); + +// ./test/core/local_get.wast:148 +assert_invalid( + () => instantiate(`(module (func $$type-local-num-vs-num (result i64) (local i32) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:152 +assert_invalid( + () => instantiate(`(module (func $$type-local-num-vs-num (result i32) (local f32) (i32.eqz (local.get 0))))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:156 +assert_invalid( + () => instantiate(`(module (func $$type-local-num-vs-num (result f64) (local f64 i64) (f64.neg (local.get 1))))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:164 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num (param i32) (result i64) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:168 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num (param f32) (result i32) (i32.eqz (local.get 0))))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:172 +assert_invalid( + () => instantiate(`(module (func $$type-param-num-vs-num (param f64 i64) (result f64) (f64.neg (local.get 1))))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:180 +assert_invalid( + () => instantiate(`(module (func $$type-empty-vs-i32 (local i32) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:184 +assert_invalid( + () => instantiate(`(module (func $$type-empty-vs-i64 (local i64) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:188 +assert_invalid( + () => instantiate(`(module (func $$type-empty-vs-f32 (local f32) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:192 +assert_invalid( + () => instantiate(`(module (func $$type-empty-vs-f64 (local f64) (local.get 0)))`), + `type mismatch`, +); + +// ./test/core/local_get.wast:200 +assert_invalid( + () => instantiate(`(module (func $$unbound-local (local i32 i64) (local.get 3) drop))`), + `unknown local`, +); + +// ./test/core/local_get.wast:204 +assert_invalid( + () => instantiate(`(module (func $$large-local (local i32 i64) (local.get 14324343) drop))`), + `unknown local`, +); + +// ./test/core/local_get.wast:209 +assert_invalid( + () => instantiate(`(module (func $$unbound-param (param i32 i64) (local.get 2) drop))`), + `unknown local`, +); + +// ./test/core/local_get.wast:213 +assert_invalid( + () => instantiate(`(module (func $$large-param (param i32 i64) (local.get 714324343) drop))`), + `unknown local`, +); + +// ./test/core/local_get.wast:218 +assert_invalid( + () => instantiate(`(module (func $$unbound-mixed (param i32) (local i32 i64) (local.get 3) drop))`), + `unknown local`, +); + +// ./test/core/local_get.wast:222 +assert_invalid( + () => instantiate(`(module (func $$large-mixed (param i64) (local i32 i64) (local.get 214324343) drop))`), + `unknown local`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/ref.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/ref.wast.js new file mode 100644 index 0000000000..5d2fce2314 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/ref.wast.js @@ -0,0 +1,110 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/ref.wast + +// ./test/core/ref.wast:3 +let $0 = instantiate(`(module + (type $$t (func)) + + (func + (param + funcref + externref + (ref func) + (ref extern) + (ref 0) + (ref $$t) + (ref 0) + (ref $$t) + (ref null func) + (ref null extern) + (ref null 0) + (ref null $$t) + ) + ) +)`); + +// ./test/core/ref.wast:27 +assert_invalid( + () => instantiate(`(module (type $$type-func-param-invalid (func (param (ref 1)))))`), + `unknown type`, +); + +// ./test/core/ref.wast:31 +assert_invalid( + () => instantiate(`(module (type $$type-func-result-invalid (func (result (ref 1)))))`), + `unknown type`, +); + +// ./test/core/ref.wast:36 +assert_invalid( + () => instantiate(`(module (global $$global-invalid (ref null 1) (ref.null 1)))`), + `unknown type`, +); + +// ./test/core/ref.wast:41 +assert_invalid( + () => instantiate(`(module (table $$table-invalid 10 (ref null 1)))`), + `unknown type`, +); + +// ./test/core/ref.wast:46 +assert_invalid( + () => instantiate(`(module (elem $$elem-invalid (ref 1)))`), + `unknown type`, +); + +// ./test/core/ref.wast:51 +assert_invalid( + () => instantiate(`(module (func $$func-param-invalid (param (ref 1))))`), + `unknown type`, +); + +// ./test/core/ref.wast:55 +assert_invalid( + () => instantiate(`(module (func $$func-result-invalid (result (ref 1))))`), + `unknown type`, +); + +// ./test/core/ref.wast:59 +assert_invalid( + () => instantiate(`(module (func $$func-local-invalid (local (ref null 1))))`), + `unknown type`, +); + +// ./test/core/ref.wast:64 +assert_invalid( + () => instantiate(`(module (func $$block-result-invalid (drop (block (result (ref 1)) (unreachable)))))`), + `unknown type`, +); + +// ./test/core/ref.wast:68 +assert_invalid( + () => instantiate(`(module (func $$loop-result-invalid (drop (loop (result (ref 1)) (unreachable)))))`), + `unknown type`, +); + +// ./test/core/ref.wast:72 +assert_invalid( + () => instantiate(`(module (func $$if-invalid (drop (if (result (ref 1)) (then) (else)))))`), + `unknown type`, +); + +// ./test/core/ref.wast:77 +assert_invalid( + () => instantiate(`(module (func $$select-result-invalid (drop (select (result (ref 1)) (unreachable)))))`), + `unknown type`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/ref_as_non_null.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/ref_as_non_null.wast.js new file mode 100644 index 0000000000..af2628a7b6 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/ref_as_non_null.wast.js @@ -0,0 +1,71 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/ref_as_non_null.wast + +// ./test/core/ref_as_non_null.wast:1 +let $0 = instantiate(`(module + (type $$t (func (result i32))) + + (func $$nn (param $$r (ref $$t)) (result i32) + (call_ref $$t (ref.as_non_null (local.get $$r))) + ) + (func $$n (param $$r (ref null $$t)) (result i32) + (call_ref $$t (ref.as_non_null (local.get $$r))) + ) + + (elem func $$f) + (func $$f (result i32) (i32.const 7)) + + (func (export "nullable-null") (result i32) (call $$n (ref.null $$t))) + (func (export "nonnullable-f") (result i32) (call $$nn (ref.func $$f))) + (func (export "nullable-f") (result i32) (call $$n (ref.func $$f))) + + (func (export "unreachable") (result i32) + (unreachable) + (ref.as_non_null) + (call $$nn) + ) +)`); + +// ./test/core/ref_as_non_null.wast:25 +assert_trap(() => invoke($0, `unreachable`, []), `unreachable`); + +// ./test/core/ref_as_non_null.wast:27 +assert_trap(() => invoke($0, `nullable-null`, []), `null reference`); + +// ./test/core/ref_as_non_null.wast:28 +assert_return(() => invoke($0, `nonnullable-f`, []), [value("i32", 7)]); + +// ./test/core/ref_as_non_null.wast:29 +assert_return(() => invoke($0, `nullable-f`, []), [value("i32", 7)]); + +// ./test/core/ref_as_non_null.wast:31 +assert_invalid( + () => instantiate(`(module + (type $$t (func (result i32))) + (func $$g (param $$r (ref $$t)) (drop (ref.as_non_null (local.get $$r)))) + (func (call $$g (ref.null $$t))) + )`), + `type mismatch`, +); + +// ./test/core/ref_as_non_null.wast:41 +let $1 = instantiate(`(module + (type $$t (func)) + (func (param $$r (ref $$t)) (drop (ref.as_non_null (local.get $$r)))) + (func (param $$r (ref func)) (drop (ref.as_non_null (local.get $$r)))) + (func (param $$r (ref extern)) (drop (ref.as_non_null (local.get $$r)))) +)`); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/ref_func.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/ref_func.wast.js new file mode 100644 index 0000000000..3ca5cea002 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/ref_func.wast.js @@ -0,0 +1,156 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/ref_func.wast + +// ./test/core/ref_func.wast:1 +let $0 = instantiate(`(module + (func (export "f") (param $$x i32) (result i32) (local.get $$x)) +)`); + +// ./test/core/ref_func.wast:4 +register($0, `M`); + +// ./test/core/ref_func.wast:6 +let $1 = instantiate(`(module + (func $$f (import "M" "f") (param i32) (result i32)) + (func $$g (param $$x i32) (result i32) + (i32.add (local.get $$x) (i32.const 1)) + ) + + (global funcref (ref.func $$f)) + (global funcref (ref.func $$g)) + (global $$v (mut funcref) (ref.func $$f)) + + (global funcref (ref.func $$gf1)) + (global funcref (ref.func $$gf2)) + (func (drop (ref.func $$ff1)) (drop (ref.func $$ff2))) + (elem declare func $$gf1 $$ff1) + (elem declare funcref (ref.func $$gf2) (ref.func $$ff2)) + (func $$gf1) + (func $$gf2) + (func $$ff1) + (func $$ff2) + + (func (export "is_null-f") (result i32) + (ref.is_null (ref.func $$f)) + ) + (func (export "is_null-g") (result i32) + (ref.is_null (ref.func $$g)) + ) + (func (export "is_null-v") (result i32) + (ref.is_null (global.get $$v)) + ) + + (func (export "set-f") (global.set $$v (ref.func $$f))) + (func (export "set-g") (global.set $$v (ref.func $$g))) + + (table $$t 1 funcref) + (elem declare func $$f $$g) + + (func (export "call-f") (param $$x i32) (result i32) + (table.set $$t (i32.const 0) (ref.func $$f)) + (call_indirect $$t (param i32) (result i32) (local.get $$x) (i32.const 0)) + ) + (func (export "call-g") (param $$x i32) (result i32) + (table.set $$t (i32.const 0) (ref.func $$g)) + (call_indirect $$t (param i32) (result i32) (local.get $$x) (i32.const 0)) + ) + (func (export "call-v") (param $$x i32) (result i32) + (table.set $$t (i32.const 0) (global.get $$v)) + (call_indirect $$t (param i32) (result i32) (local.get $$x) (i32.const 0)) + ) +)`); + +// ./test/core/ref_func.wast:56 +assert_return(() => invoke($1, `is_null-f`, []), [value("i32", 0)]); + +// ./test/core/ref_func.wast:57 +assert_return(() => invoke($1, `is_null-g`, []), [value("i32", 0)]); + +// ./test/core/ref_func.wast:58 +assert_return(() => invoke($1, `is_null-v`, []), [value("i32", 0)]); + +// ./test/core/ref_func.wast:60 +assert_return(() => invoke($1, `call-f`, [4]), [value("i32", 4)]); + +// ./test/core/ref_func.wast:61 +assert_return(() => invoke($1, `call-g`, [4]), [value("i32", 5)]); + +// ./test/core/ref_func.wast:62 +assert_return(() => invoke($1, `call-v`, [4]), [value("i32", 4)]); + +// ./test/core/ref_func.wast:63 +invoke($1, `set-g`, []); + +// ./test/core/ref_func.wast:64 +assert_return(() => invoke($1, `call-v`, [4]), [value("i32", 5)]); + +// ./test/core/ref_func.wast:65 +invoke($1, `set-f`, []); + +// ./test/core/ref_func.wast:66 +assert_return(() => invoke($1, `call-v`, [4]), [value("i32", 4)]); + +// ./test/core/ref_func.wast:68 +assert_invalid( + () => instantiate(`(module + (func $$f (import "M" "f") (param i32) (result i32)) + (func $$g (import "M" "g") (param i32) (result i32)) + (global funcref (ref.func 7)) + )`), + `unknown function 7`, +); + +// ./test/core/ref_func.wast:80 +let $2 = instantiate(`(module + (func $$f1) + (func $$f2) + (func $$f3) + (func $$f4) + (func $$f5) + (func $$f6) + + (table $$t 1 funcref) + + (global funcref (ref.func $$f1)) + (export "f" (func $$f2)) + (elem (table $$t) (i32.const 0) func $$f3) + (elem (table $$t) (i32.const 0) funcref (ref.func $$f4)) + (elem func $$f5) + (elem funcref (ref.func $$f6)) + + (func + (ref.func $$f1) + (ref.func $$f2) + (ref.func $$f3) + (ref.func $$f4) + (ref.func $$f5) + (ref.func $$f6) + (return) + ) +)`); + +// ./test/core/ref_func.wast:108 +assert_invalid( + () => instantiate(`(module (func $$f (drop (ref.func $$f))))`), + `undeclared function reference`, +); + +// ./test/core/ref_func.wast:112 +assert_invalid( + () => instantiate(`(module (start $$f) (func $$f (drop (ref.func $$f))))`), + `undeclared function reference`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/return_call_ref.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/return_call_ref.wast.js new file mode 100644 index 0000000000..3ea51a8cb0 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/return_call_ref.wast.js @@ -0,0 +1,460 @@ +// |jit-test| --wasm-tail-calls; skip-if: !wasmTailCallsEnabled() +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/return_call_ref.wast + +// ./test/core/return_call_ref.wast:3 +let $0 = instantiate(`(module + ;; Auxiliary definitions + (type $$proc (func)) + (type $$-i32 (func (result i32))) + (type $$-i64 (func (result i64))) + (type $$-f32 (func (result f32))) + (type $$-f64 (func (result f64))) + + (type $$i32-i32 (func (param i32) (result i32))) + (type $$i64-i64 (func (param i64) (result i64))) + (type $$f32-f32 (func (param f32) (result f32))) + (type $$f64-f64 (func (param f64) (result f64))) + + (type $$f32-i32 (func (param f32 i32) (result i32))) + (type $$i32-i64 (func (param i32 i64) (result i64))) + (type $$f64-f32 (func (param f64 f32) (result f32))) + (type $$i64-f64 (func (param i64 f64) (result f64))) + + (type $$i64i64-i64 (func (param i64 i64) (result i64))) + + (func $$const-i32 (result i32) (i32.const 0x132)) + (func $$const-i64 (result i64) (i64.const 0x164)) + (func $$const-f32 (result f32) (f32.const 0xf32)) + (func $$const-f64 (result f64) (f64.const 0xf64)) + + (func $$id-i32 (param i32) (result i32) (local.get 0)) + (func $$id-i64 (param i64) (result i64) (local.get 0)) + (func $$id-f32 (param f32) (result f32) (local.get 0)) + (func $$id-f64 (param f64) (result f64) (local.get 0)) + + (func $$f32-i32 (param f32 i32) (result i32) (local.get 1)) + (func $$i32-i64 (param i32 i64) (result i64) (local.get 1)) + (func $$f64-f32 (param f64 f32) (result f32) (local.get 1)) + (func $$i64-f64 (param i64 f64) (result f64) (local.get 1)) + + (global $$const-i32 (ref $$-i32) (ref.func $$const-i32)) + (global $$const-i64 (ref $$-i64) (ref.func $$const-i64)) + (global $$const-f32 (ref $$-f32) (ref.func $$const-f32)) + (global $$const-f64 (ref $$-f64) (ref.func $$const-f64)) + + (global $$id-i32 (ref $$i32-i32) (ref.func $$id-i32)) + (global $$id-i64 (ref $$i64-i64) (ref.func $$id-i64)) + (global $$id-f32 (ref $$f32-f32) (ref.func $$id-f32)) + (global $$id-f64 (ref $$f64-f64) (ref.func $$id-f64)) + + (global $$f32-i32 (ref $$f32-i32) (ref.func $$f32-i32)) + (global $$i32-i64 (ref $$i32-i64) (ref.func $$i32-i64)) + (global $$f64-f32 (ref $$f64-f32) (ref.func $$f64-f32)) + (global $$i64-f64 (ref $$i64-f64) (ref.func $$i64-f64)) + + (elem declare func + $$const-i32 $$const-i64 $$const-f32 $$const-f64 + $$id-i32 $$id-i64 $$id-f32 $$id-f64 + $$f32-i32 $$i32-i64 $$f64-f32 $$i64-f64 + ) + + ;; Typing + + (func (export "type-i32") (result i32) + (return_call_ref $$-i32 (global.get $$const-i32)) + ) + (func (export "type-i64") (result i64) + (return_call_ref $$-i64 (global.get $$const-i64)) + ) + (func (export "type-f32") (result f32) + (return_call_ref $$-f32 (global.get $$const-f32)) + ) + (func (export "type-f64") (result f64) + (return_call_ref $$-f64 (global.get $$const-f64)) + ) + + (func (export "type-first-i32") (result i32) + (return_call_ref $$i32-i32 (i32.const 32) (global.get $$id-i32)) + ) + (func (export "type-first-i64") (result i64) + (return_call_ref $$i64-i64 (i64.const 64) (global.get $$id-i64)) + ) + (func (export "type-first-f32") (result f32) + (return_call_ref $$f32-f32 (f32.const 1.32) (global.get $$id-f32)) + ) + (func (export "type-first-f64") (result f64) + (return_call_ref $$f64-f64 (f64.const 1.64) (global.get $$id-f64)) + ) + + (func (export "type-second-i32") (result i32) + (return_call_ref $$f32-i32 (f32.const 32.1) (i32.const 32) (global.get $$f32-i32)) + ) + (func (export "type-second-i64") (result i64) + (return_call_ref $$i32-i64 (i32.const 32) (i64.const 64) (global.get $$i32-i64)) + ) + (func (export "type-second-f32") (result f32) + (return_call_ref $$f64-f32 (f64.const 64) (f32.const 32) (global.get $$f64-f32)) + ) + (func (export "type-second-f64") (result f64) + (return_call_ref $$i64-f64 (i64.const 64) (f64.const 64.1) (global.get $$i64-f64)) + ) + + ;; Null + + (func (export "null") + (return_call_ref $$proc (ref.null $$proc)) + ) + + ;; Recursion + + (global $$fac-acc (ref $$i64i64-i64) (ref.func $$fac-acc)) + + (elem declare func $$fac-acc) + (func $$fac-acc (export "fac-acc") (param i64 i64) (result i64) + (if (result i64) (i64.eqz (local.get 0)) + (then (local.get 1)) + (else + (return_call_ref $$i64i64-i64 + (i64.sub (local.get 0) (i64.const 1)) + (i64.mul (local.get 0) (local.get 1)) + (global.get $$fac-acc) + ) + ) + ) + ) + + (global $$count (ref $$i64-i64) (ref.func $$count)) + + (elem declare func $$count) + (func $$count (export "count") (param i64) (result i64) + (if (result i64) (i64.eqz (local.get 0)) + (then (local.get 0)) + (else + (return_call_ref $$i64-i64 + (i64.sub (local.get 0) (i64.const 1)) + (global.get $$count) + ) + ) + ) + ) + + (global $$even (ref $$i64-i64) (ref.func $$even)) + (global $$odd (ref $$i64-i64) (ref.func $$odd)) + + (elem declare func $$even) + (func $$even (export "even") (param i64) (result i64) + (if (result i64) (i64.eqz (local.get 0)) + (then (i64.const 44)) + (else + (return_call_ref $$i64-i64 + (i64.sub (local.get 0) (i64.const 1)) + (global.get $$odd) + ) + ) + ) + ) + (elem declare func $$odd) + (func $$odd (export "odd") (param i64) (result i64) + (if (result i64) (i64.eqz (local.get 0)) + (then (i64.const 99)) + (else + (return_call_ref $$i64-i64 + (i64.sub (local.get 0) (i64.const 1)) + (global.get $$even) + ) + ) + ) + ) +)`); + +// ./test/core/return_call_ref.wast:168 +assert_return(() => invoke($0, `type-i32`, []), [value("i32", 306)]); + +// ./test/core/return_call_ref.wast:169 +assert_return(() => invoke($0, `type-i64`, []), [value("i64", 356n)]); + +// ./test/core/return_call_ref.wast:170 +assert_return(() => invoke($0, `type-f32`, []), [value("f32", 3890)]); + +// ./test/core/return_call_ref.wast:171 +assert_return(() => invoke($0, `type-f64`, []), [value("f64", 3940)]); + +// ./test/core/return_call_ref.wast:173 +assert_return(() => invoke($0, `type-first-i32`, []), [value("i32", 32)]); + +// ./test/core/return_call_ref.wast:174 +assert_return(() => invoke($0, `type-first-i64`, []), [value("i64", 64n)]); + +// ./test/core/return_call_ref.wast:175 +assert_return(() => invoke($0, `type-first-f32`, []), [value("f32", 1.32)]); + +// ./test/core/return_call_ref.wast:176 +assert_return(() => invoke($0, `type-first-f64`, []), [value("f64", 1.64)]); + +// ./test/core/return_call_ref.wast:178 +assert_return(() => invoke($0, `type-second-i32`, []), [value("i32", 32)]); + +// ./test/core/return_call_ref.wast:179 +assert_return(() => invoke($0, `type-second-i64`, []), [value("i64", 64n)]); + +// ./test/core/return_call_ref.wast:180 +assert_return(() => invoke($0, `type-second-f32`, []), [value("f32", 32)]); + +// ./test/core/return_call_ref.wast:181 +assert_return(() => invoke($0, `type-second-f64`, []), [value("f64", 64.1)]); + +// ./test/core/return_call_ref.wast:183 +assert_trap(() => invoke($0, `null`, []), `null function`); + +// ./test/core/return_call_ref.wast:185 +assert_return(() => invoke($0, `fac-acc`, [0n, 1n]), [value("i64", 1n)]); + +// ./test/core/return_call_ref.wast:186 +assert_return(() => invoke($0, `fac-acc`, [1n, 1n]), [value("i64", 1n)]); + +// ./test/core/return_call_ref.wast:187 +assert_return(() => invoke($0, `fac-acc`, [5n, 1n]), [value("i64", 120n)]); + +// ./test/core/return_call_ref.wast:188 +assert_return(() => invoke($0, `fac-acc`, [25n, 1n]), [value("i64", 7034535277573963776n)]); + +// ./test/core/return_call_ref.wast:193 +assert_return(() => invoke($0, `count`, [0n]), [value("i64", 0n)]); + +// ./test/core/return_call_ref.wast:194 +assert_return(() => invoke($0, `count`, [1000n]), [value("i64", 0n)]); + +// ./test/core/return_call_ref.wast:195 +assert_return(() => invoke($0, `count`, [1000000n]), [value("i64", 0n)]); + +// ./test/core/return_call_ref.wast:197 +assert_return(() => invoke($0, `even`, [0n]), [value("i64", 44n)]); + +// ./test/core/return_call_ref.wast:198 +assert_return(() => invoke($0, `even`, [1n]), [value("i64", 99n)]); + +// ./test/core/return_call_ref.wast:199 +assert_return(() => invoke($0, `even`, [100n]), [value("i64", 44n)]); + +// ./test/core/return_call_ref.wast:200 +assert_return(() => invoke($0, `even`, [77n]), [value("i64", 99n)]); + +// ./test/core/return_call_ref.wast:201 +assert_return(() => invoke($0, `even`, [1000000n]), [value("i64", 44n)]); + +// ./test/core/return_call_ref.wast:202 +assert_return(() => invoke($0, `even`, [1000001n]), [value("i64", 99n)]); + +// ./test/core/return_call_ref.wast:203 +assert_return(() => invoke($0, `odd`, [0n]), [value("i64", 99n)]); + +// ./test/core/return_call_ref.wast:204 +assert_return(() => invoke($0, `odd`, [1n]), [value("i64", 44n)]); + +// ./test/core/return_call_ref.wast:205 +assert_return(() => invoke($0, `odd`, [200n]), [value("i64", 99n)]); + +// ./test/core/return_call_ref.wast:206 +assert_return(() => invoke($0, `odd`, [77n]), [value("i64", 44n)]); + +// ./test/core/return_call_ref.wast:207 +assert_return(() => invoke($0, `odd`, [1000000n]), [value("i64", 99n)]); + +// ./test/core/return_call_ref.wast:208 +assert_return(() => invoke($0, `odd`, [999999n]), [value("i64", 44n)]); + +// ./test/core/return_call_ref.wast:213 +let $1 = instantiate(`(module + (type $$t (func)) + (type $$t1 (func (result (ref $$t)))) + (type $$t2 (func (result (ref null $$t)))) + (type $$t3 (func (result (ref func)))) + (type $$t4 (func (result (ref null func)))) + (elem declare func $$f11 $$f22 $$f33 $$f44) + (func $$f11 (result (ref $$t)) (return_call_ref $$t1 (ref.func $$f11))) + (func $$f21 (result (ref null $$t)) (return_call_ref $$t1 (ref.func $$f11))) + (func $$f22 (result (ref null $$t)) (return_call_ref $$t2 (ref.func $$f22))) + (func $$f31 (result (ref func)) (return_call_ref $$t1 (ref.func $$f11))) + (func $$f33 (result (ref func)) (return_call_ref $$t3 (ref.func $$f33))) + (func $$f41 (result (ref null func)) (return_call_ref $$t1 (ref.func $$f11))) + (func $$f42 (result (ref null func)) (return_call_ref $$t2 (ref.func $$f22))) + (func $$f43 (result (ref null func)) (return_call_ref $$t3 (ref.func $$f33))) + (func $$f44 (result (ref null func)) (return_call_ref $$t4 (ref.func $$f44))) +)`); + +// ./test/core/return_call_ref.wast:231 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (type $$t2 (func (result (ref null $$t)))) + (elem declare func $$f22) + (func $$f12 (result (ref $$t)) (return_call_ref $$t2 (ref.func $$f22))) + (func $$f22 (result (ref null $$t)) (return_call_ref $$t2 (ref.func $$f22))) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:242 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (type $$t3 (func (result (ref func)))) + (elem declare func $$f33) + (func $$f13 (result (ref $$t)) (return_call_ref $$t3 (ref.func $$f33))) + (func $$f33 (result (ref func)) (return_call_ref $$t3 (ref.func $$f33))) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:253 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (type $$t4 (func (result (ref null func)))) + (elem declare func $$f44) + (func $$f14 (result (ref $$t)) (return_call_ref $$t4 (ref.func $$f44))) + (func $$f44 (result (ref null func)) (return_call_ref $$t4 (ref.func $$f44))) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:264 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (type $$t3 (func (result (ref func)))) + (elem declare func $$f33) + (func $$f23 (result (ref null $$t)) (return_call_ref $$t3 (ref.func $$f33))) + (func $$f33 (result (ref func)) (return_call_ref $$t3 (ref.func $$f33))) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:275 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (type $$t4 (func (result (ref null func)))) + (elem declare func $$f44) + (func $$f24 (result (ref null $$t)) (return_call_ref $$t4 (ref.func $$f44))) + (func $$f44 (result (ref null func)) (return_call_ref $$t4 (ref.func $$f44))) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:286 +assert_invalid( + () => instantiate(`(module + (type $$t4 (func (result (ref null func)))) + (elem declare func $$f44) + (func $$f34 (result (ref func)) (return_call_ref $$t4 (ref.func $$f44))) + (func $$f44 (result (ref null func)) (return_call_ref $$t4 (ref.func $$f44))) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:299 +let $2 = instantiate(`(module + (type $$t (func (result i32))) + (func (export "unreachable") (result i32) + (unreachable) + (return_call_ref $$t) + ) +)`); + +// ./test/core/return_call_ref.wast:306 +assert_trap(() => invoke($2, `unreachable`, []), `unreachable`); + +// ./test/core/return_call_ref.wast:308 +let $3 = instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (ref.func $$f) + (return_call_ref $$t) + ) +)`); + +// ./test/core/return_call_ref.wast:319 +assert_trap(() => invoke($3, `unreachable`, []), `unreachable`); + +// ./test/core/return_call_ref.wast:321 +let $4 = instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (i32.const 0) + (ref.func $$f) + (return_call_ref $$t) + (i32.const 0) + ) +)`); + +// ./test/core/return_call_ref.wast:334 +assert_trap(() => invoke($4, `unreachable`, []), `unreachable`); + +// ./test/core/return_call_ref.wast:336 +assert_invalid( + () => instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (i64.const 0) + (ref.func $$f) + (return_call_ref $$t) + ) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:352 +assert_invalid( + () => instantiate(`(module + (elem declare func $$f) + (type $$t (func (param i32) (result i32))) + (func $$f (param i32) (result i32) (local.get 0)) + + (func (export "unreachable") (result i32) + (unreachable) + (ref.func $$f) + (return_call_ref $$t) + (i64.const 0) + ) + )`), + `type mismatch`, +); + +// ./test/core/return_call_ref.wast:368 +assert_invalid( + () => instantiate(`(module + (type $$t (func)) + (func $$f (param $$r externref) + (return_call_ref $$t (local.get $$r)) + ) + )`), + `type mismatch`, +); diff --git a/js/src/jit-test/tests/wasm/spec/function-references/unreached-valid.wast.js b/js/src/jit-test/tests/wasm/spec/function-references/unreached-valid.wast.js new file mode 100644 index 0000000000..e25a157431 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/function-references/unreached-valid.wast.js @@ -0,0 +1,109 @@ +/* Copyright 2021 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ./test/core/unreached-valid.wast + +// ./test/core/unreached-valid.wast:1 +let $0 = instantiate(`(module + + ;; Check that both sides of the select are evaluated + (func (export "select-trap-left") (param $$cond i32) (result i32) + (select (unreachable) (i32.const 0) (local.get $$cond)) + ) + (func (export "select-trap-right") (param $$cond i32) (result i32) + (select (i32.const 0) (unreachable) (local.get $$cond)) + ) + + (func (export "select-unreached") + (unreachable) (select) + (unreachable) (i32.const 0) (select) + (unreachable) (i32.const 0) (i32.const 0) (select) + (unreachable) (i32.const 0) (i32.const 0) (i32.const 0) (select) + (unreachable) (f32.const 0) (i32.const 0) (select) + (unreachable) + ) + + (func (export "select-unreached-result1") (result i32) + (unreachable) (i32.add (select)) + ) + + (func (export "select-unreached-result2") (result i64) + (unreachable) (i64.add (select (i64.const 0) (i32.const 0))) + ) + + (func (export "select-unreached-num") + (unreachable) + (select) + (i32.eqz) + (drop) + ) + (func (export "select-unreached-ref") + (unreachable) + (select) + (ref.is_null) + (drop) + ) + + (type $$t (func (param i32) (result i32))) + (func (export "call_ref-unreached") (result i32) + (unreachable) + (call_ref $$t) + ) +)`); + +// ./test/core/unreached-valid.wast:48 +assert_trap(() => invoke($0, `select-trap-left`, [1]), `unreachable`); + +// ./test/core/unreached-valid.wast:49 +assert_trap(() => invoke($0, `select-trap-left`, [0]), `unreachable`); + +// ./test/core/unreached-valid.wast:50 +assert_trap(() => invoke($0, `select-trap-right`, [1]), `unreachable`); + +// ./test/core/unreached-valid.wast:51 +assert_trap(() => invoke($0, `select-trap-right`, [0]), `unreachable`); + +// ./test/core/unreached-valid.wast:53 +assert_trap(() => invoke($0, `select-unreached-result1`, []), `unreachable`); + +// ./test/core/unreached-valid.wast:54 +assert_trap(() => invoke($0, `select-unreached-result2`, []), `unreachable`); + +// ./test/core/unreached-valid.wast:55 +assert_trap(() => invoke($0, `select-unreached-num`, []), `unreachable`); + +// ./test/core/unreached-valid.wast:56 +assert_trap(() => invoke($0, `select-unreached-ref`, []), `unreachable`); + +// ./test/core/unreached-valid.wast:58 +assert_trap(() => invoke($0, `call_ref-unreached`, []), `unreachable`); + +// ./test/core/unreached-valid.wast:63 +let $1 = instantiate(`(module + (func (export "meet-bottom") + (block (result f64) + (block (result f32) + (unreachable) + (br_table 0 1 1 (i32.const 1)) + ) + (drop) + (f64.const 0) + ) + (drop) + ) +)`); + +// ./test/core/unreached-valid.wast:77 +assert_trap(() => invoke($1, `meet-bottom`, []), `unreachable`); -- cgit v1.2.3