summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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