summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-10-07 08:02:09 -0500
committerGitHub <noreply@github.com>2022-10-07 06:02:09 -0700
commit7fc26f3e78f72ecaa5b79ebe042b95a0be422327 (patch)
treef87c84fc691aaf311fbd71c176ee37723c76ae20
parente8884de3c880a7de4bb1f8eae3df5f00f4164b4d (diff)
downloadbinaryen-7fc26f3e78f72ecaa5b79ebe042b95a0be422327.tar.gz
binaryen-7fc26f3e78f72ecaa5b79ebe042b95a0be422327.tar.bz2
binaryen-7fc26f3e78f72ecaa5b79ebe042b95a0be422327.zip
Implement bottom heap types (#5115)
These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/binaryen-c.cpp188
-rw-r--r--src/binaryen-c.h4
-rw-r--r--src/ir/effects.h28
-rw-r--r--src/ir/manipulation.h1
-rw-r--r--src/ir/possible-contents.cpp34
-rw-r--r--src/ir/struct-utils.h5
-rw-r--r--src/literal.h23
-rw-r--r--src/passes/Inlining.cpp36
-rw-r--r--src/passes/JSPI.cpp6
-rw-r--r--src/passes/OptimizeInstructions.cpp37
-rw-r--r--src/passes/Precompute.cpp4
-rw-r--r--src/passes/Print.cpp55
-rw-r--r--src/passes/TypeRefining.cpp2
-rw-r--r--src/tools/fuzzing/fuzzing.cpp57
-rw-r--r--src/tools/fuzzing/heap-types.cpp37
-rw-r--r--src/tools/wasm-ctor-eval.cpp5
-rw-r--r--src/tools/wasm-reduce.cpp2
-rw-r--r--src/wasm-binary.h8
-rw-r--r--src/wasm-builder.h38
-rw-r--r--src/wasm-interpreter.h7
-rw-r--r--src/wasm-type.h13
-rw-r--r--src/wasm/literal.cpp146
-rw-r--r--src/wasm/wasm-binary.cpp168
-rw-r--r--src/wasm/wasm-s-parser.cpp30
-rw-r--r--src/wasm/wasm-stack.cpp29
-rw-r--r--src/wasm/wasm-type.cpp156
-rw-r--r--src/wasm/wasm-validator.cpp102
-rw-r--r--src/wasm/wasm.cpp9
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt20
-rw-r--r--test/ctor-eval/bad-indirect-call3.wast.out2
-rw-r--r--test/ctor-eval/gc.wast.out2
-rw-r--r--test/example/c-api-kitchen-sink.c35
-rw-r--r--test/example/c-api-kitchen-sink.txt34
-rw-r--r--test/example/cpp-unit.cpp37
-rw-r--r--test/example/cpp-unit.txt2
-rw-r--r--test/example/typeinfo.txt2
-rw-r--r--test/gc.wast.from-wast18
-rw-r--r--test/gc.wast.fromBinary18
-rw-r--r--test/gc.wast.fromBinary.noDebugInfo18
-rw-r--r--test/gtest/possible-contents.cpp2
-rw-r--r--test/gtest/type-builder.cpp4
-rw-r--r--test/heap-types.wast37
-rw-r--r--test/heap-types.wast.from-wast73
-rw-r--r--test/heap-types.wast.fromBinary63
-rw-r--r--test/heap-types.wast.fromBinary.noDebugInfo91
-rw-r--r--test/lit/fuzz-types/isorecursive.test40
-rw-r--r--test/lit/fuzz-types/nominal.test40
-rw-r--r--test/lit/fuzz-types/structural.test36
-rw-r--r--test/lit/gc-eh.wast4
-rw-r--r--test/lit/global-only.wast2
-rw-r--r--test/lit/heap-types.wast10
-rw-r--r--test/lit/isorecursive-singleton-group.wast2
-rw-r--r--test/lit/isorecursive-whole-group.wast2
-rw-r--r--test/lit/lub-bug-3843.wast15
-rw-r--r--test/lit/nominal-chain.wast8
-rw-r--r--test/lit/parse-double-unreachable.wast43
-rw-r--r--test/lit/parse-nominal-types-extends.wast30
-rw-r--r--test/lit/parse-nominal-types.wast30
-rw-r--r--test/lit/passes/cfp.wast554
-rw-r--r--test/lit/passes/coalesce-locals-gc.wast31
-rw-r--r--test/lit/passes/dae-gc-refine-params.wast53
-rw-r--r--test/lit/passes/dae-gc-refine-return.wast6
-rw-r--r--test/lit/passes/dae-gc.wast8
-rw-r--r--test/lit/passes/flatten_all-features.wast13
-rw-r--r--test/lit/passes/global-refining.wast19
-rw-r--r--test/lit/passes/gsi.wast226
-rw-r--r--test/lit/passes/gto-mutability.wast157
-rw-r--r--test/lit/passes/gto-removals.wast39
-rw-r--r--test/lit/passes/gufa-refs.wast208
-rw-r--r--test/lit/passes/gufa-vs-cfp.wast31
-rw-r--r--test/lit/passes/gufa.wast10
-rw-r--r--test/lit/passes/heap2local.wast436
-rw-r--r--test/lit/passes/inlining-gc.wast2
-rw-r--r--test/lit/passes/inlining-optimizing.wast1
-rw-r--r--test/lit/passes/inlining_all-features.wast14
-rw-r--r--test/lit/passes/inlining_splitting.wast36
-rw-r--r--test/lit/passes/intrinsic-lowering.wast21
-rw-r--r--test/lit/passes/jspi.wast2
-rw-r--r--test/lit/passes/local-subtyping-nn.wast18
-rw-r--r--test/lit/passes/local-subtyping.wast17
-rw-r--r--test/lit/passes/merge-blocks.wast20
-rw-r--r--test/lit/passes/optimize-instructions-call_ref.wast3
-rw-r--r--test/lit/passes/optimize-instructions-gc-heap.wast7
-rw-r--r--test/lit/passes/optimize-instructions-gc-tnh.wast43
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast222
-rw-r--r--test/lit/passes/precompute-gc-immutable.wast8
-rw-r--r--test/lit/passes/precompute-gc.wast58
-rw-r--r--test/lit/passes/remove-unused-brs-gc.wast28
-rw-r--r--test/lit/passes/remove-unused-brs.wast6
-rw-r--r--test/lit/passes/remove-unused-module-elements-refs.wast60
-rw-r--r--test/lit/passes/roundtrip.wast2
-rw-r--r--test/lit/passes/signature-pruning.wast4
-rw-r--r--test/lit/passes/signature-refining.wast15
-rw-r--r--test/lit/passes/simplify-locals-gc-nn.wast4
-rw-r--r--test/lit/passes/simplify-locals-gc-validation.wast2
-rw-r--r--test/lit/passes/simplify-locals-gc.wast14
-rw-r--r--test/lit/passes/type-refining-isorecursive.wast12
-rw-r--r--test/lit/passes/type-refining.wast82
-rw-r--r--test/lit/table-operations.wast6
-rw-r--r--test/lit/types-function-references.wast36
-rw-r--r--test/lit/validation/eqref.wast12
-rw-r--r--test/multi-table.wast.from-wast6
-rw-r--r--test/multi-table.wast.fromBinary6
-rw-r--r--test/multi-table.wast.fromBinary.noDebugInfo6
-rw-r--r--test/multivalue.wast.from-wast4
-rw-r--r--test/multivalue.wast.fromBinary4
-rw-r--r--test/multivalue.wast.fromBinary.noDebugInfo4
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.txt4
-rw-r--r--test/passes/precompute_all-features.txt12
-rw-r--r--test/passes/remove-unused-brs_all-features.txt26
-rw-r--r--test/passes/simplify-globals_all-features.txt4
-rw-r--r--test/passes/simplify-globals_all-features_fuzz-exec.txt2
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.txt2
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt70
-rw-r--r--test/reference-types.wast.from-wast102
-rw-r--r--test/reference-types.wast.fromBinary94
-rw-r--r--test/reference-types.wast.fromBinary.noDebugInfo94
-rw-r--r--test/unit/input/gc_target_feature.wasmbin94 -> 94 bytes
119 files changed, 2807 insertions, 2132 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2298928bb..d79c1c0f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,9 @@ Current Trunk
- 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.
+- Implemented bottom heap types: `none`, `nofunc`, and `noextern`. RefNull
+ expressions and null `Literal`s must now have type `nullref`, `nullfuncref`,
+ or `nullexternref`.
v110
----
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index cc7ed5b15..f2908920c 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -51,96 +51,111 @@ static_assert(sizeof(BinaryenLiteral) == sizeof(Literal),
BinaryenLiteral toBinaryenLiteral(Literal x) {
BinaryenLiteral ret;
ret.type = x.type.getID();
- if (x.type.isRef()) {
- auto heapType = x.type.getHeapType();
- if (heapType.isBasic()) {
- switch (heapType.getBasic()) {
- case HeapType::func:
- ret.func = x.isNull() ? nullptr : x.getFunc().c_str();
- break;
- case HeapType::ext:
- case HeapType::eq:
- assert(x.isNull() && "unexpected non-null reference type literal");
- break;
- case HeapType::any:
- case HeapType::i31:
- case HeapType::data:
- case HeapType::string:
- case HeapType::stringview_wtf8:
- case HeapType::stringview_wtf16:
- case HeapType::stringview_iter:
- WASM_UNREACHABLE("TODO: reftypes");
- }
- return ret;
+ assert(x.type.isSingle());
+ if (x.type.isBasic()) {
+ switch (x.type.getBasic()) {
+ case Type::i32:
+ ret.i32 = x.geti32();
+ return ret;
+ case Type::i64:
+ ret.i64 = x.geti64();
+ return ret;
+ case Type::f32:
+ ret.i32 = x.reinterpreti32();
+ return ret;
+ case Type::f64:
+ ret.i64 = x.reinterpreti64();
+ return ret;
+ case Type::v128:
+ memcpy(&ret.v128, x.getv128Ptr(), 16);
+ return ret;
+ case Type::none:
+ case Type::unreachable:
+ WASM_UNREACHABLE("unexpected type");
}
- WASM_UNREACHABLE("TODO: reftypes");
}
- TODO_SINGLE_COMPOUND(x.type);
- switch (x.type.getBasic()) {
- case Type::i32:
- ret.i32 = x.geti32();
- break;
- case Type::i64:
- ret.i64 = x.geti64();
- break;
- case Type::f32:
- ret.i32 = x.reinterpreti32();
- break;
- case Type::f64:
- ret.i64 = x.reinterpreti64();
- break;
- case Type::v128:
- memcpy(&ret.v128, x.getv128Ptr(), 16);
- break;
- case Type::none:
- case Type::unreachable:
- WASM_UNREACHABLE("unexpected type");
+ assert(x.type.isRef());
+ auto heapType = x.type.getHeapType();
+ if (heapType.isBasic()) {
+ switch (heapType.getBasic()) {
+ case HeapType::i31:
+ WASM_UNREACHABLE("TODO: i31");
+ case HeapType::ext:
+ case HeapType::any:
+ WASM_UNREACHABLE("TODO: extern literals");
+ case HeapType::eq:
+ case HeapType::func:
+ case HeapType::data:
+ WASM_UNREACHABLE("invalid type");
+ case HeapType::string:
+ case HeapType::stringview_wtf8:
+ case HeapType::stringview_wtf16:
+ case HeapType::stringview_iter:
+ WASM_UNREACHABLE("TODO: string literals");
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ // Null.
+ return ret;
+ }
}
- return ret;
+ if (heapType.isSignature()) {
+ ret.func = x.getFunc().c_str();
+ return ret;
+ }
+ assert(x.isData());
+ WASM_UNREACHABLE("TODO: gc data");
}
Literal fromBinaryenLiteral(BinaryenLiteral x) {
auto type = Type(x.type);
- if (type.isRef()) {
- auto heapType = type.getHeapType();
- if (type.isNullable()) {
- return Literal::makeNull(heapType);
+ if (type.isBasic()) {
+ switch (type.getBasic()) {
+ case Type::i32:
+ return Literal(x.i32);
+ case Type::i64:
+ return Literal(x.i64);
+ case Type::f32:
+ return Literal(x.i32).castToF32();
+ case Type::f64:
+ return Literal(x.i64).castToF64();
+ case Type::v128:
+ return Literal(x.v128);
+ case Type::none:
+ case Type::unreachable:
+ WASM_UNREACHABLE("unexpected type");
}
- if (heapType.isBasic()) {
- switch (heapType.getBasic()) {
- case HeapType::func:
- case HeapType::any:
- case HeapType::eq:
- case HeapType::data:
- assert(false && "Literals must have concrete types");
- WASM_UNREACHABLE("no fallthrough here");
- case HeapType::ext:
- case HeapType::i31:
- case HeapType::string:
- case HeapType::stringview_wtf8:
- case HeapType::stringview_wtf16:
- case HeapType::stringview_iter:
- WASM_UNREACHABLE("TODO: reftypes");
- }
+ }
+ assert(type.isRef());
+ auto heapType = type.getHeapType();
+ if (heapType.isBasic()) {
+ switch (heapType.getBasic()) {
+ case HeapType::i31:
+ WASM_UNREACHABLE("TODO: i31");
+ case HeapType::ext:
+ case HeapType::any:
+ WASM_UNREACHABLE("TODO: extern literals");
+ case HeapType::eq:
+ case HeapType::func:
+ case HeapType::data:
+ WASM_UNREACHABLE("invalid type");
+ case HeapType::string:
+ case HeapType::stringview_wtf8:
+ case HeapType::stringview_wtf16:
+ case HeapType::stringview_iter:
+ WASM_UNREACHABLE("TODO: string literals");
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ assert(type.isNullable());
+ return Literal::makeNull(heapType);
}
}
- assert(type.isBasic());
- switch (type.getBasic()) {
- case Type::i32:
- return Literal(x.i32);
- case Type::i64:
- return Literal(x.i64);
- case Type::f32:
- return Literal(x.i32).castToF32();
- case Type::f64:
- return Literal(x.i64).castToF64();
- case Type::v128:
- return Literal(x.v128);
- case Type::none:
- case Type::unreachable:
- WASM_UNREACHABLE("unexpected type");
+ if (heapType.isSignature()) {
+ return Literal::makeFunc(Name(x.func), heapType);
}
- WASM_UNREACHABLE("invalid type");
+ assert(heapType.isData());
+ WASM_UNREACHABLE("TODO: gc data");
}
// Mutexes (global for now; in theory if multiple modules
@@ -197,6 +212,15 @@ BinaryenType BinaryenTypeStringviewWTF16() {
BinaryenType BinaryenTypeStringviewIter() {
return Type(HeapType::stringview_iter, Nullable).getID();
}
+BinaryenType BinaryenTypeNullref() {
+ return Type(HeapType::none, Nullable).getID();
+}
+BinaryenType BinaryenTypeNullExternref(void) {
+ return Type(HeapType::noext, Nullable).getID();
+}
+BinaryenType BinaryenTypeNullFuncref(void) {
+ return Type(HeapType::nofunc, Nullable).getID();
+}
BinaryenType BinaryenTypeUnreachable(void) { return Type::unreachable; }
BinaryenType BinaryenTypeAuto(void) { return uintptr_t(-1); }
@@ -1484,7 +1508,8 @@ BinaryenExpressionRef BinaryenRefNull(BinaryenModuleRef module,
BinaryenType type) {
Type type_(type);
assert(type_.isNullable());
- return static_cast<Expression*>(Builder(*(Module*)module).makeRefNull(type_));
+ return static_cast<Expression*>(
+ Builder(*(Module*)module).makeRefNull(type_.getHeapType()));
}
BinaryenExpressionRef BinaryenRefIs(BinaryenModuleRef module,
@@ -1699,10 +1724,11 @@ BinaryenExpressionRef BinaryenArrayInit(BinaryenModuleRef module,
BinaryenExpressionRef BinaryenArrayGet(BinaryenModuleRef module,
BinaryenExpressionRef ref,
BinaryenExpressionRef index,
+ BinaryenType type,
bool signed_) {
return static_cast<Expression*>(
Builder(*(Module*)module)
- .makeArrayGet((Expression*)ref, (Expression*)index, signed_));
+ .makeArrayGet((Expression*)ref, (Expression*)index, Type(type), signed_));
}
BinaryenExpressionRef BinaryenArraySet(BinaryenModuleRef module,
BinaryenExpressionRef ref,
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 5b343e8ba..9cc282721 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -109,6 +109,9 @@ BINARYEN_API BinaryenType BinaryenTypeStringref(void);
BINARYEN_API BinaryenType BinaryenTypeStringviewWTF8(void);
BINARYEN_API BinaryenType BinaryenTypeStringviewWTF16(void);
BINARYEN_API BinaryenType BinaryenTypeStringviewIter(void);
+BINARYEN_API BinaryenType BinaryenTypeNullref(void);
+BINARYEN_API BinaryenType BinaryenTypeNullExternref(void);
+BINARYEN_API BinaryenType BinaryenTypeNullFuncref(void);
BINARYEN_API BinaryenType BinaryenTypeUnreachable(void);
// Not a real type. Used as the last parameter to BinaryenBlock to let
// the API figure out the type instead of providing one.
@@ -1044,6 +1047,7 @@ BinaryenArrayInit(BinaryenModuleRef module,
BINARYEN_API BinaryenExpressionRef BinaryenArrayGet(BinaryenModuleRef module,
BinaryenExpressionRef ref,
BinaryenExpressionRef index,
+ BinaryenType type,
bool signed_);
BINARYEN_API BinaryenExpressionRef
BinaryenArraySet(BinaryenModuleRef module,
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 63d9fafc5..2dfe616f9 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -701,6 +701,10 @@ private:
}
}
void visitCallRef(CallRef* curr) {
+ if (curr->target->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
parent.calls = true;
if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {
parent.throws_ = true;
@@ -724,6 +728,10 @@ private:
if (curr->ref->type == Type::unreachable) {
return;
}
+ if (curr->ref->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
if (curr->ref->type.getHeapType()
.getStruct()
.fields[curr->index]
@@ -736,6 +744,10 @@ private:
}
}
void visitStructSet(StructSet* curr) {
+ if (curr->ref->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
parent.writesStruct = true;
// traps when the arg is null
if (curr->ref->type.isNullable()) {
@@ -745,22 +757,38 @@ private:
void visitArrayNew(ArrayNew* curr) {}
void visitArrayInit(ArrayInit* curr) {}
void visitArrayGet(ArrayGet* curr) {
+ if (curr->ref->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
parent.readsArray = true;
// traps when the arg is null or the index out of bounds
parent.implicitTrap = true;
}
void visitArraySet(ArraySet* curr) {
+ if (curr->ref->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
parent.writesArray = true;
// traps when the arg is null or the index out of bounds
parent.implicitTrap = true;
}
void visitArrayLen(ArrayLen* curr) {
+ if (curr->ref->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
// traps when the arg is null
if (curr->ref->type.isNullable()) {
parent.implicitTrap = true;
}
}
void visitArrayCopy(ArrayCopy* curr) {
+ if (curr->destRef->type.isNull() || curr->srcRef->type.isNull()) {
+ parent.trap = true;
+ return;
+ }
parent.readsArray = true;
parent.writesArray = true;
// traps when a ref is null, or when out of bounds.
diff --git a/src/ir/manipulation.h b/src/ir/manipulation.h
index 54822f2bd..33c7d1bd7 100644
--- a/src/ir/manipulation.h
+++ b/src/ir/manipulation.h
@@ -41,6 +41,7 @@ template<typename InputType> inline Nop* nop(InputType* target) {
template<typename InputType>
inline RefNull* refNull(InputType* target, Type type) {
+ assert(type.isNullable() && type.getHeapType().isBottom());
auto* ret = convert<InputType, RefNull>(target);
ret->finalize(type);
return ret;
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index 7c69121e6..9ad43f090 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -47,23 +47,6 @@ void PossibleContents::combine(const PossibleContents& other) {
// First handle the trivial cases of them being equal, or one of them is
// None or Many.
if (*this == other) {
- // Nulls are a special case, since they compare equal even if their type is
- // different. We would like to make this function symmetric, that is, that
- // combine(a, b) == combine(b, a) (otherwise, things can be odd and we could
- // get nondeterminism in the flow analysis which does not have a
- // determinstic order). To fix that, pick the LUB.
- if (isNull()) {
- assert(other.isNull());
- auto lub = HeapType::getLeastUpperBound(type.getHeapType(),
- otherType.getHeapType());
- if (!lub) {
- // TODO: Remove this workaround once we have bottom types to assign to
- // null literals.
- value = Many();
- return;
- }
- value = Literal::makeNull(*lub);
- }
return;
}
if (other.isNone()) {
@@ -97,10 +80,18 @@ void PossibleContents::combine(const PossibleContents& other) {
// Special handling for references from here.
- // Nulls are always equal to each other, even if their types differ.
+ if (isNull() && other.isNull()) {
+ // These must be nulls in different hierarchies, otherwise this would have
+ // been handled by the `*this == other` case above.
+ assert(type != otherType);
+ value = Many();
+ return;
+ }
+
+ // Nulls can be combined in by just adding nullability to a type.
if (isNull() || other.isNull()) {
- // Only one of them can be null here, since we already checked if *this ==
- // other, which would have been true had both been null.
+ // Only one of them can be null here, since we already handled the case
+ // where they were both null.
assert(!isNull() || !other.isNull());
// If only one is a null, but the other's type is known exactly, then the
// combination is to add nullability (if the type is *not* known exactly,
@@ -797,7 +788,8 @@ struct InfoCollector
// part of the main IR, which is potentially confusing during debugging,
// however, which is a downside.
Builder builder(*getModule());
- auto* get = builder.makeArrayGet(curr->srcRef, curr->srcIndex);
+ auto* get =
+ builder.makeArrayGet(curr->srcRef, curr->srcIndex, curr->srcRef->type);
visitArrayGet(get);
auto* set = builder.makeArraySet(curr->destRef, curr->destIndex, get);
visitArraySet(set);
diff --git a/src/ir/struct-utils.h b/src/ir/struct-utils.h
index 9d02bb779..9f880985f 100644
--- a/src/ir/struct-utils.h
+++ b/src/ir/struct-utils.h
@@ -50,6 +50,7 @@ struct StructValuesMap : public std::unordered_map<HeapType, StructValues<T>> {
// When we access an item, if it does not already exist, create it with a
// vector of the right length for that type.
StructValues<T>& operator[](HeapType type) {
+ assert(type.isStruct());
auto inserted = this->insert({type, {}});
auto& values = inserted.first->second;
if (inserted.second) {
@@ -159,7 +160,7 @@ struct StructScanner
void visitStructSet(StructSet* curr) {
auto type = curr->ref->type;
- if (type == Type::unreachable) {
+ if (type == Type::unreachable || type.isNull()) {
return;
}
@@ -173,7 +174,7 @@ struct StructScanner
void visitStructGet(StructGet* curr) {
auto type = curr->ref->type;
- if (type == Type::unreachable) {
+ if (type == Type::unreachable || type.isNull()) {
return;
}
diff --git a/src/literal.h b/src/literal.h
index 318ab012a..7d7c778bc 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -79,7 +79,9 @@ public:
explicit Literal(const std::array<Literal, 4>&);
explicit Literal(const std::array<Literal, 2>&);
explicit Literal(Name func, HeapType type)
- : func(func), type(type, NonNullable) {}
+ : func(func), type(type, NonNullable) {
+ assert(type.isSignature());
+ }
explicit Literal(std::shared_ptr<GCData> gcData, HeapType type);
Literal(const Literal& other);
Literal& operator=(const Literal& other);
@@ -90,21 +92,8 @@ public:
bool isFunction() const { return type.isFunction(); }
bool isData() const { return type.isData(); }
- bool isNull() const {
- if (type.isNullable()) {
- if (type.isFunction()) {
- return func.isNull();
- }
- if (isData()) {
- return !gcData;
- }
- if (type.getHeapType() == HeapType::i31) {
- return i32 == 0;
- }
- return true;
- }
- return false;
- }
+ bool isNull() const { return type.isNull(); }
+
bool isZero() const {
switch (type.getBasic()) {
case Type::i32:
@@ -239,7 +228,7 @@ public:
}
}
static Literal makeNull(HeapType type) {
- return Literal(Type(type, Nullable));
+ return Literal(Type(type.getBottom(), Nullable));
}
static Literal makeFunc(Name func, HeapType type) {
return Literal(func, type);
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index c03b404b0..f325f70c6 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -32,6 +32,7 @@
#include "ir/branch-utils.h"
#include "ir/debug.h"
+#include "ir/drop.h"
#include "ir/eh-utils.h"
#include "ir/element-utils.h"
#include "ir/literal-utils.h"
@@ -251,6 +252,10 @@ struct Updater : public PostWalker<Updater> {
Name returnName;
bool isReturn;
Builder* builder;
+ PassOptions& options;
+
+ Updater(PassOptions& options) : options(options) {}
+
void visitReturn(Return* curr) {
replaceCurrent(builder->makeBreak(returnName, curr->value));
}
@@ -259,7 +264,7 @@ struct Updater : public PostWalker<Updater> {
// achieve this, make the call a non-return call and add a break. This does
// not cause unbounded stack growth because inlining and return calling both
// avoid creating a new stack frame.
- template<typename T> void handleReturnCall(T* curr, HeapType targetType) {
+ template<typename T> void handleReturnCall(T* curr, Type results) {
if (isReturn) {
// If the inlined callsite was already a return_call, then we can keep
// return_calls in the inlined function rather than downgrading them.
@@ -269,7 +274,7 @@ struct Updater : public PostWalker<Updater> {
return;
}
curr->isReturn = false;
- curr->type = targetType.getSignature().results;
+ curr->type = results;
if (curr->type.isConcrete()) {
replaceCurrent(builder->makeBreak(returnName, curr));
} else {
@@ -278,17 +283,25 @@ struct Updater : public PostWalker<Updater> {
}
void visitCall(Call* curr) {
if (curr->isReturn) {
- handleReturnCall(curr, module->getFunction(curr->target)->type);
+ handleReturnCall(curr, module->getFunction(curr->target)->getResults());
}
}
void visitCallIndirect(CallIndirect* curr) {
if (curr->isReturn) {
- handleReturnCall(curr, curr->heapType);
+ handleReturnCall(curr, curr->heapType.getSignature().results);
}
}
void visitCallRef(CallRef* curr) {
+ Type targetType = curr->target->type;
+ if (targetType.isNull()) {
+ // We don't know what type the call should return, but we can't leave it
+ // as a potentially-invalid return_call_ref, either.
+ replaceCurrent(getDroppedChildrenAndAppend(
+ curr, *module, options, Builder(*module).makeUnreachable()));
+ return;
+ }
if (curr->isReturn) {
- handleReturnCall(curr, curr->target->type.getHeapType());
+ handleReturnCall(curr, targetType.getHeapType().getSignature().results);
}
}
void visitLocalGet(LocalGet* curr) {
@@ -301,8 +314,10 @@ struct Updater : public PostWalker<Updater> {
// Core inlining logic. Modifies the outside function (adding locals as
// needed), and returns the inlined code.
-static Expression*
-doInlining(Module* module, Function* into, const InliningAction& action) {
+static Expression* doInlining(Module* module,
+ Function* into,
+ const InliningAction& action,
+ PassOptions& options) {
Function* from = action.contents;
auto* call = (*action.callSite)->cast<Call>();
// Works for return_call, too
@@ -337,7 +352,7 @@ doInlining(Module* module, Function* into, const InliningAction& action) {
*action.callSite = block;
}
// Prepare to update the inlined code's locals and other things.
- Updater updater;
+ Updater updater(options);
updater.module = module;
updater.returnName = block->name;
updater.isReturn = call->isReturn;
@@ -1002,7 +1017,7 @@ struct Inlining : public Pass {
action.contents = getActuallyInlinedFunction(action.contents);
// Perform the inlining and update counts.
- doInlining(module, func, action);
+ doInlining(module, func, action, getPassOptions());
inlinedUses[inlinedName]++;
inlinedInto.insert(func);
assert(inlinedUses[inlinedName] <= infos[inlinedName].refs);
@@ -1116,7 +1131,8 @@ struct InlineMainPass : public Pass {
// No call at all.
return;
}
- doInlining(module, main, InliningAction(callSite, originalMain));
+ doInlining(
+ module, main, InliningAction(callSite, originalMain), getPassOptions());
}
};
diff --git a/src/passes/JSPI.cpp b/src/passes/JSPI.cpp
index 9660b962d..fe24d60f7 100644
--- a/src/passes/JSPI.cpp
+++ b/src/passes/JSPI.cpp
@@ -45,8 +45,10 @@ struct JSPI : public Pass {
// Create a global to store the suspender that is passed into exported
// functions and will then need to be passed out to the imported functions.
Name suspender = Names::getValidGlobalName(*module, "suspender");
- module->addGlobal(builder.makeGlobal(
- suspender, externref, builder.makeRefNull(externref), Builder::Mutable));
+ module->addGlobal(builder.makeGlobal(suspender,
+ externref,
+ builder.makeRefNull(HeapType::noext),
+ Builder::Mutable));
// Keep track of already wrapped functions since they can be exported
// multiple times, but only one wrapper is needed.
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 4ffd6be67..059ef28fb 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1267,6 +1267,10 @@ struct OptimizeInstructions
}
void visitCallRef(CallRef* curr) {
+ skipNonNullCast(curr->target);
+ if (trapOnNull(curr, curr->target)) {
+ return;
+ }
if (curr->target->type == Type::unreachable) {
// The call_ref is not reached; leave this for DCE.
return;
@@ -1509,6 +1513,17 @@ struct OptimizeInstructions
return getDroppedChildrenAndAppend(curr, result);
}
+ bool trapOnNull(Expression* curr, Expression* ref) {
+ if (ref->type.isNull()) {
+ replaceCurrent(getDroppedChildrenAndAppend(
+ curr, Builder(*getModule()).makeUnreachable()));
+ // Propagate the unreachability.
+ refinalize = true;
+ return true;
+ }
+ return false;
+ }
+
void visitRefEq(RefEq* curr) {
// The types may prove that the same reference cannot appear on both sides.
auto leftType = curr->left->type;
@@ -1564,10 +1579,16 @@ struct OptimizeInstructions
}
}
- void visitStructGet(StructGet* curr) { skipNonNullCast(curr->ref); }
+ void visitStructGet(StructGet* curr) {
+ skipNonNullCast(curr->ref);
+ trapOnNull(curr, curr->ref);
+ }
void visitStructSet(StructSet* curr) {
skipNonNullCast(curr->ref);
+ if (trapOnNull(curr, curr->ref)) {
+ return;
+ }
if (curr->ref->type != Type::unreachable && curr->value->type.isInteger()) {
const auto& fields = curr->ref->type.getHeapType().getStruct().fields;
@@ -1715,10 +1736,16 @@ struct OptimizeInstructions
return true;
}
- void visitArrayGet(ArrayGet* curr) { skipNonNullCast(curr->ref); }
+ void visitArrayGet(ArrayGet* curr) {
+ skipNonNullCast(curr->ref);
+ trapOnNull(curr, curr->ref);
+ }
void visitArraySet(ArraySet* curr) {
skipNonNullCast(curr->ref);
+ if (trapOnNull(curr, curr->ref)) {
+ return;
+ }
if (curr->ref->type != Type::unreachable && curr->value->type.isInteger()) {
auto element = curr->ref->type.getHeapType().getArray().element;
@@ -1726,11 +1753,15 @@ struct OptimizeInstructions
}
}
- void visitArrayLen(ArrayLen* curr) { skipNonNullCast(curr->ref); }
+ void visitArrayLen(ArrayLen* curr) {
+ skipNonNullCast(curr->ref);
+ trapOnNull(curr, curr->ref);
+ }
void visitArrayCopy(ArrayCopy* curr) {
skipNonNullCast(curr->destRef);
skipNonNullCast(curr->srcRef);
+ trapOnNull(curr, curr->destRef) || trapOnNull(curr, curr->srcRef);
}
bool canBeCastTo(HeapType a, HeapType b) {
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 466614d14..c90fdf167 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -130,7 +130,7 @@ public:
}
Flow visitStructSet(StructSet* curr) { return Flow(NONCONSTANT_FLOW); }
Flow visitStructGet(StructGet* curr) {
- if (curr->ref->type != Type::unreachable) {
+ if (curr->ref->type != Type::unreachable && !curr->ref->type.isNull()) {
// If this field is immutable then we may be able to precompute this, as
// if we also created the data in this function (or it was created in an
// immutable global) then we know the value in the field. If it is
@@ -164,7 +164,7 @@ public:
}
Flow visitArraySet(ArraySet* curr) { return Flow(NONCONSTANT_FLOW); }
Flow visitArrayGet(ArrayGet* curr) {
- if (curr->ref->type != Type::unreachable) {
+ if (curr->ref->type != Type::unreachable && !curr->ref->type.isNull()) {
// See above with struct.get
auto element = curr->ref->type.getHeapType().getArray().element;
if (element.mutable_ == Immutable) {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 01b004d97..7ebad3322 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -115,6 +115,15 @@ bool maybePrintRefShorthand(std::ostream& o, Type type) {
case HeapType::stringview_iter:
o << "stringview_iter";
return true;
+ case HeapType::none:
+ o << "nullref";
+ return true;
+ case HeapType::noext:
+ o << "nullexternref";
+ return true;
+ case HeapType::nofunc:
+ o << "nullfuncref";
+ return true;
}
}
return false;
@@ -2058,10 +2067,17 @@ struct PrintExpressionContents
}
return false;
}
+ bool printUnreachableOrNullReplacement(Expression* curr) {
+ if (curr->type == Type::unreachable || curr->type.isNull()) {
+ printMedium(o, "block");
+ return true;
+ }
+ return false;
+ }
void visitCallRef(CallRef* curr) {
// TODO: Workaround if target has bottom type.
- if (printUnreachableReplacement(curr->target)) {
+ if (printUnreachableOrNullReplacement(curr->target)) {
return;
}
printMedium(o, curr->isReturn ? "return_call_ref " : "call_ref ");
@@ -2144,7 +2160,7 @@ struct PrintExpressionContents
});
}
void visitStructGet(StructGet* curr) {
- if (printUnreachableReplacement(curr->ref)) {
+ if (printUnreachableOrNullReplacement(curr->ref)) {
return;
}
auto heapType = curr->ref->type.getHeapType();
@@ -2163,7 +2179,7 @@ struct PrintExpressionContents
printFieldName(heapType, curr->index);
}
void visitStructSet(StructSet* curr) {
- if (printUnreachableReplacement(curr->ref)) {
+ if (printUnreachableOrNullReplacement(curr->ref)) {
return;
}
printMedium(o, "struct.set ");
@@ -2192,7 +2208,7 @@ struct PrintExpressionContents
TypeNamePrinter(o, wasm).print(curr->type.getHeapType());
}
void visitArrayGet(ArrayGet* curr) {
- if (printUnreachableReplacement(curr->ref)) {
+ if (printUnreachableOrNullReplacement(curr->ref)) {
return;
}
const auto& element = curr->ref->type.getHeapType().getArray().element;
@@ -2208,22 +2224,22 @@ struct PrintExpressionContents
TypeNamePrinter(o, wasm).print(curr->ref->type.getHeapType());
}
void visitArraySet(ArraySet* curr) {
- if (printUnreachableReplacement(curr->ref)) {
+ if (printUnreachableOrNullReplacement(curr->ref)) {
return;
}
printMedium(o, "array.set ");
TypeNamePrinter(o, wasm).print(curr->ref->type.getHeapType());
}
void visitArrayLen(ArrayLen* curr) {
- if (printUnreachableReplacement(curr->ref)) {
+ if (printUnreachableOrNullReplacement(curr->ref)) {
return;
}
printMedium(o, "array.len ");
TypeNamePrinter(o, wasm).print(curr->ref->type.getHeapType());
}
void visitArrayCopy(ArrayCopy* curr) {
- if (printUnreachableReplacement(curr->srcRef) ||
- printUnreachableReplacement(curr->destRef)) {
+ if (printUnreachableOrNullReplacement(curr->srcRef) ||
+ printUnreachableOrNullReplacement(curr->destRef)) {
return;
}
printMedium(o, "array.copy ");
@@ -2746,19 +2762,29 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
drop.value = child;
printFullLine(&drop);
}
+ Unreachable unreachable;
+ printFullLine(&unreachable);
decIndent();
}
+ // This must be used for the same Expressions that use
+ // PrintExpressionContents::printUnreachableOrNullReplacement.
+ void maybePrintUnreachableOrNullReplacement(Expression* curr, Type type) {
+ if (type.isNull()) {
+ type = Type::unreachable;
+ }
+ maybePrintUnreachableReplacement(curr, type);
+ }
void visitCallRef(CallRef* curr) {
- maybePrintUnreachableReplacement(curr, curr->target->type);
+ maybePrintUnreachableOrNullReplacement(curr, curr->target->type);
}
void visitStructNew(StructNew* curr) {
maybePrintUnreachableReplacement(curr, curr->type);
}
void visitStructSet(StructSet* curr) {
- maybePrintUnreachableReplacement(curr, curr->ref->type);
+ maybePrintUnreachableOrNullReplacement(curr, curr->ref->type);
}
void visitStructGet(StructGet* curr) {
- maybePrintUnreachableReplacement(curr, curr->ref->type);
+ maybePrintUnreachableOrNullReplacement(curr, curr->ref->type);
}
void visitArrayNew(ArrayNew* curr) {
maybePrintUnreachableReplacement(curr, curr->type);
@@ -2767,10 +2793,13 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
maybePrintUnreachableReplacement(curr, curr->type);
}
void visitArraySet(ArraySet* curr) {
- maybePrintUnreachableReplacement(curr, curr->ref->type);
+ maybePrintUnreachableOrNullReplacement(curr, curr->ref->type);
}
void visitArrayGet(ArrayGet* curr) {
- maybePrintUnreachableReplacement(curr, curr->ref->type);
+ maybePrintUnreachableOrNullReplacement(curr, curr->ref->type);
+ }
+ void visitArrayLen(ArrayLen* curr) {
+ maybePrintUnreachableOrNullReplacement(curr, curr->ref->type);
}
// Module-level visitors
void printSupertypeOr(HeapType curr, std::string noSuper) {
diff --git a/src/passes/TypeRefining.cpp b/src/passes/TypeRefining.cpp
index 6ce503cc0..e9aa07ca6 100644
--- a/src/passes/TypeRefining.cpp
+++ b/src/passes/TypeRefining.cpp
@@ -251,7 +251,7 @@ struct TypeRefining : public Pass {
}
void visitStructGet(StructGet* curr) {
- if (curr->ref->type == Type::unreachable) {
+ if (curr->ref->type == Type::unreachable || curr->ref->type.isNull()) {
return;
}
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 2b368a4e8..09df9ac31 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -1976,7 +1976,7 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) {
// to add a ref.as_non_null to validate, and the code will trap when we get
// here).
if ((type.isNullable() && oneIn(2)) || (type.isNonNullable() && oneIn(16))) {
- Expression* ret = builder.makeRefNull(Type(heapType, Nullable));
+ Expression* ret = builder.makeRefNull(HeapType::nofunc);
if (!type.isNullable()) {
ret = builder.makeRefAs(RefAsNonNull, ret);
}
@@ -2000,7 +2000,7 @@ Expression* TranslateToFuzzReader::makeConst(Type type) {
assert(wasm.features.hasReferenceTypes());
// With a low chance, just emit a null if that is valid.
if (type.isNullable() && oneIn(8)) {
- return builder.makeRefNull(type);
+ return builder.makeRefNull(type.getHeapType());
}
if (type.getHeapType().isBasic()) {
return makeConstBasicRef(type);
@@ -2050,7 +2050,7 @@ Expression* TranslateToFuzzReader::makeConstBasicRef(Type type) {
// a subtype of anyref, but we cannot create constants of it, except
// for null.
assert(type.isNullable());
- return builder.makeRefNull(type);
+ return builder.makeRefNull(HeapType::none);
}
auto nullability = getSubType(type.getNullability());
// i31.new is not allowed in initializer expressions.
@@ -2065,7 +2065,7 @@ Expression* TranslateToFuzzReader::makeConstBasicRef(Type type) {
case HeapType::i31: {
assert(wasm.features.hasGC());
if (type.isNullable() && oneIn(4)) {
- return builder.makeRefNull(type);
+ return builder.makeRefNull(HeapType::none);
}
return builder.makeI31New(makeConst(Type::i32));
}
@@ -2086,10 +2086,22 @@ Expression* TranslateToFuzzReader::makeConstBasicRef(Type type) {
return builder.makeArrayInit(trivialArray, {});
}
}
- default: {
- WASM_UNREACHABLE("invalid basic ref type");
+ case HeapType::string:
+ case HeapType::stringview_wtf8:
+ case HeapType::stringview_wtf16:
+ case HeapType::stringview_iter:
+ WASM_UNREACHABLE("TODO: strings");
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc: {
+ auto null = builder.makeRefNull(heapType);
+ if (!type.isNullable()) {
+ return builder.makeRefAs(RefAsNonNull, null);
+ }
+ return null;
}
}
+ WASM_UNREACHABLE("invalid basic ref type");
}
Expression* TranslateToFuzzReader::makeConstCompoundRef(Type type) {
@@ -2104,15 +2116,14 @@ Expression* TranslateToFuzzReader::makeConstCompoundRef(Type type) {
// We weren't able to directly materialize a non-null constant. Try again to
// create a null.
if (type.isNullable()) {
- return builder.makeRefNull(type);
+ return builder.makeRefNull(heapType);
}
// We have to produce a non-null value. Possibly create a null and cast it
// to non-null even though that will trap at runtime. We must have a
// function context for this because the cast is not allowed in globals.
if (funcContext) {
- return builder.makeRefAs(RefAsNonNull,
- builder.makeRefNull(Type(heapType, Nullable)));
+ return builder.makeRefAs(RefAsNonNull, builder.makeRefNull(heapType));
}
// Otherwise, we are not in a function context. This can happen if we need
@@ -3138,33 +3149,49 @@ Nullability TranslateToFuzzReader::getSubType(Nullability nullability) {
}
HeapType TranslateToFuzzReader::getSubType(HeapType type) {
+ if (oneIn(2)) {
+ return type;
+ }
if (type.isBasic()) {
switch (type.getBasic()) {
case HeapType::func:
// TODO: Typed function references.
- return HeapType::func;
+ return pick(FeatureOptions<HeapType>()
+ .add(FeatureSet::ReferenceTypes, HeapType::func)
+ .add(FeatureSet::GC, HeapType::nofunc));
case HeapType::ext:
- return HeapType::ext;
+ return pick(FeatureOptions<HeapType>()
+ .add(FeatureSet::ReferenceTypes, HeapType::ext)
+ .add(FeatureSet::GC, HeapType::noext));
case HeapType::any:
// TODO: nontrivial types as well.
assert(wasm.features.hasReferenceTypes());
assert(wasm.features.hasGC());
- return pick(HeapType::any, HeapType::eq, HeapType::i31, HeapType::data);
+ return pick(HeapType::any,
+ HeapType::eq,
+ HeapType::i31,
+ HeapType::data,
+ HeapType::none);
case HeapType::eq:
// TODO: nontrivial types as well.
assert(wasm.features.hasReferenceTypes());
assert(wasm.features.hasGC());
- return pick(HeapType::eq, HeapType::i31, HeapType::data);
+ return pick(
+ HeapType::eq, HeapType::i31, HeapType::data, HeapType::none);
case HeapType::i31:
- return HeapType::i31;
+ return pick(HeapType::i31, HeapType::none);
case HeapType::data:
// TODO: nontrivial types as well.
- return HeapType::data;
+ return pick(HeapType::data, HeapType::none);
case HeapType::string:
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
WASM_UNREACHABLE("TODO: fuzz strings");
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ break;
}
}
// TODO: nontrivial types as well.
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index ad87c6fab..351035f93 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -69,7 +69,7 @@ struct HeapTypeGeneratorImpl {
typeIndices.insert({builder[i], i});
// Everything is a subtype of itself.
subtypeIndices[i].push_back(i);
- if (i < numRoots) {
+ if (i < numRoots || rand.oneIn(2)) {
// This is a root type with no supertype. Choose a kind for this type.
typeKinds.emplace_back(generateHeapTypeKind());
} else {
@@ -148,6 +148,11 @@ struct HeapTypeGeneratorImpl {
}
HeapType::BasicHeapType generateBasicHeapType() {
+ // Choose bottom types more rarely.
+ if (rand.oneIn(16)) {
+ return rand.pick(HeapType::noext, HeapType::nofunc, HeapType::none);
+ }
+ // TODO: strings
return rand.pick(HeapType::func,
HeapType::ext,
HeapType::any,
@@ -254,6 +259,8 @@ struct HeapTypeGeneratorImpl {
HeapType pickSubFunc() {
if (auto type = pickKind<SignatureKind>()) {
return *type;
+ } else if (rand.oneIn(2)) {
+ return HeapType::nofunc;
} else {
return HeapType::func;
}
@@ -262,6 +269,8 @@ struct HeapTypeGeneratorImpl {
HeapType pickSubData() {
if (auto type = pickKind<DataKind>()) {
return *type;
+ } else if (rand.oneIn(2)) {
+ return HeapType::none;
} else {
return HeapType::data;
}
@@ -292,7 +301,7 @@ struct HeapTypeGeneratorImpl {
// can only choose those defined before the end of the current recursion
// group.
std::vector<Index> candidateIndices;
- for (auto i : subtypeIndices[typeIndices[type]]) {
+ for (auto i : subtypeIndices[it->second]) {
if (i < recGroupEnds[index]) {
candidateIndices.push_back(i);
}
@@ -301,6 +310,9 @@ struct HeapTypeGeneratorImpl {
} else {
// This is not a constructed type, so it must be a basic type.
assert(type.isBasic());
+ if (rand.oneIn(8)) {
+ return type.getBottom();
+ }
switch (type.getBasic()) {
case HeapType::ext:
return HeapType::ext;
@@ -318,7 +330,10 @@ struct HeapTypeGeneratorImpl {
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
- WASM_UNREACHABLE("TODO: fuzz strings");
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ return type;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -403,6 +418,17 @@ struct HeapTypeGeneratorImpl {
}
HeapTypeKind getSubKind(HeapTypeKind super) {
+ if (rand.oneIn(16)) {
+ // Occasionally go directly to the bottom type.
+ if (auto* basic = std::get_if<BasicKind>(&super)) {
+ return HeapType(*basic).getBottom();
+ } else if (std::get_if<SignatureKind>(&super)) {
+ return HeapType::nofunc;
+ } else if (std::get_if<DataKind>(&super)) {
+ return HeapType::none;
+ }
+ WASM_UNREACHABLE("unexpected kind");
+ }
if (auto* basic = std::get_if<BasicKind>(&super)) {
if (rand.oneIn(8)) {
return super;
@@ -441,7 +467,10 @@ struct HeapTypeGeneratorImpl {
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
- WASM_UNREACHABLE("TODO: fuzz strings");
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ return super;
}
WASM_UNREACHABLE("unexpected kind");
} else {
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 5e9874ccc..45cc63c37 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -553,10 +553,7 @@ public:
// This is GC data, which we must handle in a more careful way.
auto* data = value.getGCData().get();
- if (!data) {
- // This is a null, so simply emit one.
- return builder.makeRefNull(value.type);
- }
+ assert(data);
// There was actual GC data allocated here.
auto type = value.type;
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 6febcf6b9..557e8a770 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -1142,7 +1142,7 @@ struct Reducer
}
// try to replace with a trivial value
if (curr->type.isNullable()) {
- RefNull* n = builder->makeRefNull(curr->type);
+ RefNull* n = builder->makeRefNull(curr->type.getHeapType());
return tryToReplaceCurrent(n);
}
if (curr->type.isTuple() && curr->type.isDefaultable()) {
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index e9ad665c4..ca21662e6 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -382,6 +382,10 @@ enum EncodedType {
stringview_wtf8 = -0x1d, // 0x63
stringview_wtf16 = -0x1e, // 0x62
stringview_iter = -0x1f, // 0x61
+ // bottom types
+ nullexternref = -0x17, // 0x69
+ nullfuncref = -0x18, // 0x68
+ nullref = -0x1b, // 0x65
// type forms
Func = -0x20, // 0x60
Struct = -0x21, // 0x5f
@@ -411,6 +415,10 @@ enum EncodedHeapType {
stringview_wtf8_heap = -0x1d, // 0x63
stringview_wtf16_heap = -0x1e, // 0x62
stringview_iter_heap = -0x1f, // 0x61
+ // bottom types
+ noext = -0x17, // 0x69
+ nofunc = -0x18, // 0x68
+ none = -0x1b, // 0x65
};
namespace UserSections {
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index cc3b99138..b07af4627 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -699,10 +699,11 @@ public:
}
RefNull* makeRefNull(HeapType type) {
auto* ret = wasm.allocator.alloc<RefNull>();
- ret->finalize(Type(type, Nullable));
+ ret->finalize(Type(type.getBottom(), Nullable));
return ret;
}
RefNull* makeRefNull(Type type) {
+ assert(type.isNullable() && type.isNull());
auto* ret = wasm.allocator.alloc<RefNull>();
ret->finalize(type);
return ret;
@@ -942,11 +943,14 @@ public:
ret->finalize();
return ret;
}
- ArrayGet*
- makeArrayGet(Expression* ref, Expression* index, bool signed_ = false) {
+ ArrayGet* makeArrayGet(Expression* ref,
+ Expression* index,
+ Type type,
+ bool signed_ = false) {
auto* ret = wasm.allocator.alloc<ArrayGet>();
ret->ref = ref;
ret->index = index;
+ ret->type = type;
ret->signed_ = signed_;
ret->finalize();
return ret;
@@ -1262,7 +1266,7 @@ public:
if (curr->type.isTuple() && curr->type.isDefaultable()) {
return makeConstantExpression(Literal::makeZeros(curr->type));
}
- if (curr->type.isNullable()) {
+ if (curr->type.isNullable() && curr->type.isNull()) {
return ExpressionManipulator::refNull(curr, curr->type);
}
if (curr->type.isRef() && curr->type.getHeapType() == HeapType::i31) {
@@ -1329,18 +1333,24 @@ public:
Expression* validateAndMakeCallRef(Expression* target,
const T& args,
bool isReturn = false) {
- if (!target->type.isRef()) {
- if (target->type == Type::unreachable) {
- // 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.
- auto* block = makeBlock(args);
- block->list.push_back(target);
- block->finalize(Type::unreachable);
- return block;
- }
+ 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);
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 69434a297..10b84a82f 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1350,12 +1350,11 @@ public:
case RefIsNull:
return Literal(value.isNull());
case RefIsFunc:
- return Literal(!value.isNull() && value.type.isFunction());
+ return Literal(value.type.isFunction());
case RefIsData:
- return Literal(!value.isNull() && value.isData());
+ return Literal(value.isData());
case RefIsI31:
- return Literal(!value.isNull() &&
- value.type.getHeapType() == HeapType::i31);
+ return Literal(value.type.getHeapType() == HeapType::i31);
default:
WASM_UNREACHABLE("unimplemented ref.is_*");
}
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 940009cbe..dbdbe3d31 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -169,6 +169,8 @@ public:
// is irrelevant. (For that reason, this is only the negation of isNullable()
// on references, but both return false on non-references.)
bool isNonNullable() const;
+ // Whether this type is only inhabited by null values.
+ bool isNull() const;
bool isStruct() const;
bool isArray() const;
bool isDefaultable() const;
@@ -326,8 +328,11 @@ public:
stringview_wtf8,
stringview_wtf16,
stringview_iter,
+ none,
+ noext,
+ nofunc,
};
- static constexpr BasicHeapType _last_basic_type = stringview_iter;
+ static constexpr BasicHeapType _last_basic_type = nofunc;
// BasicHeapType can be implicitly upgraded to HeapType
constexpr HeapType(BasicHeapType id) : id(id) {}
@@ -358,6 +363,7 @@ public:
bool isSignature() const;
bool isStruct() const;
bool isArray() const;
+ bool isBottom() const;
Signature getSignature() const;
const Struct& getStruct() const;
@@ -371,6 +377,9 @@ public:
// number of supertypes in its supertype chain.
size_t getDepth() const;
+ // Get the bottom heap type for this heap type's hierarchy.
+ BasicHeapType getBottom() const;
+
// Get the recursion group for this non-basic type.
RecGroup getRecGroup() const;
size_t getRecGroupIndex() const;
@@ -421,6 +430,8 @@ public:
std::string toString() const;
};
+inline bool Type::isNull() const { return isRef() && getHeapType().isBottom(); }
+
// A recursion group consisting of one or more HeapTypes. HeapTypes with single
// members are encoded without using any additional memory, which is why
// `getHeapTypes` has to return a vector by value; it might have to create one
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 43f407525..09022eea0 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -44,19 +44,25 @@ Literal::Literal(Type type) : type(type) {
memset(&v128, 0, 16);
return;
case Type::none:
- return;
case Type::unreachable:
- break;
+ WASM_UNREACHABLE("Invalid literal type");
+ return;
}
}
- if (isData()) {
- assert(!type.isNonNullable());
+ if (type.isNull()) {
+ assert(type.isNullable());
new (&gcData) std::shared_ptr<GCData>();
- } else {
- // For anything else, zero out all the union data.
- memset(&v128, 0, 16);
+ return;
}
+
+ if (type.isRef() && type.getHeapType() == HeapType::i31) {
+ assert(type.isNonNullable());
+ i32 = 0;
+ return;
+ }
+
+ WASM_UNREACHABLE("Unexpected literal type");
}
Literal::Literal(const uint8_t init[16]) : type(Type::v128) {
@@ -64,9 +70,9 @@ Literal::Literal(const uint8_t init[16]) : type(Type::v128) {
}
Literal::Literal(std::shared_ptr<GCData> gcData, HeapType type)
- : gcData(gcData), type(type, gcData ? NonNullable : Nullable) {
+ : gcData(gcData), type(type, NonNullable) {
// The type must be a proper type for GC data.
- assert(isData());
+ assert((isData() && gcData) || (type.isBottom() && !gcData));
}
Literal::Literal(const Literal& other) : type(other.type) {
@@ -89,6 +95,10 @@ Literal::Literal(const Literal& other) : type(other.type) {
break;
}
}
+ if (other.isNull()) {
+ new (&gcData) std::shared_ptr<GCData>();
+ return;
+ }
if (other.isData()) {
new (&gcData) std::shared_ptr<GCData>(other.gcData);
return;
@@ -98,23 +108,30 @@ Literal::Literal(const Literal& other) : type(other.type) {
return;
}
if (type.isRef()) {
+ assert(!type.isNullable());
auto heapType = type.getHeapType();
if (heapType.isBasic()) {
switch (heapType.getBasic()) {
- case HeapType::ext:
- case HeapType::any:
- case HeapType::eq:
- return; // null
case HeapType::i31:
i32 = other.i32;
return;
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ // Null
+ return;
+ case HeapType::ext:
+ case HeapType::any:
+ WASM_UNREACHABLE("TODO: extern literals");
+ case HeapType::eq:
case HeapType::func:
case HeapType::data:
+ WASM_UNREACHABLE("invalid type");
case HeapType::string:
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
- WASM_UNREACHABLE("invalid type");
+ WASM_UNREACHABLE("TODO: string literals");
}
}
}
@@ -125,7 +142,7 @@ Literal::~Literal() {
if (type.isBasic()) {
return;
}
- if (isData()) {
+ if (isNull() || isData()) {
gcData.~shared_ptr();
}
}
@@ -239,7 +256,7 @@ std::array<uint8_t, 16> Literal::getv128() const {
}
std::shared_ptr<GCData> Literal::getGCData() const {
- assert(isData());
+ assert(isNull() || isData());
return gcData;
}
@@ -325,11 +342,6 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
}
bool Literal::operator==(const Literal& other) const {
- // The types must be identical, unless both are references - in that case,
- // nulls of different types *do* compare equal.
- if (type.isRef() && other.type.isRef() && (isNull() || other.isNull())) {
- return isNull() && other.isNull();
- }
if (type != other.type) {
return false;
}
@@ -350,7 +362,9 @@ bool Literal::operator==(const Literal& other) const {
}
} else if (type.isRef()) {
assert(type.isRef());
- // Note that we've already handled nulls earlier.
+ if (type.isNull()) {
+ return true;
+ }
if (type.isFunction()) {
assert(func.is() && other.func.is());
return func == other.func;
@@ -361,8 +375,6 @@ bool Literal::operator==(const Literal& other) const {
if (type.getHeapType() == HeapType::i31) {
return i32 == other.i32;
}
- // other non-null reference type literals cannot represent concrete values,
- // i.e. there is no concrete anyref or eqref other than null.
WASM_UNREACHABLE("unexpected type");
}
WASM_UNREACHABLE("unexpected type");
@@ -463,52 +475,8 @@ void Literal::printVec128(std::ostream& o, const std::array<uint8_t, 16>& v) {
std::ostream& operator<<(std::ostream& o, Literal literal) {
prepareMinorColor(o);
- if (literal.type.isFunction()) {
- if (literal.isNull()) {
- o << "funcref(null)";
- } else {
- o << "funcref(" << literal.getFunc() << ")";
- }
- } else if (literal.type.isRef()) {
- if (literal.isData()) {
- auto data = literal.getGCData();
- if (data) {
- o << "[ref " << data->type << ' ' << data->values << ']';
- } else {
- o << "[ref null " << literal.type << ']';
- }
- } else {
- switch (literal.type.getHeapType().getBasic()) {
- case HeapType::ext:
- assert(literal.isNull() && "unexpected non-null externref literal");
- o << "externref(null)";
- break;
- case HeapType::any:
- assert(literal.isNull() && "unexpected non-null anyref literal");
- o << "anyref(null)";
- break;
- case HeapType::eq:
- assert(literal.isNull() && "unexpected non-null eqref literal");
- o << "eqref(null)";
- break;
- case HeapType::i31:
- if (literal.isNull()) {
- o << "i31ref(null)";
- } else {
- o << "i31ref(" << literal.geti31() << ")";
- }
- break;
- case HeapType::func:
- case HeapType::data:
- case HeapType::string:
- case HeapType::stringview_wtf8:
- case HeapType::stringview_wtf16:
- case HeapType::stringview_iter:
- WASM_UNREACHABLE("type should have been handled above");
- }
- }
- } else {
- TODO_SINGLE_COMPOUND(literal.type);
+ assert(literal.type.isSingle());
+ if (literal.type.isBasic()) {
switch (literal.type.getBasic()) {
case Type::none:
o << "?";
@@ -532,6 +500,44 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
}
+ } else {
+ assert(literal.type.isRef());
+ auto heapType = literal.type.getHeapType();
+ if (heapType.isBasic()) {
+ switch (heapType.getBasic()) {
+ case HeapType::i31:
+ o << "i31ref(" << literal.geti31() << ")";
+ break;
+ case HeapType::none:
+ o << "nullref";
+ break;
+ case HeapType::noext:
+ o << "nullexternref";
+ break;
+ case HeapType::nofunc:
+ o << "nullfuncref";
+ break;
+ case HeapType::ext:
+ case HeapType::any:
+ WASM_UNREACHABLE("TODO: extern literals");
+ case HeapType::eq:
+ case HeapType::func:
+ case HeapType::data:
+ WASM_UNREACHABLE("invalid type");
+ case HeapType::string:
+ case HeapType::stringview_wtf8:
+ case HeapType::stringview_wtf16:
+ case HeapType::stringview_iter:
+ WASM_UNREACHABLE("TODO: string literals");
+ }
+ } else if (heapType.isSignature()) {
+ o << "funcref(" << literal.getFunc() << ")";
+ } else {
+ assert(literal.isData());
+ auto data = literal.getGCData();
+ assert(data);
+ o << "[ref " << data->type << ' ' << data->values << ']';
+ }
}
restoreNormalColor(o);
return o;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 55dafadd4..f2698bd79 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1429,6 +1429,25 @@ void WasmBinaryWriter::writeType(Type type) {
case HeapType::stringview_iter:
o << S32LEB(BinaryConsts::EncodedType::stringview_iter);
return;
+ case HeapType::none:
+ o << S32LEB(BinaryConsts::EncodedType::nullref);
+ return;
+ case HeapType::noext:
+ // See comment on writeHeapType.
+ if (!wasm->features.hasGC()) {
+ o << S32LEB(BinaryConsts::EncodedType::externref);
+ } else {
+ o << S32LEB(BinaryConsts::EncodedType::nullexternref);
+ }
+ return;
+ case HeapType::nofunc:
+ // See comment on writeHeapType.
+ if (!wasm->features.hasGC()) {
+ o << S32LEB(BinaryConsts::EncodedType::funcref);
+ } else {
+ o << S32LEB(BinaryConsts::EncodedType::nullfuncref);
+ }
+ return;
}
}
if (type.isNullable()) {
@@ -1468,46 +1487,63 @@ void WasmBinaryWriter::writeType(Type type) {
}
void WasmBinaryWriter::writeHeapType(HeapType type) {
+ // ref.null always has a bottom heap type in Binaryen IR, but those types are
+ // only actually valid with GC enabled. When GC is not enabled, emit the
+ // corresponding valid top types instead.
+ if (!wasm->features.hasGC()) {
+ if (type == HeapType::nofunc || type.isSignature()) {
+ type = HeapType::func;
+ } else if (type == HeapType::noext) {
+ type = HeapType::ext;
+ }
+ }
+
if (type.isSignature() || type.isStruct() || type.isArray()) {
o << S64LEB(getTypeIndex(type)); // TODO: Actually s33
return;
}
int ret = 0;
- if (type.isBasic()) {
- switch (type.getBasic()) {
- case HeapType::ext:
- ret = BinaryConsts::EncodedHeapType::ext;
- break;
- case HeapType::func:
- ret = BinaryConsts::EncodedHeapType::func;
- break;
- case HeapType::any:
- ret = BinaryConsts::EncodedHeapType::any;
- break;
- case HeapType::eq:
- ret = BinaryConsts::EncodedHeapType::eq;
- break;
- case HeapType::i31:
- ret = BinaryConsts::EncodedHeapType::i31;
- break;
- case HeapType::data:
- ret = BinaryConsts::EncodedHeapType::data;
- break;
- case HeapType::string:
- ret = BinaryConsts::EncodedHeapType::string;
- break;
- case HeapType::stringview_wtf8:
- ret = BinaryConsts::EncodedHeapType::stringview_wtf8_heap;
- break;
- case HeapType::stringview_wtf16:
- ret = BinaryConsts::EncodedHeapType::stringview_wtf16_heap;
- break;
- case HeapType::stringview_iter:
- ret = BinaryConsts::EncodedHeapType::stringview_iter_heap;
- break;
- }
- } else {
- WASM_UNREACHABLE("TODO: compound GC types");
+ assert(type.isBasic());
+ switch (type.getBasic()) {
+ case HeapType::ext:
+ ret = BinaryConsts::EncodedHeapType::ext;
+ break;
+ case HeapType::func:
+ ret = BinaryConsts::EncodedHeapType::func;
+ break;
+ case HeapType::any:
+ ret = BinaryConsts::EncodedHeapType::any;
+ break;
+ case HeapType::eq:
+ ret = BinaryConsts::EncodedHeapType::eq;
+ break;
+ case HeapType::i31:
+ ret = BinaryConsts::EncodedHeapType::i31;
+ break;
+ case HeapType::data:
+ ret = BinaryConsts::EncodedHeapType::data;
+ break;
+ case HeapType::string:
+ ret = BinaryConsts::EncodedHeapType::string;
+ break;
+ case HeapType::stringview_wtf8:
+ ret = BinaryConsts::EncodedHeapType::stringview_wtf8_heap;
+ break;
+ case HeapType::stringview_wtf16:
+ ret = BinaryConsts::EncodedHeapType::stringview_wtf16_heap;
+ break;
+ case HeapType::stringview_iter:
+ ret = BinaryConsts::EncodedHeapType::stringview_iter_heap;
+ break;
+ case HeapType::none:
+ ret = BinaryConsts::EncodedHeapType::none;
+ break;
+ case HeapType::noext:
+ ret = BinaryConsts::EncodedHeapType::noext;
+ break;
+ case HeapType::nofunc:
+ ret = BinaryConsts::EncodedHeapType::nofunc;
+ break;
}
o << S64LEB(ret); // TODO: Actually s33
}
@@ -1867,6 +1903,15 @@ bool WasmBinaryBuilder::getBasicType(int32_t code, Type& out) {
case BinaryConsts::EncodedType::stringview_iter:
out = Type(HeapType::stringview_iter, Nullable);
return true;
+ case BinaryConsts::EncodedType::nullref:
+ out = Type(HeapType::none, Nullable);
+ return true;
+ case BinaryConsts::EncodedType::nullexternref:
+ out = Type(HeapType::noext, Nullable);
+ return true;
+ case BinaryConsts::EncodedType::nullfuncref:
+ out = Type(HeapType::nofunc, Nullable);
+ return true;
default:
return false;
}
@@ -1904,6 +1949,15 @@ bool WasmBinaryBuilder::getBasicHeapType(int64_t code, HeapType& out) {
case BinaryConsts::EncodedHeapType::stringview_iter_heap:
out = HeapType::stringview_iter;
return true;
+ case BinaryConsts::EncodedHeapType::none:
+ out = HeapType::none;
+ return true;
+ case BinaryConsts::EncodedHeapType::noext:
+ out = HeapType::noext;
+ return true;
+ case BinaryConsts::EncodedHeapType::nofunc:
+ out = HeapType::nofunc;
+ return true;
default:
return false;
}
@@ -2849,7 +2903,14 @@ void WasmBinaryBuilder::skipUnreachableCode() {
expressionStack = savedStack;
return;
}
- pushExpression(curr);
+ if (curr->type == Type::unreachable) {
+ // Nothing before this unreachable should be available to future
+ // expressions. They will get `(unreachable)`s if they try to pop past
+ // this point.
+ expressionStack.clear();
+ } else {
+ pushExpression(curr);
+ }
}
}
@@ -6530,7 +6591,7 @@ void WasmBinaryBuilder::visitDrop(Drop* curr) {
void WasmBinaryBuilder::visitRefNull(RefNull* curr) {
BYN_TRACE("zz node: RefNull\n");
- curr->finalize(getHeapType());
+ curr->finalize(getHeapType().getBottom());
}
void WasmBinaryBuilder::visitRefIs(RefIs* curr, uint8_t code) {
@@ -6941,28 +7002,29 @@ bool WasmBinaryBuilder::maybeVisitStructNew(Expression*& out, uint32_t code) {
}
bool WasmBinaryBuilder::maybeVisitStructGet(Expression*& out, uint32_t code) {
- StructGet* curr;
+ bool signed_ = false;
switch (code) {
case BinaryConsts::StructGet:
- curr = allocator.alloc<StructGet>();
+ case BinaryConsts::StructGetU:
break;
case BinaryConsts::StructGetS:
- curr = allocator.alloc<StructGet>();
- curr->signed_ = true;
- break;
- case BinaryConsts::StructGetU:
- curr = allocator.alloc<StructGet>();
- curr->signed_ = false;
+ signed_ = true;
break;
default:
return false;
}
auto heapType = getIndexedHeapType();
- curr->index = getU32LEB();
- curr->ref = popNonVoidExpression();
- validateHeapTypeUsingChild(curr->ref, heapType);
- curr->finalize();
- out = curr;
+ if (!heapType.isStruct()) {
+ throwError("Expected struct heaptype");
+ }
+ auto index = getU32LEB();
+ if (index >= heapType.getStruct().fields.size()) {
+ throwError("Struct field index out of bounds");
+ }
+ auto type = heapType.getStruct().fields[index].type;
+ auto ref = popNonVoidExpression();
+ validateHeapTypeUsingChild(ref, heapType);
+ out = Builder(wasm).makeStructGet(index, ref, type, signed_);
return true;
}
@@ -7022,10 +7084,14 @@ bool WasmBinaryBuilder::maybeVisitArrayGet(Expression*& out, uint32_t code) {
return false;
}
auto heapType = getIndexedHeapType();
+ if (!heapType.isArray()) {
+ throwError("Expected array heaptype");
+ }
+ auto type = heapType.getArray().element.type;
auto* index = popNonVoidExpression();
auto* ref = popNonVoidExpression();
validateHeapTypeUsingChild(ref, heapType);
- out = Builder(wasm).makeArrayGet(ref, index, signed_);
+ out = Builder(wasm).makeArrayGet(ref, index, type, signed_);
return true;
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 6de8744a6..b23419071 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1196,6 +1196,15 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
if (strncmp(str, "stringview_iter", 15) == 0 && (prefix || str[15] == 0)) {
return Type(HeapType::stringview_iter, Nullable);
}
+ if (strncmp(str, "nullref", 7) == 0 && (prefix || str[7] == 0)) {
+ return Type(HeapType::none, Nullable);
+ }
+ if (strncmp(str, "nullexternref", 13) == 0 && (prefix || str[13] == 0)) {
+ return Type(HeapType::noext, Nullable);
+ }
+ if (strncmp(str, "nullfuncref", 11) == 0 && (prefix || str[11] == 0)) {
+ return Type(HeapType::nofunc, Nullable);
+ }
if (allowError) {
return Type::none;
}
@@ -1249,6 +1258,17 @@ HeapType SExpressionWasmBuilder::stringToHeapType(const char* str,
return HeapType::stringview_iter;
}
}
+ if (str[0] == 'n') {
+ if (strncmp(str, "none", 4) == 0 && (prefix || str[4] == 0)) {
+ return HeapType::none;
+ }
+ if (strncmp(str, "noextern", 8) == 0 && (prefix || str[8] == 0)) {
+ return HeapType::noext;
+ }
+ if (strncmp(str, "nofunc", 6) == 0 && (prefix || str[6] == 0)) {
+ return HeapType::nofunc;
+ }
+ }
throw ParseException(std::string("invalid wasm heap type: ") + str);
}
@@ -2615,9 +2635,9 @@ Expression* SExpressionWasmBuilder::makeRefNull(Element& s) {
// (ref.null func), or it may be the name of a defined type, such as
// (ref.null $struct.FOO)
if (s[1]->dollared()) {
- ret->finalize(parseHeapType(*s[1]));
+ ret->finalize(parseHeapType(*s[1]).getBottom());
} else {
- ret->finalize(stringToHeapType(s[1]->str()));
+ ret->finalize(stringToHeapType(s[1]->str()).getBottom());
}
return ret;
}
@@ -2990,10 +3010,14 @@ Expression* SExpressionWasmBuilder::makeArrayInitStatic(Element& s) {
Expression* SExpressionWasmBuilder::makeArrayGet(Element& s, bool signed_) {
auto heapType = parseHeapType(*s[1]);
+ if (!heapType.isArray()) {
+ throw ParseException("bad array heap type", s.line, s.col);
+ }
auto ref = parseExpression(*s[2]);
+ auto type = heapType.getArray().element.type;
validateHeapTypeUsingChild(ref, heapType, s);
auto index = parseExpression(*s[3]);
- return Builder(wasm).makeArrayGet(ref, index, signed_);
+ return Builder(wasm).makeArrayGet(ref, index, type, signed_);
}
Expression* SExpressionWasmBuilder::makeArraySet(Element& s) {
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 71bc98928..13d85d338 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2014,7 +2014,10 @@ void BinaryInstWriter::visitI31Get(I31Get* curr) {
void BinaryInstWriter::visitCallRef(CallRef* curr) {
assert(curr->target->type != Type::unreachable);
- // TODO: `emitUnreachable` if target has bottom type.
+ if (curr->target->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
o << int8_t(curr->isReturn ? BinaryConsts::RetCallRef
: BinaryConsts::CallRef);
parent.writeIndexedHeapType(curr->target->type.getHeapType());
@@ -2090,6 +2093,10 @@ void BinaryInstWriter::visitStructNew(StructNew* curr) {
}
void BinaryInstWriter::visitStructGet(StructGet* curr) {
+ if (curr->ref->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
const auto& heapType = curr->ref->type.getHeapType();
const auto& field = heapType.getStruct().fields[curr->index];
int8_t op;
@@ -2106,6 +2113,10 @@ void BinaryInstWriter::visitStructGet(StructGet* curr) {
}
void BinaryInstWriter::visitStructSet(StructSet* curr) {
+ if (curr->ref->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StructSet);
parent.writeIndexedHeapType(curr->ref->type.getHeapType());
o << U32LEB(curr->index);
@@ -2129,6 +2140,10 @@ void BinaryInstWriter::visitArrayInit(ArrayInit* curr) {
}
void BinaryInstWriter::visitArrayGet(ArrayGet* curr) {
+ if (curr->ref->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
auto heapType = curr->ref->type.getHeapType();
const auto& field = heapType.getArray().element;
int8_t op;
@@ -2144,16 +2159,28 @@ void BinaryInstWriter::visitArrayGet(ArrayGet* curr) {
}
void BinaryInstWriter::visitArraySet(ArraySet* curr) {
+ if (curr->ref->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArraySet);
parent.writeIndexedHeapType(curr->ref->type.getHeapType());
}
void BinaryInstWriter::visitArrayLen(ArrayLen* curr) {
+ if (curr->ref->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArrayLen);
parent.writeIndexedHeapType(curr->ref->type.getHeapType());
}
void BinaryInstWriter::visitArrayCopy(ArrayCopy* curr) {
+ if (curr->srcRef->type.isNull() || curr->destRef->type.isNull()) {
+ emitUnreachable();
+ return;
+ }
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArrayCopy);
parent.writeIndexedHeapType(curr->destRef->type.getHeapType());
parent.writeIndexedHeapType(curr->srcRef->type.getHeapType());
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index d24e42acb..43b381a1b 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -578,6 +578,15 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a,
if (a == b) {
return a;
}
+ if (HeapType(a).getBottom() != HeapType(b).getBottom()) {
+ return {};
+ }
+ if (HeapType(a).isBottom()) {
+ return b;
+ }
+ if (HeapType(b).isBottom()) {
+ return a;
+ }
// Canonicalize to have `a` be the lesser type.
if (unsigned(a) > unsigned(b)) {
std::swap(a, b);
@@ -585,7 +594,7 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a,
switch (a) {
case HeapType::ext:
case HeapType::func:
- return {};
+ return std::nullopt;
case HeapType::any:
return {HeapType::any};
case HeapType::eq:
@@ -604,6 +613,11 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a,
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
return {HeapType::any};
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ // Bottom types already handled.
+ break;
}
WASM_UNREACHABLE("unexpected basic type");
}
@@ -1085,6 +1099,12 @@ FeatureSet Type::getFeatures() const {
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
return FeatureSet::ReferenceTypes | FeatureSet::Strings;
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
+ // Technically introduced in GC, but used internally as part of
+ // ref.null with just reference types.
+ return FeatureSet::ReferenceTypes;
}
}
// Note: Technically typed function references also require the typed
@@ -1360,6 +1380,29 @@ bool HeapType::isArray() const {
}
}
+bool HeapType::isBottom() const {
+ if (isBasic()) {
+ switch (getBasic()) {
+ case ext:
+ case func:
+ case any:
+ case eq:
+ case i31:
+ case data:
+ case string:
+ case stringview_wtf8:
+ case stringview_wtf16:
+ case stringview_iter:
+ return false;
+ case none:
+ case noext:
+ case nofunc:
+ return true;
+ }
+ }
+ return false;
+}
+
Signature HeapType::getSignature() const {
assert(isSignature());
return getHeapTypeInfo(*this)->signature;
@@ -1420,11 +1463,52 @@ size_t HeapType::getDepth() const {
case HeapType::stringview_iter:
depth += 2;
break;
+ case HeapType::none:
+ case HeapType::nofunc:
+ case HeapType::noext:
+ // Bottom types are infinitely deep.
+ depth = size_t(-1l);
}
}
return depth;
}
+HeapType::BasicHeapType HeapType::getBottom() const {
+ if (isBasic()) {
+ switch (getBasic()) {
+ case ext:
+ return noext;
+ case func:
+ return nofunc;
+ case any:
+ case eq:
+ case i31:
+ case data:
+ case string:
+ case stringview_wtf8:
+ case stringview_wtf16:
+ case stringview_iter:
+ case none:
+ return none;
+ case noext:
+ return noext;
+ case nofunc:
+ return nofunc;
+ }
+ }
+ auto* info = getHeapTypeInfo(*this);
+ switch (info->kind) {
+ case HeapTypeInfo::BasicKind:
+ return HeapType(info->basic).getBottom();
+ case HeapTypeInfo::SignatureKind:
+ return nofunc;
+ case HeapTypeInfo::StructKind:
+ case HeapTypeInfo::ArrayKind:
+ return none;
+ }
+ WASM_UNREACHABLE("unexpected kind");
+}
+
bool HeapType::isSubType(HeapType left, HeapType right) {
// As an optimization, in the common case do not even construct a SubTyper.
if (left == right) {
@@ -1451,6 +1535,15 @@ std::optional<HeapType> HeapType::getLeastUpperBound(HeapType a, HeapType b) {
if (a == b) {
return a;
}
+ if (a.getBottom() != b.getBottom()) {
+ return {};
+ }
+ if (a.isBottom()) {
+ return b;
+ }
+ if (b.isBottom()) {
+ return a;
+ }
if (getTypeSystem() == TypeSystem::Equirecursive) {
return TypeBounder().getLeastUpperBound(a, b);
}
@@ -1653,27 +1746,34 @@ bool SubTyper::isSubType(HeapType a, HeapType b) {
if (b.isBasic()) {
switch (b.getBasic()) {
case HeapType::ext:
- return a == HeapType::ext;
+ return a == HeapType::noext;
case HeapType::func:
- return a.isSignature();
+ return a == HeapType::nofunc || a.isSignature();
case HeapType::any:
- return a != HeapType::ext && !a.isFunction();
+ return a == HeapType::eq || a == HeapType::i31 || a == HeapType::data ||
+ a == HeapType::none || a.isData();
case HeapType::eq:
- return a == HeapType::i31 || a.isData();
+ return a == HeapType::i31 || a == HeapType::data ||
+ a == HeapType::none || a.isData();
case HeapType::i31:
- return false;
+ return a == HeapType::none;
case HeapType::data:
- return a.isData();
+ return a == HeapType::none || a.isData();
case HeapType::string:
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
case HeapType::stringview_iter:
+ return a == HeapType::none;
+ case HeapType::none:
+ case HeapType::noext:
+ case HeapType::nofunc:
return false;
}
}
if (a.isBasic()) {
- // Basic HeapTypes are never subtypes of compound HeapTypes.
- return false;
+ // Basic HeapTypes are only subtypes of compound HeapTypes if they are
+ // bottom types.
+ return a == b.getBottom();
}
if (typeSystem == TypeSystem::Nominal ||
typeSystem == TypeSystem::Isorecursive) {
@@ -1823,6 +1923,15 @@ std::optional<HeapType> TypeBounder::lub(HeapType a, HeapType b) {
if (a == b) {
return a;
}
+ if (a.getBottom() != b.getBottom()) {
+ return {};
+ }
+ if (a.isBottom()) {
+ return b;
+ }
+ if (b.isBottom()) {
+ return a;
+ }
if (a.isBasic() || b.isBasic()) {
return getBasicHeapTypeLUB(getBasicHeapSupertype(a),
@@ -2000,12 +2109,18 @@ std::ostream& TypePrinter::print(Type type) {
// Print shorthands for certain basic heap types.
if (type.isNullable()) {
switch (heapType.getBasic()) {
+ case HeapType::ext:
+ return os << "externref";
case HeapType::func:
return os << "funcref";
case HeapType::any:
return os << "anyref";
case HeapType::eq:
return os << "eqref";
+ case HeapType::i31:
+ return os << "i31ref";
+ case HeapType::data:
+ return os << "dataref";
case HeapType::string:
return os << "stringref";
case HeapType::stringview_wtf8:
@@ -2014,17 +2129,12 @@ std::ostream& TypePrinter::print(Type type) {
return os << "stringview_wtf16";
case HeapType::stringview_iter:
return os << "stringview_iter";
- default:
- break;
- }
- } else {
- switch (heapType.getBasic()) {
- case HeapType::i31:
- return os << "i31ref";
- case HeapType::data:
- return os << "dataref";
- default:
- break;
+ case HeapType::none:
+ return os << "nullref";
+ case HeapType::noext:
+ return os << "nullexternref";
+ case HeapType::nofunc:
+ return os << "nullfuncref";
}
}
}
@@ -2063,6 +2173,12 @@ std::ostream& TypePrinter::print(HeapType type) {
return os << "stringview_wtf16";
case HeapType::stringview_iter:
return os << "stringview_iter";
+ case HeapType::none:
+ return os << "none";
+ case HeapType::noext:
+ return os << "noextern";
+ case HeapType::nofunc:
+ return os << "nofunc";
}
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 5e3fdc6e7..ba309ddea 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -2110,13 +2110,12 @@ void FunctionValidator::visitRefNull(RefNull* curr) {
shouldBeTrue(!getFunction() || getModule()->features.hasReferenceTypes(),
curr,
"ref.null requires reference-types to be enabled");
+ if (!shouldBeTrue(
+ curr->type.isNullable(), curr, "ref.null types must be nullable")) {
+ return;
+ }
shouldBeTrue(
- curr->type.isNullable(), curr, "ref.null types must be nullable");
-
- // The type of the null must also be valid for the features.
- shouldBeTrue(curr->type.getFeatures() <= getModule()->features,
- curr->type,
- "ref.null type should be allowed");
+ curr->type.isNull(), curr, "ref.null must have a bottom heap type");
}
void FunctionValidator::visitRefIs(RefIs* curr) {
@@ -2454,12 +2453,15 @@ void FunctionValidator::visitCallRef(CallRef* curr) {
validateReturnCall(curr);
shouldBeTrue(
getModule()->features.hasGC(), curr, "call_ref requires gc to be enabled");
- if (curr->target->type != Type::unreachable) {
- if (shouldBeTrue(curr->target->type.isFunction(),
- curr,
- "call_ref target must be a function reference")) {
- validateCallParamsAndResult(curr, curr->target->type.getHeapType());
- }
+ if (curr->target->type == Type::unreachable ||
+ (curr->target->type.isRef() &&
+ curr->target->type.getHeapType() == HeapType::nofunc)) {
+ return;
+ }
+ if (shouldBeTrue(curr->target->type.isFunction(),
+ curr,
+ "call_ref target must be a function reference")) {
+ validateCallParamsAndResult(curr, curr->target->type.getHeapType());
}
}
@@ -2580,7 +2582,7 @@ void FunctionValidator::visitStructGet(StructGet* curr) {
shouldBeTrue(getModule()->features.hasGC(),
curr,
"struct.get requires gc to be enabled");
- if (curr->ref->type == Type::unreachable) {
+ if (curr->type == Type::unreachable || curr->ref->type.isNull()) {
return;
}
if (!shouldBeTrue(curr->ref->type.isStruct(),
@@ -2610,22 +2612,28 @@ void FunctionValidator::visitStructSet(StructSet* curr) {
if (curr->ref->type == Type::unreachable) {
return;
}
- if (!shouldBeTrue(curr->ref->type.isStruct(),
+ if (!shouldBeTrue(curr->ref->type.isRef(),
curr->ref,
- "struct.set ref must be a struct")) {
+ "struct.set ref must be a reference type")) {
return;
}
- if (curr->ref->type != Type::unreachable) {
- const auto& fields = curr->ref->type.getHeapType().getStruct().fields;
- shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field");
- auto& field = fields[curr->index];
- shouldBeSubType(curr->value->type,
- field.type,
- curr,
- "struct.set must have the proper type");
- shouldBeEqual(
- field.mutable_, Mutable, curr, "struct.set field must be mutable");
+ auto type = curr->ref->type.getHeapType();
+ if (type == HeapType::none) {
+ return;
}
+ if (!shouldBeTrue(
+ type.isStruct(), curr->ref, "struct.set ref must be a struct")) {
+ return;
+ }
+ const auto& fields = type.getStruct().fields;
+ shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field");
+ auto& field = fields[curr->index];
+ shouldBeSubType(curr->value->type,
+ field.type,
+ curr,
+ "struct.set must have the proper type");
+ shouldBeEqual(
+ field.mutable_, Mutable, curr, "struct.set field must be mutable");
}
void FunctionValidator::visitArrayNew(ArrayNew* curr) {
@@ -2688,7 +2696,18 @@ void FunctionValidator::visitArrayGet(ArrayGet* curr) {
if (curr->type == Type::unreachable) {
return;
}
- const auto& element = curr->ref->type.getHeapType().getArray().element;
+ // TODO: array rather than data once we've implemented that.
+ if (!shouldBeSubType(curr->ref->type,
+ Type(HeapType::data, Nullable),
+ curr,
+ "array.get target should be an array reference")) {
+ return;
+ }
+ auto heapType = curr->ref->type.getHeapType();
+ if (heapType == HeapType::none) {
+ return;
+ }
+ const auto& element = heapType.getArray().element;
// If the type is not packed, it must be marked internally as unsigned, by
// convention.
if (element.type != Type::i32 || element.packedType == Field::not_packed) {
@@ -2706,6 +2725,17 @@ void FunctionValidator::visitArraySet(ArraySet* curr) {
if (curr->type == Type::unreachable) {
return;
}
+ // TODO: array rather than data once we've implemented that.
+ if (!shouldBeSubType(curr->ref->type,
+ Type(HeapType::data, Nullable),
+ curr,
+ "array.set target should be an array reference")) {
+ return;
+ }
+ auto heapType = curr->ref->type.getHeapType();
+ if (heapType == HeapType::none) {
+ return;
+ }
const auto& element = curr->ref->type.getHeapType().getArray().element;
shouldBeSubType(curr->value->type,
element.type,
@@ -2736,9 +2766,23 @@ void FunctionValidator::visitArrayCopy(ArrayCopy* curr) {
if (curr->type == Type::unreachable) {
return;
}
- const auto& srcElement = curr->srcRef->type.getHeapType().getArray().element;
- const auto& destElement =
- curr->destRef->type.getHeapType().getArray().element;
+ if (!shouldBeSubType(curr->srcRef->type,
+ Type(HeapType::data, Nullable),
+ curr,
+ "array.copy source should be an array reference") ||
+ !shouldBeSubType(curr->destRef->type,
+ Type(HeapType::data, Nullable),
+ curr,
+ "array.copy destination should be an array reference")) {
+ return;
+ }
+ auto srcHeapType = curr->srcRef->type.getHeapType();
+ auto destHeapType = curr->destRef->type.getHeapType();
+ if (srcHeapType == HeapType::none || destHeapType == HeapType::none) {
+ return;
+ }
+ const auto& srcElement = srcHeapType.getArray().element;
+ const auto& destElement = destHeapType.getArray().element;
shouldBeSubType(srcElement.type,
destElement.type,
curr,
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 724fc12e2..27690f43e 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -796,7 +796,10 @@ void MemoryGrow::finalize() {
}
}
-void RefNull::finalize(HeapType heapType) { type = Type(heapType, Nullable); }
+void RefNull::finalize(HeapType heapType) {
+ assert(heapType.isBottom());
+ type = Type(heapType, Nullable);
+}
void RefNull::finalize(Type type_) { type = type_; }
@@ -1033,7 +1036,7 @@ void StructNew::finalize() {
void StructGet::finalize() {
if (ref->type == Type::unreachable) {
type = Type::unreachable;
- } else {
+ } else if (!ref->type.isNull()) {
type = ref->type.getHeapType().getStruct().fields[index].type;
}
}
@@ -1066,7 +1069,7 @@ void ArrayInit::finalize() {
void ArrayGet::finalize() {
if (ref->type == Type::unreachable || index->type == Type::unreachable) {
type = Type::unreachable;
- } else {
+ } else if (!ref->type.isNull()) {
type = ref->type.getHeapType().getArray().element.type;
}
}
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index 076e0bedd..104405c8a 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -2072,12 +2072,12 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(ref.is_null
- (ref.null extern)
+ (ref.null noextern)
)
)
(drop
(ref.is_null
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -2087,15 +2087,15 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(select (result funcref)
- (ref.null func)
+ (ref.null nofunc)
(ref.func "$kitchen()sinker")
(i32.const 1)
)
)
(drop
(ref.eq
- (ref.null eq)
- (ref.null eq)
+ (ref.null none)
+ (ref.null none)
)
)
(try
@@ -4176,12 +4176,12 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(ref.is_null
- (ref.null extern)
+ (ref.null noextern)
)
)
(drop
(ref.is_null
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -4191,15 +4191,15 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(select (result funcref)
- (ref.null func)
+ (ref.null nofunc)
(ref.func "$kitchen()sinker")
(i32.const 1)
)
)
(drop
(ref.eq
- (ref.null eq)
- (ref.null eq)
+ (ref.null none)
+ (ref.null none)
)
)
(try
diff --git a/test/ctor-eval/bad-indirect-call3.wast.out b/test/ctor-eval/bad-indirect-call3.wast.out
index 4b470e10a..2f3cd9709 100644
--- a/test/ctor-eval/bad-indirect-call3.wast.out
+++ b/test/ctor-eval/bad-indirect-call3.wast.out
@@ -15,7 +15,7 @@
)
(func $sig_mismatch
(call_indirect $0 (type $funcref_=>_none)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 0)
)
)
diff --git a/test/ctor-eval/gc.wast.out b/test/ctor-eval/gc.wast.out
index e1520f12b..45e5ff5ca 100644
--- a/test/ctor-eval/gc.wast.out
+++ b/test/ctor-eval/gc.wast.out
@@ -32,7 +32,7 @@
(global.get $ctor-eval$global_0)
)
(call $import
- (ref.null $struct)
+ (ref.null none)
)
(call $import
(local.get $0)
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index bc6b4b873..251aa3b90 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -431,9 +431,9 @@ void test_core() {
temp15 = makeInt32(module, 110),
temp16 = makeInt64(module, 111);
BinaryenExpressionRef externrefExpr =
- BinaryenRefNull(module, BinaryenTypeExternref());
+ BinaryenRefNull(module, BinaryenTypeNullExternref());
BinaryenExpressionRef funcrefExpr =
- BinaryenRefNull(module, BinaryenTypeFuncref());
+ BinaryenRefNull(module, BinaryenTypeNullFuncref());
funcrefExpr =
BinaryenRefFunc(module, "kitchen()sinker", BinaryenTypeFuncref());
BinaryenExpressionRef i31refExpr =
@@ -973,40 +973,40 @@ void test_core() {
BinaryenSelect(
module,
temp10,
- BinaryenRefNull(module, BinaryenTypeFuncref()),
+ BinaryenRefNull(module, BinaryenTypeNullFuncref()),
BinaryenRefFunc(module, "kitchen()sinker", BinaryenTypeFuncref()),
BinaryenTypeFuncref()),
// GC
BinaryenRefEq(module,
- BinaryenRefNull(module, BinaryenTypeEqref()),
- BinaryenRefNull(module, BinaryenTypeEqref())),
+ BinaryenRefNull(module, BinaryenTypeNullref()),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefIs(module,
BinaryenRefIsFunc(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefIs(module,
BinaryenRefIsData(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefIs(module,
BinaryenRefIsI31(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefAs(module,
BinaryenRefAsNonNull(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefAs(module,
BinaryenRefAsFunc(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefAs(module,
BinaryenRefAsData(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefAs(module,
BinaryenRefAsI31(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
BinaryenRefAs(module,
BinaryenRefAsExternInternalize(),
- BinaryenRefNull(module, BinaryenTypeExternref())),
+ BinaryenRefNull(module, BinaryenTypeNullExternref())),
BinaryenRefAs(module,
BinaryenRefAsExternExternalize(),
- BinaryenRefNull(module, BinaryenTypeAnyref())),
+ BinaryenRefNull(module, BinaryenTypeNullref())),
// Exception handling
BinaryenTry(module, NULL, tryBody, catchTags, 1, catchBodies, 2, NULL),
// (try $try_outer
@@ -1103,11 +1103,8 @@ void test_core() {
BinaryenArrayGet(module,
BinaryenGlobalGet(module, "i8Array-global", i8Array),
makeInt32(module, 0),
+ BinaryenTypeInt32(),
true),
- BinaryenArrayGet(module,
- BinaryenGlobalGet(module, "i8Array-global", i8Array),
- makeInt32(module, 0),
- false),
BinaryenArraySet(module,
BinaryenGlobalGet(module, "i8Array-global", i8Array),
makeInt32(module, 0),
@@ -1420,7 +1417,7 @@ void test_core() {
BinaryenTableSizeSetTable(tablesize, table);
BinaryenExpressionRef valueExpr =
- BinaryenRefNull(module, BinaryenTypeFuncref());
+ BinaryenRefNull(module, BinaryenTypeNullFuncref());
BinaryenExpressionRef sizeExpr = makeInt32(module, 0);
BinaryenExpressionRef growExpr =
BinaryenTableGrow(module, "0", valueExpr, sizeExpr);
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index a8e4d200b..3d2b74938 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -58,7 +58,7 @@ BinaryenFeatureAll: 126975
)
(table.size $0)
(table.grow $0
- (ref.null func)
+ (ref.null nofunc)
(i32.const 0)
)
(module
@@ -1974,7 +1974,7 @@ BinaryenFeatureAll: 126975
)
(drop
(ref.is_null
- (ref.null extern)
+ (ref.null noextern)
)
)
(drop
@@ -1984,60 +1984,60 @@ BinaryenFeatureAll: 126975
)
(drop
(select (result funcref)
- (ref.null func)
+ (ref.null nofunc)
(ref.func "$kitchen()sinker")
(i32.const 1)
)
)
(drop
(ref.eq
- (ref.null eq)
- (ref.null eq)
+ (ref.null none)
+ (ref.null none)
)
)
(drop
(ref.is_func
- (ref.null any)
+ (ref.null none)
)
)
(drop
(ref.is_data
- (ref.null any)
+ (ref.null none)
)
)
(drop
(ref.is_i31
- (ref.null any)
+ (ref.null none)
)
)
(drop
(ref.as_non_null
- (ref.null any)
+ (ref.null none)
)
)
(drop
(ref.as_func
- (ref.null any)
+ (ref.null none)
)
)
(drop
(ref.as_data
- (ref.null any)
+ (ref.null none)
)
)
(drop
(ref.as_i31
- (ref.null any)
+ (ref.null none)
)
)
(drop
(extern.internalize
- (ref.null extern)
+ (ref.null noextern)
)
)
(drop
(extern.externalize
- (ref.null any)
+ (ref.null none)
)
)
(try
@@ -2207,12 +2207,6 @@ BinaryenFeatureAll: 126975
(i32.const 0)
)
)
- (drop
- (array.get_u $[mut:i8]
- (global.get $i8Array-global)
- (i32.const 0)
- )
- )
(array.set $[mut:i8]
(global.get $i8Array-global)
(i32.const 0)
diff --git a/test/example/cpp-unit.cpp b/test/example/cpp-unit.cpp
index b94530401..d2339f030 100644
--- a/test/example/cpp-unit.cpp
+++ b/test/example/cpp-unit.cpp
@@ -605,7 +605,30 @@ void test_effects() {
// ArrayCopy can trap, reads arrays, and writes arrays (but not structs).
{
+ Type arrayref = Type(HeapType(Array(Field(Type::i32, Mutable))), Nullable);
+ LocalGet dest;
+ dest.index = 0;
+ dest.type = arrayref;
+ LocalGet destIndex;
+ destIndex.index = 1;
+ destIndex.type = Type::i32;
+ LocalGet src;
+ src.index = 0;
+ src.type = arrayref;
+ LocalGet srcIndex;
+ srcIndex.index = 1;
+ srcIndex.type = Type::i32;
+ LocalGet length;
+ srcIndex.index = 2;
+ srcIndex.type = Type::i32;
ArrayCopy arrayCopy(module.allocator);
+ arrayCopy.destRef = &dest;
+ arrayCopy.destIndex = &destIndex;
+ arrayCopy.srcRef = &src;
+ arrayCopy.srcIndex = &srcIndex;
+ arrayCopy.length = &length;
+ arrayCopy.finalize();
+
EffectAnalyzer effects(options, module);
effects.visit(&arrayCopy);
assert_equal(effects.trap, true);
@@ -616,19 +639,6 @@ void test_effects() {
}
}
-void test_literals() {
- // The i31 heap type may or may not be basic, depending on if it is nullable.
- // Verify we handle both code paths.
- {
- Literal x(Type(HeapType::i31, Nullable));
- std::cout << x << '\n';
- }
- {
- Literal x(Type(HeapType::i31, NonNullable));
- std::cout << x << '\n';
- }
-}
-
void test_field() {
// Simple types
assert_equal(Field(Type::i32, Immutable).getByteSize(), 4);
@@ -681,7 +691,6 @@ int main() {
test_bits();
test_cost();
test_effects();
- test_literals();
test_field();
test_queue();
diff --git a/test/example/cpp-unit.txt b/test/example/cpp-unit.txt
index d1f1fc1fb..35821117c 100644
--- a/test/example/cpp-unit.txt
+++ b/test/example/cpp-unit.txt
@@ -1,3 +1 @@
-i31ref(null)
-i31ref(0)
Success
diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt
index 2fbd8ec52..7015e6cfc 100644
--- a/test/example/typeinfo.txt
+++ b/test/example/typeinfo.txt
@@ -9,8 +9,8 @@ eq
eqref
(ref eq)
i31
-(ref null i31)
i31ref
+(ref i31)
(func)
(struct)
(array i32)
diff --git a/test/gc.wast.from-wast b/test/gc.wast.from-wast
index 19936135c..a518ceffa 100644
--- a/test/gc.wast.from-wast
+++ b/test/gc.wast.from-wast
@@ -1,12 +1,12 @@
(module
(type $i31ref_dataref_=>_none (func (param i31ref dataref)))
(type $i31ref_ref|i31|_dataref_ref|data|_=>_none (func (param i31ref (ref i31) dataref (ref data))))
- (global $global_anyref (mut anyref) (ref.null any))
- (global $global_eqref (mut eqref) (ref.null eq))
+ (global $global_anyref (mut anyref) (ref.null none))
+ (global $global_eqref (mut eqref) (ref.null none))
(global $global_i31ref (mut i31ref) (i31.new
(i32.const 0)
))
- (global $global_anyref2 (mut anyref) (ref.null eq))
+ (global $global_anyref2 (mut anyref) (ref.null none))
(global $global_anyref3 (mut anyref) (i31.new
(i32.const 0)
))
@@ -24,7 +24,7 @@
(global.get $global_anyref)
)
(local.set $local_anyref
- (ref.null any)
+ (ref.null none)
)
(local.set $local_eqref
(local.get $local_eqref)
@@ -33,7 +33,7 @@
(global.get $global_eqref)
)
(local.set $local_eqref
- (ref.null eq)
+ (ref.null none)
)
(local.set $local_i31ref
(local.get $local_i31ref)
@@ -53,7 +53,7 @@
(global.get $global_eqref)
)
(local.set $local_anyref
- (ref.null eq)
+ (ref.null none)
)
(local.set $local_anyref
(local.get $local_i31ref)
@@ -84,7 +84,7 @@
(global.get $global_anyref)
)
(global.set $global_anyref
- (ref.null any)
+ (ref.null none)
)
(global.set $global_eqref
(local.get $local_eqref)
@@ -93,7 +93,7 @@
(global.get $global_eqref)
)
(global.set $global_eqref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_i31ref
(local.get $local_i31ref)
@@ -113,7 +113,7 @@
(global.get $global_eqref)
)
(global.set $global_anyref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_anyref
(local.get $local_i31ref)
diff --git a/test/gc.wast.fromBinary b/test/gc.wast.fromBinary
index 80d12cf1d..72c1508e7 100644
--- a/test/gc.wast.fromBinary
+++ b/test/gc.wast.fromBinary
@@ -1,12 +1,12 @@
(module
(type $i31ref_dataref_=>_none (func (param i31ref dataref)))
(type $i31ref_ref|i31|_dataref_ref|data|_=>_none (func (param i31ref (ref i31) dataref (ref data))))
- (global $global_anyref (mut anyref) (ref.null any))
- (global $global_eqref (mut eqref) (ref.null eq))
+ (global $global_anyref (mut anyref) (ref.null none))
+ (global $global_eqref (mut eqref) (ref.null none))
(global $global_i31ref (mut i31ref) (i31.new
(i32.const 0)
))
- (global $global_anyref2 (mut anyref) (ref.null eq))
+ (global $global_anyref2 (mut anyref) (ref.null none))
(global $global_anyref3 (mut anyref) (i31.new
(i32.const 0)
))
@@ -24,7 +24,7 @@
(global.get $global_anyref)
)
(local.set $local_anyref
- (ref.null any)
+ (ref.null none)
)
(local.set $local_eqref
(local.get $local_eqref)
@@ -33,7 +33,7 @@
(global.get $global_eqref)
)
(local.set $local_eqref
- (ref.null eq)
+ (ref.null none)
)
(local.set $local_i31ref
(local.get $local_i31ref)
@@ -53,7 +53,7 @@
(global.get $global_eqref)
)
(local.set $local_anyref
- (ref.null eq)
+ (ref.null none)
)
(local.set $local_anyref
(local.get $local_i31ref)
@@ -84,7 +84,7 @@
(global.get $global_anyref)
)
(global.set $global_anyref
- (ref.null any)
+ (ref.null none)
)
(global.set $global_eqref
(local.get $local_eqref)
@@ -93,7 +93,7 @@
(global.get $global_eqref)
)
(global.set $global_eqref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_i31ref
(local.get $local_i31ref)
@@ -113,7 +113,7 @@
(global.get $global_eqref)
)
(global.set $global_anyref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_anyref
(local.get $local_i31ref)
diff --git a/test/gc.wast.fromBinary.noDebugInfo b/test/gc.wast.fromBinary.noDebugInfo
index 0ab9159aa..614376881 100644
--- a/test/gc.wast.fromBinary.noDebugInfo
+++ b/test/gc.wast.fromBinary.noDebugInfo
@@ -1,12 +1,12 @@
(module
(type $i31ref_dataref_=>_none (func (param i31ref dataref)))
(type $i31ref_ref|i31|_dataref_ref|data|_=>_none (func (param i31ref (ref i31) dataref (ref data))))
- (global $global$0 (mut anyref) (ref.null any))
- (global $global$1 (mut eqref) (ref.null eq))
+ (global $global$0 (mut anyref) (ref.null none))
+ (global $global$1 (mut eqref) (ref.null none))
(global $global$2 (mut i31ref) (i31.new
(i32.const 0)
))
- (global $global$3 (mut anyref) (ref.null eq))
+ (global $global$3 (mut anyref) (ref.null none))
(global $global$4 (mut anyref) (i31.new
(i32.const 0)
))
@@ -24,7 +24,7 @@
(global.get $global$0)
)
(local.set $3
- (ref.null any)
+ (ref.null none)
)
(local.set $4
(local.get $4)
@@ -33,7 +33,7 @@
(global.get $global$1)
)
(local.set $4
- (ref.null eq)
+ (ref.null none)
)
(local.set $0
(local.get $0)
@@ -53,7 +53,7 @@
(global.get $global$1)
)
(local.set $3
- (ref.null eq)
+ (ref.null none)
)
(local.set $3
(local.get $0)
@@ -84,7 +84,7 @@
(global.get $global$0)
)
(global.set $global$0
- (ref.null any)
+ (ref.null none)
)
(global.set $global$1
(local.get $4)
@@ -93,7 +93,7 @@
(global.get $global$1)
)
(global.set $global$1
- (ref.null eq)
+ (ref.null none)
)
(global.set $global$2
(local.get $0)
@@ -113,7 +113,7 @@
(global.get $global$1)
)
(global.set $global$0
- (ref.null eq)
+ (ref.null none)
)
(global.set $global$0
(local.get $0)
diff --git a/test/gtest/possible-contents.cpp b/test/gtest/possible-contents.cpp
index 17d1da0d3..2ba008570 100644
--- a/test/gtest/possible-contents.cpp
+++ b/test/gtest/possible-contents.cpp
@@ -139,8 +139,8 @@ TEST_F(PossibleContentsTest, TestComparisons) {
// Nulls
assertNotEqualSymmetric(i32Zero, anyNull);
+ assertNotEqualSymmetric(anyNull, funcNull);
assertEqualSymmetric(anyNull, anyNull);
- assertEqualSymmetric(anyNull, funcNull); // All nulls compare equal.
assertEqualSymmetric(exactNonNullAnyref, exactNonNullAnyref);
assertNotEqualSymmetric(exactNonNullAnyref, exactAnyref);
diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp
index 94a2a1f80..d642893c3 100644
--- a/test/gtest/type-builder.cpp
+++ b/test/gtest/type-builder.cpp
@@ -656,4 +656,8 @@ TEST_F(NominalTest, TestDepth) {
EXPECT_EQ(HeapType(HeapType::stringview_wtf8).getDepth(), 2U);
EXPECT_EQ(HeapType(HeapType::stringview_wtf16).getDepth(), 2U);
EXPECT_EQ(HeapType(HeapType::stringview_iter).getDepth(), 2U);
+
+ EXPECT_EQ(HeapType(HeapType::none).getDepth(), size_t(-1));
+ EXPECT_EQ(HeapType(HeapType::nofunc).getDepth(), size_t(-1));
+ EXPECT_EQ(HeapType(HeapType::noext).getDepth(), size_t(-1));
}
diff --git a/test/heap-types.wast b/test/heap-types.wast
index d34eaf5eb..35e866e9b 100644
--- a/test/heap-types.wast
+++ b/test/heap-types.wast
@@ -40,7 +40,7 @@
(struct.new_default $struct.A)
)
- (func $structs (param $x (ref $struct.A)) (result (ref $struct.B))
+ (func $structs (param $x (ref $struct.A)) (param $struct.A.prime (ref null $struct.A.prime)) (param $grandchild (ref null $grandchild)) (param $struct.C (ref null $struct.C)) (param $nested-child-struct (ref null $nested-child-struct)) (result (ref $struct.B))
(local $tA (ref null $struct.A))
(local $tB (ref null $struct.B))
(local $tc (ref null $struct.C))
@@ -62,7 +62,7 @@
(struct.get $struct.A $named (local.get $x))
)
(drop
- (struct.get $struct.A.prime $othername (ref.null $struct.A.prime))
+ (struct.get $struct.A.prime $othername (local.get $struct.A.prime))
)
(drop
(struct.get_u $struct.B 0 (local.get $tB))
@@ -72,10 +72,7 @@
)
;; immutable fields allow subtyping.
(drop
- (struct.get $child 0 (ref.null $grandchild))
- )
- (drop
- (ref.null $struct.A)
+ (struct.get $child 0 (local.get $grandchild))
)
(drop
(block (result (ref null $struct.A))
@@ -102,14 +99,14 @@
)
)
(struct.set $struct.C 0
- (ref.null $struct.C)
+ (local.get $struct.C)
(f32.const 100)
)
;; values may be subtypes
(struct.set $nested-child-struct 0
- (ref.null $nested-child-struct)
+ (local.get $nested-child-struct)
(ref.as_non_null
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
@@ -124,7 +121,7 @@
)
(unreachable)
)
- (func $arrays (param $x (ref $vector)) (result (ref $matrix))
+ (func $arrays (param $x (ref $vector)) (param $nested-child-array (ref null $nested-child-array)) (param $grandchild (ref null $grandchild)) (result (ref $matrix))
(local $tv (ref null $vector))
(local $tm (ref null $matrix))
(local $tb (ref null $bytes))
@@ -153,10 +150,10 @@
)
;; values may be subtypes
(array.set $nested-child-array
- (ref.null $nested-child-array)
+ (local.get $nested-child-array)
(i32.const 3)
(ref.as_non_null
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
@@ -266,8 +263,8 @@
(struct.get $struct.C 0 (unreachable))
)
)
- (func $unreachables-2
- (struct.set $struct.C 0 (ref.null $struct.C) (unreachable))
+ (func $unreachables-2 (param $struct.C (ref null $struct.C))
+ (struct.set $struct.C 0 (local.get $struct.C) (unreachable))
)
(func $unreachables-3
(struct.set $struct.C 0 (unreachable) (unreachable))
@@ -281,9 +278,9 @@
(i32.const 2)
)
)
- (func $unreachables-array-2
+ (func $unreachables-array-2 (param $vector (ref null $vector))
(array.get $vector
- (ref.null $vector)
+ (local.get $vector)
(unreachable)
)
)
@@ -294,16 +291,16 @@
(f64.const 2.18281828)
)
)
- (func $unreachables-array-4
+ (func $unreachables-array-4 (param $vector (ref null $vector))
(array.set $vector
- (ref.null $vector)
+ (local.get $vector)
(unreachable)
(f64.const 2.18281828)
)
)
- (func $unreachables-array-5
+ (func $unreachables-array-5 (param $vector (ref null $vector))
(array.set $vector
- (ref.null $vector)
+ (local.get $vector)
(i32.const 2)
(unreachable)
)
diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast
index 09a12833f..dd3067e5a 100644
--- a/test/heap-types.wast.from-wast
+++ b/test/heap-types.wast.from-wast
@@ -8,17 +8,19 @@
(type $bytes (array (mut i8)))
(type $grandchild (struct (field i32) (field i64)))
(type $anyref_=>_none (func (param anyref)))
+ (type $ref?|$vector|_=>_none (func (param (ref null $vector))))
(type $nested-child-struct (struct (field (mut (ref $child)))))
(type $words (array (mut i32)))
(type $nested-child-array (array (mut (ref $child))))
(type $child (struct (field i32)))
- (type $ref|$struct.A|_=>_ref|$struct.B| (func (param (ref $struct.A)) (result (ref $struct.B))))
- (type $ref|$vector|_=>_ref|$matrix| (func (param (ref $vector)) (result (ref $matrix))))
+ (type $ref|$struct.A|_ref?|$struct.A|_ref?|$grandchild|_ref?|$struct.C|_ref?|$nested-child-struct|_=>_ref|$struct.B| (func (param (ref $struct.A) (ref null $struct.A) (ref null $grandchild) (ref null $struct.C) (ref null $nested-child-struct)) (result (ref $struct.B))))
+ (type $ref|$vector|_ref?|$nested-child-array|_ref?|$grandchild|_=>_ref|$matrix| (func (param (ref $vector) (ref null $nested-child-array) (ref null $grandchild)) (result (ref $matrix))))
+ (type $ref?|$struct.C|_=>_none (func (param (ref null $struct.C))))
(type $ref|$vector|_ref?|$vector|_=>_none (func (param (ref $vector) (ref null $vector))))
(type $none_=>_ref|$vector| (func (result (ref $vector))))
(type $none_=>_ref|$bytes| (func (result (ref $bytes))))
(global $struct.new-in-global (ref $struct.A) (struct.new_default $struct.A))
- (func $structs (param $x (ref $struct.A)) (result (ref $struct.B))
+ (func $structs (param $x (ref $struct.A)) (param $struct.A.prime (ref null $struct.A)) (param $grandchild (ref null $grandchild)) (param $struct.C (ref null $struct.C)) (param $nested-child-struct (ref null $nested-child-struct)) (result (ref $struct.B))
(local $tA (ref null $struct.A))
(local $tB (ref null $struct.B))
(local $tc (ref null $struct.C))
@@ -49,7 +51,7 @@
)
(drop
(struct.get $struct.A $named
- (ref.null $struct.A)
+ (local.get $struct.A.prime)
)
)
(drop
@@ -64,13 +66,10 @@
)
(drop
(struct.get $grandchild 0
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
- (ref.null $struct.A)
- )
- (drop
(block (result (ref null $struct.A))
(local.get $x)
)
@@ -95,13 +94,13 @@
)
)
(struct.set $struct.C $named-mut
- (ref.null $struct.C)
+ (local.get $struct.C)
(f32.const 100)
)
(struct.set $nested-child-struct 0
- (ref.null $nested-child-struct)
+ (local.get $nested-child-struct)
(ref.as_non_null
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
@@ -116,7 +115,7 @@
)
(unreachable)
)
- (func $arrays (param $x (ref $vector)) (result (ref $matrix))
+ (func $arrays (param $x (ref $vector)) (param $nested-child-array (ref null $nested-child-array)) (param $grandchild (ref null $grandchild)) (result (ref $matrix))
(local $tv (ref null $vector))
(local $tm (ref null $matrix))
(local $tb (ref null $bytes))
@@ -144,10 +143,10 @@
(f64.const 2.18281828)
)
(array.set $nested-child-array
- (ref.null $nested-child-array)
+ (local.get $nested-child-array)
(i32.const 3)
(ref.as_non_null
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
@@ -237,7 +236,7 @@
(local.get $x)
)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -247,7 +246,7 @@
(local.get $x)
)
)
- (ref.null data)
+ (ref.null none)
)
)
(drop
@@ -257,7 +256,7 @@
(local.get $x)
)
)
- (ref.null i31)
+ (ref.null none)
)
)
(drop
@@ -275,7 +274,7 @@
(local.get $x)
)
)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -285,7 +284,7 @@
(local.get $x)
)
)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -295,7 +294,7 @@
(local.get $x)
)
)
- (ref.null any)
+ (ref.null none)
)
)
)
@@ -305,12 +304,13 @@
(drop
(unreachable)
)
+ (unreachable)
)
)
)
- (func $unreachables-2
+ (func $unreachables-2 (param $struct.C (ref null $struct.C))
(struct.set $struct.C $named-mut
- (ref.null $struct.C)
+ (local.get $struct.C)
(unreachable)
)
)
@@ -322,6 +322,7 @@
(drop
(unreachable)
)
+ (unreachable)
)
)
(func $unreachables-4
@@ -332,6 +333,7 @@
(drop
(f32.const 1)
)
+ (unreachable)
)
)
(func $unreachables-array-1
@@ -342,11 +344,12 @@
(drop
(i32.const 2)
)
+ (unreachable)
)
)
- (func $unreachables-array-2
+ (func $unreachables-array-2 (param $vector (ref null $vector))
(array.get $vector
- (ref.null $vector)
+ (local.get $vector)
(unreachable)
)
)
@@ -361,25 +364,29 @@
(drop
(f64.const 2.18281828)
)
+ (unreachable)
)
)
- (func $unreachables-array-4
+ (func $unreachables-array-4 (param $vector (ref null $vector))
(array.set $vector
- (ref.null $vector)
+ (local.get $vector)
(unreachable)
(f64.const 2.18281828)
)
)
- (func $unreachables-array-5
+ (func $unreachables-array-5 (param $vector (ref null $vector))
(array.set $vector
- (ref.null $vector)
+ (local.get $vector)
(i32.const 2)
(unreachable)
)
)
(func $unreachables-array-6
(drop
- (block
+ (block ;; (replaces something unreachable we can't emit)
+ (drop
+ (unreachable)
+ )
(unreachable)
)
)
@@ -413,19 +420,19 @@
(local $temp.B (ref null $struct.B))
(drop
(ref.test_static $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(drop
(ref.cast_static $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(drop
(block $out-B (result (ref $struct.B))
(local.set $temp.A
(br_on_cast_static $out-B $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(unreachable)
@@ -435,7 +442,7 @@
(block $out-A (result (ref null $struct.A))
(local.set $temp.B
(br_on_cast_static_fail $out-A $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(unreachable)
diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary
index 266d04f93..dc55e1e8f 100644
--- a/test/heap-types.wast.fromBinary
+++ b/test/heap-types.wast.fromBinary
@@ -8,17 +8,19 @@
(type $struct.C (struct (field $named-mut (mut f32))))
(type $grandchild (struct (field i32) (field i64)))
(type $anyref_=>_none (func (param anyref)))
+ (type $ref?|$vector|_=>_none (func (param (ref null $vector))))
(type $nested-child-struct (struct (field (mut (ref $child)))))
(type $words (array (mut i32)))
(type $nested-child-array (array (mut (ref $child))))
(type $child (struct (field i32)))
- (type $ref|$struct.A|_=>_ref|$struct.B| (func (param (ref $struct.A)) (result (ref $struct.B))))
- (type $ref|$vector|_=>_ref|$matrix| (func (param (ref $vector)) (result (ref $matrix))))
+ (type $ref|$struct.A|_ref?|$struct.A|_ref?|$grandchild|_ref?|$struct.C|_ref?|$nested-child-struct|_=>_ref|$struct.B| (func (param (ref $struct.A) (ref null $struct.A) (ref null $grandchild) (ref null $struct.C) (ref null $nested-child-struct)) (result (ref $struct.B))))
+ (type $ref|$vector|_ref?|$nested-child-array|_ref?|$grandchild|_=>_ref|$matrix| (func (param (ref $vector) (ref null $nested-child-array) (ref null $grandchild)) (result (ref $matrix))))
+ (type $ref?|$struct.C|_=>_none (func (param (ref null $struct.C))))
(type $ref|$vector|_ref?|$vector|_=>_none (func (param (ref $vector) (ref null $vector))))
(type $none_=>_ref|$vector| (func (result (ref $vector))))
(type $none_=>_ref|$bytes| (func (result (ref $bytes))))
(global $struct.new-in-global (ref $struct.A) (struct.new_default $struct.A))
- (func $structs (param $x (ref $struct.A)) (result (ref $struct.B))
+ (func $structs (param $x (ref $struct.A)) (param $struct.A.prime (ref null $struct.A)) (param $grandchild (ref null $grandchild)) (param $struct.C (ref null $struct.C)) (param $nested-child-struct (ref null $nested-child-struct)) (result (ref $struct.B))
(local $tA (ref null $struct.A))
(local $tB (ref null $struct.B))
(local $tc (ref null $struct.C))
@@ -49,7 +51,7 @@
)
(drop
(struct.get $struct.A $named
- (ref.null $struct.A)
+ (local.get $struct.A.prime)
)
)
(drop
@@ -64,13 +66,10 @@
)
(drop
(struct.get $grandchild 0
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
- (ref.null $struct.A)
- )
- (drop
(local.get $x)
)
(drop
@@ -93,13 +92,13 @@
)
)
(struct.set $struct.C $named-mut
- (ref.null $struct.C)
+ (local.get $struct.C)
(f32.const 100)
)
(struct.set $nested-child-struct 0
- (ref.null $nested-child-struct)
+ (local.get $nested-child-struct)
(ref.as_non_null
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
@@ -114,7 +113,7 @@
)
(unreachable)
)
- (func $arrays (param $x (ref $vector)) (result (ref $matrix))
+ (func $arrays (param $x (ref $vector)) (param $nested-child-array (ref null $nested-child-array)) (param $grandchild (ref null $grandchild)) (result (ref $matrix))
(local $tv (ref null $vector))
(local $tm (ref null $matrix))
(local $tb (ref null $bytes))
@@ -142,10 +141,10 @@
(f64.const 2.18281828)
)
(array.set $nested-child-array
- (ref.null $nested-child-array)
+ (local.get $nested-child-array)
(i32.const 3)
(ref.as_non_null
- (ref.null $grandchild)
+ (local.get $grandchild)
)
)
(drop
@@ -235,7 +234,7 @@
(local.get $x)
)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -245,7 +244,7 @@
(local.get $x)
)
)
- (ref.null data)
+ (ref.null none)
)
)
(drop
@@ -255,7 +254,7 @@
(local.get $x)
)
)
- (ref.null i31)
+ (ref.null none)
)
)
(drop
@@ -273,7 +272,7 @@
(local.get $x)
)
)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -283,7 +282,7 @@
(local.get $x)
)
)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -293,16 +292,16 @@
(local.get $x)
)
)
- (ref.null any)
+ (ref.null none)
)
)
)
(func $unreachables-1
(unreachable)
)
- (func $unreachables-2
+ (func $unreachables-2 (param $struct.C (ref null $struct.C))
(drop
- (ref.null $struct.C)
+ (local.get $struct.C)
)
(unreachable)
)
@@ -315,24 +314,24 @@
(func $unreachables-array-1
(unreachable)
)
- (func $unreachables-array-2
+ (func $unreachables-array-2 (param $vector (ref null $vector))
(drop
- (ref.null $vector)
+ (local.get $vector)
)
(unreachable)
)
(func $unreachables-array-3
(unreachable)
)
- (func $unreachables-array-4
+ (func $unreachables-array-4 (param $vector (ref null $vector))
(drop
- (ref.null $vector)
+ (local.get $vector)
)
(unreachable)
)
- (func $unreachables-array-5
+ (func $unreachables-array-5 (param $vector (ref null $vector))
(drop
- (ref.null $vector)
+ (local.get $vector)
)
(drop
(i32.const 2)
@@ -371,19 +370,19 @@
(local $temp.B (ref null $struct.B))
(drop
(ref.test_static $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(drop
(ref.cast_static $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(drop
(block $label$1 (result (ref $struct.B))
(local.set $temp.A
(br_on_cast_static $label$1 $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(unreachable)
@@ -393,7 +392,7 @@
(block $label$2 (result (ref null $struct.A))
(local.set $temp.B
(br_on_cast_static_fail $label$2 $struct.B
- (ref.null $struct.A)
+ (ref.null none)
)
)
(unreachable)
diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo
index 03970672f..9c5194750 100644
--- a/test/heap-types.wast.fromBinary.noDebugInfo
+++ b/test/heap-types.wast.fromBinary.noDebugInfo
@@ -8,22 +8,24 @@
(type ${mut:f32} (struct (field (mut f32))))
(type ${i32_i64} (struct (field i32) (field i64)))
(type $anyref_=>_none (func (param anyref)))
+ (type $ref?|[mut:f64]|_=>_none (func (param (ref null $[mut:f64]))))
(type ${mut:ref|{i32}|} (struct (field (mut (ref ${i32})))))
(type $[mut:i32] (array (mut i32)))
(type $[mut:ref|{i32}|] (array (mut (ref ${i32}))))
(type ${i32} (struct (field i32)))
- (type $ref|{i32_f32_f64}|_=>_ref|{i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}| (func (param (ref ${i32_f32_f64})) (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))))
- (type $ref|[mut:f64]|_=>_ref|[mut:ref?|[mut:f64]|]| (func (param (ref $[mut:f64])) (result (ref $[mut:ref?|[mut:f64]|]))))
+ (type $ref|{i32_f32_f64}|_ref?|{i32_f32_f64}|_ref?|{i32_i64}|_ref?|{mut:f32}|_ref?|{mut:ref|{i32}|}|_=>_ref|{i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}| (func (param (ref ${i32_f32_f64}) (ref null ${i32_f32_f64}) (ref null ${i32_i64}) (ref null ${mut:f32}) (ref null ${mut:ref|{i32}|})) (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))))
+ (type $ref|[mut:f64]|_ref?|[mut:ref|{i32}|]|_ref?|{i32_i64}|_=>_ref|[mut:ref?|[mut:f64]|]| (func (param (ref $[mut:f64]) (ref null $[mut:ref|{i32}|]) (ref null ${i32_i64})) (result (ref $[mut:ref?|[mut:f64]|]))))
+ (type $ref?|{mut:f32}|_=>_none (func (param (ref null ${mut:f32}))))
(type $ref|[mut:f64]|_ref?|[mut:f64]|_=>_none (func (param (ref $[mut:f64]) (ref null $[mut:f64]))))
(type $none_=>_ref|[mut:f64]| (func (result (ref $[mut:f64]))))
(type $none_=>_ref|[mut:i8]| (func (result (ref $[mut:i8]))))
(global $global$0 (ref ${i32_f32_f64}) (struct.new_default ${i32_f32_f64}))
- (func $0 (param $0 (ref ${i32_f32_f64})) (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
- (local $1 (ref null ${i32_f32_f64}))
- (local $2 (ref null ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
- (local $3 (ref null ${mut:f32}))
- (local $4 (ref null $[mut:f64]))
- (local $5 (ref null $[mut:ref?|[mut:f64]|]))
+ (func $0 (param $0 (ref ${i32_f32_f64})) (param $1 (ref null ${i32_f32_f64})) (param $2 (ref null ${i32_i64})) (param $3 (ref null ${mut:f32})) (param $4 (ref null ${mut:ref|{i32}|})) (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
+ (local $5 (ref null ${i32_f32_f64}))
+ (local $6 (ref null ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
+ (local $7 (ref null ${mut:f32}))
+ (local $8 (ref null $[mut:f64]))
+ (local $9 (ref null $[mut:ref?|[mut:f64]|]))
(drop
(local.get $0)
)
@@ -49,28 +51,25 @@
)
(drop
(struct.get ${i32_f32_f64} 2
- (ref.null ${i32_f32_f64})
+ (local.get $1)
)
)
(drop
(struct.get_u ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|} 0
- (local.get $2)
+ (local.get $6)
)
)
(drop
(struct.get_s ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|} 0
- (local.get $2)
+ (local.get $6)
)
)
(drop
(struct.get ${i32_i64} 0
- (ref.null ${i32_i64})
+ (local.get $2)
)
)
(drop
- (ref.null ${i32_f32_f64})
- )
- (drop
(local.get $0)
)
(drop
@@ -93,13 +92,13 @@
)
)
(struct.set ${mut:f32} 0
- (ref.null ${mut:f32})
+ (local.get $3)
(f32.const 100)
)
(struct.set ${mut:ref|{i32}|} 0
- (ref.null ${mut:ref|{i32}|})
+ (local.get $4)
(ref.as_non_null
- (ref.null ${i32_i64})
+ (local.get $2)
)
)
(drop
@@ -114,11 +113,11 @@
)
(unreachable)
)
- (func $1 (param $0 (ref $[mut:f64])) (result (ref $[mut:ref?|[mut:f64]|]))
- (local $1 (ref null $[mut:f64]))
- (local $2 (ref null $[mut:ref?|[mut:f64]|]))
- (local $3 (ref null $[mut:i8]))
- (local $4 (ref null $[mut:i32]))
+ (func $1 (param $0 (ref $[mut:f64])) (param $1 (ref null $[mut:ref|{i32}|])) (param $2 (ref null ${i32_i64})) (result (ref $[mut:ref?|[mut:f64]|]))
+ (local $3 (ref null $[mut:f64]))
+ (local $4 (ref null $[mut:ref?|[mut:f64]|]))
+ (local $5 (ref null $[mut:i8]))
+ (local $6 (ref null $[mut:i32]))
(drop
(array.new $[mut:f64]
(f64.const 3.14159)
@@ -142,10 +141,10 @@
(f64.const 2.18281828)
)
(array.set $[mut:ref|{i32}|]
- (ref.null $[mut:ref|{i32}|])
+ (local.get $1)
(i32.const 3)
(ref.as_non_null
- (ref.null ${i32_i64})
+ (local.get $2)
)
)
(drop
@@ -155,19 +154,19 @@
)
(drop
(array.get $[mut:i32]
- (local.get $4)
+ (local.get $6)
(i32.const 1)
)
)
(drop
(array.get_u $[mut:i8]
- (local.get $3)
+ (local.get $5)
(i32.const 2)
)
)
(drop
(array.get_s $[mut:i8]
- (local.get $3)
+ (local.get $5)
(i32.const 3)
)
)
@@ -235,7 +234,7 @@
(local.get $0)
)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -245,7 +244,7 @@
(local.get $0)
)
)
- (ref.null data)
+ (ref.null none)
)
)
(drop
@@ -255,7 +254,7 @@
(local.get $0)
)
)
- (ref.null i31)
+ (ref.null none)
)
)
(drop
@@ -273,7 +272,7 @@
(local.get $0)
)
)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -283,7 +282,7 @@
(local.get $0)
)
)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -293,16 +292,16 @@
(local.get $0)
)
)
- (ref.null any)
+ (ref.null none)
)
)
)
(func $5
(unreachable)
)
- (func $6
+ (func $6 (param $0 (ref null ${mut:f32}))
(drop
- (ref.null ${mut:f32})
+ (local.get $0)
)
(unreachable)
)
@@ -315,24 +314,24 @@
(func $9
(unreachable)
)
- (func $10
+ (func $10 (param $0 (ref null $[mut:f64]))
(drop
- (ref.null $[mut:f64])
+ (local.get $0)
)
(unreachable)
)
(func $11
(unreachable)
)
- (func $12
+ (func $12 (param $0 (ref null $[mut:f64]))
(drop
- (ref.null $[mut:f64])
+ (local.get $0)
)
(unreachable)
)
- (func $13
+ (func $13 (param $0 (ref null $[mut:f64]))
(drop
- (ref.null $[mut:f64])
+ (local.get $0)
)
(drop
(i32.const 2)
@@ -371,19 +370,19 @@
(local $1 (ref null ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
(drop
(ref.test_static ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}
- (ref.null ${i32_f32_f64})
+ (ref.null none)
)
)
(drop
(ref.cast_static ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}
- (ref.null ${i32_f32_f64})
+ (ref.null none)
)
)
(drop
(block $label$1 (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
(local.set $0
(br_on_cast_static $label$1 ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}
- (ref.null ${i32_f32_f64})
+ (ref.null none)
)
)
(unreachable)
@@ -393,7 +392,7 @@
(block $label$2 (result (ref null ${i32_f32_f64}))
(local.set $1
(br_on_cast_static_fail $label$2 ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}
- (ref.null ${i32_f32_f64})
+ (ref.null none)
)
)
(unreachable)
diff --git a/test/lit/fuzz-types/isorecursive.test b/test/lit/fuzz-types/isorecursive.test
index 18fade75b..ccbb63d5e 100644
--- a/test/lit/fuzz-types/isorecursive.test
+++ b/test/lit/fuzz-types/isorecursive.test
@@ -1,26 +1,26 @@
;; RUN: wasm-fuzz-types --hybrid -v --seed=0 | filecheck %s
;; CHECK: (rec
-;; CHECK-NEXT: (type $0 (struct_subtype data))
-;; CHECK-NEXT: (type $1 (func_subtype (param (ref $0)) func))
-;; CHECK-NEXT: (type $2 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32) data))
-;; CHECK-NEXT: (type $3 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32) $2))
-;; CHECK-NEXT: (type $4 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32) $2))
-;; CHECK-NEXT: (type $5 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32) $3))
-;; CHECK-NEXT: (type $6 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32 v128) $3))
-;; CHECK-NEXT: (type $7 (struct_subtype $0))
-;; CHECK-NEXT: (type $8 (struct_subtype $0))
-;; CHECK-NEXT: (type $9 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32 v128) $6))
-;; CHECK-NEXT: (type $10 (struct_subtype (field (mut i64)) $0))
-;; CHECK-NEXT: (type $11 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32) $2))
-;; CHECK-NEXT: (type $12 (struct_subtype $0))
-;; CHECK-NEXT: (type $13 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32 v128) $6))
+;; CHECK-NEXT: (type $0 (array_subtype (mut i64) data))
+;; CHECK-NEXT: (type $1 (func_subtype (param i32 (ref eq) (ref null $3)) (result v128) func))
+;; CHECK-NEXT: (type $2 (array_subtype (mut v128) data))
+;; CHECK-NEXT: (type $3 (array_subtype (mut i64) $0))
+;; CHECK-NEXT: (type $4 (array_subtype i32 data))
+;; CHECK-NEXT: (type $5 none)
+;; CHECK-NEXT: (type $6 extern)
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $14 (struct_subtype (field (mut i64) (ref null $11) v128) $10))
-;; CHECK-NEXT: (type $15 (func_subtype (param (ref $0)) $1))
-;; CHECK-NEXT: (type $16 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32 (mut i64)) $2))
-;; CHECK-NEXT: (type $17 (struct_subtype (field (mut i64) (ref $11) v128 i16 i8) $14))
-;; CHECK-NEXT: (type $18 (struct_subtype (field (mut f64)) $12))
-;; CHECK-NEXT: (type $19 (func_subtype (param (ref $0)) $15))
+;; CHECK-NEXT: (type $7 (array_subtype (mut i64) $3))
+;; CHECK-NEXT: (type $8 (func_subtype (result v128) func))
+;; CHECK-NEXT: (type $9 (array_subtype (mut v128) $2))
+;; CHECK-NEXT: (type $10 none)
+;; CHECK-NEXT: (type $11 none)
+;; CHECK-NEXT: (type $12 (array_subtype (mut v128) $2))
+;; CHECK-NEXT: (type $13 (func_subtype (param f32 (ref none) (ref null $3)) (result eqref) func))
+;; CHECK-NEXT: (type $14 (array_subtype (mut i64) $7))
+;; CHECK-NEXT: (type $15 (func_subtype (param (ref null $17) v128 (ref i31)) func))
+;; CHECK-NEXT: (type $16 (array_subtype i32 data))
+;; CHECK-NEXT: (type $17 (func_subtype (param (ref i31)) (result v128) func))
+;; CHECK-NEXT: (type $18 (func_subtype (param f32) func))
+;; CHECK-NEXT: (type $19 (array_subtype (mut i64) $3))
;; CHECK-NEXT: )
diff --git a/test/lit/fuzz-types/nominal.test b/test/lit/fuzz-types/nominal.test
index 7ef381bfe..bb84f6991 100644
--- a/test/lit/fuzz-types/nominal.test
+++ b/test/lit/fuzz-types/nominal.test
@@ -1,22 +1,22 @@
;; RUN: wasm-fuzz-types --nominal -v --seed=0 | filecheck %s
-;; CHECK: (type $0 (struct_subtype (field v128 (ref null $4)) data))
-;; CHECK-NEXT: (type $1 (func_subtype (param (ref $3)) (result i32) func))
-;; CHECK-NEXT: (type $2 (struct_subtype (field (mut i64) f64) data))
-;; CHECK-NEXT: (type $3 (struct_subtype (field (mut i64) f64 (mut (ref $12)) i64) $2))
-;; CHECK-NEXT: (type $4 (struct_subtype (field (mut i64) f64) $2))
-;; CHECK-NEXT: (type $5 (struct_subtype (field (mut i64) f64 (mut (ref $12)) i64) $3))
-;; CHECK-NEXT: (type $6 (struct_subtype (field (mut i64) f64 (mut (ref $12)) i64) $3))
-;; CHECK-NEXT: (type $7 (struct_subtype (field v128 (ref null $4)) $0))
-;; CHECK-NEXT: (type $8 (struct_subtype (field v128 (ref $4) (ref null $3) v128) $0))
-;; CHECK-NEXT: (type $9 (struct_subtype (field (mut i64) f64 (mut (ref $12)) i64) $6))
-;; CHECK-NEXT: (type $10 (struct_subtype (field v128 (ref null $4)) $0))
-;; CHECK-NEXT: (type $11 (struct_subtype (field (mut i64) f64) $2))
-;; CHECK-NEXT: (type $12 (struct_subtype (field v128 (ref null $4) (mut (ref null $3))) $0))
-;; CHECK-NEXT: (type $13 (struct_subtype (field (mut i64) f64 (mut (ref $12)) i64) $6))
-;; CHECK-NEXT: (type $14 (struct_subtype (field v128 (ref null $4)) $10))
-;; CHECK-NEXT: (type $15 (func_subtype (param (ref $3)) (result i32) $1))
-;; CHECK-NEXT: (type $16 (struct_subtype (field (mut i64) f64) $2))
-;; CHECK-NEXT: (type $17 (struct_subtype (field v128 (ref null $4) i32) $14))
-;; CHECK-NEXT: (type $18 (struct_subtype (field v128 (ref null $4) (mut (ref null $3)) i16 f64) $12))
-;; CHECK-NEXT: (type $19 (func_subtype (param (ref $3)) (result i32) $15))
+;; CHECK: (type $0 (array_subtype (mut (ref null $8)) data))
+;; CHECK-NEXT: (type $1 (func_subtype (param nullref) (result v128) func))
+;; CHECK-NEXT: (type $2 (struct_subtype (field (mut i64) (mut i8) (mut (ref $12)) (mut f32)) data))
+;; CHECK-NEXT: (type $3 (array_subtype (mut (ref null $8)) $0))
+;; CHECK-NEXT: (type $4 (array_subtype (mut i64) data))
+;; CHECK-NEXT: (type $5 none)
+;; CHECK-NEXT: (type $6 extern)
+;; CHECK-NEXT: (type $7 (array_subtype (mut (ref null $8)) $3))
+;; CHECK-NEXT: (type $8 (func_subtype (result (ref $9)) func))
+;; CHECK-NEXT: (type $9 (struct_subtype (field (mut i64) (mut i8) (mut (ref $12)) (mut f32) i16) $2))
+;; CHECK-NEXT: (type $10 none)
+;; CHECK-NEXT: (type $11 none)
+;; CHECK-NEXT: (type $12 (struct_subtype (field (mut i64) (mut i8) (mut (ref $12)) (mut f32) (mut f32) (mut (ref $4))) $2))
+;; CHECK-NEXT: (type $13 (func_subtype (param dataref) func))
+;; CHECK-NEXT: (type $14 (array_subtype (mut (ref null $8)) $7))
+;; CHECK-NEXT: (type $15 (func_subtype (param externref) func))
+;; CHECK-NEXT: (type $16 (array_subtype v128 data))
+;; CHECK-NEXT: (type $17 (func_subtype (result (ref extern)) func))
+;; CHECK-NEXT: (type $18 (func_subtype (param v128 i64) func))
+;; CHECK-NEXT: (type $19 (array_subtype (mut (ref null $8)) $3))
diff --git a/test/lit/fuzz-types/structural.test b/test/lit/fuzz-types/structural.test
index 345590e2b..3dcec3179 100644
--- a/test/lit/fuzz-types/structural.test
+++ b/test/lit/fuzz-types/structural.test
@@ -1,22 +1,22 @@
;; RUN: wasm-fuzz-types --structural -v --seed=0 | filecheck %s
-;; CHECK: (type $0 (struct (field v128 (ref null $2))))
-;; CHECK-NEXT: (type $1 (func (param (ref $3)) (result i32)))
-;; CHECK-NEXT: (type $2 (struct (field (mut i64) f64)))
-;; CHECK-NEXT: (type $3 (struct (field (mut i64) f64 (mut (ref $12)) i64)))
-;; CHECK-NEXT: (type $4 identical to $2)
-;; CHECK-NEXT: (type $5 identical to $3)
-;; CHECK-NEXT: (type $6 identical to $3)
+;; CHECK: (type $0 (array (mut (ref null $8))))
+;; CHECK-NEXT: (type $1 (func (param nullref) (result v128)))
+;; CHECK-NEXT: (type $2 (struct (field (mut i64) (mut i8) (mut (ref $12)) (mut f32))))
+;; CHECK-NEXT: (type $3 identical to $0)
+;; CHECK-NEXT: (type $4 (array (mut i64)))
+;; CHECK-NEXT: (type $5 none)
+;; CHECK-NEXT: (type $6 extern)
;; CHECK-NEXT: (type $7 identical to $0)
-;; CHECK-NEXT: (type $8 (struct (field v128 (ref $2) (ref null $3) v128)))
-;; CHECK-NEXT: (type $9 identical to $3)
-;; CHECK-NEXT: (type $10 identical to $0)
-;; CHECK-NEXT: (type $11 identical to $2)
-;; CHECK-NEXT: (type $12 (struct (field v128 (ref null $2) (mut (ref null $3)))))
-;; CHECK-NEXT: (type $13 identical to $3)
+;; CHECK-NEXT: (type $8 (func (result (ref $9))))
+;; CHECK-NEXT: (type $9 (struct (field (mut i64) (mut i8) (mut (ref $12)) (mut f32) i16)))
+;; CHECK-NEXT: (type $10 none)
+;; CHECK-NEXT: (type $11 none)
+;; CHECK-NEXT: (type $12 (struct (field (mut i64) (mut i8) (mut (ref $12)) (mut f32) (mut f32) (mut (ref $4)))))
+;; CHECK-NEXT: (type $13 (func (param dataref)))
;; CHECK-NEXT: (type $14 identical to $0)
-;; CHECK-NEXT: (type $15 identical to $1)
-;; CHECK-NEXT: (type $16 identical to $2)
-;; CHECK-NEXT: (type $17 (struct (field v128 (ref null $2) i32)))
-;; CHECK-NEXT: (type $18 (struct (field v128 (ref null $2) (mut (ref null $3)) i16 f64)))
-;; CHECK-NEXT: (type $19 identical to $1)
+;; CHECK-NEXT: (type $15 (func (param externref)))
+;; CHECK-NEXT: (type $16 (array v128))
+;; CHECK-NEXT: (type $17 (func (result (ref extern))))
+;; CHECK-NEXT: (type $18 (func (param v128 i64)))
+;; CHECK-NEXT: (type $19 identical to $0)
diff --git a/test/lit/gc-eh.wast b/test/lit/gc-eh.wast
index 41897d0b3..335bad525 100644
--- a/test/lit/gc-eh.wast
+++ b/test/lit/gc-eh.wast
@@ -27,7 +27,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; NOMNL: (func $foo (type $none_=>_ref?|$A|) (result (ref null $A))
;; NOMNL-NEXT: (try $try
@@ -40,7 +40,7 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
(func $foo (result (ref null $A))
(try
diff --git a/test/lit/global-only.wast b/test/lit/global-only.wast
index 6dce13d6d..ac3e1ee8f 100644
--- a/test/lit/global-only.wast
+++ b/test/lit/global-only.wast
@@ -8,6 +8,6 @@
(module $parse
;; CHECK: (type $t (struct ))
(type $t (struct))
- ;; CHECK: (global $g (ref null $t) (ref.null $t))
+ ;; CHECK: (global $g (ref null $t) (ref.null none))
(global $g (ref null $t) (ref.null $t))
)
diff --git a/test/lit/heap-types.wast b/test/lit/heap-types.wast
index ff9e59290..13d37217e 100644
--- a/test/lit/heap-types.wast
+++ b/test/lit/heap-types.wast
@@ -10,21 +10,20 @@
(module
;; CHECK: (type $struct.A (struct (field i32)))
- ;; NOMNL: (type $struct.A (struct_subtype (field i32) data))
(type $struct.A (struct i32))
;; NOMNL: (type $struct.B (struct_subtype (field i32) data))
(type $struct.B (struct i32))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.test_static $struct.A
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $test (type $none_=>_none)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.test_static $struct.B
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -37,21 +36,20 @@
(module
;; CHECK: (type $struct.A (struct (field i32)))
- ;; NOMNL: (type $struct.A (struct_subtype (field i32) data))
(type $struct.A (struct i32))
;; NOMNL: (type $struct.B (struct_subtype (field i32) data))
(type $struct.B (struct i32))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $struct.A
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $test (type $none_=>_none)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.cast_static $struct.B
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
diff --git a/test/lit/isorecursive-singleton-group.wast b/test/lit/isorecursive-singleton-group.wast
index c36717376..bde2848bf 100644
--- a/test/lit/isorecursive-singleton-group.wast
+++ b/test/lit/isorecursive-singleton-group.wast
@@ -15,6 +15,6 @@
)
;; Use the type so it appears in the output.
- ;; CHECK: (global $g (ref null $singleton) (ref.null $singleton))
+ ;; CHECK: (global $g (ref null $singleton) (ref.null none))
(global $g (ref null $singleton) (ref.null $singleton))
)
diff --git a/test/lit/isorecursive-whole-group.wast b/test/lit/isorecursive-whole-group.wast
index 6f12eeb7a..70f2f1e4e 100644
--- a/test/lit/isorecursive-whole-group.wast
+++ b/test/lit/isorecursive-whole-group.wast
@@ -17,6 +17,6 @@
(type $unused (struct_subtype data))
)
- ;; CHECK: (global $g (ref null $used) (ref.null $used))
+ ;; CHECK: (global $g (ref null $used) (ref.null none))
(global $g (ref null $used) (ref.null $used))
)
diff --git a/test/lit/lub-bug-3843.wast b/test/lit/lub-bug-3843.wast
index f5bb439f2..768d47fdc 100644
--- a/test/lit/lub-bug-3843.wast
+++ b/test/lit/lub-bug-3843.wast
@@ -15,37 +15,38 @@
;; NOMNL: (type $B (struct_subtype (field (ref null $D)) $A))
(type $B (struct_subtype (field (ref null $D)) $A))
+ ;; CHECK: (type $C (struct (field (mut (ref $A)))))
+
;; CHECK: (type $D (struct (field (mut (ref $A))) (field (mut (ref $A)))))
;; NOMNL: (type $C (struct_subtype (field (mut (ref $A))) data))
;; NOMNL: (type $D (struct_subtype (field (mut (ref $A))) (field (mut (ref $A))) $C))
(type $D (struct_subtype (field (mut (ref $A))) (field (mut (ref $A))) $C))
- ;; CHECK: (type $C (struct (field (mut (ref $A)))))
(type $C (struct (field (mut (ref $A)))))
- ;; CHECK: (func $foo (param $a (ref null $A)) (result (ref null $A))
+ ;; CHECK: (func $foo (param $a (ref null $A)) (param $b (ref null $B)) (result (ref null $A))
;; CHECK-NEXT: (select (result (ref null $A))
;; CHECK-NEXT: (local.get $a)
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $b)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $foo (type $ref?|$A|_=>_ref?|$A|) (param $a (ref null $A)) (result (ref null $A))
+ ;; NOMNL: (func $foo (type $ref?|$A|_ref?|$B|_=>_ref?|$A|) (param $a (ref null $A)) (param $b (ref null $B)) (result (ref null $A))
;; NOMNL-NEXT: (select (result (ref null $A))
;; NOMNL-NEXT: (local.get $a)
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (local.get $b)
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- (func $foo (param $a (ref null $A)) (result (ref null $A))
+ (func $foo (param $a (ref null $A)) (param $b (ref null $B)) (result (ref null $A))
;; the select should have type $A
(select (result (ref null $A))
;; one arm has type $A
(local.get $a)
;; one arm has type $B (a subtype of $A)
- (ref.null $B)
+ (local.get $b)
(i32.const 0)
)
)
diff --git a/test/lit/nominal-chain.wast b/test/lit/nominal-chain.wast
index dda04b32c..1403fbea4 100644
--- a/test/lit/nominal-chain.wast
+++ b/test/lit/nominal-chain.wast
@@ -26,10 +26,10 @@
(type $root (struct))
- ;; CHECK: (func $make-root (type $none_=>_ref?|$root|) (result (ref null $root))
- ;; CHECK-NEXT: (ref.null $leaf)
+ ;; CHECK: (func $make-root (type $ref|$leaf|_=>_ref?|$root|) (param $leaf (ref $leaf)) (result (ref null $root))
+ ;; CHECK-NEXT: (local.get $leaf)
;; CHECK-NEXT: )
- (func $make-root (result (ref null $root))
- (ref.null $leaf)
+ (func $make-root (param $leaf (ref $leaf)) (result (ref null $root))
+ (local.get $leaf)
)
)
diff --git a/test/lit/parse-double-unreachable.wast b/test/lit/parse-double-unreachable.wast
new file mode 100644
index 000000000..0dd657a62
--- /dev/null
+++ b/test/lit/parse-double-unreachable.wast
@@ -0,0 +1,43 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
+
+;; RUN: wasm-opt %s -all --nominal --roundtrip -S -o - | filecheck %s
+
+;; Regression test for a bug in which we could pop the expression stack past an
+;; unreachable if we were already in unreachable parsing mode.
+
+(module
+
+ ;; CHECK: (type $array (array_subtype i8 data))
+ (type $array (array i8))
+ (type $func (func (result i32)))
+
+ ;; CHECK: (func $double-unreachable (type $ref|$array|_=>_i32) (param $x (ref $array)) (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $double-unreachable (param $x (ref $array)) (result i32)
+
+ (drop
+ ;; This gets emitted as an unreachable, but it doesn't have type
+ ;; unreachable, so we continue emitting instructions afterward. When
+ ;; parsing, this will put us into unreachable mode.
+ (call_ref $func
+ (ref.null nofunc)
+ )
+ )
+
+ (array.get_u $array
+ (local.get $x)
+
+ ;; Since this call_ref will be emitted as an unreachable, it does not consume
+ ;; the ref.null when parsing. Due to the bug, the ref.null would remain on
+ ;; the stack and would be incorrectly consumed as the index to the
+ ;; array.get_u, producing a type error.
+ (call_ref $func
+ (ref.null nofunc)
+ )
+ )
+ )
+)
diff --git a/test/lit/parse-nominal-types-extends.wast b/test/lit/parse-nominal-types-extends.wast
index ea9461e67..9dbf6a0de 100644
--- a/test/lit/parse-nominal-types-extends.wast
+++ b/test/lit/parse-nominal-types-extends.wast
@@ -8,65 +8,55 @@
;; void function type
(module
- ;; CHECK: (type $super (func_subtype func))
-
- ;; CHECK: (type $sub (func_subtype $super))
(type $sub (func) (extends $super))
+ ;; CHECK: (type $super (func_subtype func))
(type $super (func))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
(global $g (ref null $super) (ref.null $sub))
)
;; function type with params and results
(module
- ;; CHECK: (type $super (func_subtype (param i32) (result i32) func))
-
- ;; CHECK: (type $sub (func_subtype (param i32) (result i32) $super))
(type $sub (func (param i32) (result i32)) (extends $super))
+ ;; CHECK: (type $super (func_subtype (param i32) (result i32) func))
(type $super (func (param i32) (result i32)))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
(global $g (ref null $super) (ref.null $sub))
)
;; empty struct type
(module
- ;; CHECK: (type $super (struct_subtype data))
-
- ;; CHECK: (type $sub (struct_subtype $super))
(type $sub (struct) (extends $super))
+ ;; CHECK: (type $super (struct_subtype data))
(type $super (struct))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null none))
(global $g (ref null $super) (ref.null $sub))
)
;; struct type with fields
(module
- ;; CHECK: (type $super (struct_subtype (field i32) (field i64) data))
-
- ;; CHECK: (type $sub (struct_subtype (field i32) (field i64) $super))
(type $sub (struct i32 (field i64)) (extends $super))
+ ;; CHECK: (type $super (struct_subtype (field i32) (field i64) data))
(type $super (struct (field i32) i64))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null none))
(global $g (ref null $super) (ref.null $sub))
)
;; array type
(module
- ;; CHECK: (type $super (array_subtype i8 data))
-
- ;; CHECK: (type $sub (array_subtype i8 $super))
(type $sub (array i8) (extends $super))
+ ;; CHECK: (type $super (array_subtype i8 data))
(type $super (array i8))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null none))
(global $g (ref null $super) (ref.null $sub))
)
diff --git a/test/lit/parse-nominal-types.wast b/test/lit/parse-nominal-types.wast
index db681ead9..6bb0c8383 100644
--- a/test/lit/parse-nominal-types.wast
+++ b/test/lit/parse-nominal-types.wast
@@ -8,65 +8,55 @@
;; void function type
(module
- ;; CHECK: (type $super (func_subtype func))
-
- ;; CHECK: (type $sub (func_subtype $super))
(type $sub (func_subtype $super))
+ ;; CHECK: (type $super (func_subtype func))
(type $super (func_subtype func))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
(global $g (ref null $super) (ref.null $sub))
)
;; function type with params and results
(module
- ;; CHECK: (type $super (func_subtype (param i32) (result i32) func))
-
- ;; CHECK: (type $sub (func_subtype (param i32) (result i32) $super))
(type $sub (func_subtype (param i32) (result i32) $super))
+ ;; CHECK: (type $super (func_subtype (param i32) (result i32) func))
(type $super (func_subtype (param i32) (result i32) func))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
(global $g (ref null $super) (ref.null $sub))
)
;; empty struct type
(module
- ;; CHECK: (type $super (struct_subtype data))
-
- ;; CHECK: (type $sub (struct_subtype $super))
(type $sub (struct_subtype $super))
+ ;; CHECK: (type $super (struct_subtype data))
(type $super (struct_subtype data))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null none))
(global $g (ref null $super) (ref.null $sub))
)
;; struct type with fields
(module
- ;; CHECK: (type $super (struct_subtype (field i32) (field i64) data))
-
- ;; CHECK: (type $sub (struct_subtype (field i32) (field i64) $super))
(type $sub (struct_subtype i32 (field i64) $super))
+ ;; CHECK: (type $super (struct_subtype (field i32) (field i64) data))
(type $super (struct_subtype (field i32) i64 data))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null none))
(global $g (ref null $super) (ref.null $sub))
)
;; array type
(module
- ;; CHECK: (type $super (array_subtype i8 data))
-
- ;; CHECK: (type $sub (array_subtype i8 $super))
(type $sub (array_subtype i8 $super))
+ ;; CHECK: (type $super (array_subtype i8 data))
(type $super (array_subtype i8 data))
- ;; CHECK: (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (global $g (ref null $super) (ref.null none))
(global $g (ref null $super) (ref.null $sub))
)
diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast
index 437ace803..b1790bd17 100644
--- a/test/lit/passes/cfp.wast
+++ b/test/lit/passes/cfp.wast
@@ -9,22 +9,23 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
;; CHECK: (func $impossible-get (type $none_=>_none)
+ ;; CHECK-NEXT: (local $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $impossible-get
+ (func $impossible-get (local $struct (ref null $struct))
(drop
;; This type is never created, so a get is impossible, and we will trap
;; anyhow. So we can turn this into an unreachable (plus a drop of the
;; reference).
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -33,9 +34,9 @@
(module
;; CHECK: (type $struct (struct_subtype (field i64) data))
(type $struct (struct i64))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
@@ -43,14 +44,14 @@
;; CHECK-NEXT: (block (result i64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i64.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
;; The only place this type is created is with a default value, and so we
;; can optimize the later get into a constant (plus a drop of the ref).
;;
@@ -63,7 +64,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -72,9 +73,9 @@
(module
;; CHECK: (type $struct (struct_subtype (field f32) data))
(type $struct (struct f32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
@@ -84,14 +85,14 @@
;; CHECK-NEXT: (block (result f32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
;; The only place this type is created is with a constant value, and so we
;; can optimize the later get into a constant (plus a drop of the ref).
(drop
@@ -101,7 +102,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -110,9 +111,9 @@
(module
;; CHECK: (type $struct (struct_subtype (field f32) data))
(type $struct (struct f32))
- ;; CHECK: (type $f32_=>_none (func_subtype (param f32) func))
+ ;; CHECK: (type $f32_ref?|$struct|_=>_none (func_subtype (param f32 (ref null $struct)) func))
- ;; CHECK: (func $test (type $f32_=>_none) (param $f f32)
+ ;; CHECK: (func $test (type $f32_ref?|$struct|_=>_none) (param $f f32) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (local.get $f)
@@ -120,11 +121,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test (param $f f32)
+ (func $test (param $f f32) (param $struct (ref null $struct))
;; The value given is not a constant, and so we cannot optimize.
(drop
(struct.new $struct
@@ -133,7 +134,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -142,10 +143,12 @@
;; Create in one function, get in another. The 10 should be forwarded to the
;; get.
(module
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -160,22 +163,22 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -184,27 +187,29 @@
;; As before, but with the order of functions reversed to check for any ordering
;; issues.
(module
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -230,9 +235,9 @@
(module
;; CHECK: (type $struct (struct_subtype (field f32) data))
(type $struct (struct f32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
@@ -245,11 +250,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $struct
(f32.const 42)
@@ -262,7 +267,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -272,6 +277,8 @@
(module
;; CHECK: (type $struct (struct_subtype (field (mut f32)) data))
(type $struct (struct (mut f32)))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_none)
@@ -288,29 +295,29 @@
)
)
)
- ;; CHECK: (func $set (type $none_=>_none)
+ ;; CHECK: (func $set (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (f32.const 1337)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $set
+ (func $set (param $struct (ref null $struct))
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(f32.const 1337)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -321,6 +328,8 @@
(module
;; CHECK: (type $struct (struct_subtype (field (mut f32)) data))
(type $struct (struct (mut f32)))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_none)
@@ -337,34 +346,34 @@
)
)
)
- ;; CHECK: (func $set (type $none_=>_none)
+ ;; CHECK: (func $set (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (f32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $set
+ (func $set (param $struct (ref null $struct))
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(f32.const 42) ;; The last testcase had 1337 here.
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -376,7 +385,9 @@
(type $struct (struct (mut f32)))
;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $i32_=>_none (func_subtype (param i32) func))
+ ;; CHECK: (type $i32_ref?|$struct|_=>_none (func_subtype (param i32 (ref null $struct)) func))
+
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
@@ -399,9 +410,9 @@
)
)
)
- ;; CHECK: (func $set (type $i32_=>_none) (param $x i32)
+ ;; CHECK: (func $set (type $i32_ref?|$struct|_=>_none) (param $x i32) (param $struct (ref null $struct))
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (if (result f32)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (unreachable)
@@ -409,9 +420,9 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $set (param $x i32)
+ (func $set (param $x i32) (param $struct (ref null $struct))
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
;; Fall though a 42 via an if.
(if (result f32)
(local.get $x)
@@ -420,22 +431,22 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -443,30 +454,30 @@
;; Test a function reference instead of a number.
(module
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (type $struct (struct_subtype (field funcref) data))
(type $struct (struct funcref))
;; CHECK: (elem declare func $test)
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (ref.func $test)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref $none_=>_none))
+ ;; CHECK-NEXT: (block (result (ref $ref?|$struct|_=>_none))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $test)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $struct
(ref.func $test)
@@ -474,7 +485,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -491,6 +502,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -498,6 +510,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
@@ -507,6 +520,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $test
@@ -535,6 +549,8 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
+ ;; CHECK: (type $ref?|$substruct|_=>_none (func_subtype (param (ref null $substruct)) func))
+
;; CHECK: (type $substruct (struct_subtype (field i32) $struct))
(type $substruct (struct_subtype i32 $struct))
@@ -552,20 +568,20 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$substruct|_=>_none) (param $substruct (ref null $substruct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $substruct)
+ ;; CHECK-NEXT: (local.get $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $substruct (ref null $substruct))
(drop
(struct.get $substruct 0
- (ref.null $substruct)
+ (local.get $substruct)
)
)
)
@@ -578,49 +594,51 @@
(module
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
+ ;; CHECK: (type $ref?|$substruct|_=>_none (func_subtype (param (ref null $substruct)) func))
;; CHECK: (type $substruct (struct_subtype (field (mut i32)) $struct))
(type $substruct (struct_subtype (mut i32) $struct))
- ;; CHECK: (func $create (type $none_=>_none)
+ ;; CHECK: (func $create (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $create
+ (func $create (param $struct (ref null $struct))
(drop
(struct.new $struct
(i32.const 10)
)
)
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(i32.const 10)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$substruct|_=>_none) (param $substruct (ref null $substruct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $substruct)
+ ;; CHECK-NEXT: (local.get $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $substruct (ref null $substruct))
(drop
(struct.get $substruct 0
- (ref.null $substruct)
+ (local.get $substruct)
)
)
)
@@ -639,6 +657,8 @@
(type $struct (struct i32))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $substruct
@@ -655,22 +675,22 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -679,13 +699,15 @@
;; Subtyping: Create both a subtype and a supertype, with identical constants
;; for the shared field, and get the supertype.
(module
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
(type $substruct (struct_subtype i32 f64 $struct))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -712,22 +734,22 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -744,6 +766,8 @@
;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
(type $substruct (struct_subtype i32 f64 $struct))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -770,17 +794,17 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -791,8 +815,6 @@
;; shared between the types, but we only create the substruct with
;; one value, so we can optimize.
(module
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
;; CHECK: (type $struct (struct_subtype (field i32) data))
;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
@@ -800,6 +822,10 @@
(type $struct (struct i32))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
+ ;; CHECK: (type $ref?|$substruct|_=>_none (func_subtype (param (ref null $substruct)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -826,22 +852,22 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$substruct|_=>_none) (param $substruct (ref null $substruct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $substruct)
+ ;; CHECK-NEXT: (local.get $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $substruct (ref null $substruct))
(drop
(struct.get $substruct 0
- (ref.null $substruct)
+ (local.get $substruct)
)
)
)
@@ -855,16 +881,18 @@
;; CHECK: (type $substruct (struct_subtype (field (mut i32)) (field f64) $struct))
(type $substruct (struct_subtype (mut i32) f64 $struct))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
- ;; CHECK: (func $create (type $none_=>_none)
+ ;; CHECK: (type $ref?|$substruct|_=>_none (func_subtype (param (ref null $substruct)) func))
+
+ ;; CHECK: (func $create (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -874,14 +902,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $create
+ (func $create (param $struct (ref null $struct))
(drop
(struct.new $struct
(i32.const 10)
)
)
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(i32.const 10)
)
(drop
@@ -891,17 +919,17 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$substruct|_=>_none) (param $substruct (ref null $substruct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $substruct 0
- ;; CHECK-NEXT: (ref.null $substruct)
+ ;; CHECK-NEXT: (local.get $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $substruct (ref null $substruct))
(drop
(struct.get $substruct 0
- (ref.null $substruct)
+ (local.get $substruct)
)
)
)
@@ -923,12 +951,14 @@
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func_subtype (param (ref null $struct1) (ref null $struct2) (ref null $struct3)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -937,16 +967,16 @@
(struct.new $struct3
(i32.const 20)
(f64.const 3.14159)
- (ref.null any)
+ (ref.null none)
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
@@ -956,7 +986,7 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
@@ -966,7 +996,7 @@
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 3.14159)
@@ -976,7 +1006,7 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
@@ -986,56 +1016,56 @@
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 3.14159)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; Get field 0 from the $struct1. This can be optimized to a constant
;; since we only ever created an instance of struct3 with a constant there.
(drop
(struct.get $struct1 0
- (ref.null $struct1)
+ (local.get $struct1)
)
)
;; Get both fields of $struct2.
(drop
(struct.get $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct2 1
- (ref.null $struct2)
+ (local.get $struct2)
)
)
;; Get all 3 fields of $struct3
(drop
(struct.get $struct3 0
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 1
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 2
- (ref.null $struct3)
+ (local.get $struct3)
)
)
)
@@ -1058,7 +1088,7 @@
;; CHECK: (type $anyref_=>_none (func_subtype (param anyref) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func_subtype (param (ref null $struct1) (ref null $struct2) (ref null $struct3)) func))
;; CHECK: (func $create (type $anyref_=>_none) (param $any anyref)
;; CHECK-NEXT: (drop
@@ -1073,7 +1103,7 @@
;; CHECK-NEXT: (i32.const 999)
;; CHECK-NEXT: (f64.const 2.71828)
;; CHECK-NEXT: (f64.const 9.9999999)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $any)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1097,12 +1127,12 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
@@ -1110,14 +1140,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct1 1
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
@@ -1127,7 +1157,7 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 999)
@@ -1137,7 +1167,7 @@
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 2.71828)
@@ -1147,7 +1177,7 @@
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 9.9999999)
@@ -1157,7 +1187,7 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
@@ -1167,7 +1197,7 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 999)
@@ -1177,7 +1207,7 @@
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 2.71828)
@@ -1187,88 +1217,88 @@
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 9.9999999)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct3 5
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; Get all the fields of all the structs.
(drop
(struct.get $struct1 0
- (ref.null $struct1)
+ (local.get $struct1)
)
)
(drop
(struct.get $struct1 1
- (ref.null $struct1)
+ (local.get $struct1)
)
)
(drop
(struct.get $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct2 1
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct2 2
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct2 3
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct3 0
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 1
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 2
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 3
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 4
- (ref.null $struct3)
+ (local.get $struct3)
)
)
(drop
(struct.get $struct3 5
- (ref.null $struct3)
+ (local.get $struct3)
)
)
)
@@ -1281,11 +1311,13 @@
(type $struct1 (struct (mut i32)))
;; CHECK: (type $struct2 (struct_subtype (field (mut i32)) (field f64) $struct1))
(type $struct2 (struct_subtype (mut i32) f64 $struct1))
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
;; CHECK: (type $struct3 (struct_subtype (field (mut i32)) (field f64) (field anyref) $struct2))
(type $struct3 (struct_subtype (mut i32) f64 anyref $struct2))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
+ ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func_subtype (param (ref null $struct1) (ref null $struct2) (ref null $struct3)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct1
@@ -1302,7 +1334,7 @@
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1326,43 +1358,43 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct1 0
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct2 0
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; Get field 0 in all the types.
(drop
(struct.get $struct1 0
- (ref.null $struct1)
+ (local.get $struct1)
)
)
(drop
(struct.get $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct3 0
- (ref.null $struct3)
+ (local.get $struct3)
)
)
)
@@ -1381,9 +1413,11 @@
;; CHECK: (type $struct3 (struct_subtype (field (mut i32)) (field f64) (field anyref) $struct2))
(type $struct3 (struct_subtype (mut i32) f64 anyref $struct2))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct2|_=>_none (func_subtype (param (ref null $struct2)) func))
- ;; CHECK: (func $create (type $none_=>_none)
+ ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func_subtype (param (ref null $struct1) (ref null $struct2) (ref null $struct3)) func))
+
+ ;; CHECK: (func $create (type $ref?|$struct2|_=>_none) (param $struct2 (ref null $struct2))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
@@ -1396,18 +1430,18 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct2 0
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $create
+ (func $create (param $struct2 (ref null $struct2))
(drop
(struct.new $struct1
(i32.const 10)
@@ -1420,7 +1454,7 @@
)
)
(struct.set $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
(i32.const 9999) ;; use a different value here
(f64.const 0)
)
@@ -1432,38 +1466,38 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct1 0
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct2 0
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct3 0
- ;; CHECK-NEXT: (ref.null $struct3)
+ ;; CHECK-NEXT: (local.get $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2)) (param $struct3 (ref null $struct3))
;; Get field 0 in all the types.
(drop
(struct.get $struct1 0
- (ref.null $struct1)
+ (local.get $struct1)
)
)
(drop
(struct.get $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
)
)
(drop
(struct.get $struct3 0
- (ref.null $struct3)
+ (local.get $struct3)
)
)
)
@@ -1477,6 +1511,8 @@
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -1503,17 +1539,17 @@
)
)
)
- ;; CHECK: (func $get (type $none_=>_none)
+ ;; CHECK: (func $get (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 3.14159)
@@ -1523,7 +1559,7 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
@@ -1531,14 +1567,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 3
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 30)
@@ -1548,43 +1584,43 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 30)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $get
+ (func $get (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $struct 1
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $struct 2
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $struct 3
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $struct 4
- (ref.null $struct)
+ (local.get $struct)
)
)
;; Also test for multiple gets of the same field.
(drop
(struct.get $struct 4
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1659,18 +1695,18 @@
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_ref?|$struct|_=>_none (func_subtype (param (ref null $struct) (ref null $struct)) func))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_ref?|$struct|_=>_none) (param $struct (ref null $struct)) (param $other (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
@@ -1680,28 +1716,28 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct)) (param $other (ref null $struct))
(drop
(struct.new_default $struct)
)
;; This copy does not actually introduce any new possible values, and so it
;; remains true that the only possible value is the default.
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $other)
)
)
)
@@ -1712,44 +1748,44 @@
(module
;; CHECK: (type $struct (struct_subtype (field (mut f32)) (field (mut i32)) data))
(type $struct (struct (mut f32) (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_ref?|$other|_=>_none (func_subtype (param (ref null $struct) (ref null $other)) func))
;; CHECK: (type $other (struct_subtype (field (mut f64)) (field (mut i32)) data))
(type $other (struct (mut f64) (mut i32)))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_ref?|$other|_=>_none) (param $struct (ref null $struct)) (param $other (ref null $other))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 1
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $other)
+ ;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 1
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct)) (param $other (ref null $other))
(drop
(struct.new_default $struct)
)
;; As this is not a copy, we cannot optimize struct.1's get lower down.
(struct.set $struct 1
- (ref.null $struct)
+ (local.get $struct)
(struct.get $other 1
- (ref.null $other)
+ (local.get $other)
)
)
(drop
(struct.get $struct 1
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1760,18 +1796,18 @@
;; CHECK: (type $struct (struct_subtype (field (mut i32)) (field (mut i32)) data))
(type $struct (struct (mut i32) (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
@@ -1779,24 +1815,24 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new_default $struct)
)
;; As this is not a copy, we cannot optimize struct.0's get lower down.
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(struct.get $struct 1
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1806,12 +1842,12 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global i32 (i32.const 42))
(global $global i32 (i32.const 42))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (global.get $global)
@@ -1821,14 +1857,14 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
;; An immutable global is the only thing written to this field, so we can
;; propagate the value to the struct.get and replace it with a global.get.
(drop
@@ -1838,7 +1874,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1848,12 +1884,12 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global (mut i32) (i32.const 42))
(global $global (mut i32) (i32.const 42))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (global.get $global)
@@ -1861,11 +1897,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
;; As above, but the global is *not* immutable, so we cannot optimize.
(drop
(struct.new $struct
@@ -1874,7 +1910,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1884,33 +1920,33 @@
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global i32 (i32.const 42))
(global $global i32 (i32.const 42))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $struct
(global.get $global)
@@ -1920,12 +1956,12 @@
;; so that is fine. Also, the struct's field is now mutable as well to allow
;; that, and that also does not prevent optimization.
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(global.get $global)
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1935,30 +1971,30 @@
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global i32 (i32.const 42))
(global $global i32 (i32.const 42))
;; CHECK: (global $global-2 i32 (i32.const 1337))
(global $global-2 i32 (i32.const 1337))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (global.get $global-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $struct
(global.get $global)
@@ -1966,12 +2002,12 @@
)
;; As above, but set a different global, which prevents optimization.
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(global.get $global-2)
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -1981,30 +2017,30 @@
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global i32 (i32.const 42))
(global $global i32 (i32.const 42))
;; CHECK: (global $global-2 i32 (i32.const 1337))
(global $global-2 i32 (i32.const 1337))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $struct
(global.get $global)
@@ -2013,12 +2049,12 @@
;; As above, but set a constant, which means we are mixing constants with
;; globals, which prevents the optimization.
(struct.set $struct 0
- (ref.null $struct)
+ (local.get $struct)
(i32.const 1337)
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -2038,11 +2074,11 @@
;; CHECK: (type $object (struct_subtype (field $itable (ref $itable)) data))
(type $object (struct (field $itable (ref $itable))))
- ;; CHECK: (type $none_=>_funcref (func_subtype (result funcref) func))
+ ;; CHECK: (type $ref?|$object|_=>_funcref (func_subtype (param (ref null $object)) (result funcref) func))
;; CHECK: (global $global (ref $itable) (array.init_static $itable
;; CHECK-NEXT: (struct.new $vtable
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.new $vtable
;; CHECK-NEXT: (ref.func $test)
@@ -2057,7 +2093,7 @@
)
))
- ;; CHECK: (func $test (type $none_=>_funcref) (result funcref)
+ ;; CHECK: (func $test (type $ref?|$object|_=>_funcref) (param $object (ref null $object)) (result funcref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $object
;; CHECK-NEXT: (global.get $global)
@@ -2068,7 +2104,7 @@
;; CHECK-NEXT: (block (result (ref $itable))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $object)
+ ;; CHECK-NEXT: (local.get $object)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global)
@@ -2077,7 +2113,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test (result funcref)
+ (func $test (param $object (ref null $object)) (result funcref)
(drop
(struct.new $object
(global.get $global)
@@ -2092,7 +2128,7 @@
(struct.get $vtable 0
(array.get $itable
(struct.get $object $itable
- (ref.null $object)
+ (local.get $object)
)
(i32.const 1)
)
diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast
index 0113af23c..5947aae11 100644
--- a/test/lit/passes/coalesce-locals-gc.wast
+++ b/test/lit/passes/coalesce-locals-gc.wast
@@ -10,7 +10,7 @@
(module
;; CHECK: (type $array (array (mut i8)))
(type $array (array (mut i8)))
- ;; CHECK: (global $global (ref null $array) (ref.null $array))
+ ;; CHECK: (global $global (ref null $array) (ref.null none))
(global $global (ref null $array) (ref.null $array))
;; CHECK: (func $test-dead-get-non-nullable (param $0 (ref data))
@@ -136,4 +136,33 @@
(local.get $x)
)
)
+
+ ;; CHECK: (func $unreachable-get-null
+ ;; CHECK-NEXT: (local $0 anyref)
+ ;; CHECK-NEXT: (local $1 i31ref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i31.new
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-get-null
+ ;; Check that we don't replace the local.get $null with a ref.null, which
+ ;; would have a more precise type.
+ (local $null-any anyref)
+ (local $null-i31 i31ref)
+ (unreachable)
+ (drop
+ (local.get $null-any)
+ )
+ (drop
+ (local.get $null-i31)
+ )
+ )
)
diff --git a/test/lit/passes/dae-gc-refine-params.wast b/test/lit/passes/dae-gc-refine-params.wast
index 3b104bdcc..a6cfb7ac5 100644
--- a/test/lit/passes/dae-gc-refine-params.wast
+++ b/test/lit/passes/dae-gc-refine-params.wast
@@ -3,27 +3,28 @@
;; RUN: wasm-opt %s -all --dae --nominal -S -o - | filecheck %s --check-prefix NOMNL
(module
+ ;; CHECK: (type ${} (struct ))
+
;; CHECK: (type ${i32} (struct (field i32)))
;; NOMNL: (type ${} (struct_subtype data))
;; NOMNL: (type ${i32} (struct_subtype (field i32) ${}))
(type ${i32} (struct_subtype (field i32) ${}))
- ;; CHECK: (type ${} (struct ))
(type ${} (struct))
+ ;; CHECK: (type ${f64} (struct (field f64)))
+
;; CHECK: (type ${i32_i64} (struct (field i32) (field i64)))
+ ;; NOMNL: (type ${f64} (struct_subtype (field f64) ${}))
+
;; NOMNL: (type ${i32_i64} (struct_subtype (field i32) (field i64) ${i32}))
(type ${i32_i64} (struct_subtype (field i32) (field i64) ${i32}))
- ;; CHECK: (type ${i32_f32} (struct (field i32) (field f32)))
-
- ;; CHECK: (type ${f64} (struct (field f64)))
- ;; NOMNL: (type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
-
- ;; NOMNL: (type ${f64} (struct_subtype (field f64) ${}))
(type ${f64} (struct_subtype (field f64) ${}))
+ ;; CHECK: (type ${i32_f32} (struct (field i32) (field f32)))
+ ;; NOMNL: (type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
(type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
;; CHECK: (func $call-various-params-no
@@ -230,7 +231,7 @@
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (struct.new_default ${})
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $2)
@@ -256,7 +257,7 @@
;; NOMNL-NEXT: (local.get $y)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
- ;; NOMNL-NEXT: (ref.null ${})
+ ;; NOMNL-NEXT: (struct.new_default ${})
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.get $2)
@@ -277,7 +278,7 @@
;; force us to do a fixup: the param will get the new type, and a new local
;; will stay at the old type, and we will use that local throughout the
;; function.
- (local.set $x (ref.null ${}))
+ (local.set $x (struct.new ${}))
(drop
(local.get $x)
)
@@ -345,32 +346,32 @@
;; CHECK: (func $call-various-params-null
;; CHECK-NEXT: (call $various-params-null
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $get_null_{i32})
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $various-params-null
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $call-various-params-null (type $none_=>_none)
;; NOMNL-NEXT: (call $various-params-null
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null ${i32})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $get_null_{i32})
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $various-params-null
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null ${i32})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null ${i32})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -388,7 +389,7 @@
)
;; This function is called in ways that allow us to make the first parameter
;; non-nullable.
- ;; CHECK: (func $various-params-null (param $x (ref ${i32})) (param $y (ref null ${i32}))
+ ;; CHECK: (func $various-params-null (param $x (ref none)) (param $y (ref null ${i32}))
;; CHECK-NEXT: (local $temp i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
@@ -400,7 +401,7 @@
;; CHECK-NEXT: (local.get $temp)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $various-params-null (type $ref|${i32}|_ref?|${i32}|_=>_none) (param $x (ref ${i32})) (param $y (ref null ${i32}))
+ ;; NOMNL: (func $various-params-null (type $ref|none|_ref?|${i32}|_=>_none) (param $x (ref none)) (param $y (ref null ${i32}))
;; NOMNL-NEXT: (local $temp i32)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.get $x)
@@ -542,7 +543,7 @@
;; CHECK: (func $call-update-null
;; CHECK-NEXT: (call $update-null
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $update-null
;; CHECK-NEXT: (struct.new_default ${})
@@ -550,7 +551,7 @@
;; CHECK-NEXT: )
;; NOMNL: (func $call-update-null (type $none_=>_none)
;; NOMNL-NEXT: (call $update-null
- ;; NOMNL-NEXT: (ref.null ${})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $update-null
;; NOMNL-NEXT: (struct.new_default ${})
@@ -585,10 +586,10 @@
)
;; CHECK: (func $get_null_{i32} (result (ref null ${i32}))
- ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; NOMNL: (func $get_null_{i32} (type $none_=>_ref?|${i32}|) (result (ref null ${i32}))
- ;; NOMNL-NEXT: (ref.null ${i32})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
(func $get_null_{i32} (result (ref null ${i32}))
;; Helper function that returns a null value of ${i32}. We use this instead of
@@ -597,20 +598,20 @@
)
;; CHECK: (func $get_null_{i32_i64} (result (ref null ${i32_i64}))
- ;; CHECK-NEXT: (ref.null ${i32_i64})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; NOMNL: (func $get_null_{i32_i64} (type $none_=>_ref?|${i32_i64}|) (result (ref null ${i32_i64}))
- ;; NOMNL-NEXT: (ref.null ${i32_i64})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
(func $get_null_{i32_i64} (result (ref null ${i32_i64}))
(ref.null ${i32_i64})
)
;; CHECK: (func $get_null_{i32_f32} (result (ref null ${i32_f32}))
- ;; CHECK-NEXT: (ref.null ${i32_f32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; NOMNL: (func $get_null_{i32_f32} (type $none_=>_ref?|${i32_f32}|) (result (ref null ${i32_f32}))
- ;; NOMNL-NEXT: (ref.null ${i32_f32})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
(func $get_null_{i32_f32} (result (ref null ${i32_f32}))
(ref.null ${i32_f32})
diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast
index 84e161651..90084b957 100644
--- a/test/lit/passes/dae-gc-refine-return.wast
+++ b/test/lit/passes/dae-gc-refine-return.wast
@@ -641,6 +641,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $tail-caller-call_ref-unreachable (type $none_=>_anyref) (result anyref)
@@ -648,6 +649,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $tail-caller-call_ref-unreachable (result anyref)
@@ -698,7 +700,7 @@
;; CHECK-NEXT: (struct.new_default ${i32_f32})
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
- ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
@@ -715,7 +717,7 @@
;; NOMNL-NEXT: (struct.new_default ${i32_f32})
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (return
- ;; NOMNL-NEXT: (ref.null ${i32})
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (return
diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast
index e6c83f0d0..d985035c4 100644
--- a/test/lit/passes/dae-gc.wast
+++ b/test/lit/passes/dae-gc.wast
@@ -159,7 +159,7 @@
;; CHECK: (func $bar (param $0 i31ref)
;; CHECK-NEXT: (local $1 anyref)
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
@@ -173,7 +173,7 @@
;; NOMNL: (func $bar (type $i31ref_=>_none) (param $0 i31ref)
;; NOMNL-NEXT: (local $1 anyref)
;; NOMNL-NEXT: (local.set $1
- ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block
;; NOMNL-NEXT: (drop
@@ -192,7 +192,7 @@
;; CHECK: (func $call-bar
;; CHECK-NEXT: (call $bar
- ;; CHECK-NEXT: (ref.null i31)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $bar
;; CHECK-NEXT: (i31.new
@@ -202,7 +202,7 @@
;; CHECK-NEXT: )
;; NOMNL: (func $call-bar (type $none_=>_none)
;; NOMNL-NEXT: (call $bar
- ;; NOMNL-NEXT: (ref.null i31)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $bar
;; NOMNL-NEXT: (i31.new
diff --git a/test/lit/passes/flatten_all-features.wast b/test/lit/passes/flatten_all-features.wast
index 934706419..7daf00914 100644
--- a/test/lit/passes/flatten_all-features.wast
+++ b/test/lit/passes/flatten_all-features.wast
@@ -3418,8 +3418,8 @@
;; CHECK: (func $subtype (result anyref)
;; CHECK-NEXT: (local $0 eqref)
;; CHECK-NEXT: (local $1 anyref)
- ;; CHECK-NEXT: (local $2 eqref)
- ;; CHECK-NEXT: (local $3 eqref)
+ ;; CHECK-NEXT: (local $2 nullref)
+ ;; CHECK-NEXT: (local $3 nullref)
;; CHECK-NEXT: (local $4 eqref)
;; CHECK-NEXT: (local $5 eqref)
;; CHECK-NEXT: (local $6 eqref)
@@ -3427,10 +3427,10 @@
;; CHECK-NEXT: (block $label0
;; CHECK-NEXT: (block
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (br_if $label0
;; CHECK-NEXT: (i32.const 0)
@@ -3513,15 +3513,14 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(module
- ;; CHECK: (type $none_=>_none (func))
(type $none_=>_none (func))
;; CHECK: (type $none_=>_funcref (func (result funcref)))
;; CHECK: (func $0 (result funcref)
- ;; CHECK-NEXT: (local $0 (ref $none_=>_none))
+ ;; CHECK-NEXT: (local $0 (ref nofunc))
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $none_=>_none)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
diff --git a/test/lit/passes/global-refining.wast b/test/lit/passes/global-refining.wast
index 4e92880b3..645b170d4 100644
--- a/test/lit/passes/global-refining.wast
+++ b/test/lit/passes/global-refining.wast
@@ -9,7 +9,7 @@
;; CHECK: (type $foo_t (func_subtype func))
(type $foo_t (func))
- ;; CHECK: (global $func-null-init (mut funcref) (ref.null $foo_t))
+ ;; CHECK: (global $func-null-init (mut funcref) (ref.null nofunc))
(global $func-null-init (mut funcref) (ref.null $foo_t))
;; CHECK: (global $func-func-init (mut (ref $foo_t)) (ref.func $foo))
(global $func-func-init (mut funcref) (ref.func $foo))
@@ -26,17 +26,17 @@
;; CHECK: (type $foo_t (func_subtype func))
(type $foo_t (func))
- ;; CHECK: (global $func-null-init (mut funcref) (ref.null $foo_t))
+ ;; CHECK: (global $func-null-init (mut funcref) (ref.null nofunc))
(global $func-null-init (mut funcref) (ref.null $foo_t))
;; CHECK: (global $func-func-init (mut (ref null $foo_t)) (ref.func $foo))
(global $func-func-init (mut funcref) (ref.func $foo))
;; CHECK: (func $foo (type $foo_t)
;; CHECK-NEXT: (global.set $func-null-init
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $func-func-init
- ;; CHECK-NEXT: (ref.null $foo_t)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo (type $foo_t)
@@ -51,7 +51,7 @@
;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (global $func-null-init (mut (ref null $none_=>_none)) (ref.null $none_=>_none))
+ ;; CHECK: (global $func-null-init (mut (ref null $none_=>_none)) (ref.null nofunc))
(global $func-null-init (mut funcref) (ref.null func))
;; CHECK: (global $func-func-init (mut (ref $none_=>_none)) (ref.func $foo))
(global $func-func-init (mut funcref) (ref.func $foo))
@@ -80,10 +80,9 @@
;; CHECK: (type $struct (struct_subtype data))
(type $struct (struct))
- ;; CHECK: (type $array (array_subtype i8 data))
(type $array (array i8))
- ;; CHECK: (global $global (mut eqref) (ref.null eq))
+ ;; CHECK: (global $global (mut eqref) (ref.null none))
(global $global (mut anyref) (ref.null any))
;; CHECK: (func $foo (type $none_=>_none)
@@ -96,13 +95,13 @@
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $global
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $global
- ;; CHECK-NEXT: (ref.null i31)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $global
- ;; CHECK-NEXT: (ref.null $array)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo
diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast
index e378fa262..9b0315df3 100644
--- a/test/lit/passes/gsi.wast
+++ b/test/lit/passes/gsi.wast
@@ -5,7 +5,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -25,27 +25,27 @@
;; CHECK: (global $global-other i32 (i32.const 123456))
(global $global-other i32 (i32.const 123456))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
;; We can infer that this get can reference either $global1 or $global2,
;; and nothing else (aside from a null), and can emit a select between
;; those values.
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -56,7 +56,7 @@
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -72,17 +72,17 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -93,7 +93,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -102,17 +102,17 @@
(i32.const 42)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -123,7 +123,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -146,17 +146,17 @@
(i32.const 99999)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -168,7 +168,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -191,24 +191,24 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -219,7 +219,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 1337)
@@ -242,24 +242,24 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -270,7 +270,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 1337)
@@ -293,24 +293,24 @@
(i32.const 42)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -321,7 +321,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -351,17 +351,17 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -373,7 +373,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -403,24 +403,24 @@
(i32.const 42)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -431,7 +431,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -447,7 +447,7 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 1)
@@ -455,11 +455,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $struct
(i32.const 1)
@@ -467,7 +467,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -479,7 +479,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (import "a" "b" (global $global-import (ref $struct)))
(import "a" "b" (global $global-import (ref $struct)))
@@ -498,24 +498,24 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -530,7 +530,7 @@
;; CHECK: (type $tuple (struct_subtype (field anyref) (field anyref) data))
(type $tuple (struct anyref anyref))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -550,7 +550,7 @@
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 999999)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: ))
(global $global-tuple (ref $tuple) (struct.new $tuple
(struct.new $struct
@@ -559,17 +559,17 @@
(ref.null any)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -584,7 +584,7 @@
;; CHECK: (type $tuple (struct_subtype (field anyref) (field anyref) data))
(type $tuple (struct anyref anyref))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -601,32 +601,32 @@
))
;; CHECK: (global $global-tuple (ref $tuple) (struct.new $tuple
- ;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: ))
(global $global-tuple (ref $tuple) (struct.new $tuple
(ref.null any)
(ref.null any)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -637,7 +637,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -653,17 +653,17 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -674,7 +674,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct_subtype i32 data))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (type $sub-struct (struct_subtype (field i32) $struct))
(type $sub-struct (struct_subtype i32 $struct))
@@ -693,7 +693,7 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $sub-struct
;; CHECK-NEXT: (i32.const 999999)
@@ -701,11 +701,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $sub-struct
(i32.const 999999)
@@ -713,7 +713,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -728,7 +728,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) $super-struct))
(type $struct (struct_subtype i32 $super-struct))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.const 42)
@@ -744,7 +744,7 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $super-struct
;; CHECK-NEXT: (i32.const 999999)
@@ -756,14 +756,14 @@
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.new $super-struct
(i32.const 999999)
@@ -771,7 +771,7 @@
)
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -786,7 +786,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) $super-struct))
(type $struct (struct_subtype i32 $super-struct))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_ref?|$super-struct|_=>_none (func_subtype (param (ref null $struct) (ref null $super-struct)) func))
;; CHECK: (global $global1 (ref $super-struct) (struct.new $super-struct
;; CHECK-NEXT: (i32.const 42)
@@ -802,10 +802,10 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_ref?|$super-struct|_=>_none) (param $struct (ref null $struct)) (param $super-struct (ref null $super-struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -814,25 +814,25 @@
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $super-struct)
+ ;; CHECK-NEXT: (local.get $super-struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct)) (param $super-struct (ref null $super-struct))
;; We cannot optimize the first - it has just one global - but the second
;; will consider the struct and sub-struct, find 2 possible values, and
;; optimize.
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
(drop
(struct.get $super-struct 0
- (ref.null $super-struct)
+ (local.get $super-struct)
)
)
)
@@ -843,7 +843,7 @@
;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (global $global1 (ref $struct) (struct.new $struct
;; CHECK-NEXT: (i32.add
@@ -865,17 +865,17 @@
(i32.const 1337)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $struct (ref null $struct))
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -894,7 +894,7 @@
(type $struct2 (struct_subtype i32 f64 $super-struct))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$super-struct|_ref?|$struct1|_ref?|$struct2|_=>_none (func_subtype (param (ref null $super-struct) (ref null $struct1) (ref null $struct2)) func))
;; CHECK: (global $global0 (ref $super-struct) (struct.new $super-struct
;; CHECK-NEXT: (i32.const 42)
@@ -921,40 +921,40 @@
(f64.const 2.71828)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$super-struct|_ref?|$struct1|_ref?|$struct2|_=>_none) (param $super-struct (ref null $super-struct)) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $super-struct 0
- ;; CHECK-NEXT: (ref.null $super-struct)
+ ;; CHECK-NEXT: (local.get $super-struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct1 0
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct2 0
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $super-struct (ref null $super-struct)) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2))
;; This has three possible values due to the two children, so we do not
;; optimize.
(drop
(struct.get $super-struct 0
- (ref.null $super-struct)
+ (local.get $super-struct)
)
)
;; These each have one possible value, so we also do not optimize.
(drop
(struct.get $struct1 0
- (ref.null $struct1)
+ (local.get $struct1)
)
)
(drop
(struct.get $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
)
)
)
@@ -972,7 +972,7 @@
(type $struct2 (struct_subtype i32 f64 $super-struct))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$super-struct|_ref?|$struct1|_ref?|$struct2|_=>_none (func_subtype (param (ref null $super-struct) (ref null $struct1) (ref null $struct2)) func))
;; CHECK: (global $global0 (ref $super-struct) (struct.new $super-struct
;; CHECK-NEXT: (i32.const 42)
@@ -1017,10 +1017,10 @@
(f64.const 2.71828)
))
- ;; CHECK: (func $test (type $none_=>_none)
+ ;; CHECK: (func $test (type $ref?|$super-struct|_ref?|$struct1|_ref?|$struct2|_=>_none) (param $super-struct (ref null $super-struct)) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $super-struct 0
- ;; CHECK-NEXT: (ref.null $super-struct)
+ ;; CHECK-NEXT: (local.get $super-struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -1029,7 +1029,7 @@
;; CHECK-NEXT: (i32.const 1338)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct1)
+ ;; CHECK-NEXT: (local.get $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
@@ -1041,29 +1041,29 @@
;; CHECK-NEXT: (i32.const 99998)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct2)
+ ;; CHECK-NEXT: (local.get $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $test
+ (func $test (param $super-struct (ref null $super-struct)) (param $struct1 (ref null $struct1)) (param $struct2 (ref null $struct2))
;; This still cannot be optimized.
(drop
(struct.get $super-struct 0
- (ref.null $super-struct)
+ (local.get $super-struct)
)
)
;; These can be optimized, and will be different from one another.
(drop
(struct.get $struct1 0
- (ref.null $struct1)
+ (local.get $struct1)
)
)
(drop
(struct.get $struct2 0
- (ref.null $struct2)
+ (local.get $struct2)
)
)
)
diff --git a/test/lit/passes/gto-mutability.wast b/test/lit/passes/gto-mutability.wast
index 4ecab4f8c..edcf43bb2 100644
--- a/test/lit/passes/gto-mutability.wast
+++ b/test/lit/passes/gto-mutability.wast
@@ -20,7 +20,7 @@
;; CHECK: (type $none_=>_ref?|$struct| (func_subtype (result (ref null $struct)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (table $0 0 funcref)
@@ -33,18 +33,18 @@
;; CHECK-NEXT: (local $temp (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
- ;; CHECK-NEXT: (ref.null func)
- ;; CHECK-NEXT: (ref.null func)
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 2
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $temp
;; CHECK-NEXT: (local.get $x)
@@ -108,7 +108,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
(func $foo (result (ref null $struct))
;; Use a tag so that we test proper updating of its type after making
@@ -153,17 +153,17 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 2
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
+ (func $field-keepalive (param $struct (ref null $struct))
;; --gto will remove fields that are not read from, so add reads to any
;; that don't already have them.
- (drop (struct.get $struct 2 (ref.null $struct)))
+ (drop (struct.get $struct 2 (local.get $struct)))
)
)
@@ -178,12 +178,12 @@
;; CHECK: (type $ref|$A|_=>_none (func_subtype (param (ref $A)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func_subtype (param (ref null $A) (ref null $B)) func))
;; CHECK: (func $func (type $ref|$A|_=>_none) (param $x (ref $A))
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 1
;; CHECK-NEXT: (local.get $x)
@@ -201,33 +201,33 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$A|_ref?|$B|_=>_none) (param $A (ref null $A)) (param $B (ref null $B))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $A 1
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $B 0
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $B 1
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $A 0 (ref.null $A)))
- (drop (struct.get $A 1 (ref.null $A)))
- (drop (struct.get $B 0 (ref.null $B)))
- (drop (struct.get $B 1 (ref.null $B)))
+ (func $field-keepalive (param $A (ref null $A)) (param $B (ref null $B))
+ (drop (struct.get $A 0 (local.get $A)))
+ (drop (struct.get $A 1 (local.get $A)))
+ (drop (struct.get $B 0 (local.get $B)))
+ (drop (struct.get $B 1 (local.get $B)))
)
)
@@ -242,12 +242,12 @@
;; CHECK: (type $ref|$B|_=>_none (func_subtype (param (ref $B)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func_subtype (param (ref null $A) (ref null $B)) func))
;; CHECK: (func $func (type $ref|$B|_=>_none) (param $x (ref $B))
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $B 1
;; CHECK-NEXT: (local.get $x)
@@ -265,53 +265,54 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$A|_ref?|$B|_=>_none) (param $A (ref null $A)) (param $B (ref null $B))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $A 1
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $B 0
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $B 1
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $A 0 (ref.null $A)))
- (drop (struct.get $A 1 (ref.null $A)))
- (drop (struct.get $B 0 (ref.null $B)))
- (drop (struct.get $B 1 (ref.null $B)))
+ (func $field-keepalive (param $A (ref null $A)) (param $B (ref null $B))
+ (drop (struct.get $A 0 (local.get $A)))
+ (drop (struct.get $A 1 (local.get $A)))
+ (drop (struct.get $B 0 (local.get $B)))
+ (drop (struct.get $B 1 (local.get $B)))
)
)
(module
;; As before, but now one field in each can become immutable.
+ ;; CHECK: (type $A (struct_subtype (field (mut (ref null $B))) (field i32) data))
+
;; CHECK: (type $B (struct_subtype (field (ref null $A)) (field (mut f64)) data))
(type $B (struct (field (mut (ref null $A))) (field (mut f64)) ))
- ;; CHECK: (type $A (struct_subtype (field (mut (ref null $B))) (field i32) data))
(type $A (struct (field (mut (ref null $B))) (field (mut i32)) ))
;; CHECK: (type $ref|$A|_ref|$B|_=>_none (func_subtype (param (ref $A) (ref $B)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func_subtype (param (ref null $A) (ref null $B)) func))
;; CHECK: (func $func (type $ref|$A|_ref|$B|_=>_none) (param $x (ref $A)) (param $y (ref $B))
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $B 1
;; CHECK-NEXT: (local.get $y)
@@ -329,33 +330,33 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$A|_ref?|$B|_=>_none) (param $A (ref null $A)) (param $B (ref null $B))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $A 1
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $B 0
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $B 1
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $A 0 (ref.null $A)))
- (drop (struct.get $A 1 (ref.null $A)))
- (drop (struct.get $B 0 (ref.null $B)))
- (drop (struct.get $B 1 (ref.null $B)))
+ (func $field-keepalive (param $A (ref null $A)) (param $B (ref null $B))
+ (drop (struct.get $A 0 (local.get $A)))
+ (drop (struct.get $A 1 (local.get $A)))
+ (drop (struct.get $B 0 (local.get $B)))
+ (drop (struct.get $B 1 (local.get $B)))
)
)
@@ -369,7 +370,7 @@
;; CHECK: (type $ref|$struct|_=>_none (func_subtype (param (ref $struct)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct))
;; CHECK-NEXT: (struct.set $struct 2
@@ -384,27 +385,27 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 1
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 2
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $struct 0 (ref.null $struct)))
- (drop (struct.get $struct 1 (ref.null $struct)))
- (drop (struct.get $struct 2 (ref.null $struct)))
+ (func $field-keepalive (param $struct (ref null $struct))
+ (drop (struct.get $struct 0 (local.get $struct)))
+ (drop (struct.get $struct 1 (local.get $struct)))
+ (drop (struct.get $struct 2 (local.get $struct)))
)
)
@@ -419,6 +420,8 @@
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$super|_ref?|$sub|_=>_none (func_subtype (param (ref null $super) (ref null $sub)) func))
+
;; CHECK: (func $func (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $super
@@ -445,21 +448,21 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$super|_ref?|$sub|_=>_none) (param $super (ref null $super)) (param $sub (ref null $sub))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $super 0
- ;; CHECK-NEXT: (ref.null $super)
+ ;; CHECK-NEXT: (local.get $super)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $sub 0
- ;; CHECK-NEXT: (ref.null $sub)
+ ;; CHECK-NEXT: (local.get $sub)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $super 0 (ref.null $super)))
- (drop (struct.get $sub 0 (ref.null $sub)))
+ (func $field-keepalive (param $super (ref null $super)) (param $sub (ref null $sub))
+ (drop (struct.get $super 0 (local.get $super)))
+ (drop (struct.get $sub 0 (local.get $sub)))
)
)
@@ -473,7 +476,7 @@
;; CHECK: (type $ref|$super|_=>_none (func_subtype (param (ref $super)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$super|_ref?|$sub|_=>_none (func_subtype (param (ref null $super) (ref null $sub)) func))
;; CHECK: (func $func (type $ref|$super|_=>_none) (param $x (ref $super))
;; CHECK-NEXT: (drop
@@ -509,21 +512,21 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$super|_ref?|$sub|_=>_none) (param $super (ref null $super)) (param $sub (ref null $sub))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $super 0
- ;; CHECK-NEXT: (ref.null $super)
+ ;; CHECK-NEXT: (local.get $super)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $sub 0
- ;; CHECK-NEXT: (ref.null $sub)
+ ;; CHECK-NEXT: (local.get $sub)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $super 0 (ref.null $super)))
- (drop (struct.get $sub 0 (ref.null $sub)))
+ (func $field-keepalive (param $super (ref null $super)) (param $sub (ref null $sub))
+ (drop (struct.get $super 0 (local.get $super)))
+ (drop (struct.get $sub 0 (local.get $sub)))
)
)
@@ -538,7 +541,7 @@
;; CHECK: (type $ref|$sub|_=>_none (func_subtype (param (ref $sub)) func))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$super|_ref?|$sub|_=>_none (func_subtype (param (ref null $super) (ref null $sub)) func))
;; CHECK: (func $func (type $ref|$sub|_=>_none) (param $x (ref $sub))
;; CHECK-NEXT: (struct.set $sub 0
@@ -553,20 +556,20 @@
)
)
- ;; CHECK: (func $field-keepalive (type $none_=>_none)
+ ;; CHECK: (func $field-keepalive (type $ref?|$super|_ref?|$sub|_=>_none) (param $super (ref null $super)) (param $sub (ref null $sub))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $super 0
- ;; CHECK-NEXT: (ref.null $super)
+ ;; CHECK-NEXT: (local.get $super)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $sub 0
- ;; CHECK-NEXT: (ref.null $sub)
+ ;; CHECK-NEXT: (local.get $sub)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $field-keepalive
- (drop (struct.get $super 0 (ref.null $super)))
- (drop (struct.get $sub 0 (ref.null $sub)))
+ (func $field-keepalive (param $super (ref null $super)) (param $sub (ref null $sub))
+ (drop (struct.get $super 0 (local.get $super)))
+ (drop (struct.get $sub 0 (local.get $sub)))
)
)
diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast
index 5dd6ab4d1..184359f49 100644
--- a/test/lit/passes/gto-removals.wast
+++ b/test/lit/passes/gto-removals.wast
@@ -32,7 +32,7 @@
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (block (result (ref $struct))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
@@ -405,6 +405,8 @@
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref|any|_ref?|$struct|_=>_none (func_subtype (param (ref any) (ref null $struct)) func))
+
;; CHECK: (type $ref|any|_=>_none (func_subtype (param (ref any)) func))
;; CHECK: (type $i32_=>_i32 (func_subtype (param i32) (result i32) func))
@@ -419,18 +421,18 @@
;; CHECK: (global $mut-i32 (mut i32) (i32.const 5678))
(global $mut-i32 (mut i32) (i32.const 5678))
- ;; CHECK: (func $gets (type $ref|any|_=>_none) (param $x (ref any))
+ ;; CHECK: (func $gets (type $ref|any|_ref?|$struct|_=>_none) (param $x (ref any)) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $gets (param $x (ref any))
+ (func $gets (param $x (ref any)) (param $struct (ref null $struct))
;; Gets to keep certain fields alive.
(drop
(struct.get $struct 0
- (ref.null $struct)
+ (local.get $struct)
)
)
)
@@ -562,6 +564,7 @@
;; CHECK-NEXT: (i32.const 3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -781,43 +784,45 @@
;; CHECK: (type ${mut:i8} (struct_subtype data))
(type ${mut:i8} (struct_subtype (field (mut i8)) data))
+ ;; CHECK: (type $ref?|${mut:i8}|_=>_none (func_subtype (param (ref null ${mut:i8})) func))
+
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (type $none_=>_i32 (func_subtype (result i32) func))
;; CHECK: (type $none_=>_ref|${mut:i8}| (func_subtype (result (ref ${mut:i8})) func))
- ;; CHECK: (func $unreachable-set (type $none_=>_none)
+ ;; CHECK: (func $unreachable-set (type $ref?|${mut:i8}|_=>_none) (param ${mut:i8} (ref null ${mut:i8}))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (block (result (ref null ${mut:i8}))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $helper-i32)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null ${mut:i8})
+ ;; CHECK-NEXT: (local.get ${mut:i8})
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $unreachable-set
+ (func $unreachable-set (param ${mut:i8} (ref null ${mut:i8}))
;; The struct type has no reads, so we want to remove all of the sets of it.
;; This struct.set will trap on null, but first the call must run. When we
;; optimize here we should be careful to not emit something with different
;; ordering (naively emitting ref.as_non_null on the reference would trap
;; before the call, so we must reorder).
(struct.set ${mut:i8} 0
- (ref.null ${mut:i8})
+ (local.get ${mut:i8})
(call $helper-i32)
)
)
- ;; CHECK: (func $unreachable-set-2 (type $none_=>_none)
+ ;; CHECK: (func $unreachable-set-2 (type $ref?|${mut:i8}|_=>_none) (param ${mut:i8} (ref null ${mut:i8}))
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null ${mut:i8})
+ ;; CHECK-NEXT: (local.get ${mut:i8})
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br $block)
@@ -827,24 +832,24 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $unreachable-set-2
+ (func $unreachable-set-2 (param ${mut:i8} (ref null ${mut:i8}))
;; As above, but the side effects now are a br. Again, the br must happen
;; before the trap (in fact, the br will skip the trap here).
(block
(struct.set ${mut:i8} 0
- (ref.null ${mut:i8})
+ (local.get ${mut:i8})
(br $block)
)
)
)
- ;; CHECK: (func $unreachable-set-2b (type $none_=>_none)
+ ;; CHECK: (func $unreachable-set-2b (type $ref?|${mut:i8}|_=>_none) (param ${mut:i8} (ref null ${mut:i8}))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null ${mut:i8})
+ ;; CHECK-NEXT: (local.get ${mut:i8})
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
@@ -853,14 +858,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $unreachable-set-2b
+ (func $unreachable-set-2b (param ${mut:i8} (ref null ${mut:i8}))
;; As above, but with an unreachable instead of a br. We add a nop here so
;; that we are inside of a block, and then validation would fail if we do
;; not keep the type of the replacement for the struct.set identical to the
;; struct.set. That is, the type must remain unreachable.
(nop)
(struct.set ${mut:i8} 0
- (ref.null ${mut:i8})
+ (local.get ${mut:i8})
(unreachable)
)
)
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 905ce0a80..f75b0dd96 100644
--- a/test/lit/passes/gufa-refs.wast
+++ b/test/lit/passes/gufa-refs.wast
@@ -322,10 +322,10 @@
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $z)
@@ -369,19 +369,19 @@
;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (global $null anyref (ref.null any))
+ ;; CHECK: (global $null anyref (ref.null none))
(global $null (ref null any) (ref.null any))
;; CHECK: (global $something anyref (struct.new_default $struct))
(global $something (ref null any) (struct.new $struct))
- ;; CHECK: (global $mut-null (mut anyref) (ref.null any))
+ ;; CHECK: (global $mut-null (mut anyref) (ref.null none))
(global $mut-null (mut (ref null any)) (ref.null any))
- ;; CHECK: (global $mut-something (mut anyref) (ref.null any))
+ ;; CHECK: (global $mut-something (mut anyref) (ref.null none))
(global $mut-something (mut (ref null any)) (ref.null any))
;; CHECK: (func $read-globals (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
@@ -439,7 +439,7 @@
;; CHECK: (func $write-globals (type $none_=>_none)
;; CHECK-NEXT: (global.set $mut-null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $mut-something
;; CHECK-NEXT: (struct.new_default $struct)
@@ -465,19 +465,19 @@
;; CHECK: (type $struct (struct_subtype data))
(type $struct (struct))
- ;; CHECK: (global $A-null anyref (ref.null any))
+ ;; CHECK: (global $A-null anyref (ref.null none))
(global $A-null (ref null any) (ref.null any))
;; CHECK: (global $A-something anyref (struct.new_default $struct))
(global $A-something (ref null any) (struct.new $struct))
- ;; CHECK: (global $B-null (mut anyref) (ref.null any))
+ ;; CHECK: (global $B-null (mut anyref) (ref.null none))
(global $B-null (mut (ref null any)) (ref.null any))
- ;; CHECK: (global $B-something (mut anyref) (ref.null any))
+ ;; CHECK: (global $B-something (mut anyref) (ref.null none))
(global $B-something (mut (ref null any)) (ref.null any))
- ;; CHECK: (global $C-null (mut anyref) (ref.null any))
+ ;; CHECK: (global $C-null (mut anyref) (ref.null none))
(global $C-null (mut (ref null any)) (ref.null any))
- ;; CHECK: (global $C-something (mut anyref) (ref.null any))
+ ;; CHECK: (global $C-something (mut anyref) (ref.null none))
(global $C-something (mut (ref null any)) (ref.null any))
;; CHECK: (func $read-globals (type $none_=>_none)
@@ -541,10 +541,10 @@
;; CHECK: (func $write-globals (type $none_=>_none)
;; CHECK-NEXT: (global.set $B-null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $C-null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $B-something
;; CHECK-NEXT: (global.get $A-something)
@@ -946,7 +946,7 @@
;; CHECK-NEXT: (local.set $child
;; CHECK-NEXT: (struct.new $child
;; CHECK-NEXT: (struct.new_default $struct)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -955,28 +955,28 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $child 1
;; CHECK-NEXT: (local.get $child)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $parent
;; CHECK-NEXT: (struct.new $parent
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $parent 0
;; CHECK-NEXT: (local.get $parent)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -1071,55 +1071,55 @@
;; CHECK: (func $nulls (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $parent)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $block (result anyref)
+ ;; CHECK-NEXT: (block $block (result nullref)
;; CHECK-NEXT: (br $block
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $child))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $block0 (result (ref null $child))
+ ;; CHECK-NEXT: (block $block0 (result nullref)
;; CHECK-NEXT: (br $block0
- ;; CHECK-NEXT: (ref.null $child)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $child)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $child))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $block1 (result (ref null $child))
+ ;; CHECK-NEXT: (block $block1 (result nullref)
;; CHECK-NEXT: (br $block1
- ;; CHECK-NEXT: (block (result (ref null $child))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $child
- ;; CHECK-NEXT: (ref.null $parent)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $child)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $child)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1207,11 +1207,13 @@
;; Exact types: Writes to the parent class do not confuse us.
(module
+ ;; CHECK: (type $parent (struct_subtype (field (mut (ref null $struct))) data))
+
+ ;; CHECK: (type $child (struct_subtype (field (mut (ref null $struct))) (field i32) $parent))
+
;; CHECK: (type $struct (struct_subtype data))
(type $struct (struct_subtype data))
- ;; CHECK: (type $parent (struct_subtype (field (mut (ref null $struct))) data))
(type $parent (struct_subtype (field (mut (ref null $struct))) data))
- ;; CHECK: (type $child (struct_subtype (field (mut (ref null $struct))) (field i32) $parent))
(type $child (struct_subtype (field (mut (ref null $struct))) (field i32) $parent))
;; CHECK: (type $none_=>_none (func_subtype func))
@@ -1233,20 +1235,20 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $child
;; CHECK-NEXT: (struct.new $child
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $child 0
;; CHECK-NEXT: (local.get $child)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -1558,12 +1560,12 @@
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (array.get $null
;; CHECK-NEXT: (array.new_default $null
@@ -1572,7 +1574,7 @@
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -1683,7 +1685,7 @@
;; CHECK: (type $anyref_=>_anyref (func_subtype (param anyref) (result anyref) func))
- ;; CHECK: (global $x (mut anyref) (ref.null any))
+ ;; CHECK: (global $x (mut anyref) (ref.null none))
(global $x (mut (ref null any)) (ref.null any))
;; CHECK: (func $foo (type $none_=>_none)
@@ -1752,29 +1754,29 @@
;; CHECK: (type $anyref_=>_anyref (func_subtype (param anyref) (result anyref) func))
- ;; CHECK: (global $x (mut anyref) (ref.null any))
+ ;; CHECK: (global $x (mut anyref) (ref.null none))
(global $x (mut (ref null any)) (ref.null any))
;; CHECK: (func $foo (type $none_=>_none)
;; CHECK-NEXT: (local $x anyref)
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.set $x
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $storage
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $pass-through
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -1806,7 +1808,7 @@
)
;; CHECK: (func $pass-through (type $anyref_=>_anyref) (param $x anyref) (result anyref)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
(func $pass-through (param $x (ref null any)) (result (ref null any))
(local.get $x)
@@ -1827,7 +1829,7 @@
;; CHECK: (type $anyref_=>_anyref (func_subtype (param anyref) (result anyref) func))
- ;; CHECK: (global $x (mut anyref) (ref.null any))
+ ;; CHECK: (global $x (mut anyref) (ref.null none))
(global $x (mut (ref null any)) (ref.null any))
;; CHECK: (func $foo (type $none_=>_none)
@@ -1885,11 +1887,11 @@
(module
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $anyref_=>_none (func_subtype (param anyref) func))
+
;; CHECK: (type $struct (struct_subtype data))
(type $struct (struct))
- ;; CHECK: (type $anyref_=>_none (func_subtype (param anyref) func))
-
;; CHECK: (tag $nothing (param anyref))
(tag $nothing (param (ref null any)))
@@ -1902,7 +1904,7 @@
;; CHECK: (func $func (type $none_=>_none)
;; CHECK-NEXT: (local $0 anyref)
;; CHECK-NEXT: (throw $nothing
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (try $try
;; CHECK-NEXT: (do
@@ -1915,11 +1917,11 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -2117,20 +2119,20 @@
;; Exceptions with a tuple
(module
- ;; CHECK: (type $struct (struct_subtype data))
- (type $struct (struct))
-
;; CHECK: (type $anyref_anyref_=>_none (func_subtype (param anyref anyref) func))
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $struct (struct_subtype data))
+ (type $struct (struct))
+
;; CHECK: (tag $tag (param anyref anyref))
(tag $tag (param (ref null any)) (param (ref null any)))
;; CHECK: (func $func (type $none_=>_none)
;; CHECK-NEXT: (local $0 (anyref anyref))
;; CHECK-NEXT: (throw $tag
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (try $try
@@ -2142,11 +2144,11 @@
;; CHECK-NEXT: (pop anyref anyref)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2196,16 +2198,16 @@
)
(module
+ ;; CHECK: (type $none_=>_ref|${}| (func_subtype (result (ref ${})) func))
+
;; CHECK: (type ${} (struct_subtype data))
(type ${} (struct_subtype data))
- ;; CHECK: (type $none_=>_ref|${}| (func_subtype (result (ref ${})) func))
-
;; CHECK: (func $func (type $none_=>_ref|${}|) (result (ref ${}))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $block (result (ref ${}))
+ ;; CHECK-NEXT: (block $block (result (ref none))
;; CHECK-NEXT: (br_on_non_null $block
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
@@ -2312,7 +2314,7 @@
;; CHECK: (global $global-A (ref $vtable-A) (struct.new $vtable-A
;; CHECK-NEXT: (ref.func $foo)
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: ))
(global $global-A (ref $vtable-A)
@@ -2330,7 +2332,7 @@
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $vtable-A 2
@@ -2366,7 +2368,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $vtable-A
;; CHECK-NEXT: (ref.func $foo)
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: (ref.func $test)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2526,24 +2528,24 @@
;; CHECK: (func $test-nulls (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $struct
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $struct
- ;; CHECK-NEXT: (select (result eqref)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (select (result i31ref)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (i31.new
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
@@ -2554,7 +2556,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (select (result (ref null $struct))
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 6)
;; CHECK-NEXT: )
@@ -2646,11 +2648,11 @@
;; CHECK: (func $ref.test-inexact (type $i32_=>_none) (param $x i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.test_static $struct
- ;; CHECK-NEXT: (select (result anyref)
+ ;; CHECK-NEXT: (select (result (ref null $struct))
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2819,8 +2821,8 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (ref.null $struct)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -2874,7 +2876,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -3002,19 +3004,19 @@
;; CHECK-NEXT: (local $x eqref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (ref.null eq)
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (block (result (ref null $struct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -3448,7 +3450,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $chars
;; CHECK-NEXT: (array.init_static $chars
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (array.copy $chars $bytes
@@ -3533,7 +3535,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $chars
;; CHECK-NEXT: (array.init_static $chars
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (array.copy $bytes $chars
@@ -3550,14 +3552,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (array.get $chars
;; CHECK-NEXT: (local.get $chars)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -3605,11 +3607,13 @@
;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $i32_=>_none (func_subtype (param i32) func))
-
;; CHECK: (type $B (array_subtype (mut anyref) data))
(type $B (array (mut anyref)))
+ ;; CHECK: (type $i32_=>_none (func_subtype (param i32) func))
+
+ ;; CHECK: (type $ref|$B|_=>_none (func_subtype (param (ref $B)) func))
+
;; CHECK: (memory $0 10)
;; CHECK: (table $t 0 externref)
@@ -3861,7 +3865,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (table.grow $t
- ;; CHECK-NEXT: (ref.null extern)
+ ;; CHECK-NEXT: (ref.null noextern)
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -3902,17 +3906,23 @@
)
)
- ;; CHECK: (func $arrays (type $none_=>_none)
+ ;; CHECK: (func $arrays (type $ref|$B|_=>_none) (param $B (ref $B))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (array.len $B
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (array.init_static $B
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $arrays
+ (func $arrays (param $B (ref $B))
(drop
(array.len $B
- (ref.null $B)
+ (array.init_static $B
+ (ref.null none)
+ (ref.null none)
+ )
)
)
)
diff --git a/test/lit/passes/gufa-vs-cfp.wast b/test/lit/passes/gufa-vs-cfp.wast
index 9cb74fbe7..623d25679 100644
--- a/test/lit/passes/gufa-vs-cfp.wast
+++ b/test/lit/passes/gufa-vs-cfp.wast
@@ -456,6 +456,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
@@ -464,11 +465,13 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $test
@@ -599,11 +602,11 @@
(module
;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
;; CHECK: (type $substruct (struct_subtype (field (mut i32)) $struct))
(type $substruct (struct_subtype (mut i32) $struct))
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (local $ref (ref null $struct))
;; CHECK-NEXT: (local.set $ref
@@ -618,13 +621,13 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $substruct))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $substruct
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $substruct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -1015,7 +1018,7 @@
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct3))
@@ -1081,13 +1084,13 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct3 2
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1178,7 +1181,7 @@
;; CHECK-NEXT: (i32.const 999)
;; CHECK-NEXT: (f64.const 2.71828)
;; CHECK-NEXT: (f64.const 9.9999999)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1323,11 +1326,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result anyref)
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $create3)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -1421,7 +1424,7 @@
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
@@ -1726,7 +1729,7 @@
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
@@ -1842,7 +1845,7 @@
;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
@@ -2629,7 +2632,7 @@
;; CHECK: (global $global (ref $itable) (array.init_static $itable
;; CHECK-NEXT: (struct.new $vtable
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.new $vtable
;; CHECK-NEXT: (ref.func $test)
diff --git a/test/lit/passes/gufa.wast b/test/lit/passes/gufa.wast
index ae86e3b84..a1ac729c3 100644
--- a/test/lit/passes/gufa.wast
+++ b/test/lit/passes/gufa.wast
@@ -1001,7 +1001,7 @@
;; CHECK: (type $funcref_=>_none (func (param funcref)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $ref?|$A|_=>_none (func (param (ref null $A))))
;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param i32 funcref)))
(import "binaryen-intrinsics" "call.without.effects"
@@ -1015,10 +1015,10 @@
;; CHECK: (export "foo" (func $foo))
- ;; CHECK: (func $foo
+ ;; CHECK: (func $foo (param $A (ref null $A))
;; CHECK-NEXT: (call $call-without-effects
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-keep)
@@ -1027,14 +1027,14 @@
;; CHECK-NEXT: (ref.func $target-keep-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $foo (export "foo")
+ (func $foo (export "foo") (param $A (ref null $A))
;; Call the intrinsic without a RefFunc. All we infer here is the type,
;; which means we must assume anything with type $A (and a reference) can be
;; called, which will keep alive the bodies of both $target-keep and
;; $target-keep-2 - no unreachables will be placed in either one.
(call $call-without-effects
(i32.const 1)
- (ref.null $A)
+ (local.get $A)
)
(drop
(ref.func $target-keep)
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast
index 6fd744278..aace567f7 100644
--- a/test/lit/passes/heap2local.wast
+++ b/test/lit/passes/heap2local.wast
@@ -11,34 +11,30 @@
;; CHECK: (type $struct.recursive (struct (field (mut (ref null $struct.recursive)))))
- ;; CHECK: (type $struct.nondefaultable (struct (field (ref $struct.A))))
-
;; CHECK: (type $struct.packed (struct (field (mut i8))))
;; NOMNL: (type $struct.recursive (struct_subtype (field (mut (ref null $struct.recursive))) data))
;; NOMNL: (type $struct.packed (struct_subtype (field (mut i8)) data))
(type $struct.packed (struct (field (mut i8))))
- ;; NOMNL: (type $struct.nondefaultable (struct_subtype (field (ref $struct.A)) data))
(type $struct.nondefaultable (struct (field (ref $struct.A))))
(type $struct.recursive (struct (field (mut (ref null $struct.recursive)))))
- ;; NOMNL: (type $struct.nonnullable (struct_subtype (field (ref $struct.A)) data))
(type $struct.nonnullable (struct (field (ref $struct.A))))
;; CHECK: (func $simple
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (local $1 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -46,14 +42,14 @@
;; NOMNL-NEXT: (local $0 i32)
;; NOMNL-NEXT: (local $1 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $0
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -70,14 +66,14 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -86,14 +82,14 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -114,14 +110,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
@@ -134,14 +130,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $0
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $0)
@@ -167,14 +163,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
@@ -187,14 +183,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $0
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $1)
@@ -214,14 +210,14 @@
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (local $1 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $0
@@ -232,14 +228,14 @@
;; NOMNL-NEXT: (local $0 i32)
;; NOMNL-NEXT: (local $1 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $0
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $0
@@ -285,7 +281,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: )
@@ -298,7 +294,7 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
@@ -313,7 +309,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (i32.const 2)
;; NOMNL-NEXT: )
@@ -326,7 +322,7 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $0)
@@ -357,8 +353,10 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -373,8 +371,10 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -397,14 +397,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref $struct.A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.nondefaultable))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.nondefaultable)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
@@ -417,14 +417,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result (ref $struct.A))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.nondefaultable))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $0
;; NOMNL-NEXT: (local.get $1)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.nondefaultable)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $0)
@@ -447,19 +447,19 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 1)
@@ -471,19 +471,19 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 1)
@@ -509,19 +509,19 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -531,19 +531,19 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -573,22 +573,22 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -598,22 +598,22 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -675,26 +675,26 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref null $struct.A))
;; CHECK-NEXT: (block (result (ref null $struct.A))
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -704,26 +704,26 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result (ref null $struct.A))
;; NOMNL-NEXT: (block (result (ref null $struct.A))
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -847,22 +847,22 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -872,22 +872,22 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -912,23 +912,23 @@
;; CHECK-NEXT: (local $2 i32)
;; CHECK-NEXT: (local $3 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -936,7 +936,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
@@ -948,23 +948,23 @@
;; NOMNL-NEXT: (local $2 i32)
;; NOMNL-NEXT: (local $3 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -972,7 +972,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
@@ -1006,25 +1006,25 @@
;; CHECK-NEXT: (local $2 i32)
;; CHECK-NEXT: (local $3 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
@@ -1034,25 +1034,25 @@
;; NOMNL-NEXT: (local $2 i32)
;; NOMNL-NEXT: (local $3 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (if
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
@@ -1080,23 +1080,23 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref null $struct.A))
;; CHECK-NEXT: (call $send-ref
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
@@ -1107,23 +1107,23 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result (ref null $struct.A))
;; NOMNL-NEXT: (call $send-ref
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
@@ -1154,7 +1154,7 @@
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $struct.A 1
@@ -1169,7 +1169,7 @@
;; NOMNL-NEXT: (if
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: (local.set $ref
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $struct.A 1
@@ -1198,14 +1198,14 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
@@ -1215,14 +1215,14 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $1)
@@ -1241,30 +1241,30 @@
;; CHECK-NEXT: (local $ref (ref null $struct.recursive))
;; CHECK-NEXT: (local $1 (ref null $struct.recursive))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.recursive))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null $struct.recursive)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.recursive)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null $struct.recursive)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $tee-set (type $none_=>_none)
;; NOMNL-NEXT: (local $ref (ref null $struct.recursive))
;; NOMNL-NEXT: (local $1 (ref null $struct.recursive))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
- ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
- ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $tee-set
@@ -1278,28 +1278,28 @@
)
)
- ;; CHECK: (func $set-value
+ ;; CHECK: (func $set-value (param $struct.recursive (ref null $struct.recursive))
;; CHECK-NEXT: (local $ref (ref null $struct.recursive))
;; CHECK-NEXT: (struct.set $struct.recursive 0
- ;; CHECK-NEXT: (ref.null $struct.recursive)
+ ;; CHECK-NEXT: (local.get $struct.recursive)
;; CHECK-NEXT: (local.tee $ref
;; CHECK-NEXT: (struct.new_default $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $set-value (type $none_=>_none)
+ ;; NOMNL: (func $set-value (type $ref?|$struct.recursive|_=>_none) (param $struct.recursive (ref null $struct.recursive))
;; NOMNL-NEXT: (local $ref (ref null $struct.recursive))
;; NOMNL-NEXT: (struct.set $struct.recursive 0
- ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (local.get $struct.recursive)
;; NOMNL-NEXT: (local.tee $ref
;; NOMNL-NEXT: (struct.new_default $struct.recursive)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- (func $set-value
+ (func $set-value (param $struct.recursive (ref null $struct.recursive))
(local $ref (ref null $struct.recursive))
(struct.set $struct.recursive 0
- (ref.null $struct.recursive)
+ (local.get $struct.recursive)
;; As above, but operands reversed: the allocation is now the value, not
;; the reference, and so it escapes.
(local.tee $ref
@@ -1313,20 +1313,20 @@
;; CHECK-NEXT: (local $1 (ref null $struct.recursive))
;; CHECK-NEXT: (local $2 (ref null $struct.recursive))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.recursive))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (struct.new_default $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.recursive)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref null $struct.recursive))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.recursive)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
@@ -1337,20 +1337,20 @@
;; NOMNL-NEXT: (local $1 (ref null $struct.recursive))
;; NOMNL-NEXT: (local $2 (ref null $struct.recursive))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (struct.new_default $struct.recursive)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $1)
;; NOMNL-NEXT: )
@@ -1454,14 +1454,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref $struct.A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.nondefaultable))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.nondefaultable)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
@@ -1474,14 +1474,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result (ref $struct.A))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.nonnullable))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (local.get $a)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.nonnullable)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $1)
@@ -1508,7 +1508,7 @@
;; CHECK-NEXT: (local $5 f64)
;; CHECK-NEXT: (loop $outer
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $4
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: )
@@ -1521,13 +1521,13 @@
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (local.get $5)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -1537,14 +1537,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 42)
@@ -1554,13 +1554,13 @@
;; CHECK-NEXT: (loop $inner
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (i32.add
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -1577,7 +1577,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -1585,7 +1585,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
@@ -1602,7 +1602,7 @@
;; NOMNL-NEXT: (local $5 f64)
;; NOMNL-NEXT: (loop $outer
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $4
;; NOMNL-NEXT: (i32.const 2)
;; NOMNL-NEXT: )
@@ -1615,13 +1615,13 @@
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (local.get $5)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -1631,14 +1631,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 42)
@@ -1648,13 +1648,13 @@
;; NOMNL-NEXT: (loop $inner
;; NOMNL-NEXT: (block
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (i32.add
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -1671,7 +1671,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -1679,7 +1679,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
@@ -1755,14 +1755,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
@@ -1771,14 +1771,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
@@ -1787,14 +1787,14 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $4
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $5
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $5)
@@ -1811,14 +1811,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $0
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $0)
@@ -1827,14 +1827,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
@@ -1843,14 +1843,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $4
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $5
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $5)
@@ -1883,39 +1883,39 @@
;; CHECK-NEXT: (local $3 i32)
;; CHECK-NEXT: (local $4 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $4
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
@@ -1928,39 +1928,39 @@
;; NOMNL-NEXT: (local $3 i32)
;; NOMNL-NEXT: (local $4 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $1)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $4
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
@@ -1996,31 +1996,31 @@
;; CHECK-NEXT: (local $4 i32)
;; CHECK-NEXT: (local $5 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $4
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $5
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
@@ -2028,7 +2028,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $4)
;; CHECK-NEXT: )
@@ -2042,31 +2042,31 @@
;; NOMNL-NEXT: (local $4 i32)
;; NOMNL-NEXT: (local $5 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $4
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $5
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
@@ -2074,7 +2074,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $4)
;; NOMNL-NEXT: )
@@ -2112,7 +2112,7 @@
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_if $block
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2129,7 +2129,7 @@
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (br_if $block
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2172,7 +2172,7 @@
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2189,7 +2189,7 @@
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2218,14 +2218,14 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result f64)
@@ -2233,7 +2233,7 @@
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_if $block
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2250,14 +2250,14 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result f64)
@@ -2265,7 +2265,7 @@
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (br_if $block
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2313,7 +2313,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_if $block
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2338,7 +2338,7 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (br_if $block
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2515,19 +2515,19 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 1)
@@ -2535,7 +2535,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2544,19 +2544,19 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 1)
@@ -2564,7 +2564,7 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2595,22 +2595,22 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
@@ -2620,22 +2620,22 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (block (result i32)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $1)
;; NOMNL-NEXT: )
@@ -2671,7 +2671,7 @@
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_if $block
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: )
@@ -2684,7 +2684,7 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (local.get $4)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
@@ -2706,7 +2706,7 @@
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (br_if $block
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (i32.const 42)
;; NOMNL-NEXT: )
@@ -2719,7 +2719,7 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (local.get $4)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
@@ -2760,14 +2760,14 @@
;; CHECK-NEXT: (br_if $loop
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2781,14 +2781,14 @@
;; NOMNL-NEXT: (br_if $loop
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2814,14 +2814,14 @@
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local $2 f64)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -2834,14 +2834,14 @@
;; NOMNL-NEXT: (local $1 i32)
;; NOMNL-NEXT: (local $2 f64)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (unreachable)
diff --git a/test/lit/passes/inlining-gc.wast b/test/lit/passes/inlining-gc.wast
index 11ac125b2..cebdbd052 100644
--- a/test/lit/passes/inlining-gc.wast
+++ b/test/lit/passes/inlining-gc.wast
@@ -6,7 +6,7 @@
;; CHECK-NEXT: (local $0 funcref)
;; CHECK-NEXT: (block $__inlined_func$target-nullable
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
diff --git a/test/lit/passes/inlining-optimizing.wast b/test/lit/passes/inlining-optimizing.wast
index 7da2efb72..65384330a 100644
--- a/test/lit/passes/inlining-optimizing.wast
+++ b/test/lit/passes/inlining-optimizing.wast
@@ -17,6 +17,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/inlining_all-features.wast b/test/lit/passes/inlining_all-features.wast
index 5ce964ceb..9b3a426d5 100644
--- a/test/lit/passes/inlining_all-features.wast
+++ b/test/lit/passes/inlining_all-features.wast
@@ -141,23 +141,13 @@
)
;; CHECK: (func $1
;; CHECK-NEXT: (block $__inlined_func$0
- ;; CHECK-NEXT: (block
- ;; CHECK-NEXT: (call_ref $none_=>_none
- ;; CHECK-NEXT: (ref.null $none_=>_none)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (br $__inlined_func$0)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (br $__inlined_func$0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $1 (type $none_=>_none)
;; NOMNL-NEXT: (block $__inlined_func$0
- ;; NOMNL-NEXT: (block
- ;; NOMNL-NEXT: (call_ref $none_=>_none
- ;; NOMNL-NEXT: (ref.null $none_=>_none)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (br $__inlined_func$0)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: (br $__inlined_func$0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast
index aca20f8e8..c114d4551 100644
--- a/test/lit/passes/inlining_splitting.wast
+++ b/test/lit/passes/inlining_splitting.wast
@@ -432,7 +432,7 @@
;; CHECK-NEXT: (block
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-A$condition-ref.is
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (i32.eqz
@@ -449,7 +449,7 @@
;; CHECK-NEXT: (block
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-A$condition-ref.is0
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (i32.eqz
@@ -833,7 +833,7 @@
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$error-if-null (result anyref)
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (if
@@ -855,7 +855,7 @@
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$error-if-null0 (result anyref)
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (if
@@ -909,12 +909,12 @@
;; CHECK: (func $call-too-many
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $too-many
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $too-many
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -951,12 +951,12 @@
;; CHECK: (func $call-tail-not-simple
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $tail-not-simple
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $tail-not-simple
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -987,7 +987,7 @@
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$reachable-if-body (result anyref)
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (if
@@ -1010,7 +1010,7 @@
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$reachable-if-body0 (result anyref)
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (if
@@ -1087,12 +1087,12 @@
;; CHECK: (func $call-reachable-if-body-return
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $reachable-if-body-return
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $reachable-if-body-return
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1121,7 +1121,7 @@
;; CHECK-NEXT: (block
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$unreachable-if-body-no-result
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (ref.is_null
@@ -1136,7 +1136,7 @@
;; CHECK-NEXT: (block
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$unreachable-if-body-no-result0
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (ref.is_null
@@ -1185,7 +1185,7 @@
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$multi-if (result anyref)
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (if
@@ -1216,7 +1216,7 @@
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$multi-if0 (result anyref)
;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (ref.null data)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result anyref)
;; CHECK-NEXT: (if
@@ -1320,12 +1320,12 @@
;; CHECK: (func $call-too-many-ifs
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $too-many-ifs
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $too-many-ifs
- ;; CHECK-NEXT: (ref.null data)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/intrinsic-lowering.wast b/test/lit/passes/intrinsic-lowering.wast
index de1c981bc..34e994f7f 100644
--- a/test/lit/passes/intrinsic-lowering.wast
+++ b/test/lit/passes/intrinsic-lowering.wast
@@ -17,9 +17,9 @@
;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $cwe-n (param funcref)))
(import "binaryen-intrinsics" "call.without.effects" (func $cwe-n (param funcref)))
- ;; CHECK: (func $test (result i32)
+ ;; CHECK: (func $test (param $none (ref null $none))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (call $test)
+ ;; CHECK-NEXT: (call $make-i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $dif
@@ -28,18 +28,21 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_ref $none
- ;; CHECK-NEXT: (ref.null $none)
+ ;; CHECK-NEXT: (local.get $none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
- (func $test (result i32)
+ (func $test (param $none (ref null $none))
;; These will be lowered into calls.
- (drop (call $cwe-v (ref.func $test)))
+ (drop (call $cwe-v (ref.func $make-i32)))
(drop (call $cwe-dif (f64.const 3.14159) (i32.const 42) (ref.func $dif)))
;; The last must be a call_ref, as we don't see a constant ref.func
- (call $cwe-n
- (ref.null $none)
- )
+ (call $cwe-n (local.get $none))
+ )
+
+ ;; CHECK: (func $make-i32 (result i32)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ (func $make-i32 (result i32)
(i32.const 1)
)
diff --git a/test/lit/passes/jspi.wast b/test/lit/passes/jspi.wast
index 104dc2522..5b8669be1 100644
--- a/test/lit/passes/jspi.wast
+++ b/test/lit/passes/jspi.wast
@@ -24,7 +24,7 @@
(import "js" "import_and_export" (func $import_and_export (param i32) (result i32)))
;; CHECK: (import "js" "import_void_return" (func $import$import_void_return (param externref i32)))
(import "js" "import_void_return" (func $import_void_return (param i32)))
- ;; CHECK: (global $suspender (mut externref) (ref.null extern))
+ ;; CHECK: (global $suspender (mut externref) (ref.null noextern))
;; CHECK: (export "update_state_void" (func $export$update_state_void))
(export "update_state_void" (func $update_state_void))
diff --git a/test/lit/passes/local-subtyping-nn.wast b/test/lit/passes/local-subtyping-nn.wast
index 24517fb08..a34300525 100644
--- a/test/lit/passes/local-subtyping-nn.wast
+++ b/test/lit/passes/local-subtyping-nn.wast
@@ -5,8 +5,6 @@
;; RUN: | filecheck %s --check-prefix=NOMNL
(module
- ;; CHECK: (type $struct (struct ))
- ;; NOMNL: (type $struct (struct_subtype data))
(type $struct (struct))
;; CHECK: (import "out" "i32" (func $i32 (result i32)))
@@ -14,11 +12,11 @@
(import "out" "i32" (func $i32 (result i32)))
;; CHECK: (func $non-nullable
- ;; CHECK-NEXT: (local $x (ref $struct))
+ ;; CHECK-NEXT: (local $x (ref none))
;; CHECK-NEXT: (local $y (ref $none_=>_i32))
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $y
@@ -29,11 +27,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $non-nullable (type $none_=>_none)
- ;; NOMNL-NEXT: (local $x (ref $struct))
+ ;; NOMNL-NEXT: (local $x (ref none))
;; NOMNL-NEXT: (local $y (ref $none_=>_i32))
;; NOMNL-NEXT: (local.set $x
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $y
@@ -62,12 +60,12 @@
)
;; CHECK: (func $uses-default (param $i i32)
- ;; CHECK-NEXT: (local $x (ref null $struct))
+ ;; CHECK-NEXT: (local $x nullref)
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $i)
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -76,12 +74,12 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $uses-default (type $i32_=>_none) (param $i i32)
- ;; NOMNL-NEXT: (local $x (ref null $struct))
+ ;; NOMNL-NEXT: (local $x nullref)
;; NOMNL-NEXT: (if
;; NOMNL-NEXT: (local.get $i)
;; NOMNL-NEXT: (local.set $x
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
diff --git a/test/lit/passes/local-subtyping.wast b/test/lit/passes/local-subtyping.wast
index a2a5780da..e281d5cf2 100644
--- a/test/lit/passes/local-subtyping.wast
+++ b/test/lit/passes/local-subtyping.wast
@@ -11,7 +11,6 @@
;; CHECK: (type ${} (struct ))
(type ${} (struct_subtype data))
- ;; CHECK: (type ${i32} (struct (field i32)))
(type ${i32} (struct_subtype (field i32) data))
(type $array (array_subtype i8 data))
@@ -323,7 +322,7 @@
;; CHECK-NEXT: (local.tee $temp
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
@@ -332,7 +331,7 @@
;; CHECK-NEXT: (local.tee $temp
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
@@ -365,25 +364,25 @@
;; CHECK: (func $update-nulls
;; CHECK-NEXT: (local $x (ref null ${}))
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (struct.new_default ${})
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $update-nulls
diff --git a/test/lit/passes/merge-blocks.wast b/test/lit/passes/merge-blocks.wast
index f858b0dc8..58ba6f171 100644
--- a/test/lit/passes/merge-blocks.wast
+++ b/test/lit/passes/merge-blocks.wast
@@ -21,10 +21,10 @@
;; CHECK-NEXT: (block $label$1 (result i31ref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_on_i31 $label$1
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null i31)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -43,24 +43,24 @@
)
)
- ;; CHECK: (func $struct.set
+ ;; CHECK: (func $struct.set (param $struct (ref null $struct))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1234)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: (i32.const 5)
;; CHECK-NEXT: )
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- (func $struct.set
+ (func $struct.set (param $struct (ref null $struct))
(block
(nop)
(struct.set $struct 0
(block (result (ref null $struct))
(drop (i32.const 1234))
- (ref.null $struct)
+ (local.get $struct)
)
(i32.const 5)
)
@@ -68,26 +68,26 @@
)
)
- ;; CHECK: (func $struct.get
+ ;; CHECK: (func $struct.get (param $struct (ref null $struct))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1234)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- (func $struct.get
+ (func $struct.get (param $struct (ref null $struct))
(block
(nop)
(drop
(struct.get $struct 0
(block (result (ref null $struct))
(drop (i32.const 1234))
- (ref.null $struct)
+ (local.get $struct)
)
)
)
diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast
index 4f5d484cf..a82b15542 100644
--- a/test/lit/passes/optimize-instructions-call_ref.wast
+++ b/test/lit/passes/optimize-instructions-call_ref.wast
@@ -210,6 +210,9 @@
)
;; CHECK: (func $ignore-unreachable
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $ignore-unreachable
diff --git a/test/lit/passes/optimize-instructions-gc-heap.wast b/test/lit/passes/optimize-instructions-gc-heap.wast
index fc44e11de..e448e57fd 100644
--- a/test/lit/passes/optimize-instructions-gc-heap.wast
+++ b/test/lit/passes/optimize-instructions-gc-heap.wast
@@ -308,7 +308,7 @@
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
@@ -343,7 +343,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
@@ -374,7 +374,7 @@
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (local.set $other
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
@@ -717,6 +717,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast
index b1fc9a42b..d8fe7a677 100644
--- a/test/lit/passes/optimize-instructions-gc-tnh.wast
+++ b/test/lit/passes/optimize-instructions-gc-tnh.wast
@@ -52,19 +52,6 @@
;; TNH-NEXT: (drop
;; TNH-NEXT: (i32.const 1)
;; TNH-NEXT: )
- ;; TNH-NEXT: (drop
- ;; TNH-NEXT: (ref.eq
- ;; TNH-NEXT: (block (result (ref null $struct))
- ;; TNH-NEXT: (drop
- ;; TNH-NEXT: (ref.null any)
- ;; TNH-NEXT: )
- ;; TNH-NEXT: (ref.null $struct)
- ;; TNH-NEXT: )
- ;; TNH-NEXT: (ref.as_data
- ;; TNH-NEXT: (ref.null any)
- ;; TNH-NEXT: )
- ;; TNH-NEXT: )
- ;; TNH-NEXT: )
;; TNH-NEXT: )
;; NO_TNH: (func $ref.eq-no (type $eqref_eqref_=>_none) (param $a eqref) (param $b eqref)
;; NO_TNH-NEXT: (drop
@@ -83,19 +70,6 @@
;; NO_TNH-NEXT: )
;; NO_TNH-NEXT: )
;; NO_TNH-NEXT: )
- ;; NO_TNH-NEXT: (drop
- ;; NO_TNH-NEXT: (ref.eq
- ;; NO_TNH-NEXT: (block (result (ref null $struct))
- ;; NO_TNH-NEXT: (drop
- ;; NO_TNH-NEXT: (ref.null any)
- ;; NO_TNH-NEXT: )
- ;; NO_TNH-NEXT: (ref.null $struct)
- ;; NO_TNH-NEXT: )
- ;; NO_TNH-NEXT: (ref.as_data
- ;; NO_TNH-NEXT: (ref.null any)
- ;; NO_TNH-NEXT: )
- ;; NO_TNH-NEXT: )
- ;; NO_TNH-NEXT: )
;; NO_TNH-NEXT: )
(func $ref.eq-no (param $a (ref null eq)) (param $b (ref null eq))
;; We must leave the inputs to ref.eq of type eqref or a subtype. Note that
@@ -116,23 +90,6 @@
)
)
)
- ;; As above, but now with nulls of a non-eq type.
- ;; Note that we could in theory change a null's type to get validation in
- ;; such cases.
- (drop
- (ref.eq
- (ref.cast_static $struct
- (ref.null any) ;; *Not* an eqref!
- )
- (ref.as_non_null
- (ref.as_data
- (ref.as_non_null
- (ref.null any) ;; *Not* an eqref!
- )
- )
- )
- )
- )
)
;; TNH: (func $ref.is (type $eqref_=>_i32) (param $a eqref) (result i32)
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast
index da2411eed..c0d106250 100644
--- a/test/lit/passes/optimize-instructions-gc.wast
+++ b/test/lit/passes/optimize-instructions-gc.wast
@@ -14,30 +14,39 @@
(field $i64 (mut i64))
))
+ ;; CHECK: (type $B (struct (field i32) (field i32) (field f32)))
+
+ ;; CHECK: (type $array (array (mut i8)))
+
;; CHECK: (type $A (struct (field i32)))
;; NOMNL: (type $A (struct_subtype (field i32) data))
(type $A (struct (field i32)))
- ;; CHECK: (type $array (array (mut i8)))
+ ;; NOMNL: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
+
;; NOMNL: (type $array (array_subtype (mut i8) data))
(type $array (array (mut i8)))
- ;; CHECK: (type $B (struct (field i32) (field i32) (field f32)))
- ;; NOMNL: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
(type $B (struct_subtype (field i32) (field i32) (field f32) $A))
;; CHECK: (type $B-child (struct (field i32) (field i32) (field f32) (field i64)))
;; NOMNL: (type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B))
(type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B))
+ ;; NOMNL: (type $void (func_subtype func))
+
;; NOMNL: (type $C (struct_subtype (field i32) (field i32) (field f64) $A))
;; NOMNL: (type $empty (struct_subtype data))
(type $empty (struct))
+ ;; CHECK: (type $void (func))
+
;; CHECK: (type $C (struct (field i32) (field i32) (field f64)))
(type $C (struct_subtype (field i32) (field i32) (field f64) $A))
+ (type $void (func))
+
;; CHECK: (import "env" "get-i32" (func $get-i32 (result i32)))
;; NOMNL: (import "env" "get-i32" (func $get-i32 (result i32)))
(import "env" "get-i32" (func $get-i32 (result i32)))
@@ -45,10 +54,10 @@
;; These functions test if an `if` with subtyped arms is correctly folded
;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold)
;; CHECK: (func $if-arms-subtype-fold (result anyref)
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; NOMNL: (func $if-arms-subtype-fold (type $none_=>_anyref) (result anyref)
- ;; NOMNL-NEXT: (ref.null eq)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
(func $if-arms-subtype-fold (result anyref)
(if (result anyref)
@@ -58,25 +67,25 @@
)
)
;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold)
- ;; CHECK: (func $if-arms-subtype-nofold (result anyref)
+ ;; CHECK: (func $if-arms-subtype-nofold (param $i31ref i31ref) (result anyref)
;; CHECK-NEXT: (if (result anyref)
;; CHECK-NEXT: (i32.const 0)
- ;; CHECK-NEXT: (ref.null data)
- ;; CHECK-NEXT: (ref.null i31)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (local.get $i31ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $if-arms-subtype-nofold (type $none_=>_anyref) (result anyref)
+ ;; NOMNL: (func $if-arms-subtype-nofold (type $i31ref_=>_anyref) (param $i31ref i31ref) (result anyref)
;; NOMNL-NEXT: (if (result anyref)
;; NOMNL-NEXT: (i32.const 0)
- ;; NOMNL-NEXT: (ref.null data)
- ;; NOMNL-NEXT: (ref.null i31)
+ ;; NOMNL-NEXT: (ref.null none)
+ ;; NOMNL-NEXT: (local.get $i31ref)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- (func $if-arms-subtype-nofold (result anyref)
+ (func $if-arms-subtype-nofold (param $i31ref i31ref) (result anyref)
(if (result anyref)
(i32.const 0)
(ref.null data)
- (ref.null i31)
+ (local.get $i31ref)
)
)
@@ -708,7 +717,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $unneeded_unreachability (type $none_=>_none)
+ ;; NOMNL: (func $unneeded_unreachability (type $void)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.is_func
;; NOMNL-NEXT: (unreachable)
@@ -730,7 +739,7 @@
)
)
- ;; CHECK: (func $redundant-non-null-casts (param $x (ref null $struct)) (param $y (ref null $array))
+ ;; CHECK: (func $redundant-non-null-casts (param $x (ref null $struct)) (param $y (ref null $array)) (param $f (ref null $void))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $x)
@@ -761,8 +770,11 @@
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call_ref $void
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $redundant-non-null-casts (type $ref?|$struct|_ref?|$array|_=>_none) (param $x (ref null $struct)) (param $y (ref null $array))
+ ;; NOMNL: (func $redundant-non-null-casts (type $ref?|$struct|_ref?|$array|_ref?|$void|_=>_none) (param $x (ref null $struct)) (param $y (ref null $array)) (param $f (ref null $void))
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.as_non_null
;; NOMNL-NEXT: (local.get $x)
@@ -793,8 +805,11 @@
;; NOMNL-NEXT: (local.get $y)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call_ref $void
+ ;; NOMNL-NEXT: (local.get $f)
+ ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- (func $redundant-non-null-casts (param $x (ref null $struct)) (param $y (ref null $array))
+ (func $redundant-non-null-casts (param $x (ref null $struct)) (param $y (ref null $array)) (param $f (ref null $void))
(drop
(ref.as_non_null
(ref.as_non_null
@@ -839,6 +854,11 @@
)
)
)
+ (call_ref $void
+ (ref.as_non_null
+ (local.get $f)
+ )
+ )
)
;; CHECK: (func $get-eqref (result eqref)
@@ -945,7 +965,7 @@
;; CHECK: (func $nothing
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- ;; NOMNL: (func $nothing (type $none_=>_none)
+ ;; NOMNL: (func $nothing (type $void)
;; NOMNL-NEXT: (nop)
;; NOMNL-NEXT: )
(func $nothing)
@@ -1254,7 +1274,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.tee $x
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1263,7 +1283,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.tee $x
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1880,29 +1900,29 @@
)
)
- ;; CHECK: (func $hoist-LUB-danger (param $x i32) (result i32)
+ ;; CHECK: (func $hoist-LUB-danger (param $x i32) (param $b (ref $B)) (param $c (ref $C)) (result i32)
;; CHECK-NEXT: (if (result i32)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (struct.get $B 1
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (local.get $b)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $C 1
- ;; CHECK-NEXT: (ref.null $C)
+ ;; CHECK-NEXT: (local.get $c)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $hoist-LUB-danger (type $i32_=>_i32) (param $x i32) (result i32)
+ ;; NOMNL: (func $hoist-LUB-danger (type $i32_ref|$B|_ref|$C|_=>_i32) (param $x i32) (param $b (ref $B)) (param $c (ref $C)) (result i32)
;; NOMNL-NEXT: (if (result i32)
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: (struct.get $B 1
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (local.get $b)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $C 1
- ;; NOMNL-NEXT: (ref.null $C)
+ ;; NOMNL-NEXT: (local.get $c)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- (func $hoist-LUB-danger (param $x i32) (result i32)
+ (func $hoist-LUB-danger (param $x i32) (param $b (ref $B)) (param $c (ref $C)) (result i32)
;; In nominal typing, if we hoist the struct.get out of the if, then the if
;; will have a new type, $A, but $A does not have field "1" which would be an
;; error. We disallow subtyping for this reason.
@@ -1914,10 +1934,10 @@
(if (result i32)
(local.get $x)
(struct.get $B 1
- (ref.null $B)
+ (local.get $b)
)
(struct.get $C 1
- (ref.null $C)
+ (local.get $c)
)
)
)
@@ -1952,44 +1972,44 @@
;; CHECK: (func $incompatible-cast-of-null
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $array))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $array)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (block (result (ref null $array))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $array)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $incompatible-cast-of-null (type $none_=>_none)
+ ;; NOMNL: (func $incompatible-cast-of-null (type $void)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $array))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $array)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (block (result (ref null $array))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $array)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2171,74 +2191,74 @@
;; CHECK: (func $ref-cast-static-null
;; CHECK-NEXT: (local $a (ref null $A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $B))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $A))
+ ;; CHECK-NEXT: (block (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.tee $a
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $ref-cast-static-null (type $none_=>_none)
+ ;; NOMNL: (func $ref-cast-static-null (type $void)
;; NOMNL-NEXT: (local $a (ref null $A))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $B))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $A))
+ ;; NOMNL-NEXT: (block (result nullref)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.tee $a
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null $A)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -3089,4 +3109,72 @@
)
)
)
+
+ ;; CHECK: (func $impossible (result (ref none))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; NOMNL: (func $impossible (type $none_=>_ref|none|) (result (ref none))
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ (func $impossible (result (ref none))
+ (unreachable)
+ )
+
+ ;; CHECK: (func $bottom-type-accessors (param $bot (ref none)) (param $null nullref)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $impossible)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; NOMNL: (func $bottom-type-accessors (type $ref|none|_nullref_=>_none) (param $bot (ref none)) (param $null nullref)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $impossible)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ (func $bottom-type-accessors (param $bot (ref none)) (param $null nullref)
+ (drop
+ (struct.get $A 0
+ (local.get $bot)
+ )
+ )
+ (drop
+ (array.get $array
+ (local.get $null)
+ (i32.const 0)
+ )
+ )
+ (struct.set $A 0
+ (ref.null none)
+ (i32.const 42)
+ )
+ (array.set $array
+ (call $impossible)
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (call_ref $void
+ (ref.null nofunc)
+ )
+ )
)
diff --git a/test/lit/passes/precompute-gc-immutable.wast b/test/lit/passes/precompute-gc-immutable.wast
index bb627dfa1..ebb26bfb5 100644
--- a/test/lit/passes/precompute-gc-immutable.wast
+++ b/test/lit/passes/precompute-gc-immutable.wast
@@ -94,6 +94,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $helper
@@ -136,8 +137,11 @@
;; CHECK: (func $local-null (type $none_=>_none)
;; CHECK-NEXT: (local $ref-imm (ref null $struct-imm))
;; CHECK-NEXT: (call $helper
- ;; CHECK-NEXT: (struct.get $struct-imm 0
- ;; CHECK-NEXT: (ref.null $struct-imm)
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index a3fa63bb5..78e91d749 100644
--- a/test/lit/passes/precompute-gc.wast
+++ b/test/lit/passes/precompute-gc.wast
@@ -32,11 +32,11 @@
;; CHECK: (func $test-fallthrough (result i32)
;; CHECK-NEXT: (local $x funcref)
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (block (result funcref)
+ ;; CHECK-NEXT: (block (result nullfuncref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $test-fallthrough)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 1)
@@ -44,11 +44,11 @@
;; NOMNL: (func $test-fallthrough (type $func-return-i32) (result i32)
;; NOMNL-NEXT: (local $x funcref)
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (block (result funcref)
+ ;; NOMNL-NEXT: (block (result nullfuncref)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (call $test-fallthrough)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null func)
+ ;; NOMNL-NEXT: (ref.null nofunc)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (i32.const 1)
@@ -342,13 +342,13 @@
;; CHECK-NEXT: (call $log
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $log
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $log
@@ -367,13 +367,13 @@
;; NOMNL-NEXT: (call $log
;; NOMNL-NEXT: (ref.eq
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $log
;; NOMNL-NEXT: (ref.eq
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $log
@@ -1055,22 +1055,28 @@
;; CHECK: (func $odd-cast-and-get
;; CHECK-NEXT: (local $temp (ref null $B))
;; CHECK-NEXT: (local.set $temp
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.get $B 0
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $odd-cast-and-get (type $none_=>_none)
;; NOMNL-NEXT: (local $temp (ref null $B))
;; NOMNL-NEXT: (local.set $temp
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (struct.get $B 0
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null none)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1098,13 +1104,16 @@
;; CHECK-NEXT: (local $temp ((ref null $B) i32))
;; CHECK-NEXT: (local.set $temp
;; CHECK-NEXT: (tuple.make
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.get $B 0
- ;; CHECK-NEXT: (ref.null $B)
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1112,13 +1121,16 @@
;; NOMNL-NEXT: (local $temp ((ref null $B) i32))
;; NOMNL-NEXT: (local.set $temp
;; NOMNL-NEXT: (tuple.make
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: (i32.const 10)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (struct.get $B 0
- ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null none)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1199,6 +1211,7 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $new_block_unreachable (type $none_=>_anyref) (result anyref)
@@ -1208,6 +1221,7 @@
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $new_block_unreachable (result anyref)
@@ -1263,7 +1277,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (ref.null $empty)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $helper
@@ -1295,7 +1309,7 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $ref
- ;; NOMNL-NEXT: (ref.null $empty)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (call $helper
diff --git a/test/lit/passes/remove-unused-brs-gc.wast b/test/lit/passes/remove-unused-brs-gc.wast
index 3b7346e3f..9473b0627 100644
--- a/test/lit/passes/remove-unused-brs-gc.wast
+++ b/test/lit/passes/remove-unused-brs-gc.wast
@@ -8,7 +8,7 @@
;; CHECK: (func $br_on_non_data-1
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $any (result anyref)
+ ;; CHECK-NEXT: (block $any (result i31ref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br $any
;; CHECK-NEXT: (i31.new
@@ -16,7 +16,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -35,11 +35,11 @@
)
;; CHECK: (func $br_on_non_data-2 (param $data (ref data))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $any (result anyref)
+ ;; CHECK-NEXT: (block $any (result nullref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $data)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -144,7 +144,7 @@
;; CHECK-NEXT: (block $block (result (ref $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_on_cast_static $block $struct
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -191,7 +191,7 @@
;; CHECK-NEXT: (if (result i32)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (ref.test_static $struct
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
@@ -199,9 +199,9 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (if (result anyref)
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (ref.cast_static $struct
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -211,12 +211,12 @@
;; CHECK-NEXT: (block $something (result anyref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_on_cast_static $something $struct
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -225,13 +225,13 @@
;; CHECK-NEXT: (block $nothing
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_on_null $nothing
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/remove-unused-brs.wast b/test/lit/passes/remove-unused-brs.wast
index ddfbabe84..7db4bdcd5 100644
--- a/test/lit/passes/remove-unused-brs.wast
+++ b/test/lit/passes/remove-unused-brs.wast
@@ -6,9 +6,9 @@
(module
;; Regression test in which we need to calculate a proper LUB.
;; CHECK: (func $selectify-fresh-lub (param $x i32) (result anyref)
- ;; CHECK-NEXT: (select (result eqref)
- ;; CHECK-NEXT: (ref.null i31)
- ;; CHECK-NEXT: (ref.null data)
+ ;; CHECK-NEXT: (select (result nullref)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/remove-unused-module-elements-refs.wast b/test/lit/passes/remove-unused-module-elements-refs.wast
index 2a976cf8a..497af29ee 100644
--- a/test/lit/passes/remove-unused-module-elements-refs.wast
+++ b/test/lit/passes/remove-unused-module-elements-refs.wast
@@ -4,6 +4,8 @@
(module
;; CHECK: (type $A (func_subtype func))
(type $A (func))
+ ;; CHECK: (type $ref?|$A|_=>_none (func_subtype (param (ref null $A)) func))
+
;; CHECK: (type $B (func_subtype func))
(type $B (func))
@@ -11,7 +13,7 @@
;; CHECK: (export "foo" (func $foo))
- ;; CHECK: (func $foo (type $A)
+ ;; CHECK: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A)
;; CHECK-NEXT: )
@@ -19,13 +21,16 @@
;; CHECK-NEXT: (ref.func $target-B)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_ref $A
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $foo (export "foo")
+ (func $foo (export "foo") (param $A (ref null $A))
;; This export has two RefFuncs, and one CallRef.
(drop
(ref.func $target-A)
@@ -34,7 +39,7 @@
(ref.func $target-B)
)
(call_ref
- (ref.null $A)
+ (local.get $A)
)
;; Verify that we do not crash on an unreachable call_ref, which has no
;; heap type for us to analyze.
@@ -80,8 +85,11 @@
;; CHECK: (export "foo" (func $foo))
;; CHECK: (func $foo (type $A)
- ;; CHECK-NEXT: (call_ref $A
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A)
@@ -97,7 +105,7 @@
)
;; CHECK: (func $target-A (type $A)
- ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $target-A (type $A)
;; This function is reachable.
@@ -114,33 +122,35 @@
(type $A (func))
(type $B (func))
+ ;; CHECK: (type $ref?|$A|_=>_none (func_subtype (param (ref null $A)) func))
+
;; CHECK: (elem declare func $target-A-1 $target-A-2)
;; CHECK: (export "foo" (func $foo))
- ;; CHECK: (func $foo (type $A)
+ ;; CHECK: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; CHECK-NEXT: (call_ref $A
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A-1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_ref $A
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $foo (export "foo")
+ (func $foo (export "foo") (param $A (ref null $A))
(call_ref
- (ref.null $A)
+ (local.get $A)
)
(drop
(ref.func $target-A-1)
)
(call_ref
- (ref.null $A)
+ (local.get $A)
)
(drop
(ref.func $target-A-2)
@@ -173,36 +183,38 @@
(type $A (func))
(type $B (func))
+ ;; CHECK: (type $ref?|$A|_=>_none (func_subtype (param (ref null $A)) func))
+
;; CHECK: (elem declare func $target-A-1 $target-A-2)
;; CHECK: (export "foo" (func $foo))
- ;; CHECK: (func $foo (type $A)
+ ;; CHECK: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A-1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_ref $A
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_ref $A
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $foo (export "foo")
+ (func $foo (export "foo") (param $A (ref null $A))
(drop
(ref.func $target-A-1)
)
(call_ref
- (ref.null $A)
+ (local.get $A)
)
(drop
(ref.func $target-A-2)
)
(call_ref
- (ref.null $A)
+ (local.get $A)
)
)
@@ -286,6 +298,8 @@
;; CHECK: (type $funcref_=>_none (func_subtype (param funcref) func))
+ ;; CHECK: (type $ref?|$A|_=>_none (func_subtype (param (ref null $A)) func))
+
;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref)))
(import "binaryen-intrinsics" "call.without.effects"
(func $call-without-effects (param funcref)))
@@ -298,9 +312,9 @@
;; CHECK: (export "foo" (func $foo))
- ;; CHECK: (func $foo (type $A)
+ ;; CHECK: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; CHECK-NEXT: (call $call-without-effects
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-keep)
@@ -309,12 +323,12 @@
;; CHECK-NEXT: (ref.func $target-keep-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $foo (export "foo")
+ (func $foo (export "foo") (param $A (ref null $A))
;; Call the intrinsic without a RefFunc. All we infer here is the type,
;; which means we must assume anything with type $A (and a reference) can be
;; called, which will keep alive both $target-keep and $target-keep-2
(call $call-without-effects
- (ref.null $A)
+ (local.get $A)
)
(drop
(ref.func $target-keep)
diff --git a/test/lit/passes/roundtrip.wast b/test/lit/passes/roundtrip.wast
index a61e7e710..b23819b7b 100644
--- a/test/lit/passes/roundtrip.wast
+++ b/test/lit/passes/roundtrip.wast
@@ -10,7 +10,7 @@
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (block $label$1 (result funcref (ref $none))
;; CHECK-NEXT: (tuple.make
- ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast
index ec47700ef..26ecadfc9 100644
--- a/test/lit/passes/signature-pruning.wast
+++ b/test/lit/passes/signature-pruning.wast
@@ -750,7 +750,7 @@
;; CHECK: (func $foo (type $sig-foo)
;; CHECK-NEXT: (local $0 anyref)
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
@@ -776,7 +776,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $bar
- ;; CHECK-NEXT: (ref.null data)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $bar (type $sig-bar) (param $anyref anyref)
diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast
index e5f42ffa0..3d2f7b1a4 100644
--- a/test/lit/passes/signature-refining.wast
+++ b/test/lit/passes/signature-refining.wast
@@ -485,7 +485,7 @@
;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $func
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller
@@ -527,7 +527,7 @@
)
;; CHECK: (func $func-cannot-refine (type $sig-cannot-refine) (result anyref)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
(func $func-cannot-refine (type $sig-cannot-refine) (result anyref)
(ref.null any)
@@ -583,12 +583,13 @@
)
(module
+ ;; CHECK: (type $sig (func_subtype (result (ref null $struct)) func))
+
;; CHECK: (type $struct (struct_subtype data))
(type $struct (struct_subtype data))
;; This signature has multiple functions using it, and some of them have nulls
;; which should be updated when we refine.
- ;; CHECK: (type $sig (func_subtype (result (ref null $struct)) func))
(type $sig (func_subtype (result anyref) func))
;; CHECK: (func $func-1 (type $sig) (result (ref null $struct))
@@ -599,14 +600,14 @@
)
;; CHECK: (func $func-2 (type $sig) (result (ref null $struct))
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
(func $func-2 (type $sig) (result anyref)
(ref.null any)
)
;; CHECK: (func $func-3 (type $sig) (result (ref null $struct))
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
(func $func-3 (type $sig) (result anyref)
(ref.null eq)
@@ -616,7 +617,7 @@
;; CHECK-NEXT: (if
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (return
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
@@ -700,7 +701,7 @@
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $2
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/simplify-locals-gc-nn.wast b/test/lit/passes/simplify-locals-gc-nn.wast
index e5941cc0e..c7e4b6373 100644
--- a/test/lit/passes/simplify-locals-gc-nn.wast
+++ b/test/lit/passes/simplify-locals-gc-nn.wast
@@ -9,7 +9,7 @@
;; CHECK-NEXT: (do
;; CHECK-NEXT: (local.set $nn
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -56,7 +56,7 @@
;; CHECK-NEXT: (do
;; CHECK-NEXT: (local.set $nullable
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/simplify-locals-gc-validation.wast b/test/lit/passes/simplify-locals-gc-validation.wast
index bda59882b..0587303c2 100644
--- a/test/lit/passes/simplify-locals-gc-validation.wast
+++ b/test/lit/passes/simplify-locals-gc-validation.wast
@@ -13,7 +13,7 @@
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.tee $nn
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
diff --git a/test/lit/passes/simplify-locals-gc.wast b/test/lit/passes/simplify-locals-gc.wast
index ba9e144c6..75be02cf2 100644
--- a/test/lit/passes/simplify-locals-gc.wast
+++ b/test/lit/passes/simplify-locals-gc.wast
@@ -108,6 +108,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
@@ -123,6 +124,7 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.set $struct 0
@@ -154,15 +156,15 @@
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_on_null $block
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $temp
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (br $block)
;; CHECK-NEXT: (local.set $temp
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -176,15 +178,15 @@
;; NOMNL-NEXT: (block $block
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (br_on_null $block
- ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $temp
- ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (br $block)
;; NOMNL-NEXT: (local.set $temp
- ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: (ref.null none)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
diff --git a/test/lit/passes/type-refining-isorecursive.wast b/test/lit/passes/type-refining-isorecursive.wast
index 45d85a094..9df686154 100644
--- a/test/lit/passes/type-refining-isorecursive.wast
+++ b/test/lit/passes/type-refining-isorecursive.wast
@@ -17,19 +17,19 @@
;; CHECK: (func $foo (type $ref|$0|_ref|$1|_ref|$2|_=>_none) (param $x (ref $0)) (param $y (ref $1)) (param $z (ref $2))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $1
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $z)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $2
- ;; CHECK-NEXT: (ref.null i31)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -86,21 +86,21 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $0
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $all)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $1
- ;; CHECK-NEXT: (ref.null eq)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $all)
;; CHECK-NEXT: (local.get $z)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $2
- ;; CHECK-NEXT: (ref.null i31)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $all)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
diff --git a/test/lit/passes/type-refining.wast b/test/lit/passes/type-refining.wast
index 6b56e56e9..f578e3416 100644
--- a/test/lit/passes/type-refining.wast
+++ b/test/lit/passes/type-refining.wast
@@ -13,7 +13,7 @@
;; CHECK: (func $work (type $ref|$struct|_=>_none) (param $struct (ref $struct))
;; CHECK-NEXT: (struct.set $struct 1
;; CHECK-NEXT: (local.get $struct)
- ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 2
;; CHECK-NEXT: (local.get $struct)
@@ -571,7 +571,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
;; CHECK-NEXT: (local.get $struct)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $update-null (param $struct (ref $struct))
@@ -607,7 +607,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $child 0
;; CHECK-NEXT: (local.get $child)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $update-null (param $struct (ref $struct)) (param $child (ref $child))
@@ -635,7 +635,7 @@
;; CHECK: (func $update-null (type $ref|$struct|_ref|$child|_=>_none) (param $struct (ref $struct)) (param $child (ref $child))
;; CHECK-NEXT: (struct.set $struct 0
;; CHECK-NEXT: (local.get $struct)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $child 0
;; CHECK-NEXT: (local.get $child)
@@ -711,7 +711,7 @@
;; CHECK: (func $work (type $ref|$struct|_=>_none) (param $struct (ref $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
@@ -747,12 +747,12 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (local.get $child)
- ;; CHECK-NEXT: (ref.null $struct)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
- ;; CHECK-NEXT: (ref.null $child)
+ ;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -795,14 +795,15 @@
;; CHECK: (type $Leaf2-Inner (struct_subtype $Root-Inner))
(type $Leaf2-Inner (struct_subtype $Root-Inner))
- ;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref?|$Leaf1-Outer|_=>_none (func_subtype (param (ref null $Leaf1-Outer)) func))
;; CHECK: (type $Root-Outer (struct_subtype (field (ref $Leaf2-Inner)) data))
+ ;; CHECK: (type $Leaf2-Outer (struct_subtype (field (ref $Leaf2-Inner)) $Root-Outer))
+
;; CHECK: (type $Leaf1-Outer (struct_subtype (field (ref $Leaf2-Inner)) $Root-Outer))
(type $Leaf1-Outer (struct_subtype (field (ref $Leaf1-Inner)) $Root-Outer))
- ;; CHECK: (type $Leaf2-Outer (struct_subtype (field (ref $Leaf2-Inner)) $Root-Outer))
(type $Leaf2-Outer (struct_subtype (field (ref $Leaf2-Inner)) $Root-Outer))
(type $Root-Outer (struct_subtype (field (ref $Root-Inner)) data))
@@ -811,17 +812,18 @@
(type $Leaf1-Inner (struct_subtype (field i32) $Root-Inner))
- ;; CHECK: (func $func (type $none_=>_none)
+ ;; CHECK: (func $func (type $ref?|$Leaf1-Outer|_=>_none) (param $Leaf1-Outer (ref null $Leaf1-Outer))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null $Leaf1-Outer)
+ ;; CHECK-NEXT: (local.get $Leaf1-Outer)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -830,7 +832,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $func
+ (func $func (param $Leaf1-Outer (ref null $Leaf1-Outer))
(drop
;; The situation here is that we have only a get for some types, and no
;; other constraints. As we ignore gets, we work under no constraints at
@@ -852,7 +854,7 @@
;; unreachable here.
(struct.get $Leaf1-Inner 0
(struct.get $Leaf1-Outer 0
- (ref.null $Leaf1-Outer)
+ (local.get $Leaf1-Outer)
)
)
)
@@ -868,19 +870,19 @@
;; CHECK: (type $A (struct_subtype (field (mut (ref null $A))) data))
(type $A (struct_subtype (field (mut (ref null $A))) data))
- ;; CHECK: (type $ref|$A|_=>_none (func_subtype (param (ref $A)) func))
+ ;; CHECK: (type $ref|$A|_ref?|$A|_=>_none (func_subtype (param (ref $A) (ref null $A)) func))
- ;; CHECK: (func $non-nullability (type $ref|$A|_=>_none) (param $nn (ref $A))
+ ;; CHECK: (func $non-nullability (type $ref|$A|_ref?|$A|_=>_none) (param $nn (ref $A)) (param $A (ref null $A))
;; CHECK-NEXT: (local $temp (ref null $A))
;; CHECK-NEXT: (struct.set $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (local.get $nn)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (local.tee $temp
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -888,17 +890,17 @@
;; CHECK-NEXT: (struct.new $A
;; CHECK-NEXT: (local.tee $temp
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $non-nullability (param $nn (ref $A))
+ (func $non-nullability (param $nn (ref $A)) (param $A (ref null $A))
(local $temp (ref null $A))
;; Set a non-null value to the field.
(struct.set $A 0
- (ref.null $A)
+ (local.get $A)
(local.get $nn)
)
;; Set a get of the same field to the field - this is a copy. However, the
@@ -907,10 +909,10 @@
;; the local. We could add casts perhaps, but for now we do not optimize,
;; and type $A's field will remain nullable.
(struct.set $A 0
- (ref.null $A)
+ (local.get $A)
(local.tee $temp
(struct.get $A 0
- (ref.null $A)
+ (local.get $A)
)
)
)
@@ -919,7 +921,7 @@
(struct.new $A
(local.tee $temp
(struct.get $A 0
- (ref.null $A)
+ (local.get $A)
)
)
)
@@ -933,9 +935,9 @@
;; CHECK: (type $B (struct_subtype (field (ref null $B)) $A))
(type $B (struct_subtype (field (ref null $A)) $A))
- ;; CHECK: (type $ref?|$B|_=>_none (func_subtype (param (ref null $B)) func))
+ ;; CHECK: (type $ref?|$B|_ref?|$A|_=>_none (func_subtype (param (ref null $B) (ref null $A)) func))
- ;; CHECK: (func $heap-type (type $ref?|$B|_=>_none) (param $b (ref null $B))
+ ;; CHECK: (func $heap-type (type $ref?|$B|_ref?|$A|_=>_none) (param $b (ref null $B)) (param $A (ref null $A))
;; CHECK-NEXT: (local $a (ref null $A))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $B
@@ -946,13 +948,13 @@
;; CHECK-NEXT: (struct.new $A
;; CHECK-NEXT: (local.tee $a
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $heap-type (param $b (ref null $B))
+ (func $heap-type (param $b (ref null $B)) (param $A (ref null $A))
(local $a (ref null $A))
;; Similar to the above, but instead of non-nullability being the issue,
;; now it is the heap type. We write a B to B's field, so we can trivially
@@ -969,7 +971,7 @@
(struct.new $A
(local.tee $a
(struct.get $A 0
- (ref.null $A)
+ (local.get $A)
)
)
)
@@ -981,19 +983,19 @@
;; CHECK: (type $A (struct_subtype (field (mut (ref $A))) data))
(type $A (struct_subtype (field (mut (ref null $A))) data))
- ;; CHECK: (type $ref|$A|_=>_none (func_subtype (param (ref $A)) func))
+ ;; CHECK: (type $ref|$A|_ref?|$A|_=>_none (func_subtype (param (ref $A) (ref null $A)) func))
- ;; CHECK: (func $non-nullability-block (type $ref|$A|_=>_none) (param $nn (ref $A))
+ ;; CHECK: (func $non-nullability-block (type $ref|$A|_ref?|$A|_=>_none) (param $nn (ref $A)) (param $A (ref null $A))
;; CHECK-NEXT: (struct.set $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (local.get $nn)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (if (result (ref $A))
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
@@ -1003,27 +1005,27 @@
;; CHECK-NEXT: (if (result (ref $A))
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (struct.get $A 0
- ;; CHECK-NEXT: (ref.null $A)
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $non-nullability-block (param $nn (ref $A))
+ (func $non-nullability-block (param $nn (ref $A)) (param $A (ref null $A))
(struct.set $A 0
- (ref.null $A)
+ (local.get $A)
(local.get $nn)
)
;; As above, but instead of a local.tee fallthrough, use an if. We *can*
;; optimize in this case, as ifs etc do not pose a problem (we'll refinalize
;; the ifs to the proper, non-nullable type, the same as the field).
(struct.set $A 0
- (ref.null $A)
+ (local.get $A)
(if (result (ref null $A))
(i32.const 1)
(struct.get $A 0
- (ref.null $A)
+ (local.get $A)
)
(unreachable)
)
@@ -1033,7 +1035,7 @@
(if (result (ref null $A))
(i32.const 1)
(struct.get $A 0
- (ref.null $A)
+ (local.get $A)
)
(unreachable)
)
diff --git a/test/lit/table-operations.wast b/test/lit/table-operations.wast
index ace31a9c7..842270561 100644
--- a/test/lit/table-operations.wast
+++ b/test/lit/table-operations.wast
@@ -134,13 +134,13 @@
;; CHECK-BINARY: (func $table-grow (param $sz i32) (result i32)
;; CHECK-BINARY-NEXT: (table.grow $table-1
- ;; CHECK-BINARY-NEXT: (ref.null func)
+ ;; CHECK-BINARY-NEXT: (ref.null nofunc)
;; CHECK-BINARY-NEXT: (local.get $sz)
;; CHECK-BINARY-NEXT: )
;; CHECK-BINARY-NEXT: )
;; CHECK-TEXT: (func $table-grow (param $sz i32) (result i32)
;; CHECK-TEXT-NEXT: (table.grow $table-1
- ;; CHECK-TEXT-NEXT: (ref.null func)
+ ;; CHECK-TEXT-NEXT: (ref.null nofunc)
;; CHECK-TEXT-NEXT: (local.get $sz)
;; CHECK-TEXT-NEXT: )
;; CHECK-TEXT-NEXT: )
@@ -197,7 +197,7 @@
;; CHECK-NODEBUG: (func $4 (param $0 i32) (result i32)
;; CHECK-NODEBUG-NEXT: (table.grow $0
-;; CHECK-NODEBUG-NEXT: (ref.null func)
+;; CHECK-NODEBUG-NEXT: (ref.null nofunc)
;; CHECK-NODEBUG-NEXT: (local.get $0)
;; CHECK-NODEBUG-NEXT: )
;; CHECK-NODEBUG-NEXT: )
diff --git a/test/lit/types-function-references.wast b/test/lit/types-function-references.wast
index f4b244c50..8722ff3fd 100644
--- a/test/lit/types-function-references.wast
+++ b/test/lit/types-function-references.wast
@@ -22,8 +22,6 @@
(type $_=>_eqref (func (result eqref)))
;; CHECK-BINARY: (type $i32-i32 (func (param i32) (result i32)))
- ;; CHECK-BINARY: (type $=>eqref (func (result eqref)))
-
;; CHECK-BINARY: (type $ref|$i32-i32|_=>_i32 (func (param (ref $i32-i32)) (result i32)))
;; CHECK-BINARY: (type $ref?|$i32-i32|_=>_i32 (func (param (ref null $i32-i32)) (result i32)))
@@ -33,8 +31,6 @@
;; CHECK-BINARY: (type $f64_=>_ref_null<_->_eqref> (func (param f64) (result (ref null $=>eqref))))
;; CHECK-TEXT: (type $i32-i32 (func (param i32) (result i32)))
- ;; CHECK-TEXT: (type $=>eqref (func (result eqref)))
-
;; CHECK-TEXT: (type $ref|$i32-i32|_=>_i32 (func (param (ref $i32-i32)) (result i32)))
;; CHECK-TEXT: (type $ref?|$i32-i32|_=>_i32 (func (param (ref null $i32-i32)) (result i32)))
@@ -43,18 +39,26 @@
;; CHECK-TEXT: (type $f64_=>_ref_null<_->_eqref> (func (param f64) (result (ref null $=>eqref))))
(type $f64_=>_ref_null<_->_eqref> (func (param f64) (result (ref null $_=>_eqref))))
- (type $=>eqref (func (result eqref)))
;; CHECK-BINARY: (type $=>anyref (func (result anyref)))
+
+ ;; CHECK-BINARY: (type $none_=>_i32_ref?|$mixed_results|_f64 (func (result i32 (ref null $mixed_results) f64)))
+
+ ;; CHECK-BINARY: (type $ref?|$mixed_results|_=>_none (func (param (ref null $mixed_results))))
+
+ ;; CHECK-BINARY: (type $=>eqref (func (result eqref)))
;; CHECK-TEXT: (type $=>anyref (func (result anyref)))
+
+ ;; CHECK-TEXT: (type $none_=>_i32_ref?|$mixed_results|_f64 (func (result i32 (ref null $mixed_results) f64)))
+
+ ;; CHECK-TEXT: (type $ref?|$mixed_results|_=>_none (func (param (ref null $mixed_results))))
+
+ ;; CHECK-TEXT: (type $=>eqref (func (result eqref)))
+ (type $=>eqref (func (result eqref)))
(type $=>anyref (func (result anyref)))
(type $mixed_results (func (result anyref f32 anyref f32)))
(type $i32-i32 (func (param i32) (result i32)))
- ;; CHECK-BINARY: (type $none_=>_i32_ref?|$mixed_results|_f64 (func (result i32 (ref null $mixed_results) f64)))
-
- ;; CHECK-BINARY: (type $ref?|$mixed_results|_=>_none (func (param (ref null $mixed_results))))
-
;; CHECK-BINARY: (elem declare func $call-ref $call-ref-more)
;; CHECK-BINARY: (func $call-ref
@@ -62,10 +66,6 @@
;; CHECK-BINARY-NEXT: (ref.func $call-ref)
;; CHECK-BINARY-NEXT: )
;; CHECK-BINARY-NEXT: )
- ;; CHECK-TEXT: (type $none_=>_i32_ref?|$mixed_results|_f64 (func (result i32 (ref null $mixed_results) f64)))
-
- ;; CHECK-TEXT: (type $ref?|$mixed_results|_=>_none (func (param (ref null $mixed_results))))
-
;; CHECK-TEXT: (elem declare func $call-ref $call-ref-more)
;; CHECK-TEXT: (func $call-ref
@@ -160,10 +160,10 @@
(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 $=>eqref)
+ ;; CHECK-BINARY-NEXT: (ref.null nofunc)
;; CHECK-BINARY-NEXT: )
;; CHECK-TEXT: (func $ref-in-sig (param $0 f64) (result (ref null $=>eqref))
- ;; CHECK-TEXT-NEXT: (ref.null $=>eqref)
+ ;; CHECK-TEXT-NEXT: (ref.null nofunc)
;; CHECK-TEXT-NEXT: )
(func $ref-in-sig (param $0 f64) (result (ref null $=>eqref))
(ref.null $=>eqref)
@@ -380,8 +380,6 @@
;; CHECK-NODEBUG: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; CHECK-NODEBUG: (type $none_=>_eqref (func (result eqref)))
-
;; CHECK-NODEBUG: (type $ref|i32_->_i32|_=>_i32 (func (param (ref $i32_=>_i32)) (result i32)))
;; CHECK-NODEBUG: (type $ref?|i32_->_i32|_=>_i32 (func (param (ref null $i32_=>_i32)) (result i32)))
@@ -396,6 +394,8 @@
;; CHECK-NODEBUG: (type $ref?|none_->_anyref_f32_anyref_f32|_=>_none (func (param (ref null $none_=>_anyref_f32_anyref_f32))))
+;; CHECK-NODEBUG: (type $none_=>_eqref (func (result eqref)))
+
;; CHECK-NODEBUG: (elem declare func $0 $2)
;; CHECK-NODEBUG: (func $0
@@ -443,7 +443,7 @@
;; CHECK-NODEBUG-NEXT: )
;; CHECK-NODEBUG: (func $6 (param $0 f64) (result (ref null $none_=>_eqref))
-;; CHECK-NODEBUG-NEXT: (ref.null $none_=>_eqref)
+;; CHECK-NODEBUG-NEXT: (ref.null nofunc)
;; CHECK-NODEBUG-NEXT: )
;; CHECK-NODEBUG: (func $7
diff --git a/test/lit/validation/eqref.wast b/test/lit/validation/eqref.wast
index 78b6e75d2..4c97ad39b 100644
--- a/test/lit/validation/eqref.wast
+++ b/test/lit/validation/eqref.wast
@@ -4,16 +4,12 @@
;; RUN: not wasm-opt --enable-reference-types %s 2>&1 | filecheck %s --check-prefix NO-GC
;; RUN: wasm-opt --enable-reference-types --enable-gc %s -o - -S | filecheck %s --check-prefix GC
-;; NO-GC: ref.null type should be allowed
+;; NO-GC: all used types should be allowed
-;; GC: (drop
-;; GC: (ref.null eq)
-;; GC: )
+;; GC: (func $foo (param $x eqref)
(module
- (func $foo
- (drop
- (ref.null eq)
- )
+ (func $foo (param $x eqref)
+ (nop)
)
)
diff --git a/test/multi-table.wast.from-wast b/test/multi-table.wast.from-wast
index 73a9abea3..ece92124c 100644
--- a/test/multi-table.wast.from-wast
+++ b/test/multi-table.wast.from-wast
@@ -10,11 +10,11 @@
(elem $0 (table $t1) (i32.const 0) func $f)
(elem $1 (table $t2) (i32.const 0) func $f)
(elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g)
- (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null func))
+ (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc))
(elem $e3-2 (table $t3) (i32.const 2) func $f $g)
(elem $passive-1 func $f $g)
- (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null func))
- (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null $none_=>_none) (global.get $g1))
+ (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc))
+ (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1))
(elem $empty func)
(elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h))
(func $f
diff --git a/test/multi-table.wast.fromBinary b/test/multi-table.wast.fromBinary
index 427fb44f3..b70e78a2f 100644
--- a/test/multi-table.wast.fromBinary
+++ b/test/multi-table.wast.fromBinary
@@ -10,11 +10,11 @@
(elem $0 (table $t1) (i32.const 0) func $f)
(elem $1 (table $t2) (i32.const 0) func $f)
(elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g)
- (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null func))
+ (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc))
(elem $e3-2 (table $t3) (i32.const 2) func $f $g)
(elem $passive-1 func $f $g)
- (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null func))
- (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null $none_=>_none) (global.get $g1))
+ (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc))
+ (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1))
(elem $empty func)
(elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h))
(func $f
diff --git a/test/multi-table.wast.fromBinary.noDebugInfo b/test/multi-table.wast.fromBinary.noDebugInfo
index 7fc667087..cf938054a 100644
--- a/test/multi-table.wast.fromBinary.noDebugInfo
+++ b/test/multi-table.wast.fromBinary.noDebugInfo
@@ -10,11 +10,11 @@
(elem $0 (table $timport$0) (i32.const 0) func $0)
(elem $1 (table $0) (i32.const 0) func $0)
(elem $2 (table $0) (i32.const 1) func $0 $1)
- (elem $3 (table $1) (global.get $global$1) funcref (ref.func $0) (ref.null func))
+ (elem $3 (table $1) (global.get $global$1) funcref (ref.func $0) (ref.null nofunc))
(elem $4 (table $1) (i32.const 2) func $0 $1)
(elem $5 func $0 $1)
- (elem $6 funcref (ref.func $0) (ref.func $1) (ref.null func))
- (elem $7 (ref null $none_=>_none) (ref.func $0) (ref.func $1) (ref.null $none_=>_none) (global.get $global$0))
+ (elem $6 funcref (ref.func $0) (ref.func $1) (ref.null nofunc))
+ (elem $7 (ref null $none_=>_none) (ref.func $0) (ref.func $1) (ref.null nofunc) (global.get $global$0))
(elem $8 func)
(elem $9 (table $3) (i32.const 0) (ref null $none_=>_none) (ref.func $0) (ref.func $2))
(func $0
diff --git a/test/multivalue.wast.from-wast b/test/multivalue.wast.from-wast
index bdeb80cd4..a09eb88ce 100644
--- a/test/multivalue.wast.from-wast
+++ b/test/multivalue.wast.from-wast
@@ -139,12 +139,12 @@
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null extern)
+ (ref.null noextern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null extern)
+ (ref.null noextern)
)
)
)
diff --git a/test/multivalue.wast.fromBinary b/test/multivalue.wast.fromBinary
index dd39d4b34..28e24a2f4 100644
--- a/test/multivalue.wast.fromBinary
+++ b/test/multivalue.wast.fromBinary
@@ -397,12 +397,12 @@
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null extern)
+ (ref.null noextern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null extern)
+ (ref.null noextern)
)
)
)
diff --git a/test/multivalue.wast.fromBinary.noDebugInfo b/test/multivalue.wast.fromBinary.noDebugInfo
index 66c0f52c5..192902759 100644
--- a/test/multivalue.wast.fromBinary.noDebugInfo
+++ b/test/multivalue.wast.fromBinary.noDebugInfo
@@ -397,12 +397,12 @@
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null extern)
+ (ref.null noextern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null extern)
+ (ref.null noextern)
)
)
)
diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt
index b3c8b936a..e19110848 100644
--- a/test/passes/Oz_fuzz-exec_all-features.txt
+++ b/test/passes/Oz_fuzz-exec_all-features.txt
@@ -173,7 +173,7 @@
(struct.new_default $struct)
)
(drop
- (block $any (result anyref)
+ (block $any (result (ref null $struct))
(call $log
(i32.const 1)
)
@@ -185,7 +185,7 @@
(call $log
(i32.const 999)
)
- (ref.null any)
+ (ref.null none)
)
)
)
diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt
index 1fbea9d64..ea582d8d4 100644
--- a/test/passes/precompute_all-features.txt
+++ b/test/passes/precompute_all-features.txt
@@ -254,7 +254,7 @@
(i32.const 1)
)
(func $reftype-test (result externref)
- (ref.null extern)
+ (ref.null noextern)
)
(func $dummy
(nop)
@@ -276,22 +276,22 @@
)
)
(drop
- (block $l2 (result externref)
+ (block $l2 (result nullexternref)
(drop
(block $l3
(global.set $global-mut
(i32.const 1)
)
(br $l2
- (ref.null extern)
+ (ref.null noextern)
)
)
)
- (ref.null extern)
+ (ref.null noextern)
)
)
(drop
- (block $l4 (result funcref)
+ (block $l4 (result (ref null $none_=>_none))
(drop
(block $l5
(global.set $global-mut
@@ -302,7 +302,7 @@
)
)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
)
diff --git a/test/passes/remove-unused-brs_all-features.txt b/test/passes/remove-unused-brs_all-features.txt
index c340519f8..ab3ead0f4 100644
--- a/test/passes/remove-unused-brs_all-features.txt
+++ b/test/passes/remove-unused-brs_all-features.txt
@@ -18,7 +18,7 @@
(i32.const 1)
)
)
- (ref.null $struct)
+ (ref.null none)
)
)
(func $test-prefinalize (result f64)
@@ -136,59 +136,59 @@
)
(func $br_on-to-flow
(drop
- (block $data (result dataref)
+ (block $data (result nullref)
(drop
(ref.func $br_on-to-flow)
)
- (ref.null data)
+ (ref.null none)
)
)
(drop
- (block $datab (result dataref)
+ (block $datab (result nullref)
(drop
(i31.new
(i32.const 1337)
)
)
- (ref.null data)
+ (ref.null none)
)
)
(drop
- (block $func (result funcref)
+ (block $func (result nullfuncref)
(drop
(array.new_default $vector
(i32.const 2)
)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
- (block $funcb (result funcref)
+ (block $funcb (result nullfuncref)
(drop
(i31.new
(i32.const 1337)
)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
- (block $i31 (result i31ref)
+ (block $i31 (result nullref)
(drop
(array.new_default $vector
(i32.const 2)
)
)
- (ref.null i31)
+ (ref.null none)
)
)
(drop
- (block $i31b (result i31ref)
+ (block $i31b (result nullref)
(drop
(ref.func $br_on-to-flow)
)
- (ref.null i31)
+ (ref.null none)
)
)
)
diff --git a/test/passes/simplify-globals_all-features.txt b/test/passes/simplify-globals_all-features.txt
index ace056aac..d94ac55d3 100644
--- a/test/passes/simplify-globals_all-features.txt
+++ b/test/passes/simplify-globals_all-features.txt
@@ -215,7 +215,7 @@
(type $none_=>_none (func))
(import "env" "global-1" (global $g1 externref))
(global $g2 externref (global.get $g1))
- (global $g3 externref (ref.null extern))
+ (global $g3 externref (ref.null noextern))
(func $test1
(drop
(global.get $g1)
@@ -226,7 +226,7 @@
)
(func $test2
(drop
- (ref.null extern)
+ (ref.null noextern)
)
)
)
diff --git a/test/passes/simplify-globals_all-features_fuzz-exec.txt b/test/passes/simplify-globals_all-features_fuzz-exec.txt
index d38d06704..f4e2df478 100644
--- a/test/passes/simplify-globals_all-features_fuzz-exec.txt
+++ b/test/passes/simplify-globals_all-features_fuzz-exec.txt
@@ -3,7 +3,7 @@
(module
(type $f32_i31ref_i64_f64_funcref_=>_none (func (param f32 i31ref i64 f64 funcref)))
(type $none_=>_funcref (func (result funcref)))
- (global $global$0 (mut funcref) (ref.null func))
+ (global $global$0 (mut funcref) (ref.null nofunc))
(elem declare func $0)
(export "export" (func $1))
(func $0 (param $0 f32) (param $1 i31ref) (param $2 i64) (param $3 f64) (param $4 funcref)
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
index b460f8801..8e2d73001 100644
--- a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
@@ -19,7 +19,7 @@
(func $foo (result v128 externref)
(tuple.make
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
- (ref.null extern)
+ (ref.null noextern)
)
)
(func $bar (result v128 externref)
diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
index 927c07bca..e984e8be5 100644
--- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
+++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
@@ -1,45 +1,45 @@
total
- [exports] : 14
- [funcs] : 19
+ [exports] : 7
+ [funcs] : 7
[globals] : 6
[imports] : 5
[memories] : 1
[memory-data] : 22
- [table-data] : 12
+ [table-data] : 8
[tables] : 1
[tags] : 2
- [total] : 771
- [vars] : 27
- ArrayInit : 1
- AtomicCmpxchg : 1
- AtomicFence : 1
+ [total] : 433
+ [vars] : 6
AtomicRMW : 1
- Binary : 82
- Block : 105
- Break : 19
- Call : 23
- CallIndirect : 3
- CallRef : 2
- Const : 145
- DataDrop : 1
- Drop : 7
- GlobalGet : 65
- GlobalSet : 31
- I31New : 3
- If : 35
- Load : 21
- LocalGet : 48
- LocalSet : 26
- Loop : 12
- Nop : 16
- RefEq : 1
- RefFunc : 17
- RefNull : 4
- Return : 35
+ Binary : 56
+ Block : 36
+ Break : 4
+ Call : 22
+ CallRef : 8
+ Const : 113
+ Drop : 5
+ GlobalGet : 24
+ GlobalSet : 11
+ I31Get : 2
+ I31New : 7
+ If : 14
+ Load : 17
+ LocalGet : 24
+ LocalSet : 17
+ Loop : 4
+ MemoryFill : 1
+ Nop : 1
+ RefEq : 2
+ RefFunc : 18
+ RefIs : 1
+ RefNull : 2
+ Return : 12
SIMDExtract : 1
- Select : 1
- Store : 6
+ SIMDLoad : 1
+ Select : 7
+ Store : 2
StructNew : 1
- TupleExtract : 2
- TupleMake : 8
- Unary : 47
+ Switch : 1
+ TupleMake : 2
+ Unary : 13
+ Unreachable : 3
diff --git a/test/reference-types.wast.from-wast b/test/reference-types.wast.from-wast
index 121f3c6f4..e3a04c760 100644
--- a/test/reference-types.wast.from-wast
+++ b/test/reference-types.wast.from-wast
@@ -10,11 +10,11 @@
(type $eqref_=>_funcref (func (param eqref) (result funcref)))
(import "env" "import_global" (global $import_global eqref))
(import "env" "import_func" (func $import_func (param eqref) (result funcref)))
- (global $global_eqref (mut eqref) (ref.null eq))
- (global $global_funcref (mut funcref) (ref.null func))
+ (global $global_eqref (mut eqref) (ref.null none))
+ (global $global_funcref (mut funcref) (ref.null nofunc))
(global $global_funcref_func (mut funcref) (ref.func $foo))
- (global $global_anyref (mut anyref) (ref.null any))
- (global $global_anyref2 (mut anyref) (ref.null eq))
+ (global $global_anyref (mut anyref) (ref.null none))
+ (global $global_anyref2 (mut anyref) (ref.null none))
(table $0 3 3 funcref)
(elem (i32.const 0) $take_eqref $take_funcref $take_anyref)
(elem declare func $foo $ref-taken-but-not-in-table)
@@ -44,7 +44,7 @@
(global.get $global_eqref)
)
(local.set $local_eqref
- (ref.null eq)
+ (ref.null none)
)
(local.set $local_funcref
(local.get $local_funcref)
@@ -53,7 +53,7 @@
(global.get $global_funcref)
)
(local.set $local_funcref
- (ref.null func)
+ (ref.null nofunc)
)
(local.set $local_funcref
(ref.func $foo)
@@ -65,7 +65,7 @@
(global.get $global_anyref)
)
(local.set $local_anyref
- (ref.null any)
+ (ref.null none)
)
(local.set $local_anyref
(local.get $local_eqref)
@@ -74,7 +74,7 @@
(global.get $global_eqref)
)
(local.set $local_anyref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_eqref
(global.get $global_eqref)
@@ -83,7 +83,7 @@
(local.get $local_eqref)
)
(global.set $global_eqref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_funcref
(global.get $global_funcref)
@@ -92,7 +92,7 @@
(local.get $local_funcref)
)
(global.set $global_funcref
- (ref.null func)
+ (ref.null nofunc)
)
(global.set $global_funcref
(ref.func $foo)
@@ -104,7 +104,7 @@
(local.get $local_anyref)
)
(global.set $global_anyref
- (ref.null any)
+ (ref.null none)
)
(global.set $global_anyref
(global.get $global_eqref)
@@ -113,7 +113,7 @@
(local.get $local_eqref)
)
(global.set $global_anyref
- (ref.null eq)
+ (ref.null none)
)
(call $take_eqref
(local.get $local_eqref)
@@ -122,7 +122,7 @@
(global.get $global_eqref)
)
(call $take_eqref
- (ref.null eq)
+ (ref.null none)
)
(call $take_funcref
(local.get $local_funcref)
@@ -131,7 +131,7 @@
(global.get $global_funcref)
)
(call $take_funcref
- (ref.null func)
+ (ref.null nofunc)
)
(call $take_funcref
(ref.func $foo)
@@ -143,7 +143,7 @@
(global.get $global_anyref)
)
(call $take_anyref
- (ref.null any)
+ (ref.null none)
)
(call $take_anyref
(local.get $local_eqref)
@@ -152,7 +152,7 @@
(global.get $global_eqref)
)
(call $take_anyref
- (ref.null eq)
+ (ref.null none)
)
(call_indirect $0 (type $sig_eqref)
(local.get $local_eqref)
@@ -163,7 +163,7 @@
(i32.const 0)
)
(call_indirect $0 (type $sig_eqref)
- (ref.null eq)
+ (ref.null none)
(i32.const 0)
)
(call_indirect $0 (type $sig_funcref)
@@ -175,7 +175,7 @@
(i32.const 1)
)
(call_indirect $0 (type $sig_funcref)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
(call_indirect $0 (type $sig_funcref)
@@ -191,7 +191,7 @@
(i32.const 3)
)
(call_indirect $0 (type $sig_anyref)
- (ref.null any)
+ (ref.null none)
(i32.const 3)
)
(call_indirect $0 (type $sig_anyref)
@@ -203,7 +203,7 @@
(i32.const 3)
)
(call_indirect $0 (type $sig_anyref)
- (ref.null eq)
+ (ref.null none)
(i32.const 3)
)
(drop
@@ -225,7 +225,7 @@
(drop
(block $block1 (result eqref)
(br_if $block1
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
@@ -249,7 +249,7 @@
(drop
(block $block4 (result funcref)
(br_if $block4
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
)
@@ -281,7 +281,7 @@
(drop
(block $block8 (result anyref)
(br_if $block8
- (ref.null any)
+ (ref.null none)
(i32.const 1)
)
)
@@ -297,7 +297,7 @@
(drop
(block $block10 (result anyref)
(br_if $block10
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
@@ -314,7 +314,7 @@
)
(drop
(loop $loop-in12 (result eqref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -329,7 +329,7 @@
)
(drop
(loop $loop-in15 (result funcref)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -349,7 +349,7 @@
)
(drop
(loop $loop-in19 (result anyref)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -364,28 +364,28 @@
)
(drop
(loop $loop-in22 (result anyref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
(if (result eqref)
(i32.const 1)
(local.get $local_eqref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
(if (result funcref)
(i32.const 1)
(local.get $local_funcref)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
(if (result anyref)
(i32.const 1)
(local.get $local_anyref)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -398,8 +398,8 @@
(drop
(if (result anyref)
(i32.const 1)
- (ref.null eq)
- (ref.null i31)
+ (ref.null none)
+ (ref.null none)
)
)
(drop
@@ -408,7 +408,7 @@
(i31.new
(i32.const 0)
)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -420,7 +420,7 @@
(drop
(pop i32)
)
- (ref.null eq)
+ (ref.null none)
)
)
)
@@ -433,7 +433,7 @@
(drop
(pop i32)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
)
@@ -446,14 +446,14 @@
(drop
(pop i32)
)
- (ref.null any)
+ (ref.null none)
)
)
)
(drop
(try $try30 (result anyref)
(do
- (ref.null eq)
+ (ref.null none)
)
(catch $e-i32
(drop
@@ -466,14 +466,14 @@
(drop
(select (result eqref)
(local.get $local_eqref)
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
(drop
(select (result funcref)
(local.get $local_funcref)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
)
@@ -505,7 +505,7 @@
)
(drop
(ref.is_null
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -520,7 +520,7 @@
)
(drop
(ref.is_null
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -540,7 +540,7 @@
)
(drop
(ref.is_null
- (ref.null any)
+ (ref.null none)
)
)
)
@@ -552,7 +552,7 @@
(global.get $global_eqref)
)
(func $return_eqref_null (result eqref)
- (ref.null eq)
+ (ref.null none)
)
(func $return_funcref_local (result funcref)
(local $local_funcref funcref)
@@ -562,7 +562,7 @@
(global.get $global_funcref)
)
(func $return_funcref_null (result funcref)
- (ref.null func)
+ (ref.null nofunc)
)
(func $return_funcref_func (result funcref)
(ref.func $foo)
@@ -575,7 +575,7 @@
(global.get $global_anyref)
)
(func $return_anyref_null (result anyref)
- (ref.null any)
+ (ref.null none)
)
(func $return_anyref2 (result anyref)
(local $local_eqref eqref)
@@ -585,7 +585,7 @@
(global.get $global_eqref)
)
(func $return_anyref4 (result anyref)
- (ref.null eq)
+ (ref.null none)
)
(func $returns_eqref (result eqref)
(local $local_eqref eqref)
@@ -596,7 +596,7 @@
(global.get $global_eqref)
)
(return
- (ref.null eq)
+ (ref.null none)
)
)
(func $returns_funcref (result funcref)
@@ -611,7 +611,7 @@
(ref.func $foo)
)
(return
- (ref.null func)
+ (ref.null nofunc)
)
)
(func $returns_anyref (result anyref)
@@ -623,7 +623,7 @@
(global.get $global_anyref)
)
(return
- (ref.null any)
+ (ref.null none)
)
)
(func $returns_anyref2 (result anyref)
@@ -636,7 +636,7 @@
(global.get $global_eqref)
)
(return
- (ref.null eq)
+ (ref.null none)
)
)
(func $ref-user
diff --git a/test/reference-types.wast.fromBinary b/test/reference-types.wast.fromBinary
index 80d85fd26..670645cf2 100644
--- a/test/reference-types.wast.fromBinary
+++ b/test/reference-types.wast.fromBinary
@@ -10,11 +10,11 @@
(type $eqref_=>_funcref (func (param eqref) (result funcref)))
(import "env" "import_global" (global $import_global eqref))
(import "env" "import_func" (func $import_func (param eqref) (result funcref)))
- (global $global_eqref (mut eqref) (ref.null eq))
- (global $global_funcref (mut funcref) (ref.null func))
+ (global $global_eqref (mut eqref) (ref.null none))
+ (global $global_funcref (mut funcref) (ref.null nofunc))
(global $global_funcref_func (mut funcref) (ref.func $foo))
- (global $global_anyref (mut anyref) (ref.null any))
- (global $global_anyref2 (mut anyref) (ref.null eq))
+ (global $global_anyref (mut anyref) (ref.null none))
+ (global $global_anyref2 (mut anyref) (ref.null none))
(table $0 3 3 funcref)
(elem (i32.const 0) $take_eqref $take_funcref $take_anyref)
(elem declare func $foo $ref-taken-but-not-in-table)
@@ -44,7 +44,7 @@
(global.get $global_eqref)
)
(local.set $local_eqref
- (ref.null eq)
+ (ref.null none)
)
(local.set $local_funcref
(local.get $local_funcref)
@@ -53,7 +53,7 @@
(global.get $global_funcref)
)
(local.set $local_funcref
- (ref.null func)
+ (ref.null nofunc)
)
(local.set $local_funcref
(ref.func $foo)
@@ -65,7 +65,7 @@
(global.get $global_anyref)
)
(local.set $local_anyref
- (ref.null any)
+ (ref.null none)
)
(local.set $local_anyref
(local.get $local_eqref)
@@ -74,7 +74,7 @@
(global.get $global_eqref)
)
(local.set $local_anyref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_eqref
(global.get $global_eqref)
@@ -83,7 +83,7 @@
(local.get $local_eqref)
)
(global.set $global_eqref
- (ref.null eq)
+ (ref.null none)
)
(global.set $global_funcref
(global.get $global_funcref)
@@ -92,7 +92,7 @@
(local.get $local_funcref)
)
(global.set $global_funcref
- (ref.null func)
+ (ref.null nofunc)
)
(global.set $global_funcref
(ref.func $foo)
@@ -104,7 +104,7 @@
(local.get $local_anyref)
)
(global.set $global_anyref
- (ref.null any)
+ (ref.null none)
)
(global.set $global_anyref
(global.get $global_eqref)
@@ -113,7 +113,7 @@
(local.get $local_eqref)
)
(global.set $global_anyref
- (ref.null eq)
+ (ref.null none)
)
(call $take_eqref
(local.get $local_eqref)
@@ -122,7 +122,7 @@
(global.get $global_eqref)
)
(call $take_eqref
- (ref.null eq)
+ (ref.null none)
)
(call $take_funcref
(local.get $local_funcref)
@@ -131,7 +131,7 @@
(global.get $global_funcref)
)
(call $take_funcref
- (ref.null func)
+ (ref.null nofunc)
)
(call $take_funcref
(ref.func $foo)
@@ -143,7 +143,7 @@
(global.get $global_anyref)
)
(call $take_anyref
- (ref.null any)
+ (ref.null none)
)
(call $take_anyref
(local.get $local_eqref)
@@ -152,7 +152,7 @@
(global.get $global_eqref)
)
(call $take_anyref
- (ref.null eq)
+ (ref.null none)
)
(call_indirect $0 (type $sig_eqref)
(local.get $local_eqref)
@@ -163,7 +163,7 @@
(i32.const 0)
)
(call_indirect $0 (type $sig_eqref)
- (ref.null eq)
+ (ref.null none)
(i32.const 0)
)
(call_indirect $0 (type $sig_funcref)
@@ -175,7 +175,7 @@
(i32.const 1)
)
(call_indirect $0 (type $sig_funcref)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
(call_indirect $0 (type $sig_funcref)
@@ -191,7 +191,7 @@
(i32.const 3)
)
(call_indirect $0 (type $sig_anyref)
- (ref.null any)
+ (ref.null none)
(i32.const 3)
)
(call_indirect $0 (type $sig_anyref)
@@ -203,7 +203,7 @@
(i32.const 3)
)
(call_indirect $0 (type $sig_anyref)
- (ref.null eq)
+ (ref.null none)
(i32.const 3)
)
(drop
@@ -225,7 +225,7 @@
(drop
(block $label$3 (result eqref)
(br_if $label$3
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
@@ -249,7 +249,7 @@
(drop
(block $label$6 (result funcref)
(br_if $label$6
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
)
@@ -281,7 +281,7 @@
(drop
(block $label$10 (result anyref)
(br_if $label$10
- (ref.null any)
+ (ref.null none)
(i32.const 1)
)
)
@@ -297,7 +297,7 @@
(drop
(block $label$12 (result anyref)
(br_if $label$12
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
@@ -314,7 +314,7 @@
)
(drop
(loop $label$15 (result eqref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -329,7 +329,7 @@
)
(drop
(loop $label$18 (result funcref)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -349,7 +349,7 @@
)
(drop
(loop $label$22 (result anyref)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -364,28 +364,28 @@
)
(drop
(loop $label$25 (result anyref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
(if (result eqref)
(i32.const 1)
(local.get $local_eqref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
(if (result funcref)
(i32.const 1)
(local.get $local_funcref)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
(if (result anyref)
(i32.const 1)
(local.get $local_anyref)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -398,8 +398,8 @@
(drop
(if (result anyref)
(i32.const 1)
- (ref.null eq)
- (ref.null i31)
+ (ref.null none)
+ (ref.null none)
)
)
(drop
@@ -408,7 +408,7 @@
(i31.new
(i32.const 0)
)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -420,7 +420,7 @@
(drop
(pop i32)
)
- (ref.null eq)
+ (ref.null none)
)
)
)
@@ -433,7 +433,7 @@
(drop
(pop i32)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
)
@@ -446,14 +446,14 @@
(drop
(pop i32)
)
- (ref.null any)
+ (ref.null none)
)
)
)
(drop
(try $label$49 (result anyref)
(do
- (ref.null eq)
+ (ref.null none)
)
(catch $e-i32
(drop
@@ -466,14 +466,14 @@
(drop
(select (result eqref)
(local.get $local_eqref)
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
(drop
(select (result funcref)
(local.get $local_funcref)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
)
@@ -505,7 +505,7 @@
)
(drop
(ref.is_null
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -520,7 +520,7 @@
)
(drop
(ref.is_null
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -540,7 +540,7 @@
)
(drop
(ref.is_null
- (ref.null any)
+ (ref.null none)
)
)
)
@@ -552,7 +552,7 @@
(global.get $global_eqref)
)
(func $return_eqref_null (result eqref)
- (ref.null eq)
+ (ref.null none)
)
(func $return_funcref_local (result funcref)
(local $local_funcref funcref)
@@ -562,7 +562,7 @@
(global.get $global_funcref)
)
(func $return_funcref_null (result funcref)
- (ref.null func)
+ (ref.null nofunc)
)
(func $return_funcref_func (result funcref)
(ref.func $foo)
@@ -575,7 +575,7 @@
(global.get $global_anyref)
)
(func $return_anyref_null (result anyref)
- (ref.null any)
+ (ref.null none)
)
(func $return_anyref2 (result anyref)
(local $local_eqref eqref)
@@ -585,7 +585,7 @@
(global.get $global_eqref)
)
(func $return_anyref4 (result anyref)
- (ref.null eq)
+ (ref.null none)
)
(func $returns_eqref (result eqref)
(local $local_eqref eqref)
diff --git a/test/reference-types.wast.fromBinary.noDebugInfo b/test/reference-types.wast.fromBinary.noDebugInfo
index cc05523b2..85ebc9e9e 100644
--- a/test/reference-types.wast.fromBinary.noDebugInfo
+++ b/test/reference-types.wast.fromBinary.noDebugInfo
@@ -10,11 +10,11 @@
(type $eqref_=>_funcref (func (param eqref) (result funcref)))
(import "env" "import_global" (global $gimport$0 eqref))
(import "env" "import_func" (func $fimport$0 (param eqref) (result funcref)))
- (global $global$0 (mut eqref) (ref.null eq))
- (global $global$1 (mut funcref) (ref.null func))
+ (global $global$0 (mut eqref) (ref.null none))
+ (global $global$1 (mut funcref) (ref.null nofunc))
(global $global$2 (mut funcref) (ref.func $3))
- (global $global$3 (mut anyref) (ref.null any))
- (global $global$4 (mut anyref) (ref.null eq))
+ (global $global$3 (mut anyref) (ref.null none))
+ (global $global$4 (mut anyref) (ref.null none))
(table $0 3 3 funcref)
(elem (i32.const 0) $0 $1 $2)
(elem declare func $23 $3)
@@ -44,7 +44,7 @@
(global.get $global$0)
)
(local.set $0
- (ref.null eq)
+ (ref.null none)
)
(local.set $1
(local.get $1)
@@ -53,7 +53,7 @@
(global.get $global$1)
)
(local.set $1
- (ref.null func)
+ (ref.null nofunc)
)
(local.set $1
(ref.func $3)
@@ -65,7 +65,7 @@
(global.get $global$3)
)
(local.set $2
- (ref.null any)
+ (ref.null none)
)
(local.set $2
(local.get $0)
@@ -74,7 +74,7 @@
(global.get $global$0)
)
(local.set $2
- (ref.null eq)
+ (ref.null none)
)
(global.set $global$0
(global.get $global$0)
@@ -83,7 +83,7 @@
(local.get $0)
)
(global.set $global$0
- (ref.null eq)
+ (ref.null none)
)
(global.set $global$1
(global.get $global$1)
@@ -92,7 +92,7 @@
(local.get $1)
)
(global.set $global$1
- (ref.null func)
+ (ref.null nofunc)
)
(global.set $global$1
(ref.func $3)
@@ -104,7 +104,7 @@
(local.get $2)
)
(global.set $global$3
- (ref.null any)
+ (ref.null none)
)
(global.set $global$3
(global.get $global$0)
@@ -113,7 +113,7 @@
(local.get $0)
)
(global.set $global$3
- (ref.null eq)
+ (ref.null none)
)
(call $0
(local.get $0)
@@ -122,7 +122,7 @@
(global.get $global$0)
)
(call $0
- (ref.null eq)
+ (ref.null none)
)
(call $1
(local.get $1)
@@ -131,7 +131,7 @@
(global.get $global$1)
)
(call $1
- (ref.null func)
+ (ref.null nofunc)
)
(call $1
(ref.func $3)
@@ -143,7 +143,7 @@
(global.get $global$3)
)
(call $2
- (ref.null any)
+ (ref.null none)
)
(call $2
(local.get $0)
@@ -152,7 +152,7 @@
(global.get $global$0)
)
(call $2
- (ref.null eq)
+ (ref.null none)
)
(call_indirect $0 (type $eqref_=>_none)
(local.get $0)
@@ -163,7 +163,7 @@
(i32.const 0)
)
(call_indirect $0 (type $eqref_=>_none)
- (ref.null eq)
+ (ref.null none)
(i32.const 0)
)
(call_indirect $0 (type $funcref_=>_none)
@@ -175,7 +175,7 @@
(i32.const 1)
)
(call_indirect $0 (type $funcref_=>_none)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
(call_indirect $0 (type $funcref_=>_none)
@@ -191,7 +191,7 @@
(i32.const 3)
)
(call_indirect $0 (type $anyref_=>_none)
- (ref.null any)
+ (ref.null none)
(i32.const 3)
)
(call_indirect $0 (type $anyref_=>_none)
@@ -203,7 +203,7 @@
(i32.const 3)
)
(call_indirect $0 (type $anyref_=>_none)
- (ref.null eq)
+ (ref.null none)
(i32.const 3)
)
(drop
@@ -225,7 +225,7 @@
(drop
(block $label$3 (result eqref)
(br_if $label$3
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
@@ -249,7 +249,7 @@
(drop
(block $label$6 (result funcref)
(br_if $label$6
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
)
@@ -281,7 +281,7 @@
(drop
(block $label$10 (result anyref)
(br_if $label$10
- (ref.null any)
+ (ref.null none)
(i32.const 1)
)
)
@@ -297,7 +297,7 @@
(drop
(block $label$12 (result anyref)
(br_if $label$12
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
@@ -314,7 +314,7 @@
)
(drop
(loop $label$15 (result eqref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -329,7 +329,7 @@
)
(drop
(loop $label$18 (result funcref)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -349,7 +349,7 @@
)
(drop
(loop $label$22 (result anyref)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -364,28 +364,28 @@
)
(drop
(loop $label$25 (result anyref)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
(if (result eqref)
(i32.const 1)
(local.get $0)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
(if (result funcref)
(i32.const 1)
(local.get $1)
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
(if (result anyref)
(i32.const 1)
(local.get $2)
- (ref.null any)
+ (ref.null none)
)
)
(drop
@@ -398,8 +398,8 @@
(drop
(if (result anyref)
(i32.const 1)
- (ref.null eq)
- (ref.null i31)
+ (ref.null none)
+ (ref.null none)
)
)
(drop
@@ -408,7 +408,7 @@
(i31.new
(i32.const 0)
)
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -420,7 +420,7 @@
(drop
(pop i32)
)
- (ref.null eq)
+ (ref.null none)
)
)
)
@@ -433,7 +433,7 @@
(drop
(pop i32)
)
- (ref.null func)
+ (ref.null nofunc)
)
)
)
@@ -446,14 +446,14 @@
(drop
(pop i32)
)
- (ref.null any)
+ (ref.null none)
)
)
)
(drop
(try $label$49 (result anyref)
(do
- (ref.null eq)
+ (ref.null none)
)
(catch $tag$0
(drop
@@ -466,14 +466,14 @@
(drop
(select (result eqref)
(local.get $0)
- (ref.null eq)
+ (ref.null none)
(i32.const 1)
)
)
(drop
(select (result funcref)
(local.get $1)
- (ref.null func)
+ (ref.null nofunc)
(i32.const 1)
)
)
@@ -505,7 +505,7 @@
)
(drop
(ref.is_null
- (ref.null eq)
+ (ref.null none)
)
)
(drop
@@ -520,7 +520,7 @@
)
(drop
(ref.is_null
- (ref.null func)
+ (ref.null nofunc)
)
)
(drop
@@ -540,7 +540,7 @@
)
(drop
(ref.is_null
- (ref.null any)
+ (ref.null none)
)
)
)
@@ -552,7 +552,7 @@
(global.get $global$0)
)
(func $7 (result eqref)
- (ref.null eq)
+ (ref.null none)
)
(func $8 (result funcref)
(local $0 funcref)
@@ -562,7 +562,7 @@
(global.get $global$1)
)
(func $10 (result funcref)
- (ref.null func)
+ (ref.null nofunc)
)
(func $11 (result funcref)
(ref.func $3)
@@ -575,7 +575,7 @@
(global.get $global$3)
)
(func $14 (result anyref)
- (ref.null any)
+ (ref.null none)
)
(func $15 (result anyref)
(local $0 eqref)
@@ -585,7 +585,7 @@
(global.get $global$0)
)
(func $17 (result anyref)
- (ref.null eq)
+ (ref.null none)
)
(func $18 (result eqref)
(local $0 eqref)
diff --git a/test/unit/input/gc_target_feature.wasm b/test/unit/input/gc_target_feature.wasm
index df5ab9cc0..30b1b21b6 100644
--- a/test/unit/input/gc_target_feature.wasm
+++ b/test/unit/input/gc_target_feature.wasm
Binary files differ