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, 161 insertions, 100 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c01e0aa0..51c49eab9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,7 +18,8 @@ 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` now takes a mandatory signature type immediate.
+- `call_ref` can now take a signature type immediate in the text format. The
+ type immediate will become mandatory in the future.
- 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 acde624f7..eb8e176ec 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1094,7 +1094,8 @@ enum ASTNodes {
// typed function references opcodes
- CallRef = 0x14,
+ CallRefUnannotated = 0x14,
+ CallRef = 0x17,
RetCallRef = 0x15,
// gc opcodes
@@ -1742,7 +1743,8 @@ public:
void visitTryOrTryInBlock(Expression*& out);
void visitThrow(Throw* curr);
void visitRethrow(Rethrow* curr);
- void visitCallRef(CallRef* curr);
+ void visitCallRef(CallRef* curr,
+ std::optional<HeapType> maybeType = std::nullopt);
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 a29867e55..1eb31157d 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -1342,6 +1342,35 @@ 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 782979520..e2bb0075b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3846,12 +3846,15 @@ 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);
+ visitCallRef(call, getTypeByIndex(getU32LEB()));
break;
}
case BinaryConsts::AtomicPrefix: {
@@ -6848,13 +6851,29 @@ void WasmBinaryBuilder::visitRethrow(Rethrow* curr) {
curr->finalize();
}
-void WasmBinaryBuilder::visitCallRef(CallRef* curr) {
+void WasmBinaryBuilder::visitCallRef(CallRef* curr,
+ std::optional<HeapType> maybeType) {
BYN_TRACE("zz node: CallRef\n");
curr->target = popNonVoidExpression();
- HeapType heapType = getTypeByIndex(getU32LEB());
- if (!Type::isSubType(curr->target->type, Type(heapType, Nullable))) {
- throwError("Call target has invalid type: " +
- curr->target->type.toString());
+ 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();
}
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 ab6230442..a9fd2de77 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2744,20 +2744,35 @@ Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) {
}
Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) {
- HeapType sigType = parseHeapType(*s[1]);
+ 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;
+ }
+ }
std::vector<Expression*> operands;
- parseOperands(s, 2, s.size() - 1, operands);
+ parseOperands(s, operandsStart, s.size() - 1, operands);
auto* target = parseExpression(s[s.size() - 1]);
- if (!sigType.isSignature()) {
- throw ParseException(
- std::string(isReturn ? "return_call_ref" : "call_ref") +
- " type annotation should be a signature",
- s.line,
- s.col);
+ 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);
}
- return Builder(wasm).makeCallRef(
- target, operands, sigType.getSignature().results, isReturn);
+ return ValidatingBuilder(wasm, s.line, s.col)
+ .validateAndMakeCallRef(target, operands, 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 4ca052835..4e0480ace 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 $i64
+ (call_ref
(i64.const 0)
(global.get $global$0)
)
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 310bef59b..18c6940cc 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 $two-params
+ (call_ref
(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 $i1
+ (call_ref
(i32.const 42)
(ref.func $reffed1)
)
- (call_ref $i1
+ (call_ref
(i32.const 42)
(ref.func $reffed1)
)
- (call_ref $i2
+ (call_ref
(i32.const 1337)
(ref.func $reffed2)
)
- (call_ref $i2
+ (call_ref
(i32.const 99999)
(ref.func $reffed2)
)
diff --git a/test/lit/passes/inlining-optimizing.wast b/test/lit/passes/inlining-optimizing.wast
index a7b671f10..65384330a 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 $none_=>_i32
+ (call_ref
(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 22b6b1903..d901d2d99 100644
--- a/test/lit/passes/local-cse_all-features.wast
+++ b/test/lit/passes/local-cse_all-features.wast
@@ -4,8 +4,7 @@
;; RUN: foreach %s %t wasm-opt --local-cse --all-features -S -o - | filecheck %s
(module
- ;; CHECK: (type $f (func (param i32) (result i32)))
- (type $f (func (param i32) (result i32)))
+ ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
;; CHECK: (type $none_=>_none (func))
@@ -13,13 +12,13 @@
;; CHECK: (func $calls (param $x i32) (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (call_ref $f
+ ;; CHECK-NEXT: (call_ref $i32_=>_i32
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.func $calls)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (call_ref $f
+ ;; CHECK-NEXT: (call_ref $i32_=>_i32
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.func $calls)
;; CHECK-NEXT: )
@@ -29,10 +28,10 @@
(func $calls (param $x i32) (result i32)
;; The side effects of calls prevent optimization.
(drop
- (call_ref $f (i32.const 10) (ref.func $calls))
+ (call_ref (i32.const 10) (ref.func $calls))
)
(drop
- (call_ref $f (i32.const 10) (ref.func $calls))
+ (call_ref (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 e59c09307..9718b4131 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 $v1
+ (call_ref
(table.get $table-1
(local.get $x)
)
)
- (call_ref $v2
+ (call_ref
(table.get $table-2
(local.get $x)
)
)
- (call_ref $v3
+ (call_ref
(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 66e0ee7d8..a82b15542 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 $i32_i32_=>_none
+ (call_ref
(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 $i32_i32_=>_none
+ (call_ref
;; 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 $none_=>_i32
+ (call_ref
(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 $data_=>_none
+ (call_ref
(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 $none_=>_i32
+ (call_ref
(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 $i32_i32_=>_none
+ (call_ref
(unreachable)
(unreachable)
(block (result (ref $i32_i32_=>_none))
@@ -210,16 +210,14 @@
)
;; CHECK: (func $ignore-unreachable
- ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $ignore-unreachable
;; Ignore an unreachable call_ref target entirely.
- (call_ref $i32_i32_=>_none
+ (call_ref
(unreachable)
)
)
@@ -232,7 +230,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $call-table-get (param $x i32)
- (call_ref $i32_i32_=>_none
+ (call_ref
(i32.const 1)
(i32.const 2)
(table.get $table-1
@@ -275,7 +273,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 $i32_i32_=>_none
+ (call_ref
(local.get $x)
(local.get $y)
(select
@@ -286,7 +284,7 @@
)
;; But here one arm is not constant, so we do not optimize.
- (call_ref $i32_i32_=>_none
+ (call_ref
(local.get $x)
(local.get $y)
(select
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index 896158637..78e91d749 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 $func-return-i32
+ (call_ref
(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 2c9df16f8..497af29ee 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 ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
@@ -38,12 +38,12 @@
(drop
(ref.func $target-B)
)
- (call_ref $A
+ (call_ref
(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 $A
+ (call_ref
(unreachable)
)
)
@@ -85,7 +85,7 @@
;; CHECK: (export "foo" (func $foo))
;; CHECK: (func $foo (type $A)
- ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
@@ -96,7 +96,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo (export "foo")
- (call_ref $A
+ (call_ref
(ref.null $A)
)
(drop
@@ -143,13 +143,13 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo (export "foo") (param $A (ref null $A))
- (call_ref $A
+ (call_ref
(local.get $A)
)
(drop
(ref.func $target-A-1)
)
- (call_ref $A
+ (call_ref
(local.get $A)
)
(drop
@@ -207,13 +207,13 @@
(drop
(ref.func $target-A-1)
)
- (call_ref $A
+ (call_ref
(local.get $A)
)
(drop
(ref.func $target-A-2)
)
- (call_ref $A
+ (call_ref
(local.get $A)
)
)
diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast
index 4b3cfa0c4..26ecadfc9 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 $sig
+ (call_ref
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -120,7 +120,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref $sig
+ (call_ref
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -194,7 +194,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref $sig
+ (call_ref
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -263,7 +263,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref $sig
+ (call_ref
(block (result i32)
(call $caller)
(i32.const 4)
@@ -312,7 +312,7 @@
(f32.const 2)
(f64.const 3)
)
- (call_ref $sig
+ (call_ref
(i32.const 4)
(i64.const 5)
(f32.const 6)
@@ -515,11 +515,11 @@
(call $bar
(i32.const 1)
)
- (call_ref $sig
+ (call_ref
(i32.const 2)
(ref.func $foo)
)
- (call_ref $sig
+ (call_ref
(i32.const 2)
(ref.func $bar)
)
@@ -536,7 +536,7 @@
(call $bar
(i32.const 1)
)
- (call_ref $sig
+ (call_ref
(i32.const 2)
(ref.func $foo)
)
diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast
index 8313a75f9..3d2f7b1a4 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 $sig
+ (call_ref
(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 $sig
+ (call_ref
(ref.as_data
(struct.new $struct)
)
@@ -298,7 +298,7 @@
(call $func
(struct.new $struct)
)
- (call_ref $sig
+ (call_ref
(unreachable)
(ref.func $func)
)
@@ -331,7 +331,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller
- (call_ref $sig
+ (call_ref
(unreachable)
(ref.func $func)
)
@@ -420,7 +420,7 @@
(struct.new $struct)
(struct.new $struct)
)
- (call_ref $sig-2
+ (call_ref
(local.get $i31)
(struct.new $struct)
(ref.func $func-2)
@@ -573,7 +573,7 @@
(drop
(if (result anyref)
(i32.const 1)
- (call_ref $sig-can-refine
+ (call_ref
(ref.func $func-can-refine)
)
(unreachable)
diff --git a/test/lit/types-function-references.wast b/test/lit/types-function-references.wast
index d51b73a84..8722ff3fd 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 $void (ref.func $call-ref))
+ (call_ref (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-i32 (i32.const 42) (ref.func $call-ref-more))
+ (call_ref (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-i32 (i32.const 42) (local.get $f))
+ (call_ref (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-i32 (i32.const 42) (local.get $f))
+ (call_ref (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-i32 (i32.const 42) (local.get $f))
+ (call_ref (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 9a96ed4bc..357409eef 100644
--- a/test/lit/validation/nn-locals-bad-call_ref.wast
+++ b/test/lit/validation/nn-locals-bad-call_ref.wast
@@ -6,12 +6,11 @@
(module
(tag $tag (param i32))
- (type $void (func))
(func $func
(local $0 (ref any))
(try
(do
- (call_ref $void
+ (call_ref
(ref.func $func)
)
)
diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast
index 94bc2aa3c..a07e7e3d7 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 $void_func
+ (call_ref
(ref.cast_static $void_func (ref.func $a-void-func))
)
(call $log (i32.const 1))
;; an invalid cast
- (drop (call_ref $int_func
+ (drop (call_ref
(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 df8d26b6f..1d04e878c 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 $func
+ (call_ref
(global.get $global$0)
)
)
diff --git a/test/spec/br_on_null.wast b/test/spec/br_on_null.wast
index e3c45ece7..8e0a8591f 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 $t (br_on_null $l (local.get $r))))
+ (return (call_ref (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))))
+ (return (call_ref (br_on_null $l (local.get $r))))
)
(i32.const -1)
)
@@ -22,7 +22,7 @@
(func (export "unreachable") (result i32)
(block $l
- (return (call_ref $t (br_on_null $l (unreachable))))
+ (return (call_ref (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 $t (br_on_null $l (local.get $r))))
+ (return (call_ref (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 071aa8bbf..8a34706f2 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 $ii (local.get $x) (local.get $f))
+ (call_ref (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 $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg))
+ (call_ref (call_ref (local.get $x) (local.get $rf)) (local.get $rg))
)
(func (export "null") (result i32)
- (call_ref $ii (i32.const 1) (ref.null $ii))
+ (call_ref (i32.const 1) (ref.null $ii))
)
;; Recursion
@@ -36,7 +36,7 @@
(else
(i64.mul
(local.get 0)
- (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
+ (call_ref (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 $lll
+ (call_ref
(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 $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))
+ (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))
)
)
)
@@ -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 $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $odd)))
+ (else (call_ref (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)))
+ (else (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
)
)
)
@@ -127,9 +127,8 @@
(assert_invalid
(module
- (type $t (func))
(func $f (param $r externref)
- (call_ref $t (local.get $r))
+ (call_ref (local.get $r))
)
)
"type mismatch"
diff --git a/test/spec/ref_as_non_null.wast b/test/spec/ref_as_non_null.wast
index e597e7b9b..7e9417191 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 $t (ref.as_non_null (local.get $r)))
+ (call_ref (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)))
+ (call_ref (ref.as_non_null (local.get $r)))
)
(elem func $f)