summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-builder.h29
-rw-r--r--src/wasm/wasm-binary.cpp31
-rw-r--r--src/wasm/wasm-s-parser.cpp35
-rw-r--r--test/lit/passes/dae_all-features.wast2
-rw-r--r--test/lit/passes/gufa-refs.wast10
-rw-r--r--test/lit/passes/inlining-optimizing.wast2
-rw-r--r--test/lit/passes/local-cse_all-features.wast11
-rw-r--r--test/lit/passes/optimize-instructions-call_ref-roundtrip.wast6
-rw-r--r--test/lit/passes/optimize-instructions-call_ref.wast26
-rw-r--r--test/lit/passes/precompute-gc.wast2
-rw-r--r--test/lit/passes/remove-unused-module-elements-refs.wast18
-rw-r--r--test/lit/passes/signature-pruning.wast16
-rw-r--r--test/lit/passes/signature-refining.wast12
-rw-r--r--test/lit/types-function-references.wast10
-rw-r--r--test/lit/validation/nn-locals-bad-call_ref.wast3
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.wast4
-rw-r--r--test/passes/duplicate-function-elimination_all-features.wast2
-rw-r--r--test/spec/br_on_null.wast8
-rw-r--r--test/spec/call_ref.wast21
-rw-r--r--test/spec/ref_as_non_null.wast4
22 files changed, 100 insertions, 161 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 51c49eab9..2c01e0aa0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,8 +18,7 @@ Current Trunk
- Add extra `memory64` argument for `BinaryenSetMemory` and new
`BinaryenMemoryIs64` C-API method to determine 64-bit memory. (#4963)
- `TypeBuilderSetSubType` now takes a supertype as the second argument.
-- `call_ref` can now take a signature type immediate in the text format. The
- type immediate will become mandatory in the future.
+- `call_ref` now takes a mandatory signature type immediate.
- If `THROW_ON_FATAL` is defined at compile-time, then fatal errors will throw a
`std::runtime_error` instead of terminating the process. This may be used by
embedders of Binaryen to recover from errors.
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index eb8e176ec..acde624f7 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1094,8 +1094,7 @@ enum ASTNodes {
// typed function references opcodes
- CallRefUnannotated = 0x14,
- CallRef = 0x17,
+ CallRef = 0x14,
RetCallRef = 0x15,
// gc opcodes
@@ -1743,8 +1742,7 @@ public:
void visitTryOrTryInBlock(Expression*& out);
void visitThrow(Throw* curr);
void visitRethrow(Rethrow* curr);
- void visitCallRef(CallRef* curr,
- std::optional<HeapType> maybeType = std::nullopt);
+ void visitCallRef(CallRef* curr);
void visitRefAs(RefAs* curr, uint8_t code);
[[noreturn]] void throwError(std::string text);
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 1eb31157d..a29867e55 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -1342,35 +1342,6 @@ public:
}
return makeBrOn(op, name, ref);
}
-
- template<typename T>
- Expression* validateAndMakeCallRef(Expression* target,
- const T& args,
- bool isReturn = false) {
- if (target->type != Type::unreachable && !target->type.isRef()) {
- throw ParseException("Non-reference type for a call_ref", line, col);
- }
- // TODO: This won't be necessary once type annotations are mandatory on
- // call_ref.
- if (target->type == Type::unreachable ||
- target->type.getHeapType() == HeapType::nofunc) {
- // An unreachable target is not supported. Similiar to br_on_cast, just
- // emit an unreachable sequence, since we don't have enough information
- // to create a full call_ref.
- std::vector<Expression*> children;
- for (auto* arg : args) {
- children.push_back(makeDrop(arg));
- }
- children.push_back(makeDrop(target));
- children.push_back(makeUnreachable());
- return makeBlock(children, Type::unreachable);
- }
- auto heapType = target->type.getHeapType();
- if (!heapType.isSignature()) {
- throw ParseException("Invalid reference type for a call_ref", line, col);
- }
- return makeCallRef(target, args, heapType.getSignature().results, isReturn);
- }
};
} // namespace wasm
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index e2bb0075b..782979520 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3846,15 +3846,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
visitMemoryGrow(grow);
break;
}
- case BinaryConsts::CallRefUnannotated:
- visitCallRef((curr = allocator.alloc<CallRef>())->cast<CallRef>());
- break;
case BinaryConsts::CallRef:
case BinaryConsts::RetCallRef: {
auto call = allocator.alloc<CallRef>();
call->isReturn = code == BinaryConsts::RetCallRef;
curr = call;
- visitCallRef(call, getTypeByIndex(getU32LEB()));
+ visitCallRef(call);
break;
}
case BinaryConsts::AtomicPrefix: {
@@ -6851,29 +6848,13 @@ void WasmBinaryBuilder::visitRethrow(Rethrow* curr) {
curr->finalize();
}
-void WasmBinaryBuilder::visitCallRef(CallRef* curr,
- std::optional<HeapType> maybeType) {
+void WasmBinaryBuilder::visitCallRef(CallRef* curr) {
BYN_TRACE("zz node: CallRef\n");
curr->target = popNonVoidExpression();
- HeapType heapType;
- if (maybeType) {
- heapType = *maybeType;
- if (!Type::isSubType(curr->target->type, Type(heapType, Nullable))) {
- throwError("Call target has invalid type: " +
- curr->target->type.toString());
- }
- } else {
- auto type = curr->target->type;
- if (type == Type::unreachable) {
- // If our input is unreachable, then we cannot even find out how many
- // inputs we have, and just set ourselves to unreachable as well.
- curr->finalize(type);
- return;
- }
- if (!type.isRef()) {
- throwError("Non-ref type for a call_ref: " + type.toString());
- }
- heapType = type.getHeapType();
+ HeapType heapType = getTypeByIndex(getU32LEB());
+ if (!Type::isSubType(curr->target->type, Type(heapType, Nullable))) {
+ throwError("Call target has invalid type: " +
+ curr->target->type.toString());
}
if (!heapType.isSignature()) {
throwError("Invalid reference type for a call_ref: " + heapType.toString());
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index a9fd2de77..ab6230442 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2744,35 +2744,20 @@ Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) {
}
Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) {
- Index operandsStart = 1;
- std::optional<HeapType> sigType;
- try {
- sigType = parseHeapType(*s[1]);
- operandsStart = 2;
- } catch (ParseException& p) {
- // The type annotation is required for return_call_ref but temporarily
- // optional for call_ref.
- if (isReturn) {
- throw;
- }
- }
+ HeapType sigType = parseHeapType(*s[1]);
std::vector<Expression*> operands;
- parseOperands(s, operandsStart, s.size() - 1, operands);
+ parseOperands(s, 2, s.size() - 1, operands);
auto* target = parseExpression(s[s.size() - 1]);
- if (sigType) {
- if (!sigType->isSignature()) {
- throw ParseException(
- std::string(isReturn ? "return_call_ref" : "call_ref") +
- " type annotation should be a signature",
- s.line,
- s.col);
- }
- return Builder(wasm).makeCallRef(
- target, operands, sigType->getSignature().results, isReturn);
+ if (!sigType.isSignature()) {
+ throw ParseException(
+ std::string(isReturn ? "return_call_ref" : "call_ref") +
+ " type annotation should be a signature",
+ s.line,
+ s.col);
}
- return ValidatingBuilder(wasm, s.line, s.col)
- .validateAndMakeCallRef(target, operands, isReturn);
+ return Builder(wasm).makeCallRef(
+ target, operands, sigType.getSignature().results, isReturn);
}
Expression* SExpressionWasmBuilder::makeI31New(Element& s) {
diff --git a/test/lit/passes/dae_all-features.wast b/test/lit/passes/dae_all-features.wast
index 4e0480ace..4ca052835 100644
--- a/test/lit/passes/dae_all-features.wast
+++ b/test/lit/passes/dae_all-features.wast
@@ -510,7 +510,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $1
- (call_ref
+ (call_ref $i64
(i64.const 0)
(global.get $global$0)
)
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 18c6940cc..310bef59b 100644
--- a/test/lit/passes/gufa-refs.wast
+++ b/test/lit/passes/gufa-refs.wast
@@ -888,7 +888,7 @@
(local.get $y)
)
;; Send a non-null value only to the second param.
- (call_ref
+ (call_ref $two-params
(ref.as_non_null
(ref.null $struct)
)
@@ -4592,19 +4592,19 @@
;; Call $i1 twice with the same value, and $i2 twice with different values.
;; Note that structurally the types are identical, but we still
;; differentiate them, allowing us to optimize.
- (call_ref
+ (call_ref $i1
(i32.const 42)
(ref.func $reffed1)
)
- (call_ref
+ (call_ref $i1
(i32.const 42)
(ref.func $reffed1)
)
- (call_ref
+ (call_ref $i2
(i32.const 1337)
(ref.func $reffed2)
)
- (call_ref
+ (call_ref $i2
(i32.const 99999)
(ref.func $reffed2)
)
diff --git a/test/lit/passes/inlining-optimizing.wast b/test/lit/passes/inlining-optimizing.wast
index 65384330a..a7b671f10 100644
--- a/test/lit/passes/inlining-optimizing.wast
+++ b/test/lit/passes/inlining-optimizing.wast
@@ -32,7 +32,7 @@
;; unreachable.)
(call $0)
(drop
- (call_ref
+ (call_ref $none_=>_i32
(ref.cast_static $none_=>_i32
(ref.func $0)
)
diff --git a/test/lit/passes/local-cse_all-features.wast b/test/lit/passes/local-cse_all-features.wast
index d901d2d99..22b6b1903 100644
--- a/test/lit/passes/local-cse_all-features.wast
+++ b/test/lit/passes/local-cse_all-features.wast
@@ -4,7 +4,8 @@
;; RUN: foreach %s %t wasm-opt --local-cse --all-features -S -o - | filecheck %s
(module
- ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
+ ;; CHECK: (type $f (func (param i32) (result i32)))
+ (type $f (func (param i32) (result i32)))
;; CHECK: (type $none_=>_none (func))
@@ -12,13 +13,13 @@
;; CHECK: (func $calls (param $x i32) (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (call_ref $i32_=>_i32
+ ;; CHECK-NEXT: (call_ref $f
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.func $calls)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (call_ref $i32_=>_i32
+ ;; CHECK-NEXT: (call_ref $f
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.func $calls)
;; CHECK-NEXT: )
@@ -28,10 +29,10 @@
(func $calls (param $x i32) (result i32)
;; The side effects of calls prevent optimization.
(drop
- (call_ref (i32.const 10) (ref.func $calls))
+ (call_ref $f (i32.const 10) (ref.func $calls))
)
(drop
- (call_ref (i32.const 10) (ref.func $calls))
+ (call_ref $f (i32.const 10) (ref.func $calls))
)
(i32.const 20)
)
diff --git a/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast b/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast
index 9718b4131..e59c09307 100644
--- a/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast
+++ b/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast
@@ -69,17 +69,17 @@
(func $call-table-get (param $x i32)
;; The heap type of the call_indirects that we emit here should be the
;; identical one as on the table that they correspond to.
- (call_ref
+ (call_ref $v1
(table.get $table-1
(local.get $x)
)
)
- (call_ref
+ (call_ref $v2
(table.get $table-2
(local.get $x)
)
)
- (call_ref
+ (call_ref $v3
(table.get $table-3
(local.get $x)
)
diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast
index a82b15542..66e0ee7d8 100644
--- a/test/lit/passes/optimize-instructions-call_ref.wast
+++ b/test/lit/passes/optimize-instructions-call_ref.wast
@@ -51,7 +51,7 @@
;; CHECK-NEXT: )
(func $call_ref-to-direct (param $x i32) (param $y i32)
;; This call_ref should become a direct call.
- (call_ref
+ (call_ref $i32_i32_=>_none
(local.get $x)
(local.get $y)
(ref.func $foo)
@@ -84,7 +84,7 @@
;; This call_ref should become a direct call, even though it doesn't have a
;; simple ref.func as the target - we need to look into the fallthrough, and
;; handle things with locals.
- (call_ref
+ (call_ref $i32_i32_=>_none
;; Write to $x before the block, and write to it in the block; we should not
;; reorder these things as the side effects could alter what value appears
;; in the get of $x. (There is a risk of reordering here if we naively moved
@@ -116,7 +116,7 @@
(func $fallthrough-no-params (result i32)
;; A fallthrough appears here, but there are no operands so this is easier to
;; optimize: we can just drop the call_ref's target before the call.
- (call_ref
+ (call_ref $none_=>_i32
(block (result (ref $none_=>_i32))
(nop)
(ref.func $fallthrough-no-params)
@@ -148,7 +148,7 @@
;; nullable, which means we must be careful when we create a temp local for
;; it: the local should be nullable, and gets of it should use a
;; ref.as_non_null so that we validate.
- (call_ref
+ (call_ref $data_=>_none
(local.get $x)
(block (result (ref $data_=>_none))
(nop)
@@ -174,7 +174,7 @@
;; emit non-validating code here, which would happen if we replace the
;; call_ref that returns nothing with a call that returns an i32. In fact, we
;; end up optimizing the cast into an unreachable.
- (call_ref
+ (call_ref $none_=>_i32
(ref.cast_static $none_=>_i32
(ref.func $return-nothing)
)
@@ -199,7 +199,7 @@
;; CHECK-NEXT: )
(func $fallthrough-unreachable
;; If the call is not reached, do not optimize it.
- (call_ref
+ (call_ref $i32_i32_=>_none
(unreachable)
(unreachable)
(block (result (ref $i32_i32_=>_none))
@@ -210,14 +210,16 @@
)
;; CHECK: (func $ignore-unreachable
- ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $ignore-unreachable
;; Ignore an unreachable call_ref target entirely.
- (call_ref
+ (call_ref $i32_i32_=>_none
(unreachable)
)
)
@@ -230,7 +232,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $call-table-get (param $x i32)
- (call_ref
+ (call_ref $i32_i32_=>_none
(i32.const 1)
(i32.const 2)
(table.get $table-1
@@ -273,7 +275,7 @@
;; CHECK-NEXT: )
(func $call_ref-to-select (param $x i32) (param $y i32) (param $z i32) (param $f (ref $i32_i32_=>_none))
;; This call_ref should become an if over two direct calls.
- (call_ref
+ (call_ref $i32_i32_=>_none
(local.get $x)
(local.get $y)
(select
@@ -284,7 +286,7 @@
)
;; But here one arm is not constant, so we do not optimize.
- (call_ref
+ (call_ref $i32_i32_=>_none
(local.get $x)
(local.get $y)
(select
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index 78e91d749..896158637 100644
--- a/test/lit/passes/precompute-gc.wast
+++ b/test/lit/passes/precompute-gc.wast
@@ -1198,7 +1198,7 @@
(drop
;; Read from the local, checking whether precompute set a value there (it
;; should not, as the cast fails).
- (call_ref
+ (call_ref $func-return-i32
(local.get $temp)
)
)
diff --git a/test/lit/passes/remove-unused-module-elements-refs.wast b/test/lit/passes/remove-unused-module-elements-refs.wast
index 497af29ee..2c9df16f8 100644
--- a/test/lit/passes/remove-unused-module-elements-refs.wast
+++ b/test/lit/passes/remove-unused-module-elements-refs.wast
@@ -23,7 +23,7 @@
;; CHECK-NEXT: (call_ref $A
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
@@ -38,12 +38,12 @@
(drop
(ref.func $target-B)
)
- (call_ref
+ (call_ref $A
(local.get $A)
)
;; Verify that we do not crash on an unreachable call_ref, which has no
;; heap type for us to analyze.
- (call_ref
+ (call_ref $A
(unreachable)
)
)
@@ -85,7 +85,7 @@
;; CHECK: (export "foo" (func $foo))
;; CHECK: (func $foo (type $A)
- ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
@@ -96,7 +96,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo (export "foo")
- (call_ref
+ (call_ref $A
(ref.null $A)
)
(drop
@@ -143,13 +143,13 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo (export "foo") (param $A (ref null $A))
- (call_ref
+ (call_ref $A
(local.get $A)
)
(drop
(ref.func $target-A-1)
)
- (call_ref
+ (call_ref $A
(local.get $A)
)
(drop
@@ -207,13 +207,13 @@
(drop
(ref.func $target-A-1)
)
- (call_ref
+ (call_ref $A
(local.get $A)
)
(drop
(ref.func $target-A-2)
)
- (call_ref
+ (call_ref $A
(local.get $A)
)
)
diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast
index 26ecadfc9..4b3cfa0c4 100644
--- a/test/lit/passes/signature-pruning.wast
+++ b/test/lit/passes/signature-pruning.wast
@@ -56,7 +56,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref
+ (call_ref $sig
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -120,7 +120,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref
+ (call_ref $sig
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -194,7 +194,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref
+ (call_ref $sig
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -263,7 +263,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref
+ (call_ref $sig
(block (result i32)
(call $caller)
(i32.const 4)
@@ -312,7 +312,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref
+ (call_ref $sig
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -515,11 +515,11 @@
(call $bar
(i32.const 1)
)
- (call_ref
+ (call_ref $sig
(i32.const 2)
(ref.func $foo)
)
- (call_ref
+ (call_ref $sig
(i32.const 2)
(ref.func $bar)
)
@@ -536,7 +536,7 @@
(call $bar
(i32.const 1)
)
- (call_ref
+ (call_ref $sig
(i32.const 2)
(ref.func $foo)
)
diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast
index 3d2f7b1a4..8313a75f9 100644
--- a/test/lit/passes/signature-refining.wast
+++ b/test/lit/passes/signature-refining.wast
@@ -60,7 +60,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller
- (call_ref
+ (call_ref $sig
(struct.new $struct)
(ref.func $func)
)
@@ -107,7 +107,7 @@
;; Use a local to avoid a ref.null being updated.
(local.get $struct)
)
- (call_ref
+ (call_ref $sig
(ref.as_data
(struct.new $struct)
)
@@ -298,7 +298,7 @@
(call $func
(struct.new $struct)
)
- (call_ref
+ (call_ref $sig
(unreachable)
(ref.func $func)
)
@@ -331,7 +331,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller
- (call_ref
+ (call_ref $sig
(unreachable)
(ref.func $func)
)
@@ -420,7 +420,7 @@
(struct.new $struct)
(struct.new $struct)
)
- (call_ref
+ (call_ref $sig-2
(local.get $i31)
(struct.new $struct)
(ref.func $func-2)
@@ -573,7 +573,7 @@
(drop
(if (result anyref)
(i32.const 1)
- (call_ref
+ (call_ref $sig-can-refine
(ref.func $func-can-refine)
)
(unreachable)
diff --git a/test/lit/types-function-references.wast b/test/lit/types-function-references.wast
index 8722ff3fd..d51b73a84 100644
--- a/test/lit/types-function-references.wast
+++ b/test/lit/types-function-references.wast
@@ -74,7 +74,7 @@
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
(func $call-ref
- (call_ref (ref.func $call-ref))
+ (call_ref $void (ref.func $call-ref))
)
;; CHECK-BINARY: (func $return-call-ref
;; CHECK-BINARY-NEXT: (return_call_ref $void
@@ -102,7 +102,7 @@
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
(func $call-ref-more (param i32) (result i32)
- (call_ref (i32.const 42) (ref.func $call-ref-more))
+ (call_ref $i32-i32 (i32.const 42) (ref.func $call-ref-more))
)
;; CHECK-BINARY: (func $call_from-param (param $f (ref $i32-i32)) (result i32)
;; CHECK-BINARY-NEXT: (call_ref $i32-i32
@@ -117,7 +117,7 @@
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
(func $call_from-param (param $f (ref $i32-i32)) (result i32)
- (call_ref (i32.const 42) (local.get $f))
+ (call_ref $i32-i32 (i32.const 42) (local.get $f))
)
;; CHECK-BINARY: (func $call_from-param-null (param $f (ref null $i32-i32)) (result i32)
;; CHECK-BINARY-NEXT: (call_ref $i32-i32
@@ -132,7 +132,7 @@
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
(func $call_from-param-null (param $f (ref null $i32-i32)) (result i32)
- (call_ref (i32.const 42) (local.get $f))
+ (call_ref $i32-i32 (i32.const 42) (local.get $f))
)
;; CHECK-BINARY: (func $call_from-local-null (result i32)
;; CHECK-BINARY-NEXT: (local $f (ref null $i32-i32))
@@ -157,7 +157,7 @@
(func $call_from-local-null (result i32)
(local $f (ref null $i32-i32))
(local.set $f (ref.func $call-ref-more))
- (call_ref (i32.const 42) (local.get $f))
+ (call_ref $i32-i32 (i32.const 42) (local.get $f))
)
;; CHECK-BINARY: (func $ref-in-sig (param $0 f64) (result (ref null $=>eqref))
;; CHECK-BINARY-NEXT: (ref.null nofunc)
diff --git a/test/lit/validation/nn-locals-bad-call_ref.wast b/test/lit/validation/nn-locals-bad-call_ref.wast
index 357409eef..9a96ed4bc 100644
--- a/test/lit/validation/nn-locals-bad-call_ref.wast
+++ b/test/lit/validation/nn-locals-bad-call_ref.wast
@@ -6,11 +6,12 @@
(module
(tag $tag (param i32))
+ (type $void (func))
(func $func
(local $0 (ref any))
(try
(do
- (call_ref
+ (call_ref $void
(ref.func $func)
)
)
diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast
index a07e7e3d7..94bc2aa3c 100644
--- a/test/passes/Oz_fuzz-exec_all-features.wast
+++ b/test/passes/Oz_fuzz-exec_all-features.wast
@@ -275,12 +275,12 @@
(func "cast-on-func"
(call $log (i32.const 0))
;; a valid cast
- (call_ref
+ (call_ref $void_func
(ref.cast_static $void_func (ref.func $a-void-func))
)
(call $log (i32.const 1))
;; an invalid cast
- (drop (call_ref
+ (drop (call_ref $int_func
(ref.cast_static $int_func (ref.func $a-void-func))
))
;; will never be reached
diff --git a/test/passes/duplicate-function-elimination_all-features.wast b/test/passes/duplicate-function-elimination_all-features.wast
index 1d04e878c..df8d26b6f 100644
--- a/test/passes/duplicate-function-elimination_all-features.wast
+++ b/test/passes/duplicate-function-elimination_all-features.wast
@@ -34,7 +34,7 @@
(unreachable)
)
(func "export" (result i32)
- (call_ref
+ (call_ref $func
(global.get $global$0)
)
)
diff --git a/test/spec/br_on_null.wast b/test/spec/br_on_null.wast
index 8e0a8591f..e3c45ece7 100644
--- a/test/spec/br_on_null.wast
+++ b/test/spec/br_on_null.wast
@@ -3,13 +3,13 @@
(func $nn (param $r (ref $t)) (result i32)
(block $l
- (return (call_ref (br_on_null $l (local.get $r))))
+ (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 (br_on_null $l (local.get $r))))
+ (return (call_ref $t (br_on_null $l (local.get $r))))
)
(i32.const -1)
)
@@ -22,7 +22,7 @@
(func (export "unreachable") (result i32)
(block $l
- (return (call_ref (br_on_null $l (unreachable))))
+ (return (call_ref $t (br_on_null $l (unreachable))))
)
(i32.const -1)
)
@@ -49,7 +49,7 @@
(func $nn (param $r (ref $t)) (result i32)
(block $l (ref null $t) ;; br_on_null sends no value; a br to here is bad
- (return (call_ref (br_on_null $l (local.get $r))))
+ (return (call_ref $t (br_on_null $l (local.get $r))))
)
(i32.const -1)
)
diff --git a/test/spec/call_ref.wast b/test/spec/call_ref.wast
index 8a34706f2..071aa8bbf 100644
--- a/test/spec/call_ref.wast
+++ b/test/spec/call_ref.wast
@@ -2,7 +2,7 @@
(type $ii (func (param i32) (result i32)))
(func $apply (param $f (ref $ii)) (param $x i32) (result i32)
- (call_ref (local.get $x) (local.get $f))
+ (call_ref $ii (local.get $x) (local.get $f))
)
(func $f (type $ii) (i32.mul (local.get 0) (local.get 0)))
@@ -15,11 +15,11 @@
(local $rg (ref null $ii))
(local.set $rf (ref.func $f))
(local.set $rg (ref.func $g))
- (call_ref (call_ref (local.get $x) (local.get $rf)) (local.get $rg))
+ (call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg))
)
(func (export "null") (result i32)
- (call_ref (i32.const 1) (ref.null $ii))
+ (call_ref $ii (i32.const 1) (ref.null $ii))
)
;; Recursion
@@ -36,7 +36,7 @@
(else
(i64.mul
(local.get 0)
- (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
+ (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
)
)
)
@@ -49,7 +49,7 @@
(if (result i64) (i64.eqz (local.get 0))
(then (local.get 1))
(else
- (call_ref
+ (call_ref $lll
(i64.sub (local.get 0) (i64.const 1))
(i64.mul (local.get 0) (local.get 1))
(global.get $fac-acc)
@@ -66,8 +66,8 @@
(then (i64.const 1))
(else
(i64.add
- (call_ref (i64.sub (local.get 0) (i64.const 2)) (global.get $fib))
- (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fib))
+ (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))
)
)
)
@@ -80,13 +80,13 @@
(func $even (export "even") (type $ll)
(if (result i64) (i64.eqz (local.get 0))
(then (i64.const 44))
- (else (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $odd)))
+ (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 (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
+ (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
)
)
)
@@ -127,8 +127,9 @@
(assert_invalid
(module
+ (type $t (func))
(func $f (param $r externref)
- (call_ref (local.get $r))
+ (call_ref $t (local.get $r))
)
)
"type mismatch"
diff --git a/test/spec/ref_as_non_null.wast b/test/spec/ref_as_non_null.wast
index 7e9417191..e597e7b9b 100644
--- a/test/spec/ref_as_non_null.wast
+++ b/test/spec/ref_as_non_null.wast
@@ -2,10 +2,10 @@
(type $t (func (result i32)))
(func $nn (param $r (ref $t)) (result i32)
- (call_ref (ref.as_non_null (local.get $r)))
+ (call_ref $t (ref.as_non_null (local.get $r)))
)
(func $n (param $r (ref null $t)) (result i32)
- (call_ref (ref.as_non_null (local.get $r)))
+ (call_ref $t (ref.as_non_null (local.get $r)))
)
(elem func $f)