summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/fuzz_opt.py17
-rwxr-xr-xscripts/gen-s-parser.py10
-rw-r--r--src/binaryen-c.cpp9
-rw-r--r--src/binaryen-c.h6
-rw-r--r--src/gen-s-parser.inc644
-rw-r--r--src/ir/ReFinalize.cpp2
-rw-r--r--src/ir/cost.h24
-rw-r--r--src/ir/effects.h2
-rw-r--r--src/ir/gc-type-utils.h13
-rw-r--r--src/ir/linear-execution.h1
-rw-r--r--src/ir/literal-utils.h10
-rw-r--r--src/ir/module-utils.cpp18
-rw-r--r--src/ir/possible-contents.cpp7
-rw-r--r--src/ir/properties.h9
-rw-r--r--src/ir/type-updating.cpp15
-rw-r--r--src/js/binaryen.js-post.js2
-rw-r--r--src/literal.h68
-rw-r--r--src/passes/Heap2Local.cpp7
-rw-r--r--src/passes/InstrumentMemory.cpp2
-rw-r--r--src/passes/OptimizeInstructions.cpp185
-rw-r--r--src/passes/Precompute.cpp5
-rw-r--r--src/passes/Print.cpp93
-rw-r--r--src/passes/StackIR.cpp10
-rw-r--r--src/tools/fuzzing.h11
-rw-r--r--src/tools/fuzzing/fuzzing.cpp31
-rw-r--r--src/tools/fuzzing/heap-types.cpp20
-rw-r--r--src/tools/fuzzing/parameters.h3
-rw-r--r--src/tools/wasm-ctor-eval.cpp1
-rw-r--r--src/tools/wasm-fuzz-types.cpp20
-rw-r--r--src/wasm-binary.h20
-rw-r--r--src/wasm-builder.h98
-rw-r--r--src/wasm-delegations-fields.def18
-rw-r--r--src/wasm-delegations.def2
-rw-r--r--src/wasm-interpreter.h97
-rw-r--r--src/wasm-s-parser.h10
-rw-r--r--src/wasm-type.h43
-rw-r--r--src/wasm.h59
-rw-r--r--src/wasm/literal.cpp74
-rw-r--r--src/wasm/wasm-binary.cpp122
-rw-r--r--src/wasm/wasm-s-parser.cpp127
-rw-r--r--src/wasm/wasm-stack.cpp79
-rw-r--r--src/wasm/wasm-type.cpp149
-rw-r--r--src/wasm/wasm-validator.cpp143
-rw-r--r--src/wasm/wasm.cpp66
-rw-r--r--src/wasm/wat-parser.cpp44
-rw-r--r--src/wasm2js.h8
-rw-r--r--test/binaryen.js/kitchen-sink.js2
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt18
-rw-r--r--test/example/type-builder-nominal.cpp9
-rw-r--r--test/example/type-builder-nominal.txt20
-rw-r--r--test/example/type-builder.cpp34
-rw-r--r--test/example/typeinfo.cpp47
-rw-r--r--test/example/typeinfo.txt16
-rw-r--r--test/gtest/type-builder.cpp11
-rw-r--r--test/heap-types.wast102
-rw-r--r--test/heap-types.wast.from-wast134
-rw-r--r--test/heap-types.wast.fromBinary125
-rw-r--r--test/heap-types.wast.fromBinary.noDebugInfo159
-rw-r--r--test/lit/exec/rtts.wast153
-rw-r--r--test/lit/forward-declared-types.wast26
-rw-r--r--test/lit/fuzz-types/isorecursive.test34
-rw-r--r--test/lit/fuzz-types/nominal.test40
-rw-r--r--test/lit/fuzz-types/structural.test24
-rw-r--r--test/lit/passes/cfp.wast231
-rw-r--r--test/lit/passes/dae-gc.wast30
-rw-r--r--test/lit/passes/gto-removals.wast32
-rw-r--r--test/lit/passes/gufa-refs.wast43
-rw-r--r--test/lit/passes/gufa-vs-cfp.wast233
-rw-r--r--test/lit/passes/heap2local.wast598
-rw-r--r--test/lit/passes/inlining-optimizing.wast4
-rw-r--r--test/lit/passes/inlining_all-features.wast38
-rw-r--r--test/lit/passes/inlining_splitting.wast42
-rw-r--r--test/lit/passes/local-cse_all-features.wast24
-rw-r--r--test/lit/passes/optimize-instructions-call_ref.wast6
-rw-r--r--test/lit/passes/optimize-instructions-gc-iit.wast198
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast293
-rw-r--r--test/lit/passes/optimize-instructions-iit-eh.wast29
-rw-r--r--test/lit/passes/precompute-gc.wast289
-rw-r--r--test/lit/passes/remove-unused-brs-gc.wast32
-rw-r--r--test/lit/passes/roundtrip-gc-types.wast27
-rw-r--r--test/lit/passes/roundtrip-gc.wast20
-rw-r--r--test/lit/passes/vacuum-gc.wast34
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.txt215
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.wast210
-rw-r--r--test/passes/remove-unused-brs_all-features.txt18
-rw-r--r--test/passes/remove-unused-brs_all-features.wast18
-rw-r--r--test/passes/vacuum_all-features.wast4
-rw-r--r--test/spec/array.wast24
-rw-r--r--test/spec/ref_cast.wast78
-rw-r--r--test/spec/struct.wast31
90 files changed, 1239 insertions, 4920 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py
index e43d40dec..bb25dd808 100755
--- a/scripts/fuzz_opt.py
+++ b/scripts/fuzz_opt.py
@@ -340,17 +340,17 @@ def pick_initial_contents():
FEATURE_OPTS += [
# has not been fuzzed in general yet
'--disable-memory64',
- # avoid multivalue for now due to bad interactions with gc rtts in
- # stacky code. for example, this fails to roundtrip as the tuple code
- # ends up creating stacky binary code that needs to spill rtts to locals,
- # which is not allowed:
+ # avoid multivalue for now due to bad interactions with gc non-nullable
+ # locals in stacky code. for example, this fails to roundtrip as the
+ # tuple code ends up creating stacky binary code that needs to spill
+ # non-nullable references to locals, which is not allowed:
#
# (module
# (type $other (struct))
- # (func $foo (result (rtt $other))
+ # (func $foo (result (ref $other))
# (select
- # (rtt.canon $other)
- # (rtt.canon $other)
+ # (struct.new $other)
+ # (struct.new $other)
# (tuple.extract 1
# (tuple.make
# (i32.const 0)
@@ -1223,9 +1223,10 @@ def randomize_opt_flags():
continue
if '--enable-multivalue' in FEATURE_OPTS and '--enable-reference-types' in FEATURE_OPTS:
print('avoiding --flatten due to multivalue + reference types not supporting it (spilling of non-nullable tuples)')
+ print('TODO: Resolving https://github.com/WebAssembly/binaryen/issues/4824 may fix this')
continue
if '--gc' not in FEATURE_OPTS:
- print('avoiding --flatten due to GC not supporting it (spilling of RTTs)')
+ print('avoiding --flatten due to GC not supporting it (spilling of non-nullable locals)')
continue
if INITIAL_CONTENTS and os.path.getsize(INITIAL_CONTENTS) > 2000:
print('avoiding --flatten due using a large amount of initial contents, which may blow up')
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index e36caf02e..bb56b76e3 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -567,9 +567,7 @@ instructions = [
("i31.new", "makeI31New(s)"),
("i31.get_s", "makeI31Get(s, true)"),
("i31.get_u", "makeI31Get(s, false)"),
- ("ref.test", "makeRefTest(s)"),
("ref.test_static", "makeRefTestStatic(s)"),
- ("ref.cast", "makeRefCast(s)"),
("ref.cast_static", "makeRefCastStatic(s)"),
("ref.cast_nop_static", "makeRefCastNopStatic(s)"),
("br_on_null", "makeBrOn(s, BrOnNull)"),
@@ -584,22 +582,14 @@ instructions = [
("br_on_non_data", "makeBrOn(s, BrOnNonData)"),
("br_on_i31", "makeBrOn(s, BrOnI31)"),
("br_on_non_i31", "makeBrOn(s, BrOnNonI31)"),
- ("rtt.canon", "makeRttCanon(s)"),
- ("rtt.sub", "makeRttSub(s)"),
- ("rtt.fresh_sub", "makeRttFreshSub(s)"),
- ("struct.new_with_rtt", "makeStructNew(s, false)"),
- ("struct.new_default_with_rtt", "makeStructNew(s, true)"),
("struct.new", "makeStructNewStatic(s, false)"),
("struct.new_default", "makeStructNewStatic(s, true)"),
("struct.get", "makeStructGet(s)"),
("struct.get_s", "makeStructGet(s, true)"),
("struct.get_u", "makeStructGet(s, false)"),
("struct.set", "makeStructSet(s)"),
- ("array.new_with_rtt", "makeArrayNew(s, false)"),
- ("array.new_default_with_rtt", "makeArrayNew(s, true)"),
("array.new", "makeArrayNewStatic(s, false)"),
("array.new_default", "makeArrayNewStatic(s, true)"),
- ("array.init", "makeArrayInit(s)"),
("array.init_static", "makeArrayInitStatic(s)"),
("array.get", "makeArrayGet(s)"),
("array.get_s", "makeArrayGet(s, true)"),
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index f7e8142f1..1dd9fccd2 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -1490,8 +1490,6 @@ BinaryenExpressionRef BinaryenI31Get(BinaryenModuleRef module,
// TODO (gc): ref.test
// TODO (gc): ref.cast
// TODO (gc): br_on_cast
-// TODO (gc): rtt.canon
-// TODO (gc): rtt.sub
// TODO (gc): struct.new
// TODO (gc): struct.get
// TODO (gc): struct.set
@@ -4910,13 +4908,6 @@ BinaryenType TypeBuilderGetTempTupleType(TypeBuilderRef builder,
}
return ((TypeBuilder*)builder)->getTempTupleType(Tuple(typeList)).getID();
}
-BinaryenType TypeBuilderGetTempRttType(TypeBuilderRef builder,
- BinaryenIndex depth,
- BinaryenHeapType heapType) {
- return ((TypeBuilder*)builder)
- ->getTempRttType(Rtt(depth, HeapType(heapType)))
- .getID();
-}
BinaryenType TypeBuilderGetTempRefType(TypeBuilderRef builder,
BinaryenHeapType heapType,
int nullable) {
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 6a2222f71..f02b2cb19 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -943,8 +943,6 @@ BINARYEN_API BinaryenExpressionRef BinaryenI31Get(BinaryenModuleRef module,
// TODO (gc): ref.test
// TODO (gc): ref.cast
// TODO (gc): br_on_cast
-// TODO (gc): rtt.canon
-// TODO (gc): rtt.sub
// TODO (gc): struct.new
// TODO (gc): struct.get
// TODO (gc): struct.set
@@ -2985,10 +2983,6 @@ BINARYEN_API BinaryenType TypeBuilderGetTempTupleType(TypeBuilderRef builder,
BINARYEN_API BinaryenType TypeBuilderGetTempRefType(TypeBuilderRef builder,
BinaryenHeapType heapType,
int nullable);
-// Gets a temporary RTT for use with and owned by the type builder.
-BINARYEN_API BinaryenType TypeBuilderGetTempRttType(TypeBuilderRef builder,
- BinaryenIndex depth,
- BinaryenHeapType heapType);
// Sets the type at `index` to be a subtype of the type at `superIndex`.
BINARYEN_API void TypeBuilderSetSubType(TypeBuilderRef builder,
BinaryenIndex index,
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 301164f87..caf4f5578 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -33,17 +33,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 'i': {
- switch (op[10]) {
- case '\0':
- if (strcmp(op, "array.init") == 0) { return makeArrayInit(s); }
- goto parse_error;
- case '_':
- if (strcmp(op, "array.init_static") == 0) { return makeArrayInitStatic(s); }
- goto parse_error;
- default: goto parse_error;
- }
- }
+ case 'i':
+ if (strcmp(op, "array.init_static") == 0) { return makeArrayInitStatic(s); }
+ goto parse_error;
case 'l':
if (strcmp(op, "array.len") == 0) { return makeArrayLen(s); }
goto parse_error;
@@ -52,25 +44,9 @@ switch (op[0]) {
case '\0':
if (strcmp(op, "array.new") == 0) { return makeArrayNewStatic(s, false); }
goto parse_error;
- case '_': {
- switch (op[10]) {
- case 'd': {
- switch (op[17]) {
- case '\0':
- if (strcmp(op, "array.new_default") == 0) { return makeArrayNewStatic(s, true); }
- goto parse_error;
- case '_':
- if (strcmp(op, "array.new_default_with_rtt") == 0) { return makeArrayNew(s, true); }
- goto parse_error;
- default: goto parse_error;
- }
- }
- case 'w':
- if (strcmp(op, "array.new_with_rtt") == 0) { return makeArrayNew(s, false); }
- goto parse_error;
- default: goto parse_error;
- }
- }
+ case '_':
+ if (strcmp(op, "array.new_default") == 0) { return makeArrayNewStatic(s, true); }
+ goto parse_error;
default: goto parse_error;
}
}
@@ -2984,113 +2960,92 @@ switch (op[0]) {
if (strcmp(op, "pop") == 0) { return makePop(s); }
goto parse_error;
case 'r': {
- switch (op[1]) {
- case 'e': {
- switch (op[2]) {
- case 'f': {
- switch (op[4]) {
- case 'a': {
- switch (op[7]) {
- case 'd':
- if (strcmp(op, "ref.as_data") == 0) { return makeRefAs(s, RefAsData); }
- goto parse_error;
- case 'f':
- if (strcmp(op, "ref.as_func") == 0) { return makeRefAs(s, RefAsFunc); }
- goto parse_error;
- case 'i':
- if (strcmp(op, "ref.as_i31") == 0) { return makeRefAs(s, RefAsI31); }
- goto parse_error;
- case 'n':
- if (strcmp(op, "ref.as_non_null") == 0) { return makeRefAs(s, RefAsNonNull); }
- goto parse_error;
- default: goto parse_error;
- }
- }
- case 'c': {
- switch (op[8]) {
- case '\0':
- if (strcmp(op, "ref.cast") == 0) { return makeRefCast(s); }
- goto parse_error;
- case '_': {
- switch (op[9]) {
- case 'n':
- if (strcmp(op, "ref.cast_nop_static") == 0) { return makeRefCastNopStatic(s); }
- goto parse_error;
- case 's':
- if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); }
- goto parse_error;
- default: goto parse_error;
- }
- }
- default: goto parse_error;
- }
- }
- case 'e':
- if (strcmp(op, "ref.eq") == 0) { return makeRefEq(s); }
+ switch (op[2]) {
+ case 'f': {
+ switch (op[4]) {
+ case 'a': {
+ switch (op[7]) {
+ case 'd':
+ if (strcmp(op, "ref.as_data") == 0) { return makeRefAs(s, RefAsData); }
goto parse_error;
case 'f':
- if (strcmp(op, "ref.func") == 0) { return makeRefFunc(s); }
+ if (strcmp(op, "ref.as_func") == 0) { return makeRefAs(s, RefAsFunc); }
+ goto parse_error;
+ case 'i':
+ if (strcmp(op, "ref.as_i31") == 0) { return makeRefAs(s, RefAsI31); }
goto parse_error;
- case 'i': {
- switch (op[7]) {
- case 'd':
- if (strcmp(op, "ref.is_data") == 0) { return makeRefIs(s, RefIsData); }
- goto parse_error;
- case 'f':
- if (strcmp(op, "ref.is_func") == 0) { return makeRefIs(s, RefIsFunc); }
- goto parse_error;
- case 'i':
- if (strcmp(op, "ref.is_i31") == 0) { return makeRefIs(s, RefIsI31); }
- goto parse_error;
- case 'n':
- if (strcmp(op, "ref.is_null") == 0) { return makeRefIs(s, RefIsNull); }
- goto parse_error;
- default: goto parse_error;
- }
- }
case 'n':
- if (strcmp(op, "ref.null") == 0) { return makeRefNull(s); }
+ if (strcmp(op, "ref.as_non_null") == 0) { return makeRefAs(s, RefAsNonNull); }
goto parse_error;
- case 't': {
- switch (op[8]) {
- case '\0':
- if (strcmp(op, "ref.test") == 0) { return makeRefTest(s); }
- goto parse_error;
- case '_':
- if (strcmp(op, "ref.test_static") == 0) { return makeRefTestStatic(s); }
- goto parse_error;
- default: goto parse_error;
- }
- }
default: goto parse_error;
}
}
- case 't': {
- switch (op[3]) {
- case 'h':
- if (strcmp(op, "rethrow") == 0) { return makeRethrow(s); }
+ case 'c': {
+ switch (op[9]) {
+ case 'n':
+ if (strcmp(op, "ref.cast_nop_static") == 0) { return makeRefCastNopStatic(s); }
goto parse_error;
- case 'u': {
- switch (op[6]) {
+ case 's':
+ if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'e':
+ if (strcmp(op, "ref.eq") == 0) { return makeRefEq(s); }
+ goto parse_error;
+ case 'f':
+ if (strcmp(op, "ref.func") == 0) { return makeRefFunc(s); }
+ goto parse_error;
+ case 'i': {
+ switch (op[7]) {
+ case 'd':
+ if (strcmp(op, "ref.is_data") == 0) { return makeRefIs(s, RefIsData); }
+ goto parse_error;
+ case 'f':
+ if (strcmp(op, "ref.is_func") == 0) { return makeRefIs(s, RefIsFunc); }
+ goto parse_error;
+ case 'i':
+ if (strcmp(op, "ref.is_i31") == 0) { return makeRefIs(s, RefIsI31); }
+ goto parse_error;
+ case 'n':
+ if (strcmp(op, "ref.is_null") == 0) { return makeRefIs(s, RefIsNull); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'n':
+ if (strcmp(op, "ref.null") == 0) { return makeRefNull(s); }
+ goto parse_error;
+ case 't':
+ if (strcmp(op, "ref.test_static") == 0) { return makeRefTestStatic(s); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 't': {
+ switch (op[3]) {
+ case 'h':
+ if (strcmp(op, "rethrow") == 0) { return makeRethrow(s); }
+ goto parse_error;
+ case 'u': {
+ switch (op[6]) {
+ case '\0':
+ if (strcmp(op, "return") == 0) { return makeReturn(s); }
+ goto parse_error;
+ case '_': {
+ switch (op[11]) {
case '\0':
- if (strcmp(op, "return") == 0) { return makeReturn(s); }
+ if (strcmp(op, "return_call") == 0) { return makeCall(s, /*isReturn=*/true); }
goto parse_error;
case '_': {
- switch (op[11]) {
- case '\0':
- if (strcmp(op, "return_call") == 0) { return makeCall(s, /*isReturn=*/true); }
+ switch (op[12]) {
+ case 'i':
+ if (strcmp(op, "return_call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/true); }
+ goto parse_error;
+ case 'r':
+ if (strcmp(op, "return_call_ref") == 0) { return makeCallRef(s, /*isReturn=*/true); }
goto parse_error;
- case '_': {
- switch (op[12]) {
- case 'i':
- if (strcmp(op, "return_call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/true); }
- goto parse_error;
- case 'r':
- if (strcmp(op, "return_call_ref") == 0) { return makeCallRef(s, /*isReturn=*/true); }
- goto parse_error;
- default: goto parse_error;
- }
- }
default: goto parse_error;
}
}
@@ -3103,20 +3058,6 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 't': {
- switch (op[4]) {
- case 'c':
- if (strcmp(op, "rtt.canon") == 0) { return makeRttCanon(s); }
- goto parse_error;
- case 'f':
- if (strcmp(op, "rtt.fresh_sub") == 0) { return makeRttFreshSub(s); }
- goto parse_error;
- case 's':
- if (strcmp(op, "rtt.sub") == 0) { return makeRttSub(s); }
- goto parse_error;
- default: goto parse_error;
- }
- }
default: goto parse_error;
}
}
@@ -3321,25 +3262,9 @@ switch (op[0]) {
case '\0':
if (strcmp(op, "struct.new") == 0) { return makeStructNewStatic(s, false); }
goto parse_error;
- case '_': {
- switch (op[11]) {
- case 'd': {
- switch (op[18]) {
- case '\0':
- if (strcmp(op, "struct.new_default") == 0) { return makeStructNewStatic(s, true); }
- goto parse_error;
- case '_':
- if (strcmp(op, "struct.new_default_with_rtt") == 0) { return makeStructNew(s, true); }
- goto parse_error;
- default: goto parse_error;
- }
- }
- case 'w':
- if (strcmp(op, "struct.new_with_rtt") == 0) { return makeStructNew(s, false); }
- goto parse_error;
- default: goto parse_error;
- }
- }
+ case '_':
+ if (strcmp(op, "struct.new_default") == 0) { return makeStructNewStatic(s, true); }
+ goto parse_error;
default: goto parse_error;
}
}
@@ -3631,25 +3556,13 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 'i': {
- switch (op[10]) {
- case '\0':
- if (op == "array.init"sv) {
- auto ret = makeArrayInit(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case '_':
- if (op == "array.init_static"sv) {
- auto ret = makeArrayInitStatic(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
+ case 'i':
+ if (op == "array.init_static"sv) {
+ auto ret = makeArrayInitStatic(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
+ goto parse_error;
case 'l':
if (op == "array.len"sv) {
auto ret = makeArrayLen(ctx, in);
@@ -3666,37 +3579,13 @@ switch (op[0]) {
return *ret;
}
goto parse_error;
- case '_': {
- switch (op[10]) {
- case 'd': {
- switch (op[17]) {
- case '\0':
- if (op == "array.new_default"sv) {
- auto ret = makeArrayNewStatic(ctx, in, true);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case '_':
- if (op == "array.new_default_with_rtt"sv) {
- auto ret = makeArrayNew(ctx, in, true);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
- }
- }
- case 'w':
- if (op == "array.new_with_rtt"sv) {
- auto ret = makeArrayNew(ctx, in, false);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
+ case '_':
+ if (op == "array.new_default"sv) {
+ auto ret = makeArrayNewStatic(ctx, in, true);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
+ goto parse_error;
default: goto parse_error;
}
}
@@ -8594,197 +8483,168 @@ switch (op[0]) {
}
goto parse_error;
case 'r': {
- switch (op[1]) {
- case 'e': {
- switch (op[2]) {
- case 'f': {
- switch (op[4]) {
- case 'a': {
- switch (op[7]) {
- case 'd':
- if (op == "ref.as_data"sv) {
- auto ret = makeRefAs(ctx, in, RefAsData);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'f':
- if (op == "ref.as_func"sv) {
- auto ret = makeRefAs(ctx, in, RefAsFunc);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'i':
- if (op == "ref.as_i31"sv) {
- auto ret = makeRefAs(ctx, in, RefAsI31);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'n':
- if (op == "ref.as_non_null"sv) {
- auto ret = makeRefAs(ctx, in, RefAsNonNull);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
+ switch (op[2]) {
+ case 'f': {
+ switch (op[4]) {
+ case 'a': {
+ switch (op[7]) {
+ case 'd':
+ if (op == "ref.as_data"sv) {
+ auto ret = makeRefAs(ctx, in, RefAsData);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
- case 'c': {
- switch (op[8]) {
- case '\0':
- if (op == "ref.cast"sv) {
- auto ret = makeRefCast(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case '_': {
- switch (op[9]) {
- case 'n':
- if (op == "ref.cast_nop_static"sv) {
- auto ret = makeRefCastNopStatic(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 's':
- if (op == "ref.cast_static"sv) {
- auto ret = makeRefCastStatic(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
- }
- }
- default: goto parse_error;
+ goto parse_error;
+ case 'f':
+ if (op == "ref.as_func"sv) {
+ auto ret = makeRefAs(ctx, in, RefAsFunc);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
- case 'e':
- if (op == "ref.eq"sv) {
- auto ret = makeRefEq(ctx, in);
+ goto parse_error;
+ case 'i':
+ if (op == "ref.as_i31"sv) {
+ auto ret = makeRefAs(ctx, in, RefAsI31);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 'n':
+ if (op == "ref.as_non_null"sv) {
+ auto ret = makeRefAs(ctx, in, RefAsNonNull);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'c': {
+ switch (op[9]) {
+ case 'n':
+ if (op == "ref.cast_nop_static"sv) {
+ auto ret = makeRefCastNopStatic(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 's':
+ if (op == "ref.cast_static"sv) {
+ auto ret = makeRefCastStatic(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 'e':
+ if (op == "ref.eq"sv) {
+ auto ret = makeRefEq(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 'f':
+ if (op == "ref.func"sv) {
+ auto ret = makeRefFunc(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 'i': {
+ switch (op[7]) {
+ case 'd':
+ if (op == "ref.is_data"sv) {
+ auto ret = makeRefIs(ctx, in, RefIsData);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
case 'f':
- if (op == "ref.func"sv) {
- auto ret = makeRefFunc(ctx, in);
+ if (op == "ref.is_func"sv) {
+ auto ret = makeRefIs(ctx, in, RefIsFunc);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
- case 'i': {
- switch (op[7]) {
- case 'd':
- if (op == "ref.is_data"sv) {
- auto ret = makeRefIs(ctx, in, RefIsData);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'f':
- if (op == "ref.is_func"sv) {
- auto ret = makeRefIs(ctx, in, RefIsFunc);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'i':
- if (op == "ref.is_i31"sv) {
- auto ret = makeRefIs(ctx, in, RefIsI31);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'n':
- if (op == "ref.is_null"sv) {
- auto ret = makeRefIs(ctx, in, RefIsNull);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
+ case 'i':
+ if (op == "ref.is_i31"sv) {
+ auto ret = makeRefIs(ctx, in, RefIsI31);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
+ goto parse_error;
case 'n':
- if (op == "ref.null"sv) {
- auto ret = makeRefNull(ctx, in);
+ if (op == "ref.is_null"sv) {
+ auto ret = makeRefIs(ctx, in, RefIsNull);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
- case 't': {
- switch (op[8]) {
- case '\0':
- if (op == "ref.test"sv) {
- auto ret = makeRefTest(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case '_':
- if (op == "ref.test_static"sv) {
- auto ret = makeRefTestStatic(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
- }
- }
default: goto parse_error;
}
}
- case 't': {
- switch (op[3]) {
- case 'h':
- if (op == "rethrow"sv) {
- auto ret = makeRethrow(ctx, in);
+ case 'n':
+ if (op == "ref.null"sv) {
+ auto ret = makeRefNull(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 't':
+ if (op == "ref.test_static"sv) {
+ auto ret = makeRefTestStatic(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case 't': {
+ switch (op[3]) {
+ case 'h':
+ if (op == "rethrow"sv) {
+ auto ret = makeRethrow(ctx, in);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 'u': {
+ switch (op[6]) {
+ case '\0':
+ if (op == "return"sv) {
+ auto ret = makeReturn(ctx, in);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
- case 'u': {
- switch (op[6]) {
+ case '_': {
+ switch (op[11]) {
case '\0':
- if (op == "return"sv) {
- auto ret = makeReturn(ctx, in);
+ if (op == "return_call"sv) {
+ auto ret = makeCall(ctx, in, /*isReturn=*/true);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
case '_': {
- switch (op[11]) {
- case '\0':
- if (op == "return_call"sv) {
- auto ret = makeCall(ctx, in, /*isReturn=*/true);
+ switch (op[12]) {
+ case 'i':
+ if (op == "return_call_indirect"sv) {
+ auto ret = makeCallIndirect(ctx, in, /*isReturn=*/true);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
- case '_': {
- switch (op[12]) {
- case 'i':
- if (op == "return_call_indirect"sv) {
- auto ret = makeCallIndirect(ctx, in, /*isReturn=*/true);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'r':
- if (op == "return_call_ref"sv) {
- auto ret = makeCallRef(ctx, in, /*isReturn=*/true);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
+ case 'r':
+ if (op == "return_call_ref"sv) {
+ auto ret = makeCallRef(ctx, in, /*isReturn=*/true);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
+ goto parse_error;
default: goto parse_error;
}
}
@@ -8797,32 +8657,6 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 't': {
- switch (op[4]) {
- case 'c':
- if (op == "rtt.canon"sv) {
- auto ret = makeRttCanon(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 'f':
- if (op == "rtt.fresh_sub"sv) {
- auto ret = makeRttFreshSub(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case 's':
- if (op == "rtt.sub"sv) {
- auto ret = makeRttSub(ctx, in);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
- }
- }
default: goto parse_error;
}
}
@@ -9151,37 +8985,13 @@ switch (op[0]) {
return *ret;
}
goto parse_error;
- case '_': {
- switch (op[11]) {
- case 'd': {
- switch (op[18]) {
- case '\0':
- if (op == "struct.new_default"sv) {
- auto ret = makeStructNewStatic(ctx, in, true);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- case '_':
- if (op == "struct.new_default_with_rtt"sv) {
- auto ret = makeStructNew(ctx, in, true);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
- }
- }
- case 'w':
- if (op == "struct.new_with_rtt"sv) {
- auto ret = makeStructNew(ctx, in, false);
- CHECK_ERR(ret);
- return *ret;
- }
- goto parse_error;
- default: goto parse_error;
+ case '_':
+ if (op == "struct.new_default"sv) {
+ auto ret = makeStructNewStatic(ctx, in, true);
+ CHECK_ERR(ret);
+ return *ret;
}
- }
+ goto parse_error;
default: goto parse_error;
}
}
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 771553e11..3a5e4172d 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -160,8 +160,6 @@ void ReFinalize::visitBrOn(BrOn* curr) {
updateBreakValueType(curr->name, curr->getSentType());
}
}
-void ReFinalize::visitRttCanon(RttCanon* curr) { curr->finalize(); }
-void ReFinalize::visitRttSub(RttSub* curr) { curr->finalize(); }
void ReFinalize::visitStructNew(StructNew* curr) { curr->finalize(); }
void ReFinalize::visitStructGet(StructGet* curr) { curr->finalize(); }
void ReFinalize::visitStructSet(StructSet* curr) { curr->finalize(); }
diff --git a/src/ir/cost.h b/src/ir/cost.h
index b48b777e1..823e58ded 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -604,35 +604,24 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
// Casts have a very high cost because in the VM they end up implemented as
// a combination of loads and branches. Given they contain branches, we do
// not want to add any more such work.
- return Unacceptable + nullCheckCost(curr->ref) + visit(curr->ref) +
- maybeVisit(curr->rtt);
+ return Unacceptable + nullCheckCost(curr->ref) + visit(curr->ref);
}
CostType visitRefCast(RefCast* curr) {
- return Unacceptable + nullCheckCost(curr->ref) + visit(curr->ref) +
- maybeVisit(curr->rtt);
+ return Unacceptable + nullCheckCost(curr->ref) + visit(curr->ref);
}
CostType visitBrOn(BrOn* curr) {
// BrOn of a null can be fairly fast, but anything else is a cast check
// basically, and an unacceptable cost.
CostType base =
curr->op == BrOnNull || curr->op == BrOnNonNull ? 2 : Unacceptable;
- return base + nullCheckCost(curr->ref) + maybeVisit(curr->ref) +
- maybeVisit(curr->rtt);
- }
- CostType visitRttCanon(RttCanon* curr) {
- // TODO: investigate actual RTT costs in VMs
- return 1;
- }
- CostType visitRttSub(RttSub* curr) {
- // TODO: investigate actual RTT costs in VMs
- return 2 + visit(curr->parent);
+ return base + nullCheckCost(curr->ref) + maybeVisit(curr->ref);
}
CostType visitStructNew(StructNew* curr) {
// While allocation itself is almost free with generational GC, there is
// at least some baseline cost, plus writing the fields. (If we use default
// values for the fields, then it is possible they are all 0 and if so, we
// can get that almost for free as well, so don't add anything there.)
- CostType ret = 4 + maybeVisit(curr->rtt) + curr->operands.size();
+ CostType ret = 4 + curr->operands.size();
for (auto* child : curr->operands) {
ret += visit(child);
}
@@ -645,11 +634,10 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
return 2 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->value);
}
CostType visitArrayNew(ArrayNew* curr) {
- return 4 + maybeVisit(curr->rtt) + visit(curr->size) +
- maybeVisit(curr->init);
+ return 4 + visit(curr->size) + maybeVisit(curr->init);
}
CostType visitArrayInit(ArrayInit* curr) {
- CostType ret = 4 + maybeVisit(curr->rtt);
+ CostType ret = 4;
for (auto* child : curr->values) {
ret += visit(child);
}
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 8d643ffe3..5e50441ac 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -678,8 +678,6 @@ private:
parent.implicitTrap = true;
}
void visitBrOn(BrOn* curr) { parent.breakTargets.insert(curr->name); }
- void visitRttCanon(RttCanon* curr) {}
- void visitRttSub(RttSub* curr) {}
void visitStructNew(StructNew* curr) {}
void visitStructGet(StructGet* curr) {
if (curr->ref->type == Type::unreachable) {
diff --git a/src/ir/gc-type-utils.h b/src/ir/gc-type-utils.h
index 584cde83c..cec4490e2 100644
--- a/src/ir/gc-type-utils.h
+++ b/src/ir/gc-type-utils.h
@@ -56,14 +56,11 @@ inline EvaluationResult evaluateKindCheck(Expression* curr) {
flip = true;
[[fallthrough]];
case BrOnCast:
- if (!br->rtt) {
- // This is a static cast check, which we may be able to resolve at
- // compile time. Note that the type must be non-nullable for us to
- // succeed at that inference, as otherwise a null can make us fail.
- if (Type::isSubType(br->ref->type,
- Type(br->intendedType, NonNullable))) {
- return flip ? Failure : Success;
- }
+ // Note that the type must be non-nullable for us to succeed since a
+ // null would make us fail.
+ if (Type::isSubType(br->ref->type,
+ Type(br->intendedType, NonNullable))) {
+ return flip ? Failure : Success;
}
return Unknown;
case BrOnNonFunc:
diff --git a/src/ir/linear-execution.h b/src/ir/linear-execution.h
index 230bafee5..99b3a2a22 100644
--- a/src/ir/linear-execution.h
+++ b/src/ir/linear-execution.h
@@ -130,7 +130,6 @@ struct LinearExecutionWalker : public PostWalker<SubType, VisitorType> {
case Expression::Id::BrOnId: {
self->pushTask(SubType::doVisitBrOn, currp);
self->pushTask(SubType::doNoteNonLinear, currp);
- self->maybePushTask(SubType::scan, &curr->cast<BrOn>()->rtt);
self->pushTask(SubType::scan, &curr->cast<BrOn>()->ref);
break;
}
diff --git a/src/ir/literal-utils.h b/src/ir/literal-utils.h
index ad022344e..0131ecdc9 100644
--- a/src/ir/literal-utils.h
+++ b/src/ir/literal-utils.h
@@ -33,17 +33,9 @@ inline bool canMakeZero(Type type) {
if (type.isNonNullable()) {
return false;
}
- if (type.isRtt() && type.getRtt().hasDepth()) {
- // An rtt with depth cannot be constructed as a simple zero: we'd need to
- // create not just a zero (an rtt.canon) but also some rtt.subs that add to
- // the depth, so disallow that. Also, there is no practical way to create a
- // zero Literal for such a type, as we'd need to supply the list of super
- // types somehow, and creating a zero Literal is how makeZero works.
- return false;
- }
if (type.isTuple()) {
for (auto t : type) {
- if (!canMakeZero(t)) {
+ if (t.isNonNullable()) {
return false;
}
}
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp
index 38bb6f3d9..33f8ac926 100644
--- a/src/ir/module-utils.cpp
+++ b/src/ir/module-utils.cpp
@@ -55,8 +55,6 @@ struct CodeScanner
counts.note(call->heapType);
} else if (curr->is<RefNull>()) {
counts.note(curr->type);
- } else if (curr->is<RttCanon>() || curr->is<RttSub>()) {
- counts.note(curr->type.getRtt().heapType);
} else if (auto* make = curr->dynCast<StructNew>()) {
handleMake(make);
} else if (auto* make = curr->dynCast<ArrayNew>()) {
@@ -64,12 +62,12 @@ struct CodeScanner
} else if (auto* make = curr->dynCast<ArrayInit>()) {
handleMake(make);
} else if (auto* cast = curr->dynCast<RefCast>()) {
- handleCast(cast);
+ counts.note(cast->intendedType);
} else if (auto* cast = curr->dynCast<RefTest>()) {
- handleCast(cast);
+ counts.note(cast->intendedType);
} else if (auto* cast = curr->dynCast<BrOn>()) {
if (cast->op == BrOnCast || cast->op == BrOnCastFail) {
- handleCast(cast);
+ counts.note(cast->intendedType);
}
} else if (auto* get = curr->dynCast<StructGet>()) {
counts.note(get->ref->type);
@@ -86,18 +84,10 @@ struct CodeScanner
}
template<typename T> void handleMake(T* curr) {
- if (!curr->rtt && curr->type != Type::unreachable) {
+ if (curr->type != Type::unreachable) {
counts.note(curr->type.getHeapType());
}
}
-
- template<typename T> void handleCast(T* curr) {
- // Some operations emit a HeapType in the binary format, if they are
- // static and not dynamic (if dynamic, the RTT provides the heap type).
- if (!curr->rtt) {
- counts.note(curr->intendedType);
- }
- }
};
Counts getHeapTypeCounts(Module& wasm) {
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index ab0d379f6..48a632576 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -416,8 +416,6 @@ struct InfoCollector
handleBreakValue(curr);
receiveChildValue(curr->ref, curr);
}
- void visitRttCanon(RttCanon* curr) { addRoot(curr); }
- void visitRttSub(RttSub* curr) { addRoot(curr); }
void visitRefAs(RefAs* curr) {
// TODO: optimize when possible: like RefCast, not all values flow through.
receiveChildValue(curr->value, curr);
@@ -1677,9 +1675,8 @@ void Flower::flowRefCast(const PossibleContents& contents, RefCast* cast) {
// emitting a Many in any of these code paths
filtered = contents;
} else {
- auto intendedType = cast->getIntendedType();
bool isSubType =
- HeapType::isSubType(contents.getType().getHeapType(), intendedType);
+ HeapType::isSubType(contents.getType().getHeapType(), cast->intendedType);
if (isSubType) {
// The contents are not Many, but their heap type is a subtype of the
// intended type, so we'll pass that through. Note that we pass the entire
@@ -1694,7 +1691,7 @@ void Flower::flowRefCast(const PossibleContents& contents, RefCast* cast) {
if (mayBeNull) {
// A null is possible, so pass that along.
filtered.combine(
- PossibleContents::literal(Literal::makeNull(intendedType)));
+ PossibleContents::literal(Literal::makeNull(cast->intendedType)));
}
}
if (!filtered.isNone()) {
diff --git a/src/ir/properties.h b/src/ir/properties.h
index 204b33e1e..4bd66b1d5 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -75,8 +75,8 @@ inline bool isNamedControlFlow(Expression* curr) {
// at compile time, and passes that propagate constants can try to propagate it.
// Constant expressions are also allowed in global initializers in wasm. Also
// when two constant expressions compare equal at compile time, their values at
-// runtime will be equal as well.
-// TODO: look into adding more things here like RttCanon.
+// runtime will be equal as well. TODO: combine this with
+// isValidInConstantExpression or find better names(#4845)
inline bool isSingleConstantExpression(const Expression* curr) {
return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>();
}
@@ -407,9 +407,8 @@ bool isGenerative(Expression* curr, FeatureSet features);
inline bool isValidInConstantExpression(Expression* expr, FeatureSet features) {
if (isSingleConstantExpression(expr) || expr->is<GlobalGet>() ||
- expr->is<RttCanon>() || expr->is<RttSub>() || expr->is<StructNew>() ||
- expr->is<ArrayNew>() || expr->is<ArrayInit>() || expr->is<I31New>() ||
- expr->is<StringConst>()) {
+ expr->is<StructNew>() || expr->is<ArrayNew>() || expr->is<ArrayInit>() ||
+ expr->is<I31New>() || expr->is<StringConst>()) {
return true;
}
diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp
index b08cca295..5452613bb 100644
--- a/src/ir/type-updating.cpp
+++ b/src/ir/type-updating.cpp
@@ -117,9 +117,6 @@ void GlobalTypeRewriter::update() {
if (type.isRef()) {
return Type(getNew(type.getHeapType()), type.getNullability());
}
- if (type.isRtt()) {
- return Type(Rtt(type.getRtt().depth, getNew(type.getHeapType())));
- }
if (type.isTuple()) {
auto tuple = type.getTuple();
for (auto& t : tuple.types) {
@@ -251,18 +248,6 @@ Type GlobalTypeRewriter::getTempType(Type type) {
typeBuilder.getTempHeapType(indexedTypes.indices[heapType]),
type.getNullability());
}
- if (type.isRtt()) {
- auto rtt = type.getRtt();
- auto newRtt = rtt;
- auto heapType = type.getHeapType();
- if (!indexedTypes.indices.count(heapType)) {
- // See above with references.
- return type;
- }
- newRtt.heapType =
- typeBuilder.getTempHeapType(indexedTypes.indices[heapType]);
- return typeBuilder.getTempRttType(newRtt);
- }
if (type.isTuple()) {
auto& tuple = type.getTuple();
auto newTuple = tuple;
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index d2a8eb7f5..6ba5454e9 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -111,8 +111,6 @@ function initializeConstants() {
'RefTest',
'RefCast',
'BrOn',
- 'RttCanon',
- 'RttSub',
'StructNew',
'StructGet',
'StructSet',
diff --git a/src/literal.h b/src/literal.h
index 6696103e3..ffd565c71 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -32,7 +32,6 @@ namespace wasm {
class Literals;
struct GCData;
-struct RttSupers;
class Literal {
// store only integers, whose bits are deterministic. floats
@@ -51,21 +50,6 @@ class Literal {
// Array, and for a Struct, is just the fields in order). The type is used
// to indicate whether this is a Struct or an Array, and of what type.
std::shared_ptr<GCData> gcData;
- // RTT values are "structural" in that the MVP doc says that multiple
- // invocations of ref.canon return things that are observably identical, and
- // the same is true for ref.sub. That is, what matters is the types; there
- // is no unique identifier created in each ref.canon/sub. To track the
- // types, we maintain a simple vector of the supertypes. Thus, an rtt.canon
- // of type A will have an empty vector; an rtt.sub of type B of that initial
- // canon would have a vector of size 1 containing A; a subsequent rtt.sub
- // would have A, B, and so forth.
- // (This encoding is very inefficient and not at all what a production VM
- // would do, but it is simple.)
- // The unique_ptr here is to avoid increasing the size of the union as well
- // as the Literal class itself.
- // To support the experimental RttFreshSub instruction, we not only store
- // the type, but also a reference to an allocation.
- std::unique_ptr<RttSupers> rttSupers;
// TODO: Literals of type `anyref` can only be `null` currently but we
// will need to represent external values eventually, to
// 1) run the spec tests and fuzzer with reference types enabled and
@@ -97,7 +81,6 @@ public:
explicit Literal(Name func, HeapType type)
: func(func), type(type, NonNullable) {}
explicit Literal(std::shared_ptr<GCData> gcData, HeapType type);
- explicit Literal(std::unique_ptr<RttSupers>&& rttSupers, Type type);
Literal(const Literal& other);
Literal& operator=(const Literal& other);
~Literal();
@@ -267,10 +250,6 @@ public:
return lit;
}
- // Get the canonical RTT value for a given HeapType. For nominal types, the
- // canonical RTT reflects the static supertype chain.
- static Literal makeCanonicalRtt(HeapType type);
-
Literal castToF32();
Literal castToF64();
Literal castToI32();
@@ -303,7 +282,6 @@ public:
return func;
}
std::shared_ptr<GCData> getGCData() const;
- const RttSupers& getRttSupers() const;
// careful!
int32_t* geti32Ptr() {
@@ -666,11 +644,6 @@ public:
Literal relaxedFmaF64x2(const Literal& left, const Literal& right) const;
Literal relaxedFmsF64x2(const Literal& left, const Literal& right) const;
- // Checks if an RTT value is a sub-rtt of another, that is, whether GC data
- // with this object's RTT can be successfuly cast using the other RTT
- // according to the wasm rules for that.
- bool isSubRtt(const Literal& other) const;
-
private:
Literal addSatSI8(const Literal& other) const;
Literal addSatUI8(const Literal& other) const;
@@ -721,41 +694,18 @@ public:
std::ostream& operator<<(std::ostream& o, wasm::Literal literal);
std::ostream& operator<<(std::ostream& o, wasm::Literals literals);
-// A GC Struct or Array is a set of values with a run-time type saying what it
-// is. In the case of static (rtt-free) typing, the rtt is not present and
-// instead we have a static type.
+// A GC Struct or Array is a set of values with a type saying how it should be
+// interpreted.
struct GCData {
- // The runtime type info for this struct or array.
- Literal rtt;
+ // The type of this struct or array.
+ HeapType type;
// The element or field values.
Literals values;
- GCData(Literal rtt, Literals values) : rtt(rtt), values(values) {}
-};
-
-struct RttSuper {
- // The type of the super.
- HeapType type;
- // A shared allocation, used to implement rtt.fresh_sub. This is null for a
- // normal sub, and for a fresh one we allocate a value here, which can then be
- // used to differentiate rtts. (The allocation is shared so that when copying
- // an rtt we remain equal.)
- // TODO: Remove or optimize this when the spec stabilizes.
- std::shared_ptr<size_t> freshPtr;
-
- RttSuper(HeapType type) : type(type) {}
-
- void makeFresh() { freshPtr = std::make_shared<size_t>(); }
-
- bool operator==(const RttSuper& other) const {
- return type == other.type && freshPtr == other.freshPtr;
- }
- bool operator!=(const RttSuper& other) const { return !(*this == other); }
+ GCData(HeapType type, Literals values) : type(type), values(values) {}
};
-struct RttSupers : std::vector<RttSuper> {};
-
} // namespace wasm
namespace std {
@@ -801,14 +751,6 @@ template<> struct hash<wasm::Literal> {
// 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");
- } else if (a.type.isRtt()) {
- const auto& supers = a.getRttSupers();
- wasm::rehash(digest, supers.size());
- for (auto super : supers) {
- wasm::rehash(digest, super.type.getID());
- wasm::rehash(digest, uintptr_t(super.freshPtr.get()));
- }
- return digest;
}
WASM_UNREACHABLE("unexpected type");
}
diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp
index 19259e864..86235b001 100644
--- a/src/passes/Heap2Local.cpp
+++ b/src/passes/Heap2Local.cpp
@@ -43,9 +43,8 @@
//
// ;; Allocate a boxed integer of 42 and save the reference to it.
// (local.set $ref
-// (struct.new_with_rtt $boxed-int
+// (struct.new $boxed-int
// (i32.const 42)
-// (rtt.canon $boxed-int)
// )
// )
//
@@ -407,10 +406,6 @@ struct Heap2LocalOptimizer {
}
}
- // Drop the RTT (as it may have side effects; leave it to other passes).
- if (allocation->rtt) {
- contents.push_back(builder.makeDrop(allocation->rtt));
- }
// Replace the allocation with a null reference. This changes the type
// from non-nullable to nullable, but as we optimize away the code that
// the allocation reaches, we will handle that.
diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp
index 073c78822..1180c5183 100644
--- a/src/passes/InstrumentMemory.cpp
+++ b/src/passes/InstrumentMemory.cpp
@@ -54,7 +54,7 @@
//
// GC struct and array operations are similarly instrumented, but without their
// pointers (which are references), and we only log MVP wasm types (i.e., not
-// references or rtts).
+// references).
//
#include "asmjs/shared-constants.h"
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 55176a6e9..828b2fdc9 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1434,10 +1434,9 @@ struct OptimizeInstructions
// is, if casts of the type do not affect our behavior (which is the case in
// ref.eq for example).
//
- // |requiredType| is the type we require as the final output here, or a
- // subtype of it. We will not remove a cast that would leave something that
- // would break that. If |requiredType| is not provided we will accept any type
- // there.
+ // |requiredType| is the required supertype of the final output. We will not
+ // remove a cast that would leave something that would break that. If
+ // |requiredType| is not provided we will accept any type there.
//
// See "notes on removing casts", above, for when this is safe to do.
void skipCast(Expression*& input,
@@ -1453,7 +1452,7 @@ struct OptimizeInstructions
continue;
}
} else if (auto* cast = input->dynCast<RefCast>()) {
- if (!cast->rtt && Type::isSubType(cast->ref->type, requiredType)) {
+ if (Type::isSubType(cast->ref->type, requiredType)) {
input = cast->ref;
continue;
}
@@ -1705,7 +1704,7 @@ struct OptimizeInstructions
auto fallthrough =
Properties::getFallthrough(curr->ref, getPassOptions(), *getModule());
- auto intendedType = curr->getIntendedType();
+ auto intendedType = curr->intendedType;
// If the value is a null, it will just flow through, and we do not need
// the cast. However, if that would change the type, then things are less
@@ -1716,13 +1715,8 @@ struct OptimizeInstructions
// Replace the expression with drops of the inputs, and a null. Note
// that we provide a null of the previous type, so that we do not alter
// the type received by our parent.
- std::vector<Expression*> items;
- items.push_back(builder.makeDrop(curr->ref));
- if (curr->rtt) {
- items.push_back(builder.makeDrop(curr->rtt));
- }
- items.push_back(builder.makeRefNull(intendedType));
- Expression* rep = builder.makeBlock(items);
+ Expression* rep = builder.makeSequence(builder.makeDrop(curr->ref),
+ builder.makeRefNull(intendedType));
if (curr->ref->type.isNonNullable()) {
// Avoid a type change by forcing to be non-nullable. In practice,
// this would have trapped before we get here, so this is just for
@@ -1737,22 +1731,17 @@ struct OptimizeInstructions
}
// For the cast to be able to succeed, the value being cast must be a
- // subtype of the desired type, as RTT subtyping is a subset of static
- // subtyping. For example, trying to cast an array to a struct would be
- // incompatible.
+ // subtype of the desired type. For example, trying to cast an array to a
+ // struct would be incompatible.
if (!canBeCastTo(curr->ref->type.getHeapType(), intendedType)) {
// This cast cannot succeed. If the input is not a null, it will
// definitely trap.
if (fallthrough->type.isNonNullable()) {
// Make sure to emit a block with the same type as us; leave updating
// types for other passes.
- std::vector<Expression*> items;
- items.push_back(builder.makeDrop(curr->ref));
- if (curr->rtt) {
- items.push_back(builder.makeDrop(curr->rtt));
- }
- items.push_back(builder.makeUnreachable());
- replaceCurrent(builder.makeBlock(items, curr->type));
+ replaceCurrent(builder.makeBlock(
+ {builder.makeDrop(curr->ref), builder.makeUnreachable()},
+ curr->type));
return;
}
// Otherwise, we are not sure what it is, and need to wait for runtime
@@ -1760,46 +1749,29 @@ struct OptimizeInstructions
// we can see the value is definitely a null at compile time, earlier.)
}
- if (passOptions.ignoreImplicitTraps || passOptions.trapsNeverHappen ||
- !curr->rtt) {
- // Aside from the issue of type incompatibility as mentioned above, the
- // cast can trap if the types *are* compatible but it happens to be the
- // case at runtime that the value is not of the desired subtype. If we
- // do not consider such traps possible, we can ignore that. (Note,
- // though, that we cannot do this if we cannot replace the current type
- // with the reference's type.) We can also do this if this is a static
- // cast: in that case, all we need to know about are the types.
- if (HeapType::isSubType(curr->ref->type.getHeapType(), intendedType)) {
- if (curr->rtt) {
- replaceCurrent(getResultOfFirst(curr->ref,
- builder.makeDrop(curr->rtt),
- getFunction(),
- getModule(),
- passOptions));
- } else {
- replaceCurrent(curr->ref);
+ // Check whether the cast will definitely succeed.
+ if (HeapType::isSubType(curr->ref->type.getHeapType(), intendedType)) {
+ replaceCurrent(curr->ref);
- // We must refinalize here, as we may be returning a more specific
- // type, which can alter the parent. For example:
- //
- // (struct.get $parent 0
- // (ref.cast_static $parent
- // (local.get $child)
- // )
- // )
- //
- // Try to cast a $child to its parent, $parent. That always works,
- // so the cast can be removed.
- // Then once the cast is removed, the outer struct.get
- // will have a reference with a different type, making it a
- // (struct.get $child ..) instead of $parent.
- // But if $parent and $child have different types on field 0 (the
- // child may have a more refined one) then the struct.get must be
- // refinalized so the IR node has the expected type.
- refinalize = true;
- }
- return;
- }
+ // We must refinalize here, as we may be returning a more specific
+ // type, which can alter the parent. For example:
+ //
+ // (struct.get $parent 0
+ // (ref.cast_static $parent
+ // (local.get $child)
+ // )
+ // )
+ //
+ // Try to cast a $child to its parent, $parent. That always works,
+ // so the cast can be removed.
+ // Then once the cast is removed, the outer struct.get
+ // will have a reference with a different type, making it a
+ // (struct.get $child ..) instead of $parent.
+ // But if $parent and $child have different types on field 0 (the
+ // child may have a more refined one) then the struct.get must be
+ // refinalized so the IR node has the expected type.
+ refinalize = true;
+ return;
}
// Repeated identical ref.cast operations are unnecessary. First, find the
@@ -1818,51 +1790,41 @@ struct OptimizeInstructions
}
}
if (auto* child = ref->dynCast<RefCast>()) {
- if (curr->rtt && child->rtt) {
- // Check if the casts are identical.
- if (ExpressionAnalyzer::equal(curr->rtt, child->rtt) &&
- !EffectAnalyzer(passOptions, *getModule(), curr->rtt)
- .hasSideEffects()) {
- replaceCurrent(curr->ref);
+ // Repeated casts can be removed, leaving just the most demanding of
+ // them.
+ auto childIntendedType = child->intendedType;
+ if (HeapType::isSubType(intendedType, childIntendedType)) {
+ // Skip the child.
+ if (curr->ref == child) {
+ curr->ref = child->ref;
return;
+ } else {
+ // The child is not the direct child of the parent, but it is a
+ // fallthrough value, for example,
+ //
+ // (ref.cast parent
+ // (block
+ // .. other code ..
+ // (ref.cast child)))
+ //
+ // In this case it isn't obvious that we can remove the child, as
+ // doing so might require updating the types of the things in the
+ // middle - and in fact the sole purpose of the child may be to get
+ // a proper type for validation to work. Do nothing in this case,
+ // and hope that other opts will help here (for example,
+ // trapsNeverHappen will help if the code validates without the
+ // child).
}
- } else if (!curr->rtt && !child->rtt) {
- // Repeated static casts can be removed, leaving just the most demanding
- // of them.
- auto childIntendedType = child->getIntendedType();
- if (HeapType::isSubType(intendedType, childIntendedType)) {
- // Skip the child.
- if (curr->ref == child) {
- curr->ref = child->ref;
- return;
- } else {
- // The child is not the direct child of the parent, but it is a
- // fallthrough value, for example,
- //
- // (ref.cast parent
- // (block
- // .. other code ..
- // (ref.cast child)))
- //
- // In this case it isn't obvious that we can remove the child, as
- // doing so might require updating the types of the things in the
- // middle - and in fact the sole purpose of the child may be to get
- // a proper type for validation to work. Do nothing in this case,
- // and hope that other opts will help here (for example,
- // trapsNeverHappen will help if the code validates without the
- // child).
- }
- } else if (!canBeCastTo(intendedType, childIntendedType)) {
- // The types are not compatible, so if the input is not null, this
- // will trap.
- if (!curr->type.isNullable()) {
- // Make sure to emit a block with the same type as us; leave
- // updating types for other passes.
- replaceCurrent(builder.makeBlock(
- {builder.makeDrop(curr->ref), builder.makeUnreachable()},
- curr->type));
- return;
- }
+ } else if (!canBeCastTo(intendedType, childIntendedType)) {
+ // The types are not compatible, so if the input is not null, this
+ // will trap.
+ if (!curr->type.isNullable()) {
+ // Make sure to emit a block with the same type as us; leave
+ // updating types for other passes.
+ replaceCurrent(builder.makeBlock(
+ {builder.makeDrop(curr->ref), builder.makeUnreachable()},
+ curr->type));
+ return;
}
}
}
@@ -1905,22 +1867,17 @@ struct OptimizeInstructions
Builder builder(*getModule());
auto refType = curr->ref->type.getHeapType();
- auto intendedType = curr->getIntendedType();
+ auto intendedType = curr->intendedType;
// See above in RefCast.
if (!canBeCastTo(refType, intendedType)) {
// This test cannot succeed, and will definitely return 0.
- std::vector<Expression*> items;
- items.push_back(builder.makeDrop(curr->ref));
- if (curr->rtt) {
- items.push_back(builder.makeDrop(curr->rtt));
- }
- items.push_back(builder.makeConst(int32_t(0)));
- replaceCurrent(builder.makeBlock(items));
+ replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref),
+ builder.makeConst(int32_t(0))));
return;
}
- if (!curr->rtt && curr->ref->type.isNonNullable() &&
+ if (curr->ref->type.isNonNullable() &&
HeapType::isSubType(refType, intendedType)) {
// This static test will definitely succeed.
replaceCurrent(builder.makeBlock(
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index bbaa6d533..35f218362 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -514,9 +514,8 @@ private:
if (type.isRef()) {
return false;
}
- // For now, don't try to precompute an Rtt. TODO figure out when that would
- // be safe and useful.
- return !type.isRtt();
+
+ return true;
}
};
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 962246569..62dc58c48 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -152,7 +152,6 @@ struct TypeNamePrinter {
void print(const Signature& sig);
void print(const Struct& struct_);
void print(const Array& array);
- void print(const Rtt& rtt);
// FIXME: This hard limit on how many times we call print() avoids extremely
// large outputs, which can be inconveniently large in some cases, but
@@ -179,8 +178,6 @@ void TypeNamePrinter::print(Type type) {
os << type;
} else if (type.isTuple()) {
print(type.getTuple());
- } else if (type.isRtt()) {
- print(type.getRtt());
} else if (type.isRef()) {
if (!maybePrintRefShorthand(os, type)) {
os << "ref";
@@ -301,14 +298,6 @@ void TypeNamePrinter::print(const Array& array) {
os << ']';
}
-void TypeNamePrinter::print(const Rtt& rtt) {
- os << "rtt_";
- if (rtt.hasDepth()) {
- os << rtt.depth << '_';
- }
- print(rtt.heapType);
-}
-
} // anonymous namespace
static std::ostream& printType(std::ostream& o, Type type, Module* wasm) {
@@ -323,14 +312,6 @@ static std::ostream& printType(std::ostream& o, Type type, Module* wasm) {
sep = " ";
}
o << ')';
- } else if (type.isRtt()) {
- auto rtt = type.getRtt();
- o << "(rtt ";
- if (rtt.hasDepth()) {
- o << rtt.depth << ' ';
- }
- TypeNamePrinter(o, wasm).print(rtt.heapType);
- o << ')';
} else if (type.isRef()) {
if (!maybePrintRefShorthand(o, type)) {
o << "(ref ";
@@ -2027,24 +2008,17 @@ struct PrintExpressionContents
}
}
void visitRefTest(RefTest* curr) {
- if (curr->rtt) {
- printMedium(o, "ref.test");
- } else {
- printMedium(o, "ref.test_static ");
- printHeapType(o, curr->intendedType, wasm);
- }
+ printMedium(o, "ref.test_static ");
+ printHeapType(o, curr->intendedType, wasm);
}
+
void visitRefCast(RefCast* curr) {
- if (curr->rtt) {
- printMedium(o, "ref.cast");
+ if (curr->safety == RefCast::Unsafe) {
+ printMedium(o, "ref.cast_nop_static ");
} else {
- if (curr->safety == RefCast::Unsafe) {
- printMedium(o, "ref.cast_nop_static ");
- } else {
- printMedium(o, "ref.cast_static ");
- }
- printHeapType(o, curr->intendedType, wasm);
+ printMedium(o, "ref.cast_static ");
}
+ printHeapType(o, curr->intendedType, wasm);
}
void visitBrOn(BrOn* curr) {
switch (curr->op) {
@@ -2055,27 +2029,17 @@ struct PrintExpressionContents
printMedium(o, "br_on_non_null ");
break;
case BrOnCast:
- if (curr->rtt) {
- printMedium(o, "br_on_cast ");
- } else {
- printMedium(o, "br_on_cast_static ");
- printName(curr->name, o);
- o << ' ';
- printHeapType(o, curr->intendedType, wasm);
- return;
- }
- break;
+ printMedium(o, "br_on_cast_static ");
+ printName(curr->name, o);
+ o << ' ';
+ printHeapType(o, curr->intendedType, wasm);
+ return;
case BrOnCastFail:
- if (curr->rtt) {
- printMedium(o, "br_on_cast_fail ");
- } else {
- printMedium(o, "br_on_cast_static_fail ");
- printName(curr->name, o);
- o << ' ';
- printHeapType(o, curr->intendedType, wasm);
- return;
- }
- break;
+ printMedium(o, "br_on_cast_static_fail ");
+ printName(curr->name, o);
+ o << ' ';
+ printHeapType(o, curr->intendedType, wasm);
+ return;
case BrOnFunc:
printMedium(o, "br_on_func ");
break;
@@ -2099,18 +2063,6 @@ struct PrintExpressionContents
}
printName(curr->name, o);
}
- void visitRttCanon(RttCanon* curr) {
- printMedium(o, "rtt.canon ");
- TypeNamePrinter(o, wasm).print(curr->type.getRtt().heapType);
- }
- void visitRttSub(RttSub* curr) {
- if (curr->fresh) {
- printMedium(o, "rtt.fresh_sub ");
- } else {
- printMedium(o, "rtt.sub ");
- }
- TypeNamePrinter(o, wasm).print(curr->type.getRtt().heapType);
- }
// If we cannot print a valid unreachable instruction (say, a struct.get,
// where if the ref is unreachable, we don't know what heap type to print),
@@ -2135,9 +2087,6 @@ struct PrintExpressionContents
if (curr->isWithDefault()) {
printMedium(o, "_default");
}
- if (curr->rtt) {
- printMedium(o, "_with_rtt");
- }
o << ' ';
TypeNamePrinter(o, wasm).print(curr->type.getHeapType());
}
@@ -2188,9 +2137,6 @@ struct PrintExpressionContents
if (curr->isWithDefault()) {
printMedium(o, "_default");
}
- if (curr->rtt) {
- printMedium(o, "_with_rtt");
- }
o << ' ';
TypeNamePrinter(o, wasm).print(curr->type.getHeapType());
}
@@ -2198,10 +2144,7 @@ struct PrintExpressionContents
if (printUnreachableReplacement(curr)) {
return;
}
- printMedium(o, "array.init");
- if (!curr->rtt) {
- printMedium(o, "_static");
- }
+ printMedium(o, "array.init_static");
o << ' ';
TypeNamePrinter(o, wasm).print(curr->type.getHeapType());
}
diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp
index a3d9442bf..84e19428d 100644
--- a/src/passes/StackIR.cpp
+++ b/src/passes/StackIR.cpp
@@ -72,7 +72,7 @@ public:
// Removing unneeded blocks is dangerous with GC, as if we do this:
//
// (call
- // (rtt)
+ // (struct.new)
// (block
// (nop)
// (i32)
@@ -80,7 +80,7 @@ public:
// )
// === remove inner block ==>
// (call
- // (rtt)
+ // (struct.new)
// (nop)
// (i32)
// )
@@ -90,7 +90,7 @@ public:
// (call
// (block
// (local.set
- // (rtt)
+ // (struct.new)
// )
// (nop)
// (local.get)
@@ -98,7 +98,9 @@ public:
// (i32)
// )
//
- // However, that is not valid as an rtt cannot be set to a local.
+ // However, that is not valid as an non-nullable reference cannot be set to
+ // a local. TODO: double check that this is still true now that we don't
+ // have RTTs.
if (!features.hasGC()) {
removeUnneededBlocks();
}
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index d0c92690a..47d55cfef 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -181,11 +181,11 @@ private:
// Recombination and mutation can replace a node with another node of the same
// type, but should not do so for certain types that are dangerous. For
- // example, it would be bad to add an RTT in a tuple, as that would force us
- // to use temporary locals for the tuple, but RTTs are not defaultable.
- // Also, 'pop' pseudo instruction for EH is supposed to exist only at the
- // beginning of a 'catch' block, so it shouldn't be moved around or deleted
- // freely.
+ // example, it would be bad to add a non-nullable reference to a tuple, as
+ // that would force us to use temporary locals for the tuple, but non-nullable
+ // references cannot always be stored in locals. Also, the 'pop' pseudo
+ // instruction for EH is supposed to exist only at the beginning of a 'catch'
+ // block, so it shouldn't be moved around or deleted freely.
bool canBeArbitrarilyReplaced(Expression* curr) {
return curr->type.isDefaultable() &&
!EHUtils::containsValidDanglingPop(curr);
@@ -312,7 +312,6 @@ private:
bool isLoggableType(Type type);
Nullability getSubType(Nullability nullability);
HeapType getSubType(HeapType type);
- Rtt getSubType(Rtt rtt);
Type getSubType(Type type);
// Utilities
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 59c9dca45..4d0a8d7b7 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -918,7 +918,7 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
&Self::makeSelect)
.add(FeatureSet::Multivalue, &Self::makeTupleExtract);
}
- if (type.isSingle() && !type.isRef() && !type.isRtt()) {
+ if (type.isSingle() && !type.isRef()) {
options.add(FeatureSet::MVP, {&Self::makeLoad, Important});
options.add(FeatureSet::SIMD, &Self::makeSIMD);
}
@@ -1893,8 +1893,6 @@ Expression* TranslateToFuzzReader::makeConst(Type type) {
} else {
return makeConstCompoundRef(type);
}
- } else if (type.isRtt()) {
- return builder.makeRtt(type);
} else if (type.isTuple()) {
std::vector<Expression*> operands;
for (const auto& t : type) {
@@ -2035,14 +2033,15 @@ Expression* TranslateToFuzzReader::makeUnary(Type type) {
// give up
return makeTrivial(type);
}
- // There are no unary ops for reference or RTT types.
- if (type.isRef() || type.isRtt()) {
+ // There are no unary ops for reference types.
+ // TODO: not quite true if you count struct.new and array.new.
+ if (type.isRef()) {
return makeTrivial(type);
}
switch (type.getBasic()) {
case Type::i32: {
auto singleConcreteType = getSingleConcreteType();
- if (singleConcreteType.isRef() || singleConcreteType.isRtt()) {
+ if (singleConcreteType.isRef()) {
// TODO: Do something more interesting here.
return makeTrivial(type);
}
@@ -2241,8 +2240,9 @@ Expression* TranslateToFuzzReader::makeBinary(Type type) {
// give up
return makeTrivial(type);
}
- // There are no binary ops for reference or RTT types.
- if (type.isRef() || type.isRtt()) {
+ // There are no binary ops for reference types.
+ // TODO: Use struct.new
+ if (type.isRef()) {
return makeTrivial(type);
}
switch (type.getBasic()) {
@@ -3056,19 +3056,6 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) {
return type;
}
-Rtt TranslateToFuzzReader::getSubType(Rtt rtt) {
- if (getTypeSystem() == TypeSystem::Nominal ||
- getTypeSystem() == TypeSystem::Isorecursive) {
- // With nominal or isorecursive typing the depth in rtts must match the
- // nominal hierarchy, so we cannot create a random depth like we do below.
- return rtt;
- }
- uint32_t depth = rtt.depth != Rtt::NoDepth
- ? rtt.depth
- : oneIn(2) ? Rtt::NoDepth : upTo(MAX_RTT_DEPTH + 1);
- return Rtt(depth, rtt.heapType);
-}
-
Type TranslateToFuzzReader::getSubType(Type type) {
if (type.isTuple()) {
std::vector<Type> types;
@@ -3080,8 +3067,6 @@ Type TranslateToFuzzReader::getSubType(Type type) {
auto heapType = getSubType(type.getHeapType());
auto nullability = getSubType(type.getNullability());
return Type(heapType, nullability);
- } else if (type.isRtt()) {
- return Type(getSubType(type.getRtt()));
} else {
// This is an MVP type without subtypes.
assert(type.isBasic());
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index edb96977d..364065b8b 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -181,20 +181,12 @@ struct HeapTypeGeneratorImpl {
return builder.getTempRefType(heapType, nullability);
}
- Type generateRttType() {
- auto heapType = generateHeapType();
- auto depth = rand.oneIn(2) ? Rtt::NoDepth : rand.upTo(MAX_RTT_DEPTH);
- return builder.getTempRttType(Rtt(depth, heapType));
- }
-
Type generateSingleType() {
- switch (rand.upTo(3)) {
+ switch (rand.upTo(2)) {
case 0:
return generateBasicType();
case 1:
return generateRefType();
- case 2:
- return generateRttType();
}
WASM_UNREACHABLE("unexpected");
}
@@ -412,20 +404,10 @@ struct HeapTypeGeneratorImpl {
return {pickSubHeapType(super.type), nullability};
}
- Rtt generateSubRtt(Rtt super) {
- auto depth = super.hasDepth()
- ? super.depth
- : rand.oneIn(2) ? Rtt::NoDepth : rand.upTo(MAX_RTT_DEPTH);
- return {depth, super.heapType};
- }
-
Type generateSubtype(Type type) {
if (type.isRef()) {
auto ref = generateSubRef({type.getHeapType(), type.getNullability()});
return builder.getTempRefType(ref.type, ref.nullability);
- } else if (type.isRtt()) {
- auto rtt = generateSubRtt(type.getRtt());
- return builder.getTempRttType(rtt);
} else if (type.isBasic()) {
// Non-reference basic types do not have subtypes.
return type;
diff --git a/src/tools/fuzzing/parameters.h b/src/tools/fuzzing/parameters.h
index 6618ce6db..1ba7b064f 100644
--- a/src/tools/fuzzing/parameters.h
+++ b/src/tools/fuzzing/parameters.h
@@ -38,9 +38,6 @@ constexpr int MAX_TUPLE_SIZE = 6;
// The maximum number of struct fields.
static const int MAX_STRUCT_SIZE = 6;
-// The maximum rtt depth.
-constexpr int MAX_RTT_DEPTH = 3;
-
// The number of nontrivial heap types to generate.
constexpr int MIN_HEAPTYPES = 4;
constexpr int MAX_HEAPTYPES = 20;
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 22fa87633..6150441cd 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -558,7 +558,6 @@ public:
Expression* init;
auto heapType = type.getHeapType();
- // TODO: handle rtts if we need them
if (heapType.isStruct()) {
init = builder.makeStructNew(heapType, args);
} else if (heapType.isArray()) {
diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp
index d2540636f..d80c89ea8 100644
--- a/src/tools/wasm-fuzz-types.cpp
+++ b/src/tools/wasm-fuzz-types.cpp
@@ -386,24 +386,6 @@ void Fuzzer::checkCanonicalization() {
}
}
- CopiedType getRtt(Type old) {
- auto copied = getChildHeapType(old.getHeapType());
- auto rtt = old.getRtt();
- rtt.heapType = copied.get();
- if (copied.getNew()) {
- // The child is temporary, so we must put it in a temporary type.
- return {NewType{builder.getTempRttType(rtt)}};
- } else {
- // The child is canonical, so we can either put it in a temporary type
- // or use the canonical type.
- if (rand.oneIn(2)) {
- return {NewType{builder.getTempRttType(rtt)}};
- } else {
- return {OldType{Type(rtt)}};
- }
- }
- }
-
CopiedType getRef(Type old) {
auto copied = getChildHeapType(old.getHeapType());
auto type = copied.get();
@@ -425,8 +407,6 @@ void Fuzzer::checkCanonicalization() {
CopiedType getType(Type old) {
if (old.isTuple()) {
return getTuple(old);
- } else if (old.isRtt()) {
- return getRtt(old);
} else if (old.isRef()) {
return getRef(old);
} else {
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 200252da7..6b05c38cc 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -373,10 +373,6 @@ enum EncodedType {
nonnullable = -0x15, // 0x6b
// integer reference type
i31ref = -0x16, // 0x6a
- // run-time type info type, with depth index n
- rtt_n = -0x17, // 0x69
- // run-time type info type, without depth index n
- rtt = -0x18, // 0x68
// gc and string reference types
dataref = -0x19, // 0x67
stringref = -0x1c, // 0x64
@@ -1089,36 +1085,24 @@ enum ASTNodes {
// gc opcodes
RefEq = 0xd5,
- StructNewWithRtt = 0x01,
- StructNewDefaultWithRtt = 0x02,
StructGet = 0x03,
StructGetS = 0x04,
StructGetU = 0x05,
StructSet = 0x06,
StructNew = 0x07,
StructNewDefault = 0x08,
- ArrayNewWithRtt = 0x11,
- ArrayNewDefaultWithRtt = 0x12,
ArrayGet = 0x13,
ArrayGetS = 0x14,
ArrayGetU = 0x15,
ArraySet = 0x16,
ArrayLen = 0x17,
ArrayCopy = 0x18,
- ArrayInit = 0x19,
ArrayInitStatic = 0x1a,
ArrayNew = 0x1b,
ArrayNewDefault = 0x1c,
I31New = 0x20,
I31GetS = 0x21,
I31GetU = 0x22,
- RttCanon = 0x30,
- RttSub = 0x31,
- RttFreshSub = 0x32,
- RefTest = 0x40,
- RefCast = 0x41,
- BrOnCast = 0x42,
- BrOnCastFail = 0x43,
RefTestStatic = 0x44,
RefCastStatic = 0x45,
BrOnCastStatic = 0x46,
@@ -1708,8 +1692,6 @@ public:
bool maybeVisitRefTest(Expression*& out, uint32_t code);
bool maybeVisitRefCast(Expression*& out, uint32_t code);
bool maybeVisitBrOn(Expression*& out, uint32_t code);
- bool maybeVisitRttCanon(Expression*& out, uint32_t code);
- bool maybeVisitRttSub(Expression*& out, uint32_t code);
bool maybeVisitStructNew(Expression*& out, uint32_t code);
bool maybeVisitStructGet(Expression*& out, uint32_t code);
bool maybeVisitStructSet(Expression*& out, uint32_t code);
@@ -1755,7 +1737,7 @@ public:
// Struct/Array instructions have an unnecessary heap type that is just for
// validation (except for the case of unreachability, but that's not a problem
- // anyhow, we can ignore it there). That is, we also have a reference / rtt
+ // anyhow, we can ignore it there). That is, we also have a reference typed
// child from which we can infer the type anyhow, and we just need to check
// that type is the same.
void validateHeapTypeUsingChild(Expression* child, HeapType heapType);
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 61227a811..1faf95d73 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -805,13 +805,6 @@ public:
ret->finalize();
return ret;
}
- RefTest* makeRefTest(Expression* ref, Expression* rtt) {
- auto* ret = wasm.allocator.alloc<RefTest>();
- ret->ref = ref;
- ret->rtt = rtt;
- ret->finalize();
- return ret;
- }
RefTest* makeRefTest(Expression* ref, HeapType intendedType) {
auto* ret = wasm.allocator.alloc<RefTest>();
ret->ref = ref;
@@ -819,14 +812,6 @@ public:
ret->finalize();
return ret;
}
- RefCast* makeRefCast(Expression* ref, Expression* rtt) {
- auto* ret = wasm.allocator.alloc<RefCast>();
- ret->ref = ref;
- ret->rtt = rtt;
- ret->finalize();
- return ret;
- }
-
RefCast*
makeRefCast(Expression* ref, HeapType intendedType, RefCast::Safety safety) {
auto* ret = wasm.allocator.alloc<RefCast>();
@@ -836,13 +821,11 @@ public:
ret->finalize();
return ret;
}
- BrOn*
- makeBrOn(BrOnOp op, Name name, Expression* ref, Expression* rtt = nullptr) {
+ BrOn* makeBrOn(BrOnOp op, Name name, Expression* ref) {
auto* ret = wasm.allocator.alloc<BrOn>();
ret->op = op;
ret->name = name;
ret->ref = ref;
- ret->rtt = rtt;
ret->finalize();
return ret;
}
@@ -855,37 +838,6 @@ public:
ret->finalize();
return ret;
}
- RttCanon* makeRttCanon(HeapType heapType) {
- auto* ret = wasm.allocator.alloc<RttCanon>();
- ret->type = Type(Rtt(heapType.getDepth(), heapType));
- ret->finalize();
- return ret;
- }
- RttSub* makeRttSub(HeapType heapType, Expression* parent) {
- auto* ret = wasm.allocator.alloc<RttSub>();
- ret->parent = parent;
- auto parentRtt = parent->type.getRtt();
- if (parentRtt.hasDepth()) {
- ret->type = Type(Rtt(parentRtt.depth + 1, heapType));
- } else {
- ret->type = Type(Rtt(heapType));
- }
- ret->finalize();
- return ret;
- }
- RttSub* makeRttFreshSub(HeapType heapType, Expression* parent) {
- auto* ret = makeRttSub(heapType, parent);
- ret->fresh = true;
- return ret;
- }
- template<typename T>
- StructNew* makeStructNew(Expression* rtt, const T& args) {
- auto* ret = wasm.allocator.alloc<StructNew>();
- ret->rtt = rtt;
- ret->operands.set(args);
- ret->finalize();
- return ret;
- }
template<typename T> StructNew* makeStructNew(HeapType type, const T& args) {
auto* ret = wasm.allocator.alloc<StructNew>();
ret->operands.set(args);
@@ -912,15 +864,6 @@ public:
return ret;
}
ArrayNew*
- makeArrayNew(Expression* rtt, Expression* size, Expression* init = nullptr) {
- auto* ret = wasm.allocator.alloc<ArrayNew>();
- ret->rtt = rtt;
- ret->size = size;
- ret->init = init;
- ret->finalize();
- return ret;
- }
- ArrayNew*
makeArrayNew(HeapType type, Expression* size, Expression* init = nullptr) {
auto* ret = wasm.allocator.alloc<ArrayNew>();
ret->size = size;
@@ -929,14 +872,6 @@ public:
ret->finalize();
return ret;
}
- ArrayInit* makeArrayInit(Expression* rtt,
- const std::vector<Expression*>& values) {
- auto* ret = wasm.allocator.alloc<ArrayInit>();
- ret->rtt = rtt;
- ret->values.set(values);
- ret->finalize();
- return ret;
- }
ArrayInit* makeArrayInit(HeapType type,
const std::vector<Expression*>& values) {
auto* ret = wasm.allocator.alloc<ArrayInit>();
@@ -1121,9 +1056,6 @@ public:
if (type.isRef() && type.getHeapType() == HeapType::i31) {
return makeI31New(makeConst(value.geti31()));
}
- if (type.isRtt()) {
- return makeRtt(value.type);
- }
TODO_SINGLE_COMPOUND(type);
WASM_UNREACHABLE("unsupported constant expression");
}
@@ -1141,18 +1073,6 @@ public:
}
}
- // Given a type, creates an RTT expression of that type, using a combination
- // of rtt.canon and rtt.subs.
- Expression* makeRtt(Type type) {
- Expression* ret = makeRttCanon(type.getHeapType());
- if (type.getRtt().hasDepth()) {
- for (Index i = 0; i < type.getRtt().depth; i++) {
- ret = makeRttSub(type.getHeapType(), ret);
- }
- }
- return ret;
- }
-
// Additional utility functions for building on top of nodes
// Convenient to have these on Builder, as it has allocation built in
@@ -1322,25 +1242,13 @@ public:
ValidatingBuilder(Module& wasm, size_t line, size_t col)
: Builder(wasm), line(line), col(col) {}
- Expression* validateAndMakeBrOn(BrOnOp op,
- Name name,
- Expression* ref,
- Expression* rtt = nullptr) {
- if (op == BrOnCast) {
- if (rtt->type == Type::unreachable) {
- // An unreachable rtt is not supported: the text and binary formats do
- // not provide the type, so if it's unreachable we should not even
- // create a br_on_cast in such a case, as we'd have no idea what it
- // casts to.
- return makeSequence(makeDrop(ref), rtt);
- }
- }
+ Expression* validateAndMakeBrOn(BrOnOp op, Name name, Expression* ref) {
if (op == BrOnNull) {
if (!ref->type.isRef() && ref->type != Type::unreachable) {
throw ParseException("Invalid ref for br_on_null", line, col);
}
}
- return makeBrOn(op, name, ref, rtt);
+ return makeBrOn(op, name, ref);
}
template<typename T>
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index 55a9edd16..fa1fa229f 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -601,7 +601,6 @@ switch (DELEGATE_ID) {
case Expression::Id::RefTestId: {
DELEGATE_START(RefTest);
DELEGATE_FIELD_HEAPTYPE(RefTest, intendedType);
- DELEGATE_FIELD_OPTIONAL_CHILD(RefTest, rtt);
DELEGATE_FIELD_CHILD(RefTest, ref);
DELEGATE_END(RefTest);
break;
@@ -609,7 +608,6 @@ switch (DELEGATE_ID) {
case Expression::Id::RefCastId: {
DELEGATE_START(RefCast);
DELEGATE_FIELD_HEAPTYPE(RefCast, intendedType);
- DELEGATE_FIELD_OPTIONAL_CHILD(RefCast, rtt);
DELEGATE_FIELD_CHILD(RefCast, ref);
DELEGATE_END(RefCast);
break;
@@ -619,26 +617,12 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_INT(BrOn, op);
DELEGATE_FIELD_SCOPE_NAME_USE(BrOn, name);
DELEGATE_FIELD_HEAPTYPE(BrOn, intendedType);
- DELEGATE_FIELD_OPTIONAL_CHILD(BrOn, rtt);
DELEGATE_FIELD_CHILD(BrOn, ref);
DELEGATE_END(BrOn);
break;
}
- case Expression::Id::RttCanonId: {
- DELEGATE_START(RttCanon);
- DELEGATE_END(RttCanon);
- break;
- }
- case Expression::Id::RttSubId: {
- DELEGATE_START(RttSub);
- DELEGATE_FIELD_CHILD(RttSub, parent);
- DELEGATE_FIELD_INT(RttSub, fresh);
- DELEGATE_END(RttSub);
- break;
- }
case Expression::Id::StructNewId: {
DELEGATE_START(StructNew);
- DELEGATE_FIELD_OPTIONAL_CHILD(StructNew, rtt);
DELEGATE_FIELD_CHILD_VECTOR(StructNew, operands);
DELEGATE_END(StructNew);
break;
@@ -661,7 +645,6 @@ switch (DELEGATE_ID) {
}
case Expression::Id::ArrayNewId: {
DELEGATE_START(ArrayNew);
- DELEGATE_FIELD_OPTIONAL_CHILD(ArrayNew, rtt);
DELEGATE_FIELD_CHILD(ArrayNew, size);
DELEGATE_FIELD_OPTIONAL_CHILD(ArrayNew, init);
DELEGATE_END(ArrayNew);
@@ -669,7 +652,6 @@ switch (DELEGATE_ID) {
}
case Expression::Id::ArrayInitId: {
DELEGATE_START(ArrayInit);
- DELEGATE_FIELD_OPTIONAL_CHILD(ArrayInit, rtt);
DELEGATE_FIELD_CHILD_VECTOR(ArrayInit, values);
DELEGATE_END(ArrayInit);
break;
diff --git a/src/wasm-delegations.def b/src/wasm-delegations.def
index 24531b149..b88a55556 100644
--- a/src/wasm-delegations.def
+++ b/src/wasm-delegations.def
@@ -73,8 +73,6 @@ DELEGATE(CallRef);
DELEGATE(RefTest);
DELEGATE(RefCast);
DELEGATE(BrOn);
-DELEGATE(RttCanon);
-DELEGATE(RttSub);
DELEGATE(StructNew);
DELEGATE(StructGet);
DELEGATE(StructSet);
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index d00ccac43..254a1a2e2 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1467,19 +1467,6 @@ public:
if (ref.breaking()) {
return typename Cast::Breaking{ref};
}
- // The RTT value for the type we are trying to cast to.
- Literal intendedRtt;
- if (curr->rtt) {
- // This is a dynamic check with an RTT.
- Flow rtt = self()->visit(curr->rtt);
- if (rtt.breaking()) {
- return typename Cast::Breaking{rtt};
- }
- intendedRtt = rtt.getSingleValue();
- } else {
- // If there is no explicit RTT, use the canonical RTT for the static type.
- intendedRtt = Literal::makeCanonicalRtt(curr->intendedType);
- }
Literal original = ref.getSingleValue();
if (original.isNull()) {
return typename Cast::Null{original};
@@ -1489,30 +1476,10 @@ public:
if (!original.isData() && !original.isFunction()) {
return typename Cast::Failure{original};
}
- Literal actualRtt;
- if (original.isFunction()) {
- // Function references always have the canonical RTTs of the functions
- // they reference. We must have a module to look up the function's type to
- // get that canonical RTT.
- auto* func =
- module ? module->getFunctionOrNull(original.getFunc()) : nullptr;
- if (!func) {
- return typename Cast::Breaking{NONCONSTANT_FLOW};
- }
- actualRtt = Literal::makeCanonicalRtt(func->type);
- } else {
- assert(original.isData());
- actualRtt = original.getGCData()->rtt;
- };
- // We have the actual and intended RTTs, so perform the cast.
- if (actualRtt.isSubRtt(intendedRtt)) {
- HeapType resultType = intendedRtt.type.getHeapType();
- if (original.isFunction()) {
- return typename Cast::Success{Literal{original.getFunc(), resultType}};
- } else {
- return
- typename Cast::Success{Literal(original.getGCData(), resultType)};
- }
+ HeapType actualType = original.type.getHeapType();
+ // We have the actual and intended types, so perform the cast.
+ if (HeapType::isSubType(actualType, curr->intendedType)) {
+ return typename Cast::Success{original};
} else {
return typename Cast::Failure{original};
}
@@ -1629,33 +1596,8 @@ public:
}
return {value};
}
- Flow visitRttCanon(RttCanon* curr) {
- return Literal::makeCanonicalRtt(curr->type.getHeapType());
- }
- Flow visitRttSub(RttSub* curr) {
- Flow parent = self()->visit(curr->parent);
- if (parent.breaking()) {
- return parent;
- }
- auto parentValue = parent.getSingleValue();
- auto newSupers = std::make_unique<RttSupers>(parentValue.getRttSupers());
- newSupers->push_back(parentValue.type.getHeapType());
- if (curr->fresh) {
- newSupers->back().makeFresh();
- }
- return Literal(std::move(newSupers), curr->type);
- }
-
Flow visitStructNew(StructNew* curr) {
NOTE_ENTER("StructNew");
- Literal rttVal;
- if (curr->rtt) {
- Flow rtt = self()->visit(curr->rtt);
- if (rtt.breaking()) {
- return rtt;
- }
- rttVal = rtt.getSingleValue();
- }
if (curr->type == Type::unreachable) {
// We cannot proceed to compute the heap type, as there isn't one. Just
// find why we are unreachable, and stop there.
@@ -1681,10 +1623,7 @@ public:
data[i] = value.getSingleValue();
}
}
- if (!curr->rtt) {
- rttVal = Literal::makeCanonicalRtt(heapType);
- }
- return Literal(std::make_shared<GCData>(rttVal, data),
+ return Literal(std::make_shared<GCData>(curr->type.getHeapType(), data),
curr->type.getHeapType());
}
Flow visitStructGet(StructGet* curr) {
@@ -1728,14 +1667,6 @@ public:
Flow visitArrayNew(ArrayNew* curr) {
NOTE_ENTER("ArrayNew");
- Literal rttVal;
- if (curr->rtt) {
- Flow rtt = self()->visit(curr->rtt);
- if (rtt.breaking()) {
- return rtt;
- }
- rttVal = rtt.getSingleValue();
- }
auto size = self()->visit(curr->size);
if (size.breaking()) {
return size;
@@ -1769,22 +1700,11 @@ public:
data[i] = value;
}
}
- if (!curr->rtt) {
- rttVal = Literal::makeCanonicalRtt(heapType);
- }
- return Literal(std::make_shared<GCData>(rttVal, data),
+ return Literal(std::make_shared<GCData>(curr->type.getHeapType(), data),
curr->type.getHeapType());
}
Flow visitArrayInit(ArrayInit* curr) {
NOTE_ENTER("ArrayInit");
- Literal rttVal;
- if (curr->rtt) {
- Flow rtt = self()->visit(curr->rtt);
- if (rtt.breaking()) {
- return rtt;
- }
- rttVal = rtt.getSingleValue();
- }
Index num = curr->values.size();
if (num >= ArrayLimit) {
hostLimit("allocation failure");
@@ -1810,10 +1730,7 @@ public:
}
data[i] = truncateForPacking(value.getSingleValue(), field);
}
- if (!curr->rtt) {
- rttVal = Literal::makeCanonicalRtt(heapType);
- }
- return Literal(std::make_shared<GCData>(rttVal, data),
+ return Literal(std::make_shared<GCData>(curr->type.getHeapType(), data),
curr->type.getHeapType());
}
Flow visitArrayGet(ArrayGet* curr) {
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 0829a35f2..64f764721 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -279,24 +279,16 @@ private:
Expression* makeCallRef(Element& s, bool isReturn);
Expression* makeI31New(Element& s);
Expression* makeI31Get(Element& s, bool signed_);
- Expression* makeRefTest(Element& s);
Expression* makeRefTestStatic(Element& s);
- Expression* makeRefCast(Element& s);
Expression* makeRefCastStatic(Element& s);
Expression* makeRefCastNopStatic(Element& s);
Expression* makeBrOn(Element& s, BrOnOp op);
Expression* makeBrOnStatic(Element& s, BrOnOp op);
- Expression* makeRttCanon(Element& s);
- Expression* makeRttSub(Element& s);
- Expression* makeRttFreshSub(Element& s);
- Expression* makeStructNew(Element& s, bool default_);
Expression* makeStructNewStatic(Element& s, bool default_);
Index getStructIndex(Element& type, Element& field);
Expression* makeStructGet(Element& s, bool signed_ = false);
Expression* makeStructSet(Element& s);
- Expression* makeArrayNew(Element& s, bool default_);
Expression* makeArrayNewStatic(Element& s, bool default_);
- Expression* makeArrayInit(Element& s);
Expression* makeArrayInitStatic(Element& s);
Expression* makeArrayGet(Element& s, bool signed_ = false);
Expression* makeArraySet(Element& s);
@@ -359,7 +351,7 @@ private:
// Struct/Array instructions have an unnecessary heap type that is just for
// validation (except for the case of unreachability, but that's not a problem
- // anyhow, we can ignore it there). That is, we also have a reference / rtt
+ // anyhow, we can ignore it there). That is, we also have a reference typed
// child from which we can infer the type anyhow, and we just need to check
// that type is the same.
void
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 4d87ac68d..014e28646 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -67,7 +67,6 @@ struct Signature;
struct Field;
struct Struct;
struct Array;
-struct Rtt;
enum Nullability { NonNullable, Nullable };
enum Mutability { Immutable, Mutable };
@@ -128,9 +127,6 @@ public:
// Signature, Struct or Array via implicit conversion to HeapType.
Type(HeapType, Nullability nullable);
- // Construct from rtt description
- Type(Rtt);
-
// Predicates
// Compound Concrete
// Type Basic │ Single│
@@ -152,7 +148,6 @@ public:
// ├─ Compound ──╫───┼───┼───┼───┤───────┤ │
// │ Ref ║ │ x │ x │ x │ f? n? │◄┘
// │ Tuple ║ │ x │ │ x │ │
- // │ Rtt ║ │ x │ x │ x │ │
// └─────────────╨───┴───┴───┴───┴───────┘
constexpr bool isBasic() const { return id <= _last_basic_type; }
constexpr bool isConcrete() const { return id >= i32; }
@@ -174,18 +169,10 @@ 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;
- bool isRtt() const;
bool isStruct() const;
bool isArray() const;
bool isDefaultable() const;
- // Check if a type is either defaultable or non-nullable. This is useful in
- // the case where we allow non-nullable types, but we disallow other things
- // that are non-defaultable. For example, when GC-non-nullable references are
- // allowed we can have a non-nullable reference, but we cannot have any other
- // nondefaultable type.
- bool isDefaultableOrNonNullable() const;
-
Nullability getNullability() const;
private:
@@ -237,12 +224,9 @@ public:
const Tuple& getTuple() const;
// Gets the heap type corresponding to this type, assuming that it is a
- // reference or Rtt type.
+ // reference type.
HeapType getHeapType() const;
- // Gets the Rtt for this type, assuming that it is an Rtt type.
- Rtt getRtt() const;
-
// Returns a number type based on its size in bytes and whether it is a float
// type.
static Type get(unsigned byteSize, bool float_);
@@ -561,21 +545,6 @@ struct Array {
std::string toString() const;
};
-struct Rtt {
- // An Rtt can have no depth specified
- static constexpr uint32_t NoDepth = -1;
- uint32_t depth;
- HeapType heapType;
- explicit Rtt(HeapType heapType) : depth(NoDepth), heapType(heapType) {}
- Rtt(uint32_t depth, HeapType heapType) : depth(depth), heapType(heapType) {}
- bool operator==(const Rtt& other) const {
- return depth == other.depth && heapType == other.heapType;
- }
- bool operator!=(const Rtt& other) const { return !(*this == other); }
- bool hasDepth() const { return depth != uint32_t(NoDepth); }
- std::string toString() const;
-};
-
// TypeBuilder - allows for the construction of recursive types. Contains a
// table of `n` mutable HeapTypes and can construct temporary types that are
// backed by those HeapTypes, refering to them by reference. Those temporary
@@ -623,11 +592,10 @@ struct TypeBuilder {
HeapType getTempHeapType(size_t i);
// Gets a temporary type or heap type for use in initializing the
- // TypeBuilder's HeapTypes. For Ref and Rtt types, the HeapType may be a
- // temporary HeapType owned by this builder or a canonical HeapType.
+ // TypeBuilder's HeapTypes. For Ref types, the HeapType may be a temporary
+ // HeapType owned by this builder or a canonical HeapType.
Type getTempTupleType(const Tuple&);
Type getTempRefType(HeapType heapType, Nullability nullable);
- Type getTempRttType(Rtt rtt);
// In nominal mode, or for nominal types, declare the HeapType being built at
// index `i` to be an immediate subtype of the HeapType being built at index
@@ -717,7 +685,6 @@ std::ostream& operator<<(std::ostream&, Signature);
std::ostream& operator<<(std::ostream&, Field);
std::ostream& operator<<(std::ostream&, Struct);
std::ostream& operator<<(std::ostream&, Array);
-std::ostream& operator<<(std::ostream&, Rtt);
std::ostream& operator<<(std::ostream&, TypeBuilder::ErrorReason);
} // namespace wasm
@@ -752,10 +719,6 @@ template<> class hash<wasm::HeapType> {
public:
size_t operator()(const wasm::HeapType&) const;
};
-template<> class hash<wasm::Rtt> {
-public:
- size_t operator()(const wasm::Rtt&) const;
-};
template<> class hash<wasm::RecGroup> {
public:
size_t operator()(const wasm::RecGroup&) const;
diff --git a/src/wasm.h b/src/wasm.h
index 8c0e48da2..d0f632829 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -712,8 +712,6 @@ public:
RefTestId,
RefCastId,
BrOnId,
- RttCanonId,
- RttSubId,
StructNewId,
StructGetId,
StructSetId,
@@ -1492,16 +1490,9 @@ public:
Expression* ref;
- // If rtt is provided then this is a dynamic test with an rtt. If nullptr then
- // this is a static cast and intendedType is set, and it contains the type we
- // intend to cast to.
- Expression* rtt = nullptr;
HeapType intendedType;
void finalize();
-
- // Returns the type we intend to cast to.
- HeapType getIntendedType();
};
class RefCast : public SpecificExpression<Expression::RefCastId> {
@@ -1510,8 +1501,6 @@ public:
Expression* ref;
- // See above with RefTest.
- Expression* rtt = nullptr;
HeapType intendedType;
// Support the unsafe `ref.cast_nop_static` to enable precise cast overhead
@@ -1520,9 +1509,6 @@ public:
Safety safety = Safe;
void finalize();
-
- // Returns the type we intend to cast to.
- HeapType getIntendedType();
};
class BrOn : public SpecificExpression<Expression::BrOnId> {
@@ -1533,55 +1519,18 @@ public:
Name name;
Expression* ref;
- // BrOnCast* has, like RefCast and RefTest, either an rtt or a static intended
- // type.
- Expression* rtt = nullptr;
HeapType intendedType;
- // TODO: BrOnNull also has an optional extra value in the spec, which we do
- // not support. See also the discussion on
- // https://github.com/WebAssembly/function-references/issues/45
- // - depending on the decision there, we may want to move BrOnNull into
- // Break or a new class of its own.
-
void finalize();
- // Returns the type we intend to cast to. Relevant only for the cast variants.
- HeapType getIntendedType();
-
// Returns the type sent on the branch, if it is taken.
Type getSentType();
};
-class RttCanon : public SpecificExpression<Expression::RttCanonId> {
-public:
- RttCanon(MixedArena& allocator) {}
-
- void finalize();
-};
-
-class RttSub : public SpecificExpression<Expression::RttSubId> {
-public:
- RttSub(MixedArena& allocator) {}
-
- Expression* parent;
-
- // rtt.fresh_sub is like rtt.sub, but never caching or canonicalizing (i.e.,
- // it always returns a fresh RTT, non-identical to any other RTT in the
- // system).
- bool fresh = false;
-
- void finalize();
-};
-
class StructNew : public SpecificExpression<Expression::StructNewId> {
public:
StructNew(MixedArena& allocator) : operands(allocator) {}
- // A dynamic StructNew has an rtt, while a static one declares the type using
- // the type field.
- Expression* rtt = nullptr;
-
// A struct.new_with_default has empty operands. This does leave the case of a
// struct with no fields ambiguous, but it doesn't make a difference in that
// case, and binaryen doesn't guarantee roundtripping binaries anyhow.
@@ -1625,10 +1574,6 @@ public:
Expression* init = nullptr;
Expression* size;
- // A dynamic ArrayNew has an rtt, while a static one declares the type using
- // the type field.
- Expression* rtt = nullptr;
-
bool isWithDefault() { return !init; }
void finalize();
@@ -1640,10 +1585,6 @@ public:
ExpressionList values;
- // A dynamic ArrayInit has an rtt, while a static one declares the type using
- // the type field.
- Expression* rtt = nullptr;
-
void finalize();
};
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index b8a6c7e7a..05f9d93d5 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -53,8 +53,6 @@ Literal::Literal(Type type) : type(type) {
if (isData()) {
assert(!type.isNonNullable());
new (&gcData) std::shared_ptr<GCData>();
- } else if (type.isRtt()) {
- new (this) Literal(Literal::makeCanonicalRtt(type.getHeapType()));
} else {
// For anything else, zero out all the union data.
memset(&v128, 0, 16);
@@ -71,11 +69,6 @@ Literal::Literal(std::shared_ptr<GCData> gcData, HeapType type)
assert(isData());
}
-Literal::Literal(std::unique_ptr<RttSupers>&& rttSupers, Type type)
- : rttSupers(std::move(rttSupers)), type(type) {
- assert(type.isRtt());
-}
-
Literal::Literal(const Literal& other) : type(other.type) {
if (type.isBasic()) {
switch (type.getBasic()) {
@@ -104,11 +97,6 @@ Literal::Literal(const Literal& other) : type(other.type) {
func = other.func;
return;
}
- if (type.isRtt()) {
- // Allocate a new RttSupers with a copy of the other's data.
- new (&rttSupers) auto(std::make_unique<RttSupers>(*other.rttSupers));
- return;
- }
if (type.isRef()) {
auto heapType = type.getHeapType();
if (heapType.isBasic()) {
@@ -136,11 +124,8 @@ Literal::~Literal() {
if (type.isBasic()) {
return;
}
-
if (isData()) {
gcData.~shared_ptr();
- } else if (type.isRtt()) {
- rttSupers.~unique_ptr();
}
}
@@ -152,18 +137,6 @@ Literal& Literal::operator=(const Literal& other) {
return *this;
}
-Literal Literal::makeCanonicalRtt(HeapType type) {
- auto supers = std::make_unique<RttSupers>();
- std::optional<HeapType> supertype;
- for (auto curr = type; (supertype = curr.getSuperType()); curr = *supertype) {
- supers->emplace_back(*supertype);
- }
- // We want the highest types to be first.
- std::reverse(supers->begin(), supers->end());
- size_t depth = supers->size();
- return Literal(std::move(supers), Type(Rtt(depth, type)));
-}
-
template<typename LaneT, int Lanes>
static void extractBytes(uint8_t (&dest)[16], const LaneArray<Lanes>& lanes) {
std::array<uint8_t, 16> bytes;
@@ -228,8 +201,6 @@ Literal Literal::makeZero(Type type) {
assert(type.isSingle());
if (type.isRef()) {
return makeNull(type.getHeapType());
- } else if (type.isRtt()) {
- return Literal(type);
} else {
return makeFromInt32(0, type);
}
@@ -257,11 +228,6 @@ std::shared_ptr<GCData> Literal::getGCData() const {
return gcData;
}
-const RttSupers& Literal::getRttSupers() const {
- assert(type.isRtt());
- return *rttSupers;
-}
-
Literal Literal::castToF32() {
assert(type == Type::i32);
Literal ret(Type::f32);
@@ -383,8 +349,6 @@ bool Literal::operator==(const Literal& other) const {
// 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");
- } else if (type.isRtt()) {
- return *rttSupers == *other.rttSupers;
}
WASM_UNREACHABLE("unexpected type");
}
@@ -494,7 +458,7 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
if (literal.isData()) {
auto data = literal.getGCData();
if (data) {
- o << "[ref " << data->rtt << ' ' << data->values << ']';
+ o << "[ref " << data->type << ' ' << data->values << ']';
} else {
o << "[ref null " << literal.type << ']';
}
@@ -524,15 +488,6 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
WASM_UNREACHABLE("type should have been handled above");
}
}
- } else if (literal.type.isRtt()) {
- o << "[rtt ";
- for (auto& super : literal.getRttSupers()) {
- o << super.type << " :> ";
- if (super.freshPtr) {
- o << " (fresh)";
- }
- }
- o << literal.type << ']';
} else {
TODO_SINGLE_COMPOUND(literal.type);
switch (literal.type.getBasic()) {
@@ -2564,31 +2519,4 @@ Literal Literal::relaxedFmsF64x2(const Literal& left,
return ternary<2, &Literal::getLanesF64x2, &Literal::fms>(*this, left, right);
}
-bool Literal::isSubRtt(const Literal& other) const {
- assert(type.isRtt() && other.type.isRtt());
- // For this literal to be a sub-rtt of the other rtt, the supers must be a
- // superset. That is, if other is a->b->c then we should be a->b->c as well
- // with possibly ->d->.. added. The rttSupers array represents those chains,
- // but only the supers, which means the last item in the chain is simply the
- // type of the literal.
- const auto& supers = getRttSupers();
- const auto& otherSupers = other.getRttSupers();
- if (otherSupers.size() > supers.size()) {
- return false;
- }
- for (Index i = 0; i < otherSupers.size(); i++) {
- if (supers[i] != otherSupers[i]) {
- return false;
- }
- }
- // If we have more supers than other, compare that extra super. Otherwise,
- // we have the same amount of supers, and must be completely identical to
- // other.
- if (otherSupers.size() < supers.size()) {
- return other.type.getHeapType() == supers[otherSupers.size()].type;
- } else {
- return other.type == type;
- }
-}
-
} // namespace wasm
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 4e8e3f0d7..b74ef017b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1383,17 +1383,6 @@ void WasmBinaryWriter::writeType(Type type) {
writeHeapType(type.getHeapType());
return;
}
- if (type.isRtt()) {
- auto rtt = type.getRtt();
- if (rtt.hasDepth()) {
- o << S32LEB(BinaryConsts::EncodedType::rtt_n);
- o << U32LEB(rtt.depth);
- } else {
- o << S32LEB(BinaryConsts::EncodedType::rtt);
- }
- writeIndexedHeapType(rtt.heapType);
- return;
- }
int ret = 0;
TODO_SINGLE_COMPOUND(type);
switch (type.getBasic()) {
@@ -1877,14 +1866,6 @@ Type WasmBinaryBuilder::getType(int initial) {
return Type(getHeapType(), Nullable);
case BinaryConsts::EncodedType::nonnullable:
return Type(getHeapType(), NonNullable);
- case BinaryConsts::EncodedType::rtt_n: {
- auto depth = getU32LEB();
- auto heapType = getIndexedHeapType();
- return Type(Rtt(depth, heapType));
- }
- case BinaryConsts::EncodedType::rtt: {
- return Type(Rtt(getIndexedHeapType()));
- }
default:
throwError("invalid wasm type: " + std::to_string(initial));
}
@@ -2029,16 +2010,6 @@ void WasmBinaryBuilder::readTypes() {
}
return builder.getTempRefType(builder[size_t(htCode)], nullability);
}
- case BinaryConsts::EncodedType::rtt_n:
- case BinaryConsts::EncodedType::rtt: {
- auto depth = typeCode == BinaryConsts::EncodedType::rtt ? Rtt::NoDepth
- : getU32LEB();
- auto htCode = getU32LEB();
- if (size_t(htCode) >= builder.size()) {
- throwError("invalid type index: " + std::to_string(htCode));
- }
- return builder.getTempRttType(Rtt(depth, builder[htCode]));
- }
default:
throwError("unexpected type index: " + std::to_string(typeCode));
}
@@ -3875,12 +3846,6 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitBrOn(curr, opcode)) {
break;
}
- if (maybeVisitRttCanon(curr, opcode)) {
- break;
- }
- if (maybeVisitRttSub(curr, opcode)) {
- break;
- }
if (maybeVisitStructNew(curr, opcode)) {
break;
}
@@ -6793,12 +6758,7 @@ bool WasmBinaryBuilder::maybeVisitI31Get(Expression*& out, uint32_t code) {
}
bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::RefTest) {
- auto* rtt = popNonVoidExpression();
- auto* ref = popNonVoidExpression();
- out = Builder(wasm).makeRefTest(ref, rtt);
- return true;
- } else if (code == BinaryConsts::RefTestStatic) {
+ if (code == BinaryConsts::RefTestStatic) {
auto intendedType = getIndexedHeapType();
auto* ref = popNonVoidExpression();
out = Builder(wasm).makeRefTest(ref, intendedType);
@@ -6808,13 +6768,8 @@ bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) {
}
bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::RefCast) {
- auto* rtt = popNonVoidExpression();
- auto* ref = popNonVoidExpression();
- out = Builder(wasm).makeRefCast(ref, rtt);
- return true;
- } else if (code == BinaryConsts::RefCastStatic ||
- code == BinaryConsts::RefCastNopStatic) {
+ if (code == BinaryConsts::RefCastStatic ||
+ code == BinaryConsts::RefCastNopStatic) {
auto intendedType = getIndexedHeapType();
auto* ref = popNonVoidExpression();
auto safety =
@@ -6834,11 +6789,9 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) {
case BinaryConsts::BrOnNonNull:
op = BrOnNonNull;
break;
- case BinaryConsts::BrOnCast:
case BinaryConsts::BrOnCastStatic:
op = BrOnCast;
break;
- case BinaryConsts::BrOnCastFail:
case BinaryConsts::BrOnCastStaticFail:
op = BrOnCastFail;
break;
@@ -6871,35 +6824,8 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) {
out = Builder(wasm).makeBrOn(op, name, ref, intendedType);
return true;
}
- Expression* rtt = nullptr;
- if (op == BrOnCast || op == BrOnCastFail) {
- rtt = popNonVoidExpression();
- }
auto* ref = popNonVoidExpression();
- out = ValidatingBuilder(wasm, pos).validateAndMakeBrOn(op, name, ref, rtt);
- return true;
-}
-
-bool WasmBinaryBuilder::maybeVisitRttCanon(Expression*& out, uint32_t code) {
- if (code != BinaryConsts::RttCanon) {
- return false;
- }
- auto heapType = getIndexedHeapType();
- out = Builder(wasm).makeRttCanon(heapType);
- return true;
-}
-
-bool WasmBinaryBuilder::maybeVisitRttSub(Expression*& out, uint32_t code) {
- if (code != BinaryConsts::RttSub && code != BinaryConsts::RttFreshSub) {
- return false;
- }
- auto targetHeapType = getIndexedHeapType();
- auto* parent = popNonVoidExpression();
- if (code == BinaryConsts::RttSub) {
- out = Builder(wasm).makeRttSub(targetHeapType, parent);
- } else {
- out = Builder(wasm).makeRttFreshSub(targetHeapType, parent);
- }
+ out = ValidatingBuilder(wasm, pos).validateAndMakeBrOn(op, name, ref);
return true;
}
@@ -6917,21 +6843,6 @@ bool WasmBinaryBuilder::maybeVisitStructNew(Expression*& out, uint32_t code) {
}
out = Builder(wasm).makeStructNew(heapType, operands);
return true;
- } else if (code == BinaryConsts::StructNewWithRtt ||
- code == BinaryConsts::StructNewDefaultWithRtt) {
- auto heapType = getIndexedHeapType();
- auto* rtt = popNonVoidExpression();
- validateHeapTypeUsingChild(rtt, heapType);
- std::vector<Expression*> operands;
- if (code == BinaryConsts::StructNewWithRtt) {
- auto numOperands = heapType.getStruct().fields.size();
- operands.resize(numOperands);
- for (Index i = 0; i < numOperands; i++) {
- operands[numOperands - i - 1] = popNonVoidExpression();
- }
- }
- out = Builder(wasm).makeStructNew(rtt, operands);
- return true;
}
return false;
}
@@ -6987,18 +6898,6 @@ bool WasmBinaryBuilder::maybeVisitArrayNew(Expression*& out, uint32_t code) {
}
out = Builder(wasm).makeArrayNew(heapType, size, init);
return true;
- } else if (code == BinaryConsts::ArrayNewWithRtt ||
- code == BinaryConsts::ArrayNewDefaultWithRtt) {
- auto heapType = getIndexedHeapType();
- auto* rtt = popNonVoidExpression();
- validateHeapTypeUsingChild(rtt, heapType);
- auto* size = popNonVoidExpression();
- Expression* init = nullptr;
- if (code == BinaryConsts::ArrayNewWithRtt) {
- init = popNonVoidExpression();
- }
- out = Builder(wasm).makeArrayNew(rtt, size, init);
- return true;
}
return false;
}
@@ -7013,17 +6912,6 @@ bool WasmBinaryBuilder::maybeVisitArrayInit(Expression*& out, uint32_t code) {
}
out = Builder(wasm).makeArrayInit(heapType, values);
return true;
- } else if (code == BinaryConsts::ArrayInit) {
- auto heapType = getIndexedHeapType();
- auto size = getU32LEB();
- auto* rtt = popNonVoidExpression();
- validateHeapTypeUsingChild(rtt, heapType);
- std::vector<Expression*> values(size);
- for (size_t i = 0; i < size; i++) {
- values[size - i - 1] = popNonVoidExpression();
- }
- out = Builder(wasm).makeArrayInit(rtt, values);
- return true;
}
return false;
}
@@ -7370,7 +7258,7 @@ void WasmBinaryBuilder::validateHeapTypeUsingChild(Expression* child,
if (child->type == Type::unreachable) {
return;
}
- if ((!child->type.isRef() && !child->type.isRtt()) ||
+ if (!child->type.isRef() ||
!HeapType::isSubType(child->type.getHeapType(), heapType)) {
throwError("bad heap type: expected " + heapType.toString() +
" but found " + child->type.toString());
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 38ec788ba..f13091c91 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -54,7 +54,7 @@ namespace wasm {
static Name STRUCT("struct"), FIELD("field"), ARRAY("array"),
FUNC_SUBTYPE("func_subtype"), STRUCT_SUBTYPE("struct_subtype"),
ARRAY_SUBTYPE("array_subtype"), EXTENDS("extends"), REC("rec"), I8("i8"),
- I16("i16"), RTT("rtt"), DECLARE("declare"), ITEM("item"), OFFSET("offset");
+ I16("i16"), DECLARE("declare"), ITEM("item"), OFFSET("offset");
static Address getAddress(const Element* s) { return atoll(s->c_str()); }
@@ -752,46 +752,11 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
}
};
- auto parseRttType = [&](Element& elem) -> Type {
- // '(' 'rtt' depth? typeidx ')'
- uint32_t depth;
- Element* idx;
- switch (elem.size()) {
- default:
- throw ParseException(
- "unexpected number of rtt parameters", elem.line, elem.col);
- case 2:
- depth = Rtt::NoDepth;
- idx = elem[1];
- break;
- case 3:
- if (!String::isNumber(elem[1]->c_str())) {
- throw ParseException(
- "invalid rtt depth", elem[1]->line, elem[1]->col);
- }
- depth = atoi(elem[1]->c_str());
- idx = elem[2];
- break;
- }
- if (idx->dollared()) {
- HeapType type = builder[typeIndices[idx->c_str()]];
- return builder.getTempRttType(Rtt(depth, type));
- } else if (String::isNumber(idx->c_str())) {
- size_t index = atoi(idx->c_str());
- if (index < numTypes) {
- return builder.getTempRttType(Rtt(depth, builder[index]));
- }
- }
- throw ParseException("invalid type index", idx->line, idx->col);
- };
-
auto parseValType = [&](Element& elem) {
if (elem.isStr()) {
return stringToType(elem.c_str());
} else if (*elem[0] == REF) {
return parseRefType(elem);
- } else if (*elem[0] == RTT) {
- return parseRttType(elem);
} else {
throw ParseException("unknown valtype kind", elem[0]->line, elem[0]->col);
}
@@ -1281,18 +1246,6 @@ Type SExpressionWasmBuilder::elementToType(Element& s) {
}
return Type(parseHeapType(*s[i]), nullable);
}
- if (elementStartsWith(s, RTT)) {
- // It's an RTT, something like (rtt N $typename) or just (rtt $typename)
- // if there is no depth.
- if (s[1]->dollared()) {
- auto heapType = parseHeapType(*s[1]);
- return Type(Rtt(heapType));
- } else {
- auto depth = atoi(s[1]->str().c_str());
- auto heapType = parseHeapType(*s[2]);
- return Type(Rtt(depth, heapType));
- }
- }
// It's a tuple.
std::vector<Type> types;
for (size_t i = 0; i < s.size(); ++i) {
@@ -2702,24 +2655,12 @@ Expression* SExpressionWasmBuilder::makeI31Get(Element& s, bool signed_) {
return ret;
}
-Expression* SExpressionWasmBuilder::makeRefTest(Element& s) {
- auto* ref = parseExpression(*s[1]);
- auto* rtt = parseExpression(*s[2]);
- return Builder(wasm).makeRefTest(ref, rtt);
-}
-
Expression* SExpressionWasmBuilder::makeRefTestStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
auto* ref = parseExpression(*s[2]);
return Builder(wasm).makeRefTest(ref, heapType);
}
-Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {
- auto* ref = parseExpression(*s[1]);
- auto* rtt = parseExpression(*s[2]);
- return Builder(wasm).makeRefCast(ref, rtt);
-}
-
Expression* SExpressionWasmBuilder::makeRefCastStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
auto* ref = parseExpression(*s[2]);
@@ -2735,12 +2676,8 @@ Expression* SExpressionWasmBuilder::makeRefCastNopStatic(Element& s) {
Expression* SExpressionWasmBuilder::makeBrOn(Element& s, BrOnOp op) {
auto name = getLabel(*s[1]);
auto* ref = parseExpression(*s[2]);
- Expression* rtt = nullptr;
- if (op == BrOnCast || op == BrOnCastFail) {
- rtt = parseExpression(*s[3]);
- }
return ValidatingBuilder(wasm, s.line, s.col)
- .validateAndMakeBrOn(op, name, ref, rtt);
+ .validateAndMakeBrOn(op, name, ref);
}
Expression* SExpressionWasmBuilder::makeBrOnStatic(Element& s, BrOnOp op) {
@@ -2750,39 +2687,6 @@ Expression* SExpressionWasmBuilder::makeBrOnStatic(Element& s, BrOnOp op) {
return Builder(wasm).makeBrOn(op, name, ref, heapType);
}
-Expression* SExpressionWasmBuilder::makeRttCanon(Element& s) {
- return Builder(wasm).makeRttCanon(parseHeapType(*s[1]));
-}
-
-Expression* SExpressionWasmBuilder::makeRttSub(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- auto parent = parseExpression(*s[2]);
- return Builder(wasm).makeRttSub(heapType, parent);
-}
-
-Expression* SExpressionWasmBuilder::makeRttFreshSub(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- auto parent = parseExpression(*s[2]);
- return Builder(wasm).makeRttFreshSub(heapType, parent);
-}
-
-Expression* SExpressionWasmBuilder::makeStructNew(Element& s, bool default_) {
- auto heapType = parseHeapType(*s[1]);
- auto numOperands = s.size() - 3;
- if (default_ && numOperands > 0) {
- throw ParseException(
- "arguments provided for struct.new_with_default", s.line, s.col);
- }
- std::vector<Expression*> operands;
- operands.resize(numOperands);
- for (Index i = 0; i < numOperands; i++) {
- operands[i] = parseExpression(*s[i + 2]);
- }
- auto* rtt = parseExpression(*s[s.size() - 1]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeStructNew(rtt, operands);
-}
-
Expression* SExpressionWasmBuilder::makeStructNewStatic(Element& s,
bool default_) {
auto heapType = parseHeapType(*s[1]);
@@ -2841,19 +2745,6 @@ Expression* SExpressionWasmBuilder::makeStructSet(Element& s) {
return Builder(wasm).makeStructSet(index, ref, value);
}
-Expression* SExpressionWasmBuilder::makeArrayNew(Element& s, bool default_) {
- auto heapType = parseHeapType(*s[1]);
- Expression* init = nullptr;
- size_t i = 2;
- if (!default_) {
- init = parseExpression(*s[i++]);
- }
- auto* size = parseExpression(*s[i++]);
- auto* rtt = parseExpression(*s[i++]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeArrayNew(rtt, size, init);
-}
-
Expression* SExpressionWasmBuilder::makeArrayNewStatic(Element& s,
bool default_) {
auto heapType = parseHeapType(*s[1]);
@@ -2866,18 +2757,6 @@ Expression* SExpressionWasmBuilder::makeArrayNewStatic(Element& s,
return Builder(wasm).makeArrayNew(heapType, size, init);
}
-Expression* SExpressionWasmBuilder::makeArrayInit(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- size_t i = 2;
- std::vector<Expression*> values;
- while (i < s.size() - 1) {
- values.push_back(parseExpression(*s[i++]));
- }
- auto* rtt = parseExpression(*s[i++]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeArrayInit(rtt, values);
-}
-
Expression* SExpressionWasmBuilder::makeArrayInitStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
size_t i = 2;
@@ -3853,7 +3732,7 @@ void SExpressionWasmBuilder::validateHeapTypeUsingChild(Expression* child,
if (child->type == Type::unreachable) {
return;
}
- if ((!child->type.isRef() && !child->type.isRtt()) ||
+ if (!child->type.isRef() ||
!HeapType::isSubType(child->type.getHeapType(), heapType)) {
throw ParseException("bad heap type: expected " + heapType.toString() +
" but found " + child->type.toString(),
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 2fc06b176..c29384dad 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2016,26 +2016,18 @@ void BinaryInstWriter::visitCallRef(CallRef* curr) {
void BinaryInstWriter::visitRefTest(RefTest* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::RefTest);
- } else {
- o << U32LEB(BinaryConsts::RefTestStatic);
- parent.writeIndexedHeapType(curr->intendedType);
- }
+ o << U32LEB(BinaryConsts::RefTestStatic);
+ parent.writeIndexedHeapType(curr->intendedType);
}
void BinaryInstWriter::visitRefCast(RefCast* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::RefCast);
+ if (curr->safety == RefCast::Unsafe) {
+ o << U32LEB(BinaryConsts::RefCastNopStatic);
} else {
- if (curr->safety == RefCast::Unsafe) {
- o << U32LEB(BinaryConsts::RefCastNopStatic);
- } else {
- o << U32LEB(BinaryConsts::RefCastStatic);
- }
- parent.writeIndexedHeapType(curr->intendedType);
+ o << U32LEB(BinaryConsts::RefCastStatic);
}
+ parent.writeIndexedHeapType(curr->intendedType);
}
void BinaryInstWriter::visitBrOn(BrOn* curr) {
@@ -2048,19 +2040,11 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
break;
case BrOnCast:
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::BrOnCast);
- } else {
- o << U32LEB(BinaryConsts::BrOnCastStatic);
- }
+ o << U32LEB(BinaryConsts::BrOnCastStatic);
break;
case BrOnCastFail:
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::BrOnCastFail);
- } else {
- o << U32LEB(BinaryConsts::BrOnCastStaticFail);
- }
+ o << U32LEB(BinaryConsts::BrOnCastStaticFail);
break;
case BrOnFunc:
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::BrOnFunc);
@@ -2084,36 +2068,17 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
WASM_UNREACHABLE("invalid br_on_*");
}
o << U32LEB(getBreakIndex(curr->name));
- if ((curr->op == BrOnCast || curr->op == BrOnCastFail) && !curr->rtt) {
+ if (curr->op == BrOnCast || curr->op == BrOnCastFail) {
parent.writeIndexedHeapType(curr->intendedType);
}
}
-void BinaryInstWriter::visitRttCanon(RttCanon* curr) {
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RttCanon);
- parent.writeIndexedHeapType(curr->type.getRtt().heapType);
-}
-
-void BinaryInstWriter::visitRttSub(RttSub* curr) {
- o << int8_t(BinaryConsts::GCPrefix);
- o << U32LEB(curr->fresh ? BinaryConsts::RttFreshSub : BinaryConsts::RttSub);
- parent.writeIndexedHeapType(curr->type.getRtt().heapType);
-}
-
void BinaryInstWriter::visitStructNew(StructNew* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::StructNewDefaultWithRtt);
- } else {
- o << U32LEB(BinaryConsts::StructNewWithRtt);
- }
+ if (curr->isWithDefault()) {
+ o << U32LEB(BinaryConsts::StructNewDefault);
} else {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::StructNewDefault);
- } else {
- o << U32LEB(BinaryConsts::StructNew);
- }
+ o << U32LEB(BinaryConsts::StructNew);
}
parent.writeIndexedHeapType(curr->type.getHeapType());
}
@@ -2142,29 +2107,17 @@ void BinaryInstWriter::visitStructSet(StructSet* curr) {
void BinaryInstWriter::visitArrayNew(ArrayNew* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::ArrayNewDefaultWithRtt);
- } else {
- o << U32LEB(BinaryConsts::ArrayNewWithRtt);
- }
+ if (curr->isWithDefault()) {
+ o << U32LEB(BinaryConsts::ArrayNewDefault);
} else {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::ArrayNewDefault);
- } else {
- o << U32LEB(BinaryConsts::ArrayNew);
- }
+ o << U32LEB(BinaryConsts::ArrayNew);
}
parent.writeIndexedHeapType(curr->type.getHeapType());
}
void BinaryInstWriter::visitArrayInit(ArrayInit* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::ArrayInit);
- } else {
- o << U32LEB(BinaryConsts::ArrayInitStatic);
- }
+ o << U32LEB(BinaryConsts::ArrayInitStatic);
parent.writeIndexedHeapType(curr->type.getHeapType());
o << U32LEB(curr->values.size());
}
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 84b11000f..23d2877f7 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -60,7 +60,6 @@ struct TypeInfo {
enum Kind {
TupleKind,
RefKind,
- RttKind,
} kind;
struct Ref {
HeapType heapType;
@@ -69,20 +68,17 @@ struct TypeInfo {
union {
Tuple tuple;
Ref ref;
- Rtt rtt;
};
TypeInfo(const Tuple& tuple) : kind(TupleKind), tuple(tuple) {}
TypeInfo(Tuple&& tuple) : kind(TupleKind), tuple(std::move(tuple)) {}
TypeInfo(HeapType heapType, Nullability nullable)
: kind(RefKind), ref{heapType, nullable} {}
- TypeInfo(Rtt rtt) : kind(RttKind), rtt(rtt) {}
TypeInfo(const TypeInfo& other);
~TypeInfo();
constexpr bool isTuple() const { return kind == TupleKind; }
constexpr bool isRef() const { return kind == RefKind; }
- constexpr bool isRtt() const { return kind == RttKind; }
bool isNullable() const { return kind == RefKind && ref.nullable; }
@@ -165,7 +161,6 @@ struct SubTyper {
bool isSubType(const Signature& a, const Signature& b);
bool isSubType(const Struct& a, const Struct& b);
bool isSubType(const Array& a, const Array& b);
- bool isSubType(const Rtt& a, const Rtt& b);
};
// Helper for finding the equirecursive least upper bound of two types.
@@ -192,7 +187,6 @@ private:
std::optional<Signature> lub(const Signature& a, const Signature& b);
Struct lub(const Struct& a, const Struct& b);
std::optional<Array> lub(const Array& a, const Array& b);
- std::optional<Rtt> lub(const Rtt& a, const Rtt& b);
};
// Helper for printing types.
@@ -231,7 +225,6 @@ struct TypePrinter {
std::optional<HeapType> super = std::nullopt);
std::ostream& print(const Array& array,
std::optional<HeapType> super = std::nullopt);
- std::ostream& print(const Rtt& rtt);
};
// Helper for hashing the shapes of TypeInfos and HeapTypeInfos. Keeps track of
@@ -255,7 +248,6 @@ struct FiniteShapeHasher {
size_t hash(const Signature& sig);
size_t hash(const Struct& struct_);
size_t hash(const Array& array);
- size_t hash(const Rtt& rtt);
};
// Helper for comparing the shapes of TypeInfos and HeapTypeInfos for equality.
@@ -281,7 +273,6 @@ struct FiniteShapeEquator {
bool eq(const Signature& a, const Signature& b);
bool eq(const Struct& a, const Struct& b);
bool eq(const Array& a, const Array& b);
- bool eq(const Rtt& a, const Rtt& b);
};
struct RecGroupHasher {
@@ -307,7 +298,6 @@ struct RecGroupHasher {
size_t hash(const Signature& sig) const;
size_t hash(const Struct& struct_) const;
size_t hash(const Array& array) const;
- size_t hash(const Rtt& rtt) const;
};
struct RecGroupEquator {
@@ -334,7 +324,6 @@ struct RecGroupEquator {
bool eq(const Signature& a, const Signature& b) const;
bool eq(const Struct& a, const Struct& b) const;
bool eq(const Array& a, const Array& b) const;
- bool eq(const Rtt& a, const Rtt& b) const;
};
// A wrapper around a RecGroup that provides equality and hashing based on the
@@ -626,9 +615,6 @@ TypeInfo::TypeInfo(const TypeInfo& other) {
case RefKind:
new (&ref) auto(other.ref);
return;
- case RttKind:
- new (&rtt) auto(other.rtt);
- return;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -641,9 +627,6 @@ TypeInfo::~TypeInfo() {
case RefKind:
ref.~Ref();
return;
- case RttKind:
- rtt.~Rtt();
- return;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -670,8 +653,6 @@ bool TypeInfo::operator==(const TypeInfo& other) const {
case RefKind:
return ref.nullable == other.ref.nullable &&
ref.heapType == other.ref.heapType;
- case RttKind:
- return rtt == other.rtt;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -947,11 +928,6 @@ Type::Type(HeapType heapType, Nullability nullable) {
new (this) Type(globalTypeStore.insert(TypeInfo(heapType, nullable)));
}
-Type::Type(Rtt rtt) {
- assert(!isTemp(rtt.heapType) && "Leaking temporary type!");
- new (this) Type(globalTypeStore.insert(rtt));
-}
-
bool Type::isTuple() const {
if (isBasic()) {
return false;
@@ -1002,14 +978,6 @@ bool Type::isNonNullable() const {
}
}
-bool Type::isRtt() const {
- if (isBasic()) {
- return false;
- } else {
- return getTypeInfo(*this)->isRtt();
- }
-}
-
bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); }
bool Type::isArray() const { return isRef() && getHeapType().isArray(); }
@@ -1026,19 +994,7 @@ bool Type::isDefaultable() const {
}
return true;
}
- return isConcrete() && !isNonNullable() && !isRtt();
-}
-
-bool Type::isDefaultableOrNonNullable() const {
- if (isTuple()) {
- for (auto t : *this) {
- if (!t.isDefaultableOrNonNullable()) {
- return false;
- }
- }
- return true;
- }
- return isConcrete() && !isRtt();
+ return isConcrete() && !isNonNullable();
}
Nullability Type::getNullability() const {
@@ -1132,8 +1088,6 @@ FeatureSet Type::getFeatures() const {
// load of the wasm we don't know the features yet, so we apply the more
// refined types), so we don't add that in any case here.
return FeatureSet::ReferenceTypes;
- } else if (t.isRtt()) {
- return FeatureSet::ReferenceTypes | FeatureSet::GC;
}
TODO_SINGLE_COMPOUND(t);
switch (t.getBasic()) {
@@ -1179,18 +1133,11 @@ HeapType Type::getHeapType() const {
break;
case TypeInfo::RefKind:
return info->ref.heapType;
- case TypeInfo::RttKind:
- return info->rtt.heapType;
}
WASM_UNREACHABLE("Unexpected type");
}
}
-Rtt Type::getRtt() const {
- assert(isRtt());
- return getTypeInfo(*this)->rtt;
-}
-
Type Type::get(unsigned byteSize, bool float_) {
if (byteSize < 4) {
return Type::i32;
@@ -1264,15 +1211,6 @@ Type Type::getLeastUpperBound(Type a, Type b) {
HeapType::getLeastUpperBound(a.getHeapType(), b.getHeapType());
return Type(heapType, nullability);
}
- if (a.isRtt() && b.isRtt()) {
- auto heapType = a.getHeapType();
- if (heapType != b.getHeapType()) {
- return Type::none;
- }
- auto rttA = a.getRtt(), rttB = b.getRtt();
- auto depth = rttA.depth == rttB.depth ? rttA.depth : Rtt::NoDepth;
- return Rtt(depth, heapType);
- }
return Type::none;
WASM_UNREACHABLE("unexpected type");
}
@@ -1593,7 +1531,6 @@ std::string Tuple::toString() const { return genericToString(*this); }
std::string Signature::toString() const { return genericToString(*this); }
std::string Struct::toString() const { return genericToString(*this); }
std::string Array::toString() const { return genericToString(*this); }
-std::string Rtt::toString() const { return genericToString(*this); }
std::ostream& operator<<(std::ostream& os, Type type) {
return TypePrinter(os).print(type);
@@ -1622,9 +1559,6 @@ std::ostream& operator<<(std::ostream& os, Struct struct_) {
std::ostream& operator<<(std::ostream& os, Array array) {
return TypePrinter(os).print(array);
}
-std::ostream& operator<<(std::ostream& os, Rtt rtt) {
- return TypePrinter(os).print(rtt);
-}
std::ostream& operator<<(std::ostream& os, TypeBuilder::ErrorReason reason) {
switch (reason) {
case TypeBuilder::ErrorReason::SelfSupertype:
@@ -1670,9 +1604,6 @@ bool SubTyper::isSubType(Type a, Type b) {
if (a.isTuple() && b.isTuple()) {
return isSubType(a.getTuple(), b.getTuple());
}
- if (a.isRtt() && b.isRtt()) {
- return isSubType(a.getRtt(), b.getRtt());
- }
return false;
}
@@ -1783,13 +1714,6 @@ bool SubTyper::isSubType(const Array& a, const Array& b) {
return isSubType(a.element, b.element);
}
-bool SubTyper::isSubType(const Rtt& a, const Rtt& b) {
- // (rtt n $x) is a subtype of (rtt $x), that is, if the only difference in
- // information is that the left side specifies a depth while the right side
- // allows any depth.
- return a.heapType == b.heapType && a.hasDepth() && !b.hasDepth();
-}
-
bool TypeBounder::hasLeastUpperBound(Type a, Type b) { return bool(lub(a, b)); }
Type TypeBounder::getLeastUpperBound(Type a, Type b) {
@@ -1847,12 +1771,6 @@ std::optional<Type> TypeBounder::lub(Type a, Type b) {
(a.isNullable() || b.isNullable()) ? Nullable : NonNullable;
HeapType heapType = lub(a.getHeapType(), b.getHeapType());
return builder.getTempRefType(heapType, nullability);
- } else if (a.isRtt() && b.isRtt()) {
- auto rtt = lub(a.getRtt(), b.getRtt());
- if (!rtt) {
- return {};
- }
- return builder.getTempRttType(*rtt);
}
return {};
}
@@ -1987,14 +1905,6 @@ std::optional<Array> TypeBounder::lub(const Array& a, const Array& b) {
}
}
-std::optional<Rtt> TypeBounder::lub(const Rtt& a, const Rtt& b) {
- if (a.heapType != b.heapType) {
- return {};
- }
- uint32_t depth = (a.depth == b.depth) ? a.depth : Rtt::NoDepth;
- return Rtt(depth, a.heapType);
-}
-
void TypePrinter::printHeapTypeName(HeapType type) {
if (type.isBasic()) {
print(type);
@@ -2080,8 +1990,6 @@ std::ostream& TypePrinter::print(Type type) {
}
printHeapTypeName(heapType);
os << ')';
- } else if (type.isRtt()) {
- print(type.getRtt());
} else {
WASM_UNREACHABLE("unexpected type");
}
@@ -2234,15 +2142,6 @@ std::ostream& TypePrinter::print(const Array& array,
return os << ')';
}
-std::ostream& TypePrinter::print(const Rtt& rtt) {
- os << "(rtt ";
- if (rtt.hasDepth()) {
- os << rtt.depth << ' ';
- }
- printHeapTypeName(rtt.heapType);
- return os << ')';
-}
-
size_t FiniteShapeHasher::hash(Type type) {
size_t digest = wasm::hash(type.isBasic());
if (type.isBasic()) {
@@ -2285,9 +2184,6 @@ size_t FiniteShapeHasher::hash(const TypeInfo& info) {
rehash(digest, info.ref.nullable);
hash_combine(digest, hash(info.ref.heapType));
return digest;
- case TypeInfo::RttKind:
- hash_combine(digest, hash(info.rtt));
- return digest;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2355,12 +2251,6 @@ size_t FiniteShapeHasher::hash(const Array& array) {
return hash(array.element);
}
-size_t FiniteShapeHasher::hash(const Rtt& rtt) {
- size_t digest = wasm::hash(rtt.depth);
- hash_combine(digest, hash(rtt.heapType));
- return digest;
-}
-
bool FiniteShapeEquator::eq(Type a, Type b) {
if (a.isBasic() != b.isBasic()) {
return false;
@@ -2404,8 +2294,6 @@ bool FiniteShapeEquator::eq(const TypeInfo& a, const TypeInfo& b) {
case TypeInfo::RefKind:
return a.ref.nullable == b.ref.nullable &&
eq(a.ref.heapType, b.ref.heapType);
- case TypeInfo::RttKind:
- return eq(a.rtt, b.rtt);
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2466,10 +2354,6 @@ bool FiniteShapeEquator::eq(const Array& a, const Array& b) {
return eq(a.element, b.element);
}
-bool FiniteShapeEquator::eq(const Rtt& a, const Rtt& b) {
- return a.depth == b.depth && eq(a.heapType, b.heapType);
-}
-
size_t RecGroupHasher::operator()() const {
size_t digest = wasm::hash(group.size());
for (auto type : group) {
@@ -2526,9 +2410,6 @@ size_t RecGroupHasher::hash(const TypeInfo& info) const {
rehash(digest, info.ref.nullable);
hash_combine(digest, hash(info.ref.heapType));
return digest;
- case TypeInfo::RttKind:
- hash_combine(digest, hash(info.rtt));
- return digest;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2589,12 +2470,6 @@ size_t RecGroupHasher::hash(const Array& array) const {
return hash(array.element);
}
-size_t RecGroupHasher::hash(const Rtt& rtt) const {
- size_t digest = wasm::hash(rtt.depth);
- hash_combine(digest, hash(rtt.heapType));
- return digest;
-}
-
bool RecGroupEquator::operator()() const {
if (newGroup == otherGroup) {
return true;
@@ -2655,8 +2530,6 @@ bool RecGroupEquator::eq(const TypeInfo& a, const TypeInfo& b) const {
case TypeInfo::RefKind:
return a.ref.nullable == b.ref.nullable &&
eq(a.ref.heapType, b.ref.heapType);
- case TypeInfo::RttKind:
- return eq(a.rtt, b.rtt);
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2717,10 +2590,6 @@ bool RecGroupEquator::eq(const Array& a, const Array& b) const {
return eq(a.element, b.element);
}
-bool RecGroupEquator::eq(const Rtt& a, const Rtt& b) const {
- return a.depth == b.depth && eq(a.heapType, b.heapType);
-}
-
template<typename Self> void TypeGraphWalkerBase<Self>::walkRoot(Type* type) {
assert(taskList.empty());
taskList.push_back(Task::scan(type));
@@ -2781,9 +2650,6 @@ template<typename Self> void TypeGraphWalkerBase<Self>::scanType(Type* type) {
taskList.push_back(Task::scan(&info->ref.heapType));
break;
}
- case TypeInfo::RttKind:
- taskList.push_back(Task::scan(&info->rtt.heapType));
- break;
}
}
@@ -2921,10 +2787,6 @@ Type TypeBuilder::getTempRefType(HeapType type, Nullability nullable) {
return markTemp(impl->typeStore.insert(TypeInfo(type, nullable)));
}
-Type TypeBuilder::getTempRttType(Rtt rtt) {
- return markTemp(impl->typeStore.insert(rtt));
-}
-
void TypeBuilder::setSubType(size_t i, size_t j) {
assert(i < size() && j < size() && "index out of bounds");
HeapTypeInfo* sub = impl->entries[i].info.get();
@@ -4031,12 +3893,6 @@ size_t hash<wasm::RecGroup>::operator()(const wasm::RecGroup& group) const {
return wasm::hash(group.getID());
}
-size_t hash<wasm::Rtt>::operator()(const wasm::Rtt& rtt) const {
- auto digest = wasm::hash(rtt.depth);
- wasm::rehash(digest, rtt.heapType);
- return digest;
-}
-
size_t hash<wasm::TypeInfo>::operator()(const wasm::TypeInfo& info) const {
auto digest = wasm::hash(info.kind);
switch (info.kind) {
@@ -4047,9 +3903,6 @@ size_t hash<wasm::TypeInfo>::operator()(const wasm::TypeInfo& info) const {
wasm::rehash(digest, info.ref.nullable);
wasm::rehash(digest, info.ref.heapType);
return digest;
- case wasm::TypeInfo::RttKind:
- wasm::rehash(digest, info.rtt);
- return digest;
}
WASM_UNREACHABLE("unexpected kind");
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 65a910747..bc51d8b63 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -383,8 +383,6 @@ public:
void visitRefTest(RefTest* curr);
void visitRefCast(RefCast* curr);
void visitBrOn(BrOn* curr);
- void visitRttCanon(RttCanon* curr);
- void visitRttSub(RttSub* curr);
void visitStructNew(StructNew* curr);
void visitStructGet(StructGet* curr);
void visitStructSet(StructSet* curr);
@@ -2338,23 +2336,12 @@ void FunctionValidator::visitRefTest(RefTest* curr) {
shouldBeTrue(
curr->ref->type.isRef(), curr, "ref.test ref must have ref type");
}
- if (curr->rtt) {
- if (curr->rtt->type != Type::unreachable) {
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "ref.test rtt must have rtt type");
- }
- shouldBeEqual(curr->intendedType,
+ shouldBeUnequal(curr->intendedType,
HeapType(),
curr,
- "dynamic ref.test must not use intendedType field");
- } else {
- shouldBeUnequal(curr->intendedType,
- HeapType(),
- curr,
- "static ref.test must set intendedType field");
- shouldBeTrue(
- !curr->intendedType.isBasic(), curr, "ref.test must test a non-basic");
- }
+ "static ref.test must set intendedType field");
+ shouldBeTrue(
+ !curr->intendedType.isBasic(), curr, "ref.test must test a non-basic");
}
void FunctionValidator::visitRefCast(RefCast* curr) {
@@ -2364,23 +2351,12 @@ void FunctionValidator::visitRefCast(RefCast* curr) {
shouldBeTrue(
curr->ref->type.isRef(), curr, "ref.cast ref must have ref type");
}
- if (curr->rtt) {
- if (curr->rtt->type != Type::unreachable) {
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "ref.cast rtt must have rtt type");
- }
- shouldBeEqual(curr->intendedType,
+ shouldBeUnequal(curr->intendedType,
HeapType(),
curr,
- "dynamic ref.cast must not use intendedType field");
- } else {
- shouldBeUnequal(curr->intendedType,
- HeapType(),
- curr,
- "static ref.cast must set intendedType field");
- shouldBeTrue(
- !curr->intendedType.isBasic(), curr, "ref.cast must cast to a non-basic");
- }
+ "static ref.cast must set intendedType field");
+ shouldBeTrue(
+ !curr->intendedType.isBasic(), curr, "ref.cast must cast to a non-basic");
}
void FunctionValidator::visitBrOn(BrOn* curr) {
@@ -2392,28 +2368,14 @@ void FunctionValidator::visitBrOn(BrOn* curr) {
curr->ref->type.isRef(), curr, "br_on_cast ref must have ref type");
}
if (curr->op == BrOnCast || curr->op == BrOnCastFail) {
- if (curr->rtt) {
- // Note that an unreachable rtt is not supported: the text and binary
- // formats do not provide the type, so if it's unreachable we should not
- // even create a br_on_cast in such a case, as we'd have no idea what it
- // casts to.
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "br_on_cast rtt must have rtt type");
- shouldBeEqual(curr->intendedType,
+ shouldBeUnequal(curr->intendedType,
HeapType(),
curr,
- "dynamic br_on_cast* must not use intendedType field");
- } else {
- shouldBeUnequal(curr->intendedType,
- HeapType(),
- curr,
- "static br_on_cast* must set intendedType field");
- shouldBeTrue(!curr->intendedType.isBasic(),
- curr,
- "br_on_cast* must cast to a non-basic");
- }
+ "static br_on_cast* must set intendedType field");
+ shouldBeTrue(!curr->intendedType.isBasic(),
+ curr,
+ "br_on_cast* must cast to a non-basic");
} else {
- shouldBeTrue(curr->rtt == nullptr, curr, "non-cast BrOn must not have rtt");
shouldBeEqual(curr->intendedType,
HeapType(),
curr,
@@ -2422,38 +2384,6 @@ void FunctionValidator::visitBrOn(BrOn* curr) {
noteBreak(curr->name, curr->getSentType(), curr);
}
-void FunctionValidator::visitRttCanon(RttCanon* curr) {
- shouldBeTrue(
- getModule()->features.hasGC(), curr, "rtt.canon requires gc to be enabled");
- shouldBeTrue(curr->type.isRtt(), curr, "rtt.canon must have RTT type");
- auto rtt = curr->type.getRtt();
- shouldBeEqual(rtt.depth,
- Index(curr->type.getHeapType().getDepth()),
- curr,
- "rtt.canon must have the depth of its heap type");
-}
-
-void FunctionValidator::visitRttSub(RttSub* curr) {
- shouldBeTrue(
- getModule()->features.hasGC(), curr, "rtt.sub requires gc to be enabled");
- shouldBeTrue(curr->type.isRtt(), curr, "rtt.sub must have RTT type");
- if (curr->parent->type != Type::unreachable) {
- shouldBeTrue(
- curr->parent->type.isRtt(), curr, "rtt.sub parent must have RTT type");
- auto parentRtt = curr->parent->type.getRtt();
- auto rtt = curr->type.getRtt();
- if (rtt.hasDepth() && parentRtt.hasDepth()) {
- shouldBeEqual(rtt.depth,
- parentRtt.depth + 1,
- curr,
- "rtt.canon has a depth of 1 over the parent");
- }
- shouldBeTrue(HeapType::isSubType(rtt.heapType, parentRtt.heapType),
- curr,
- "rtt.sub parent must be a supertype");
- }
-}
-
void FunctionValidator::visitStructNew(StructNew* curr) {
shouldBeTrue(getModule()->features.hasGC(),
curr,
@@ -2461,19 +2391,7 @@ void FunctionValidator::visitStructNew(StructNew* curr) {
if (curr->type == Type::unreachable) {
return;
}
- if (curr->rtt) {
- if (!shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "struct.new rtt must be rtt")) {
- return;
- }
- }
auto heapType = curr->type.getHeapType();
- if (curr->rtt) {
- shouldBeEqual(curr->rtt->type.getHeapType(),
- heapType,
- curr,
- "struct.new heap type must match rtt");
- }
if (!shouldBeTrue(
heapType.isStruct(), curr, "struct.new heap type must be struct")) {
return;
@@ -2565,19 +2483,7 @@ void FunctionValidator::visitArrayNew(ArrayNew* curr) {
if (curr->type == Type::unreachable) {
return;
}
- if (curr->rtt) {
- if (!shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "array.new rtt must be rtt")) {
- return;
- }
- }
auto heapType = curr->type.getHeapType();
- if (curr->rtt) {
- shouldBeEqual(curr->rtt->type.getHeapType(),
- heapType,
- curr,
- "array.new heap type must match rtt");
- }
if (!shouldBeTrue(
heapType.isArray(), curr, "array.new heap type must be array")) {
return;
@@ -2607,19 +2513,7 @@ void FunctionValidator::visitArrayInit(ArrayInit* curr) {
if (curr->type == Type::unreachable) {
return;
}
- if (curr->rtt) {
- if (!shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "array.init rtt must be rtt")) {
- return;
- }
- }
auto heapType = curr->type.getHeapType();
- if (curr->rtt) {
- shouldBeEqual(curr->rtt->type.getHeapType(),
- heapType,
- curr,
- "array.init heap type must match rtt");
- }
if (!shouldBeTrue(
heapType.isArray(), curr, "array.init heap type must be array")) {
return;
@@ -2716,9 +2610,7 @@ void FunctionValidator::visitFunction(Function* curr) {
}
for (const auto& var : curr->vars) {
features |= var.getFeatures();
- bool valid = getModule()->features.hasGCNNLocals()
- ? var.isDefaultableOrNonNullable()
- : var.isDefaultable();
+ bool valid = getModule()->features.hasGCNNLocals() || var.isDefaultable();
shouldBeTrue(valid, var, "vars must be defaultable");
}
shouldBeTrue(features <= getModule()->features,
@@ -3167,10 +3059,9 @@ static void validateTables(Module& module, ValidationInfo& info) {
for (auto& segment : module.elementSegments) {
// Since element segment items need to be constant expressions, that leaves
- // us with ref.null, ref.func and global.get. The GC proposal adds rtt.canon
- // and rtt.sub to the list, but Binaryen doesn't consider RTTs as reference-
- // types yet. As a result, the only possible type for element segments will
- // be function references.
+ // us with ref.null, ref.func and global.get. As a result, the only possible
+ // type for element segments will be function references.
+ // TODO: This is not true! Allow GC data here (#4846).
info.shouldBeTrue(segment->type.isFunction(),
"elem",
"element segment type must be of function type.");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 1a6acf5bd..34b1e82b7 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -931,36 +931,25 @@ void CallRef::finalize(Type type_) {
}
void RefTest::finalize() {
- if (ref->type == Type::unreachable ||
- (rtt && rtt->type == Type::unreachable)) {
+ if (ref->type == Type::unreachable) {
type = Type::unreachable;
} else {
type = Type::i32;
}
}
-HeapType RefTest::getIntendedType() {
- return rtt ? rtt->type.getHeapType() : intendedType;
-}
-
void RefCast::finalize() {
- if (ref->type == Type::unreachable ||
- (rtt && rtt->type == Type::unreachable)) {
+ if (ref->type == Type::unreachable) {
type = Type::unreachable;
} else {
// The output of ref.cast may be null if the input is null (in that case the
// null is passed through).
- type = Type(getIntendedType(), ref->type.getNullability());
+ type = Type(intendedType, ref->type.getNullability());
}
}
-HeapType RefCast::getIntendedType() {
- return rtt ? rtt->type.getHeapType() : intendedType;
-}
-
void BrOn::finalize() {
- if (ref->type == Type::unreachable ||
- (rtt && rtt->type == Type::unreachable)) {
+ if (ref->type == Type::unreachable) {
type = Type::unreachable;
return;
}
@@ -984,7 +973,7 @@ void BrOn::finalize() {
case BrOnCastFail:
// If we do not branch, the cast worked, and we have something of the cast
// type.
- type = Type(getIntendedType(), NonNullable);
+ type = Type(intendedType, NonNullable);
break;
case BrOnNonFunc:
type = Type(HeapType::func, NonNullable);
@@ -1000,11 +989,6 @@ void BrOn::finalize() {
}
}
-HeapType BrOn::getIntendedType() {
- assert(op == BrOnCast || op == BrOnCastFail);
- return rtt ? rtt->type.getHeapType() : intendedType;
-}
-
Type BrOn::getSentType() {
switch (op) {
case BrOnNull:
@@ -1022,7 +1006,7 @@ Type BrOn::getSentType() {
if (ref->type == Type::unreachable) {
return Type::unreachable;
}
- return Type(getIntendedType(), NonNullable);
+ return Type(intendedType, NonNullable);
case BrOnFunc:
return Type(HeapType::func, NonNullable);
case BrOnData:
@@ -1039,31 +1023,10 @@ Type BrOn::getSentType() {
}
}
-void RttCanon::finalize() {
- // Nothing to do - the type must have been set already during construction.
-}
-
-void RttSub::finalize() {
- if (parent->type == Type::unreachable) {
- type = Type::unreachable;
- }
- // Else nothing to do - the type must have been set already during
- // construction.
-}
-
void StructNew::finalize() {
- if (rtt && rtt->type == Type::unreachable) {
- type = Type::unreachable;
- return;
- }
if (handleUnreachableOperands(this)) {
return;
}
- // A dynamic StructNew infers the type from the rtt. A static one has the type
- // already in the type field.
- if (rtt) {
- type = Type(rtt->type.getHeapType(), NonNullable);
- }
}
void StructGet::finalize() {
@@ -1083,35 +1046,20 @@ void StructSet::finalize() {
}
void ArrayNew::finalize() {
- if ((rtt && rtt->type == Type::unreachable) ||
- size->type == Type::unreachable ||
+ if (size->type == Type::unreachable ||
(init && init->type == Type::unreachable)) {
type = Type::unreachable;
return;
}
- // A dynamic ArrayNew infers the type from the rtt. A static one has the type
- // already in the type field.
- if (rtt) {
- type = Type(rtt->type.getHeapType(), NonNullable);
- }
}
void ArrayInit::finalize() {
- if (rtt && rtt->type == Type::unreachable) {
- type = Type::unreachable;
- return;
- }
for (auto* value : values) {
if (value->type == Type::unreachable) {
type = Type::unreachable;
return;
}
}
- // A dynamic ArrayInit infers the type from the rtt. A static one has the type
- // already in the type field.
- if (rtt) {
- type = Type(rtt->type.getHeapType(), NonNullable);
- }
}
void ArrayGet::finalize() {
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp
index 8b86017ff..89eab3297 100644
--- a/src/wasm/wat-parser.cpp
+++ b/src/wasm/wat-parser.cpp
@@ -967,14 +967,6 @@ Result<typename Ctx::InstrT> makeBrOn(Ctx&, ParseInput&, BrOnOp op);
template<typename Ctx>
Result<typename Ctx::InstrT> makeBrOnStatic(Ctx&, ParseInput&, BrOnOp op);
template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttCanon(Ctx&, ParseInput&);
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttSub(Ctx&, ParseInput&);
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttFreshSub(Ctx&, ParseInput&);
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeStructNew(Ctx&, ParseInput&, bool default_);
-template<typename Ctx>
Result<typename Ctx::InstrT>
makeStructNewStatic(Ctx&, ParseInput&, bool default_);
template<typename Ctx>
@@ -983,13 +975,9 @@ makeStructGet(Ctx&, ParseInput&, bool signed_ = false);
template<typename Ctx>
Result<typename Ctx::InstrT> makeStructSet(Ctx&, ParseInput&);
template<typename Ctx>
-Result<typename Ctx::InstrT> makeArrayNew(Ctx&, ParseInput&, bool default_);
-template<typename Ctx>
Result<typename Ctx::InstrT>
makeArrayNewStatic(Ctx&, ParseInput&, bool default_);
template<typename Ctx>
-Result<typename Ctx::InstrT> makeArrayInit(Ctx&, ParseInput&);
-template<typename Ctx>
Result<typename Ctx::InstrT> makeArrayInitStatic(Ctx&, ParseInput&);
template<typename Ctx>
Result<typename Ctx::InstrT>
@@ -1779,27 +1767,6 @@ makeBrOnStatic(Ctx& ctx, ParseInput& in, BrOnOp op) {
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttCanon(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttSub(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttFreshSub(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeStructNew(Ctx& ctx, ParseInput& in, bool default_) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
Result<typename Ctx::InstrT>
makeStructNewStatic(Ctx& ctx, ParseInput& in, bool default_) {
return in.err("unimplemented instruction");
@@ -1818,22 +1785,11 @@ Result<typename Ctx::InstrT> makeStructSet(Ctx& ctx, ParseInput& in) {
template<typename Ctx>
Result<typename Ctx::InstrT>
-makeArrayNew(Ctx& ctx, ParseInput& in, bool default_) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT>
makeArrayNewStatic(Ctx& ctx, ParseInput& in, bool default_) {
return in.err("unimplemented instruction");
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeArrayInit(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
Result<typename Ctx::InstrT> makeArrayInitStatic(Ctx& ctx, ParseInput& in) {
return in.err("unimplemented instruction");
}
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 034f9a215..442fd0d6e 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -2259,14 +2259,6 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
unimplemented(curr);
WASM_UNREACHABLE("unimp");
}
- Ref visitRttCanon(RttCanon* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
- }
- Ref visitRttSub(RttSub* curr) {
- unimplemented(curr);
- WASM_UNREACHABLE("unimp");
- }
Ref visitStructNew(StructNew* curr) {
unimplemented(curr);
WASM_UNREACHABLE("unimp");
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index c613ae1a5..59f398da9 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -163,8 +163,6 @@ function test_ids() {
console.log("RefTestId: " + binaryen.RefTestId);
console.log("RefCastId: " + binaryen.RefCastId);
console.log("BrOnId: " + binaryen.BrOnId);
- console.log("RttCanonId: " + binaryen.RttCanonId);
- console.log("RttSubId: " + binaryen.RttSubId);
console.log("StructNewId: " + binaryen.StructNewId);
console.log("StructGetId: " + binaryen.StructGetId);
console.log("StructSetId: " + binaryen.StructSetId);
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index a026d4be1..2a5a05fe8 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -93,16 +93,14 @@ CallRefId: 56
RefTestId: 57
RefCastId: 58
BrOnId: 59
-RttCanonId: 60
-RttSubId: 61
-StructNewId: 62
-StructGetId: 63
-StructSetId: 64
-ArrayNewId: 65
-ArrayInitId: 66
-ArrayGetId: 67
-ArraySetId: 68
-ArrayLenId: 69
+StructNewId: 60
+StructGetId: 61
+StructSetId: 62
+ArrayNewId: 63
+ArrayInitId: 64
+ArrayGetId: 65
+ArraySetId: 66
+ArrayLenId: 67
getExpressionInfo={"id":15,"type":4,"op":6}
(f32.neg
(f32.const -33.61199951171875)
diff --git a/test/example/type-builder-nominal.cpp b/test/example/type-builder-nominal.cpp
index cbda43f1f..13224f55e 100644
--- a/test/example/type-builder-nominal.cpp
+++ b/test/example/type-builder-nominal.cpp
@@ -12,7 +12,7 @@ void test_builder() {
std::cout << ";; Test TypeBuilder\n";
// (type $sig (func (param (ref $struct)) (result (ref $array) i32)))
- // (type $struct (struct (field (ref null $array) (mut rtt 0 $array))))
+ // (type $struct (struct (field (ref null $array))))
// (type $array (array (mut anyref)))
TypeBuilder builder;
@@ -24,11 +24,10 @@ void test_builder() {
Type refStruct = builder.getTempRefType(builder[1], NonNullable);
Type refArray = builder.getTempRefType(builder[2], NonNullable);
Type refNullArray = builder.getTempRefType(builder[2], Nullable);
- Type rttArray = builder.getTempRttType(Rtt(0, builder[2]));
Type refNullAny(HeapType::any, Nullable);
Signature sig(refStruct, builder.getTempTupleType({refArray, Type::i32}));
- Struct struct_({Field(refNullArray, Immutable), Field(rttArray, Mutable)});
+ Struct struct_({Field(refNullArray, Immutable)});
Array array(Field(refNullAny, Mutable));
{
@@ -41,7 +40,6 @@ void test_builder() {
std::cout << "(ref $struct) => " << print(refStruct) << "\n";
std::cout << "(ref $array) => " << print(refArray) << "\n";
std::cout << "(ref null $array) => " << print(refNullArray) << "\n";
- std::cout << "(rtt 0 $array) => " << print(rttArray) << "\n\n";
}
builder[0] = sig;
@@ -58,7 +56,6 @@ void test_builder() {
std::cout << "(ref $struct) => " << print(refStruct) << "\n";
std::cout << "(ref $array) => " << print(refArray) << "\n";
std::cout << "(ref null $array) => " << print(refNullArray) << "\n";
- std::cout << "(rtt 0 $array) => " << print(rttArray) << "\n\n";
}
std::vector<HeapType> built = *builder.build();
@@ -67,7 +64,6 @@ void test_builder() {
Type newRefStruct = Type(built[1], NonNullable);
Type newRefArray = Type(built[2], NonNullable);
Type newRefNullArray = Type(built[2], Nullable);
- Type newRttArray = Type(Rtt(0, built[2]));
{
IndexedTypeNameGenerator print(built);
@@ -79,7 +75,6 @@ void test_builder() {
std::cout << "(ref $struct) => " << print(newRefStruct) << "\n";
std::cout << "(ref $array) => " << print(newRefArray) << "\n";
std::cout << "(ref null $array) => " << print(newRefNullArray) << "\n";
- std::cout << "(rtt 0 $array) => " << print(newRttArray) << "\n\n";
}
}
diff --git a/test/example/type-builder-nominal.txt b/test/example/type-builder-nominal.txt
index 745f63df2..8d146cc1f 100644
--- a/test/example/type-builder-nominal.txt
+++ b/test/example/type-builder-nominal.txt
@@ -7,28 +7,22 @@ $array => (; temp ;) (func_subtype func)
(ref $struct) => (; temp ;) (ref $1)
(ref $array) => (; temp ;) (ref $2)
(ref null $array) => (; temp ;) (ref null $2)
-(rtt 0 $array) => (; temp ;) (rtt 0 $2)
-
After setting heap types:
$sig => (; temp ;) (func_subtype (param (; temp ;) (ref $1)) (result (; temp ;) (ref $2) i32) func)
-$struct => (; temp ;) (struct_subtype (field (; temp ;) (ref null $2) (mut (; temp ;) (rtt 0 $2))) data)
+$struct => (; temp ;) (struct_subtype (field (; temp ;) (ref null $2)) data)
$array => (; temp ;) (array_subtype (mut anyref) data)
(ref $sig) => (; temp ;) (ref $0)
(ref $struct) => (; temp ;) (ref $1)
(ref $array) => (; temp ;) (ref $2)
(ref null $array) => (; temp ;) (ref null $2)
-(rtt 0 $array) => (; temp ;) (rtt 0 $2)
-
After building types:
$sig => (func_subtype (param (ref $1)) (result (ref $2) i32) func)
-$struct => (struct_subtype (field (ref null $2) (mut (rtt 0 $2))) data)
+$struct => (struct_subtype (field (ref null $2)) data)
$array => (array_subtype (mut anyref) data)
(ref $sig) => (ref $0)
(ref $struct) => (ref $1)
(ref $array) => (ref $2)
(ref null $array) => (ref null $2)
-(rtt 0 $array) => (rtt 0 $2)
-
;; Test canonicalization
;; Test basic
;; Test canonical signatures
@@ -64,28 +58,22 @@ $array => (; temp ;) (func_subtype func)
(ref $struct) => (; temp ;) (ref $1)
(ref $array) => (; temp ;) (ref $2)
(ref null $array) => (; temp ;) (ref null $2)
-(rtt 0 $array) => (; temp ;) (rtt 0 $2)
-
After setting heap types:
$sig => (; temp ;) (func_subtype (param (; temp ;) (ref $1)) (result (; temp ;) (ref $2) i32) func)
-$struct => (; temp ;) (struct_subtype (field (; temp ;) (ref null $2) (mut (; temp ;) (rtt 0 $2))) data)
+$struct => (; temp ;) (struct_subtype (field (; temp ;) (ref null $2)) data)
$array => (; temp ;) (array_subtype (mut anyref) data)
(ref $sig) => (; temp ;) (ref $0)
(ref $struct) => (; temp ;) (ref $1)
(ref $array) => (; temp ;) (ref $2)
(ref null $array) => (; temp ;) (ref null $2)
-(rtt 0 $array) => (; temp ;) (rtt 0 $2)
-
After building types:
$sig => (func_subtype (param (ref $1)) (result (ref $2) i32) func)
-$struct => (struct_subtype (field (ref null $2) (mut (rtt 0 $2))) data)
+$struct => (struct_subtype (field (ref null $2)) data)
$array => (array_subtype (mut anyref) data)
(ref $sig) => (ref $0)
(ref $struct) => (ref $1)
(ref $array) => (ref $2)
(ref null $array) => (ref null $2)
-(rtt 0 $array) => (rtt 0 $2)
-
;; Test canonicalization
;; Test basic
;; Test canonical signatures
diff --git a/test/example/type-builder.cpp b/test/example/type-builder.cpp
index 219282ea8..41c556878 100644
--- a/test/example/type-builder.cpp
+++ b/test/example/type-builder.cpp
@@ -396,40 +396,6 @@ void test_lub() {
assert(LUB(a, b) == lub);
}
-
- {
- // Incompatible Rtts
- Type a{Rtt(HeapType::eq)};
- Type b{Rtt(HeapType::func)};
- assert(LUB(a, b) == Type::none);
- }
-
- {
- // Rtts with matching depth
- Type a(Rtt(42, HeapType::any));
- assert(LUB(a, a) == a);
- }
-
- {
- // Rtts with mismatched depth
- Type a(Rtt(42, HeapType::any));
- Type b(Rtt(50, HeapType::any));
- Type lub{Rtt(HeapType::any)};
- assert(LUB(a, b) == lub);
- }
-
- {
- // Rtts with and without depth
- Type a(Rtt(42, HeapType::any));
- Type b{Rtt(HeapType::any)};
- assert(LUB(a, b) == b);
- }
-
- {
- // Rtts without depth
- Type a{Rtt(HeapType::any)};
- assert(LUB(a, a) == a);
- }
}
int main() {
diff --git a/test/example/typeinfo.cpp b/test/example/typeinfo.cpp
index 55e7b9082..ff20753b1 100644
--- a/test/example/typeinfo.cpp
+++ b/test/example/typeinfo.cpp
@@ -91,33 +91,6 @@ void test_compound() {
Tuple otherTuple({Type::f64, Type::i64});
assert(Type(tuple).getID() != Type(otherTuple).getID());
}
- {
- Rtt rtt(0, HeapType::func);
- assert(Type(rtt).getID() == Type(rtt).getID());
-
- Rtt sameRtt(0, HeapType::func);
- assert(rtt == sameRtt);
- assert(Type(rtt).getID() == Type(sameRtt).getID());
-
- Rtt otherDepthRtt(1, HeapType::func);
- assert(rtt != otherDepthRtt);
- assert(Type(rtt).getID() != Type(otherDepthRtt).getID());
-
- Rtt otherHeapTypeRtt(0, HeapType::any);
- assert(rtt != otherHeapTypeRtt);
- assert(Type(rtt).getID() != Type(otherHeapTypeRtt).getID());
-
- Rtt structRtt(0, Struct{});
- assert(Type(structRtt).getID() == Type(structRtt).getID());
-
- Rtt sameStructRtt(0, Struct{});
- assert(structRtt == sameStructRtt);
- assert(Type(structRtt).getID() == Type(sameStructRtt).getID());
-
- Rtt otherStructRtt(0, Struct({{Type::i32, Immutable}}));
- assert(structRtt != otherStructRtt);
- assert(Type(structRtt).getID() != Type(otherStructRtt).getID());
- }
}
void test_printing() {
@@ -190,26 +163,6 @@ void test_printing() {
std::cout << Type(tuple) << "\n";
}
{
- std::cout << "\n;; Rtt\n";
- std::cout << Rtt(0, HeapType::func) << "\n";
- std::cout << Type(Rtt(0, HeapType::func)) << "\n";
- std::cout << Rtt(2, HeapType::any) << "\n";
- std::cout << Type(Rtt(2, HeapType::any)) << "\n";
- std::cout << Rtt(3, HeapType::eq) << "\n";
- std::cout << Type(Rtt(3, HeapType::eq)) << "\n";
- std::cout << Rtt(4, HeapType::i31) << "\n";
- std::cout << Type(Rtt(4, HeapType::i31)) << "\n";
- Rtt signatureRtt(6, Signature(Type::none, Type::none));
- std::cout << signatureRtt << "\n";
- std::cout << Type(signatureRtt) << "\n";
- Rtt structRtt(7, Struct{});
- std::cout << structRtt << "\n";
- std::cout << Type(structRtt) << "\n";
- Rtt arrayRtt(8, Array({Type::i32, Immutable}));
- std::cout << arrayRtt << "\n";
- std::cout << Type(arrayRtt) << "\n";
- }
- {
std::cout << "\n;; Signature of references (param/result)\n";
Signature signature(Type(Struct{}, Nullable),
Type(Array({Type::i32, Mutable}), NonNullable));
diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt
index 838fd34a3..2fbd8ec52 100644
--- a/test/example/typeinfo.txt
+++ b/test/example/typeinfo.txt
@@ -45,22 +45,6 @@ none
(i32 f64)
(i32 f64)
-;; Rtt
-(rtt 0 func)
-(rtt 0 func)
-(rtt 2 any)
-(rtt 2 any)
-(rtt 3 eq)
-(rtt 3 eq)
-(rtt 4 i31)
-(rtt 4 i31)
-(rtt 6 $func.0)
-(rtt 6 $func.0)
-(rtt 7 $struct.0)
-(rtt 7 $struct.0)
-(rtt 8 $array.0)
-(rtt 8 $array.0)
-
;; Signature of references (param/result)
(func (param (ref null $struct.0)) (result (ref $array.0)))
diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp
index d06236130..563ea0933 100644
--- a/test/gtest/type-builder.cpp
+++ b/test/gtest/type-builder.cpp
@@ -120,7 +120,7 @@ TEST_F(TypeTest, IndexedTypePrinter) {
TEST_F(EquirecursiveTest, Basics) {
// (type $sig (func (param (ref $struct)) (result (ref $array) i32)))
- // (type $struct (struct (field (ref null $array) (mut rtt 0 $array))))
+ // (type $struct (struct (field (ref null $array))))
// (type $array (array (mut anyref)))
TypeBuilder builder(3);
ASSERT_EQ(builder.size(), size_t{3});
@@ -129,11 +129,10 @@ TEST_F(EquirecursiveTest, Basics) {
Type refStruct = builder.getTempRefType(builder[1], NonNullable);
Type refArray = builder.getTempRefType(builder[2], NonNullable);
Type refNullArray = builder.getTempRefType(builder[2], Nullable);
- Type rttArray = builder.getTempRttType(Rtt(0, builder[2]));
Type refNullAny(HeapType::any, Nullable);
Signature sig(refStruct, builder.getTempTupleType({refArray, Type::i32}));
- Struct struct_({Field(refNullArray, Immutable), Field(rttArray, Mutable)});
+ Struct struct_({Field(refNullArray, Immutable)});
Array array(Field(refNullAny, Mutable));
builder[0] = sig;
@@ -155,13 +154,10 @@ TEST_F(EquirecursiveTest, Basics) {
Type newRefStruct = Type(built[1], NonNullable);
Type newRefArray = Type(built[2], NonNullable);
Type newRefNullArray = Type(built[2], Nullable);
- Type newRttArray = Type(Rtt(0, built[2]));
EXPECT_EQ(built[0].getSignature(),
Signature(newRefStruct, {newRefArray, Type::i32}));
- EXPECT_EQ(
- built[1].getStruct(),
- Struct({Field(newRefNullArray, Immutable), Field(newRttArray, Mutable)}));
+ EXPECT_EQ(built[1].getStruct(), Struct({Field(newRefNullArray, Immutable)}));
EXPECT_EQ(built[2].getArray(), Array(Field(refNullAny, Mutable)));
// The built types should be different from the temporary types.
@@ -169,7 +165,6 @@ TEST_F(EquirecursiveTest, Basics) {
EXPECT_NE(newRefStruct, refStruct);
EXPECT_NE(newRefArray, refArray);
EXPECT_NE(newRefNullArray, refNullArray);
- EXPECT_NE(newRttArray, rttArray);
}
static void testDirectSelfSupertype() {
diff --git a/test/heap-types.wast b/test/heap-types.wast
index 3c0a5a0ef..d34eaf5eb 100644
--- a/test/heap-types.wast
+++ b/test/heap-types.wast
@@ -29,22 +29,15 @@
(type $bytes (array (mut i8)))
(type $words (array (mut i32)))
- ;; RTT
(type $parent (struct))
(type $child (struct i32))
(type $grandchild (struct i32 i64))
- (global $rttparent (rtt 0 $parent) (rtt.canon $parent))
- (global $rttchild (rtt 1 $child) (rtt.sub $child (global.get $rttparent)))
- (global $rttgrandchild (rtt 2 $grandchild) (rtt.sub $grandchild (global.get $rttchild)))
- (global $rttfreshgrandchild (rtt 2 $grandchild) (rtt.fresh_sub $grandchild (global.get $rttchild)))
(type $nested-child-struct (struct (field (mut (ref $child)))))
(type $nested-child-array (array (mut (ref $child))))
(global $struct.new-in-global (ref $struct.A)
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(func $structs (param $x (ref $struct.A)) (result (ref $struct.B))
@@ -120,16 +113,13 @@
)
)
(drop
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(drop
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 1)
(f32.const 2.345)
(f64.const 3.14159)
- (rtt.canon $struct.A)
)
)
(unreachable)
@@ -140,16 +130,14 @@
(local $tb (ref null $bytes))
(local $tw (ref null $words))
(drop
- (array.new_with_rtt $vector
+ (array.new $vector
(f64.const 3.14159)
(i32.const 3)
- (rtt.canon $vector)
)
)
(drop
- (array.new_default_with_rtt $matrix
+ (array.new_default $matrix
(i32.const 10)
- (rtt.canon $matrix)
)
)
(drop
@@ -196,42 +184,6 @@
)
(unreachable)
)
- ;; RTT types as parameters
- (func $rtt-param-with-depth (param $rtt (rtt 1 $parent)))
- (func $rtt-param-without-depth (param $rtt (rtt $parent)))
- (func $rtt-operations
- (local $temp.A (ref null $struct.A))
- (local $temp.B (ref null $struct.B))
- (drop
- (ref.test (ref.null $struct.A) (rtt.canon $struct.B))
- )
- (drop
- (ref.cast (ref.null $struct.A) (rtt.canon $struct.B))
- )
- (drop
- (block $out (result (ref $struct.B))
- ;; set the value to a local with type $struct.A, showing that the value
- ;; flowing out has the right type
- (local.set $temp.A
- (br_on_cast $out (ref.null $struct.A) (rtt.canon $struct.B))
- )
- ;; an untaken br_on_cast, with unreachable rtt - so we cannot use the
- ;; RTT in binaryen IR to find the cast type.
- (br_on_cast $out (ref.null $struct.A) (unreachable))
- (unreachable)
- )
- )
- (drop
- (block $out2 (result (ref null $struct.A))
- ;; set the value to a local with type $struct.A, showing that the value
- ;; flowing out has the right type
- (local.set $temp.B
- (br_on_cast_fail $out2 (ref.null $struct.A) (rtt.canon $struct.B))
- )
- (ref.null $struct.A)
- )
- )
- )
(func $ref.is_X (param $x anyref)
(if (ref.is_func (local.get $x)) (unreachable))
(if (ref.is_data (local.get $x)) (unreachable))
@@ -363,13 +315,6 @@
)
)
)
- (func $unreachables-7
- (drop
- (struct.new_default_with_rtt $struct.A
- (unreachable)
- )
- )
- )
(func $array-copy (param $x (ref $vector)) (param $y (ref null $vector))
(array.copy $vector $vector
(local.get $x)
@@ -380,20 +325,18 @@
)
)
(func $array-init (result (ref $vector))
- (array.init $vector
+ (array.init_static $vector
(f64.const 1)
(f64.const 2)
(f64.const 4)
(f64.const 8)
- (rtt.canon $vector)
)
)
(func $array-init-packed (result (ref $bytes))
- (array.init $bytes
+ (array.init_static $bytes
(i32.const 4)
(i32.const 2)
(i32.const 1)
- (rtt.canon $bytes)
)
)
(func $static-operations
@@ -422,35 +365,4 @@
)
)
)
- (func $static-constructions
- (drop
- (struct.new_default $struct.A)
- )
- (drop
- (struct.new $struct.A
- (i32.const 1)
- (f32.const 2.345)
- (f64.const 3.14159)
- )
- )
- (drop
- (array.new $vector
- (f64.const 3.14159)
- (i32.const 3)
- )
- )
- (drop
- (array.new_default $matrix
- (i32.const 10)
- )
- )
- (drop
- (array.init_static $vector
- (f64.const 1)
- (f64.const 2)
- (f64.const 4)
- (f64.const 8)
- )
- )
- )
)
diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast
index 937b4e6b5..705e545ef 100644
--- a/test/heap-types.wast.from-wast
+++ b/test/heap-types.wast.from-wast
@@ -1,38 +1,23 @@
(module
(type $struct.A (struct (field i32) (field f32) (field $named f64)))
- (type $struct.B (struct (field i8) (field (mut i16)) (field (ref $struct.A)) (field (mut (ref $struct.A)))))
(type $vector (array (mut f64)))
+ (type $struct.B (struct (field i8) (field (mut i16)) (field (ref $struct.A)) (field (mut (ref $struct.A)))))
(type $none_=>_none (func))
- (type $grandchild (struct (field i32) (field i64)))
- (type $matrix (array (mut (ref null $vector))))
(type $struct.C (struct (field $named-mut (mut f32))))
- (type $parent (struct ))
- (type $child (struct (field i32)))
+ (type $matrix (array (mut (ref null $vector))))
+ (type $grandchild (struct (field i32) (field i64)))
(type $bytes (array (mut i8)))
(type $anyref_=>_none (func (param anyref)))
(type $nested-child-struct (struct (field (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 $words (array (mut i32)))
(type $nested-child-array (array (mut (ref $child))))
- (type $rtt_1_$parent_=>_none (func (param (rtt 1 $parent))))
- (type $rtt_$parent_=>_none (func (param (rtt $parent))))
(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 $rttparent (rtt 0 $parent) (rtt.canon $parent))
- (global $rttchild (rtt 1 $child) (rtt.sub $child
- (global.get $rttparent)
- ))
- (global $rttgrandchild (rtt 2 $grandchild) (rtt.sub $grandchild
- (global.get $rttchild)
- ))
- (global $rttfreshgrandchild (rtt 2 $grandchild) (rtt.fresh_sub $grandchild
- (global.get $rttchild)
- ))
- (global $struct.new-in-global (ref $struct.A) (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- ))
+ (global $struct.new-in-global (ref $struct.A) (struct.new_default $struct.A))
(func $structs (param $x (ref $struct.A)) (result (ref $struct.B))
(local $tA (ref null $struct.A))
(local $tB (ref null $struct.B))
@@ -120,16 +105,13 @@
)
)
(drop
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(drop
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 1)
(f32.const 2.3450000286102295)
(f64.const 3.14159)
- (rtt.canon $struct.A)
)
)
(unreachable)
@@ -140,16 +122,14 @@
(local $tb (ref null $bytes))
(local $tw (ref null $words))
(drop
- (array.new_with_rtt $vector
+ (array.new $vector
(f64.const 3.14159)
(i32.const 3)
- (rtt.canon $vector)
)
)
(drop
- (array.new_default_with_rtt $matrix
+ (array.new_default $matrix
(i32.const 10)
- (rtt.canon $matrix)
)
)
(drop
@@ -195,56 +175,6 @@
)
(unreachable)
)
- (func $rtt-param-with-depth (param $rtt (rtt 1 $parent))
- (nop)
- )
- (func $rtt-param-without-depth (param $rtt (rtt $parent))
- (nop)
- )
- (func $rtt-operations
- (local $temp.A (ref null $struct.A))
- (local $temp.B (ref null $struct.B))
- (drop
- (ref.test
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (drop
- (ref.cast
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (drop
- (block $out (result (ref $struct.B))
- (local.set $temp.A
- (br_on_cast $out
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (block
- (drop
- (ref.null $struct.A)
- )
- (unreachable)
- )
- (unreachable)
- )
- )
- (drop
- (block $out2 (result (ref null $struct.A))
- (local.set $temp.B
- (br_on_cast_fail $out2
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (ref.null $struct.A)
- )
- )
- )
(func $ref.is_X (param $x anyref)
(if
(ref.is_func
@@ -454,15 +384,6 @@
)
)
)
- (func $unreachables-7
- (drop
- (block ;; (replaces something unreachable we can't emit)
- (drop
- (unreachable)
- )
- )
- )
- )
(func $array-copy (param $x (ref $vector)) (param $y (ref null $vector))
(array.copy $vector $vector
(local.get $x)
@@ -473,20 +394,18 @@
)
)
(func $array-init (result (ref $vector))
- (array.init $vector
+ (array.init_static $vector
(f64.const 1)
(f64.const 2)
(f64.const 4)
(f64.const 8)
- (rtt.canon $vector)
)
)
(func $array-init-packed (result (ref $bytes))
- (array.init $bytes
+ (array.init_static $bytes
(i32.const 4)
(i32.const 2)
(i32.const 1)
- (rtt.canon $bytes)
)
)
(func $static-operations
@@ -523,35 +442,4 @@
)
)
)
- (func $static-constructions
- (drop
- (struct.new_default $struct.A)
- )
- (drop
- (struct.new $struct.A
- (i32.const 1)
- (f32.const 2.3450000286102295)
- (f64.const 3.14159)
- )
- )
- (drop
- (array.new $vector
- (f64.const 3.14159)
- (i32.const 3)
- )
- )
- (drop
- (array.new_default $matrix
- (i32.const 10)
- )
- )
- (drop
- (array.init_static $vector
- (f64.const 1)
- (f64.const 2)
- (f64.const 4)
- (f64.const 8)
- )
- )
- )
)
diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary
index 2f1cac1c5..6c847ff69 100644
--- a/test/heap-types.wast.fromBinary
+++ b/test/heap-types.wast.fromBinary
@@ -1,38 +1,23 @@
(module
(type $struct.A (struct (field i32) (field f32) (field $named f64)))
- (type $struct.B (struct (field i8) (field (mut i16)) (field (ref $struct.A)) (field (mut (ref $struct.A)))))
(type $vector (array (mut f64)))
+ (type $struct.B (struct (field i8) (field (mut i16)) (field (ref $struct.A)) (field (mut (ref $struct.A)))))
(type $none_=>_none (func))
- (type $grandchild (struct (field i32) (field i64)))
(type $matrix (array (mut (ref null $vector))))
- (type $parent (struct ))
- (type $child (struct (field i32)))
(type $struct.C (struct (field $named-mut (mut f32))))
+ (type $grandchild (struct (field i32) (field i64)))
(type $bytes (array (mut i8)))
(type $anyref_=>_none (func (param anyref)))
(type $nested-child-struct (struct (field (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 $words (array (mut i32)))
(type $nested-child-array (array (mut (ref $child))))
- (type $rtt_1_$parent_=>_none (func (param (rtt 1 $parent))))
- (type $rtt_$parent_=>_none (func (param (rtt $parent))))
(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 $rttparent (rtt 0 $parent) (rtt.canon $parent))
- (global $rttchild (rtt 1 $child) (rtt.sub $child
- (global.get $rttparent)
- ))
- (global $rttgrandchild (rtt 2 $grandchild) (rtt.sub $grandchild
- (global.get $rttchild)
- ))
- (global $rttfreshgrandchild (rtt 2 $grandchild) (rtt.fresh_sub $grandchild
- (global.get $rttchild)
- ))
- (global $struct.new-in-global (ref $struct.A) (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- ))
+ (global $struct.new-in-global (ref $struct.A) (struct.new_default $struct.A))
(func $structs (param $x (ref $struct.A)) (result (ref $struct.B))
(local $tA (ref null $struct.A))
(local $tB (ref null $struct.B))
@@ -120,16 +105,13 @@
)
)
(drop
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(drop
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 1)
(f32.const 2.3450000286102295)
(f64.const 3.14159)
- (rtt.canon $struct.A)
)
)
(unreachable)
@@ -140,16 +122,14 @@
(local $tb (ref null $bytes))
(local $tw (ref null $words))
(drop
- (array.new_with_rtt $vector
+ (array.new $vector
(f64.const 3.14159)
(i32.const 3)
- (rtt.canon $vector)
)
)
(drop
- (array.new_default_with_rtt $matrix
+ (array.new_default $matrix
(i32.const 10)
- (rtt.canon $matrix)
)
)
(drop
@@ -195,55 +175,6 @@
)
(unreachable)
)
- (func $rtt-param-with-depth (param $rtt (rtt 1 $parent))
- (nop)
- )
- (func $rtt-param-without-depth (param $rtt (rtt $parent))
- (nop)
- )
- (func $rtt-operations
- (local $temp.A (ref null $struct.A))
- (local $temp.B (ref null $struct.B))
- (drop
- (ref.test
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (drop
- (ref.cast
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (drop
- (block $label$1 (result (ref $struct.B))
- (local.set $temp.A
- (br_on_cast $label$1
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (block $label$2
- (drop
- (ref.null $struct.A)
- )
- (unreachable)
- )
- )
- )
- (drop
- (block $label$3 (result (ref null $struct.A))
- (local.set $temp.B
- (br_on_cast_fail $label$3
- (ref.null $struct.A)
- (rtt.canon $struct.B)
- )
- )
- (ref.null $struct.A)
- )
- )
- )
(func $ref.is_X (param $x anyref)
(if
(ref.is_func
@@ -413,9 +344,6 @@
(func $unreachables-array-6
(unreachable)
)
- (func $unreachables-7
- (unreachable)
- )
(func $array-copy (param $x (ref $vector)) (param $y (ref null $vector))
(array.copy $vector $vector
(local.get $x)
@@ -426,20 +354,18 @@
)
)
(func $array-init (result (ref $vector))
- (array.init $vector
+ (array.init_static $vector
(f64.const 1)
(f64.const 2)
(f64.const 4)
(f64.const 8)
- (rtt.canon $vector)
)
)
(func $array-init-packed (result (ref $bytes))
- (array.init $bytes
+ (array.init_static $bytes
(i32.const 4)
(i32.const 2)
(i32.const 1)
- (rtt.canon $bytes)
)
)
(func $static-operations
@@ -476,36 +402,5 @@
)
)
)
- (func $static-constructions
- (drop
- (struct.new_default $struct.A)
- )
- (drop
- (struct.new $struct.A
- (i32.const 1)
- (f32.const 2.3450000286102295)
- (f64.const 3.14159)
- )
- )
- (drop
- (array.new $vector
- (f64.const 3.14159)
- (i32.const 3)
- )
- )
- (drop
- (array.new_default $matrix
- (i32.const 10)
- )
- )
- (drop
- (array.init_static $vector
- (f64.const 1)
- (f64.const 2)
- (f64.const 4)
- (f64.const 8)
- )
- )
- )
)
diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo
index 6e5e5e06d..ba10f28fd 100644
--- a/test/heap-types.wast.fromBinary.noDebugInfo
+++ b/test/heap-types.wast.fromBinary.noDebugInfo
@@ -1,38 +1,23 @@
(module
(type ${i32_f32_f64} (struct (field i32) (field f32) (field f64)))
- (type ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|} (struct (field i8) (field (mut i16)) (field (ref ${i32_f32_f64})) (field (mut (ref ${i32_f32_f64})))))
(type $[mut:f64] (array (mut f64)))
+ (type ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|} (struct (field i8) (field (mut i16)) (field (ref ${i32_f32_f64})) (field (mut (ref ${i32_f32_f64})))))
(type $none_=>_none (func))
- (type ${i32_i64} (struct (field i32) (field i64)))
(type $[mut:ref?|[mut:f64]|] (array (mut (ref null $[mut:f64]))))
- (type ${} (struct ))
- (type ${i32} (struct (field i32)))
(type ${mut:f32} (struct (field (mut f32))))
+ (type ${i32_i64} (struct (field i32) (field i64)))
(type $[mut:i8] (array (mut i8)))
(type $anyref_=>_none (func (param anyref)))
(type ${mut:ref|{i32}|} (struct (field (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 $[mut:i32] (array (mut i32)))
(type $[mut:ref|{i32}|] (array (mut (ref ${i32}))))
- (type $rtt_1_{}_=>_none (func (param (rtt 1 ${}))))
- (type $rtt_{}_=>_none (func (param (rtt ${}))))
(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 (rtt 0 ${}) (rtt.canon ${}))
- (global $global$1 (rtt 1 ${i32}) (rtt.sub ${i32}
- (global.get $global$0)
- ))
- (global $global$2 (rtt 2 ${i32_i64}) (rtt.sub ${i32_i64}
- (global.get $global$1)
- ))
- (global $global$3 (rtt 2 ${i32_i64}) (rtt.fresh_sub ${i32_i64}
- (global.get $global$1)
- ))
- (global $global$4 (ref ${i32_f32_f64}) (struct.new_default_with_rtt ${i32_f32_f64}
- (rtt.canon ${i32_f32_f64})
- ))
+ (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}|}))
@@ -120,16 +105,13 @@
)
)
(drop
- (struct.new_default_with_rtt ${i32_f32_f64}
- (rtt.canon ${i32_f32_f64})
- )
+ (struct.new_default ${i32_f32_f64})
)
(drop
- (struct.new_with_rtt ${i32_f32_f64}
+ (struct.new ${i32_f32_f64}
(i32.const 1)
(f32.const 2.3450000286102295)
(f64.const 3.14159)
- (rtt.canon ${i32_f32_f64})
)
)
(unreachable)
@@ -140,16 +122,14 @@
(local $3 (ref null $[mut:i8]))
(local $4 (ref null $[mut:i32]))
(drop
- (array.new_with_rtt $[mut:f64]
+ (array.new $[mut:f64]
(f64.const 3.14159)
(i32.const 3)
- (rtt.canon $[mut:f64])
)
)
(drop
- (array.new_default_with_rtt $[mut:ref?|[mut:f64]|]
+ (array.new_default $[mut:ref?|[mut:f64]|]
(i32.const 10)
- (rtt.canon $[mut:ref?|[mut:f64]|])
)
)
(drop
@@ -195,56 +175,7 @@
)
(unreachable)
)
- (func $2 (param $0 (rtt 1 ${}))
- (nop)
- )
- (func $3 (param $0 (rtt ${}))
- (nop)
- )
- (func $4
- (local $0 (ref null ${i32_f32_f64}))
- (local $1 (ref null ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
- (drop
- (ref.test
- (ref.null ${i32_f32_f64})
- (rtt.canon ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|})
- )
- )
- (drop
- (ref.cast
- (ref.null ${i32_f32_f64})
- (rtt.canon ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|})
- )
- )
- (drop
- (block $label$1 (result (ref ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
- (local.set $0
- (br_on_cast $label$1
- (ref.null ${i32_f32_f64})
- (rtt.canon ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|})
- )
- )
- (block $label$2
- (drop
- (ref.null ${i32_f32_f64})
- )
- (unreachable)
- )
- )
- )
- (drop
- (block $label$3 (result (ref null ${i32_f32_f64}))
- (local.set $1
- (br_on_cast_fail $label$3
- (ref.null ${i32_f32_f64})
- (rtt.canon ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|})
- )
- )
- (ref.null ${i32_f32_f64})
- )
- )
- )
- (func $5 (param $0 anyref)
+ (func $2 (param $0 anyref)
(if
(ref.is_func
(local.get $0)
@@ -264,7 +195,7 @@
(unreachable)
)
)
- (func $6 (param $0 anyref)
+ (func $3 (param $0 anyref)
(drop
(ref.as_non_null
(local.get $0)
@@ -286,7 +217,7 @@
)
)
)
- (func $7 (param $0 anyref)
+ (func $4 (param $0 anyref)
(local $1 anyref)
(local $2 anyref)
(local $3 funcref)
@@ -368,40 +299,40 @@
)
)
)
- (func $8
+ (func $5
(unreachable)
)
- (func $9
+ (func $6
(drop
(ref.null ${mut:f32})
)
(unreachable)
)
- (func $10
+ (func $7
(unreachable)
)
- (func $11
+ (func $8
(unreachable)
)
- (func $12
+ (func $9
(unreachable)
)
- (func $13
+ (func $10
(drop
(ref.null $[mut:f64])
)
(unreachable)
)
- (func $14
+ (func $11
(unreachable)
)
- (func $15
+ (func $12
(drop
(ref.null $[mut:f64])
)
(unreachable)
)
- (func $16
+ (func $13
(drop
(ref.null $[mut:f64])
)
@@ -410,13 +341,10 @@
)
(unreachable)
)
- (func $17
- (unreachable)
- )
- (func $18
+ (func $14
(unreachable)
)
- (func $19 (param $0 (ref $[mut:f64])) (param $1 (ref null $[mut:f64]))
+ (func $15 (param $0 (ref $[mut:f64])) (param $1 (ref null $[mut:f64]))
(array.copy $[mut:f64] $[mut:f64]
(local.get $0)
(i32.const 11)
@@ -425,24 +353,22 @@
(i32.const 1337)
)
)
- (func $20 (result (ref $[mut:f64]))
- (array.init $[mut:f64]
+ (func $16 (result (ref $[mut:f64]))
+ (array.init_static $[mut:f64]
(f64.const 1)
(f64.const 2)
(f64.const 4)
(f64.const 8)
- (rtt.canon $[mut:f64])
)
)
- (func $21 (result (ref $[mut:i8]))
- (array.init $[mut:i8]
+ (func $17 (result (ref $[mut:i8]))
+ (array.init_static $[mut:i8]
(i32.const 4)
(i32.const 2)
(i32.const 1)
- (rtt.canon $[mut:i8])
)
)
- (func $22
+ (func $18
(local $0 (ref null ${i32_f32_f64}))
(local $1 (ref null ${i8_mut:i16_ref|{i32_f32_f64}|_mut:ref|{i32_f32_f64}|}))
(drop
@@ -476,36 +402,5 @@
)
)
)
- (func $23
- (drop
- (struct.new_default ${i32_f32_f64})
- )
- (drop
- (struct.new ${i32_f32_f64}
- (i32.const 1)
- (f32.const 2.3450000286102295)
- (f64.const 3.14159)
- )
- )
- (drop
- (array.new $[mut:f64]
- (f64.const 3.14159)
- (i32.const 3)
- )
- )
- (drop
- (array.new_default $[mut:ref?|[mut:f64]|]
- (i32.const 10)
- )
- )
- (drop
- (array.init_static $[mut:f64]
- (f64.const 1)
- (f64.const 2)
- (f64.const 4)
- (f64.const 8)
- )
- )
- )
)
diff --git a/test/lit/exec/rtts.wast b/test/lit/exec/rtts.wast
deleted file mode 100644
index 7c090f180..000000000
--- a/test/lit/exec/rtts.wast
+++ /dev/null
@@ -1,153 +0,0 @@
-;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.
-
-;; Check that allocation and casting instructions with and without RTTs can be
-;; mixed correctly.
-
-;; RUN: wasm-opt %s -all --fuzz-exec-before -q --structural -o /dev/null 2>&1 \
-;; RUN: | filecheck %s --check-prefix=EQREC
-
-;; RUN: wasm-opt %s -all --fuzz-exec-before -q --nominal -o /dev/null 2>&1 \
-;; RUN: | filecheck %s --check-prefix=NOMNL
-
-(module
- (type $struct (struct_subtype i32 data))
- (type $sub-struct (struct_subtype i32 i32 $struct))
-
- (import "fuzzing-support" "log-i32" (func $log (param i32)))
-
- (global $sub-rtt (rtt 1 $sub-struct)
- (rtt.sub $sub-struct
- (rtt.canon $struct)
- )
- )
-
- (func $make-sub-struct-canon (result (ref $struct))
- (struct.new_default_with_rtt $sub-struct
- (rtt.canon $sub-struct)
- )
- )
-
- (func $make-sub-struct-sub (result (ref $struct))
- (struct.new_default_with_rtt $sub-struct
- (global.get $sub-rtt)
- )
- )
-
- (func $make-sub-struct-static (result (ref $struct))
- (struct.new_default $sub-struct)
- )
-
- ;; EQREC: [fuzz-exec] calling canon-canon
- ;; EQREC-NEXT: [LoggingExternalInterface logging 1]
- ;; NOMNL: [fuzz-exec] calling canon-canon
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "canon-canon"
- (call $log
- (ref.test
- (call $make-sub-struct-canon)
- (rtt.canon $sub-struct)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling canon-sub
- ;; EQREC-NEXT: [LoggingExternalInterface logging 0]
- ;; NOMNL: [fuzz-exec] calling canon-sub
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "canon-sub"
- (call $log
- (ref.test
- (call $make-sub-struct-canon)
- (global.get $sub-rtt)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling canon-static
- ;; EQREC-NEXT: [LoggingExternalInterface logging 1]
- ;; NOMNL: [fuzz-exec] calling canon-static
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "canon-static"
- (call $log
- (ref.test_static $sub-struct
- (call $make-sub-struct-canon)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling sub-canon
- ;; EQREC-NEXT: [LoggingExternalInterface logging 0]
- ;; NOMNL: [fuzz-exec] calling sub-canon
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "sub-canon"
- (call $log
- (ref.test
- (call $make-sub-struct-sub)
- (rtt.canon $sub-struct)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling sub-sub
- ;; EQREC-NEXT: [LoggingExternalInterface logging 1]
- ;; NOMNL: [fuzz-exec] calling sub-sub
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "sub-sub"
- (call $log
- (ref.test
- (call $make-sub-struct-sub)
- (global.get $sub-rtt)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling sub-static
- ;; EQREC-NEXT: [LoggingExternalInterface logging 0]
- ;; NOMNL: [fuzz-exec] calling sub-static
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "sub-static"
- (call $log
- (ref.test_static $sub-struct
- (call $make-sub-struct-sub)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling static-canon
- ;; EQREC-NEXT: [LoggingExternalInterface logging 1]
- ;; NOMNL: [fuzz-exec] calling static-canon
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "static-canon"
- (call $log
- (ref.test
- (call $make-sub-struct-static)
- (rtt.canon $sub-struct)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling static-sub
- ;; EQREC-NEXT: [LoggingExternalInterface logging 0]
- ;; NOMNL: [fuzz-exec] calling static-sub
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "static-sub"
- (call $log
- (ref.test
- (call $make-sub-struct-static)
- (global.get $sub-rtt)
- )
- )
- )
-
- ;; EQREC: [fuzz-exec] calling static-static
- ;; EQREC-NEXT: [LoggingExternalInterface logging 1]
- ;; NOMNL: [fuzz-exec] calling static-static
- ;; NOMNL-NEXT: [LoggingExternalInterface logging 1]
- (func "static-static"
- (call $log
- (ref.test_static $sub-struct
- (call $make-sub-struct-static)
- )
- )
- )
-)
diff --git a/test/lit/forward-declared-types.wast b/test/lit/forward-declared-types.wast
deleted file mode 100644
index c20cc3a1e..000000000
--- a/test/lit/forward-declared-types.wast
+++ /dev/null
@@ -1,26 +0,0 @@
-;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
-;; Test that types can be used before they are defined
-
-;; RUN: wasm-opt %s -all -S -o - | filecheck %s
-;; RUN: wasm-opt %s -all --nominal -S -o - | filecheck %s --check-prefix=NOMNL
-
-(module
- ;; CHECK: (type $func (func))
-
- ;; CHECK: (type $struct (struct (field (ref $array)) (field (ref null $func))))
- ;; NOMNL: (type $func (func_subtype func))
-
- ;; NOMNL: (type $struct (struct_subtype (field (ref $array)) (field (ref null $func)) data))
- (type $struct (struct
- (field (ref $array))
- (field (ref null $func))
- ))
- ;; CHECK: (type $array (array (rtt 2 $func)))
- ;; NOMNL: (type $array (array_subtype (rtt 2 $func) data))
- (type $array (array (field (rtt 2 $func))))
- (type $func (func))
-
- (func (result (ref null $struct))
- (unreachable)
- )
-)
diff --git a/test/lit/fuzz-types/isorecursive.test b/test/lit/fuzz-types/isorecursive.test
index 78315c5b1..18fade75b 100644
--- a/test/lit/fuzz-types/isorecursive.test
+++ b/test/lit/fuzz-types/isorecursive.test
@@ -2,25 +2,25 @@
;; CHECK: (rec
;; CHECK-NEXT: (type $0 (struct_subtype data))
-;; CHECK-NEXT: (type $1 (func_subtype (param f64) (result f64 i64 f32 (rtt any) f64 f32) func))
-;; CHECK-NEXT: (type $2 (struct_subtype (field f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) data))
-;; CHECK-NEXT: (type $3 (struct_subtype (field f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $2))
-;; CHECK-NEXT: (type $4 (struct_subtype (field f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $2))
-;; CHECK-NEXT: (type $5 (struct_subtype (field f64 v128 (ref null $10) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $3))
-;; CHECK-NEXT: (type $6 (struct_subtype (field f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $3))
+;; 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 (field f32 (mut i16) (ref eq) (mut (rtt $2))) $0))
-;; CHECK-NEXT: (type $9 (struct_subtype (field f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $6))
-;; CHECK-NEXT: (type $10 (struct_subtype (field (ref $2) (mut (ref $13)) (ref null i31) v128 (ref null $6)) $0))
-;; CHECK-NEXT: (type $11 (struct_subtype (field f64 v128 (ref $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $2))
+;; 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 f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $6))
+;; CHECK-NEXT: (type $13 (struct_subtype (field (mut (ref null $2)) v128 i8 (mut i8) f32 v128) $6))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $14 (struct_subtype (field (ref $2) (mut (ref $13)) i31ref v128 (ref $9) (mut (ref null $10))) $10))
-;; CHECK-NEXT: (type $15 (func_subtype (param f64) (result f64 i64 f32 (rtt any) f64 f32) $1))
-;; CHECK-NEXT: (type $16 (struct_subtype (field f64 v128 (ref null $0) (mut i16) (mut (rtt $5)) (mut (ref null $2))) $2))
-;; CHECK-NEXT: (type $17 (struct_subtype (field (ref $2) (mut (ref $13)) i31ref v128 (ref $9) (mut (ref null $10))) $14))
-;; CHECK-NEXT: (type $18 (struct_subtype $12))
-;; CHECK-NEXT: (type $19 (func_subtype (param f64) (result f64 i64 f32 (rtt any) f64 f32) $15))
+;; 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: )
diff --git a/test/lit/fuzz-types/nominal.test b/test/lit/fuzz-types/nominal.test
index 299cf2613..7ef381bfe 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 (ref null $9) (ref $5)) data))
-;; CHECK-NEXT: (type $1 (func_subtype (param (rtt 0 $8)) func))
-;; CHECK-NEXT: (type $2 (struct_subtype (field (mut (rtt $19)) (ref $4)) data))
-;; CHECK-NEXT: (type $3 (struct_subtype (field (mut (rtt $19)) (ref $4) i64 v128 (mut v128)) $2))
-;; CHECK-NEXT: (type $4 (struct_subtype (field (mut (rtt $19)) (ref $4)) $2))
-;; CHECK-NEXT: (type $5 (struct_subtype (field (mut (rtt $19)) (ref $4) i64 v128 (mut v128)) $3))
-;; CHECK-NEXT: (type $6 (struct_subtype (field (mut (rtt $19)) (ref $4) i64 v128 (mut v128)) $3))
-;; CHECK-NEXT: (type $7 (struct_subtype (field (ref null $9) (ref $5)) $0))
-;; CHECK-NEXT: (type $8 (struct_subtype (field (ref null $9) (ref $5)) $0))
-;; CHECK-NEXT: (type $9 (struct_subtype (field (mut (rtt $19)) (ref $4) i64 v128 (mut v128)) $6))
-;; CHECK-NEXT: (type $10 (struct_subtype (field (ref $9) (ref $5) i32) $0))
-;; CHECK-NEXT: (type $11 (struct_subtype (field (mut (rtt $19)) (ref $4) (mut f64) i32 (mut f32)) $2))
-;; CHECK-NEXT: (type $12 (struct_subtype (field (ref null $9) (ref $5)) $0))
-;; CHECK-NEXT: (type $13 (struct_subtype (field (mut (rtt $19)) (ref $4) i64 v128 (mut v128)) $6))
-;; CHECK-NEXT: (type $14 (struct_subtype (field (ref $9) (ref $5) i32) $10))
-;; CHECK-NEXT: (type $15 (func_subtype (param (rtt 0 $8)) $1))
-;; CHECK-NEXT: (type $16 (struct_subtype (field (mut (rtt $19)) (ref $4) (mut i16) i64 (mut (rtt 0 i31))) $2))
-;; CHECK-NEXT: (type $17 (struct_subtype (field (ref $9) (ref $5) i32) $14))
-;; CHECK-NEXT: (type $18 (struct_subtype (field (ref null $9) (ref $5)) $12))
-;; CHECK-NEXT: (type $19 (func_subtype (param (rtt 0 $8)) $15))
+;; 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))
diff --git a/test/lit/fuzz-types/structural.test b/test/lit/fuzz-types/structural.test
index e0aa75e9e..345590e2b 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 (ref null $3) (ref $3))))
-;; CHECK-NEXT: (type $1 (func (param (rtt 0 $0))))
-;; CHECK-NEXT: (type $2 (struct (field (mut (rtt $1)) (ref $2))))
-;; CHECK-NEXT: (type $3 (struct (field (mut (rtt $1)) (ref $2) i64 v128 (mut v128))))
+;; 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-NEXT: (type $7 identical to $0)
-;; CHECK-NEXT: (type $8 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 (struct (field (ref $3) (ref $3) i32)))
-;; CHECK-NEXT: (type $11 (struct (field (mut (rtt $1)) (ref $2) (mut f64) i32 (mut f32))))
-;; CHECK-NEXT: (type $12 identical to $0)
+;; 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 $14 identical to $10)
+;; CHECK-NEXT: (type $14 identical to $0)
;; CHECK-NEXT: (type $15 identical to $1)
-;; CHECK-NEXT: (type $16 (struct (field (mut (rtt $1)) (ref $2) (mut i16) i64 (mut (rtt 0 i31)))))
-;; CHECK-NEXT: (type $17 identical to $10)
-;; CHECK-NEXT: (type $18 identical to $0)
+;; 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)
diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast
index 5caadf16d..782a30af2 100644
--- a/test/lit/passes/cfp.wast
+++ b/test/lit/passes/cfp.wast
@@ -37,9 +37,7 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result i64)
@@ -61,9 +59,7 @@
;; references escaping and being stored etc. - it just thinks at the type
;; level.)
(drop
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
(drop
(struct.get $struct 0
@@ -80,9 +76,8 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -100,9 +95,8 @@
;; 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
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
(drop
@@ -120,9 +114,8 @@
;; CHECK: (func $test (type $f32_=>_none) (param $f f32)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (local.get $f)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -134,9 +127,8 @@
(func $test (param $f f32)
;; The value given is not a constant, and so we cannot optimize.
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(local.get $f)
- (rtt.canon $struct)
)
)
(drop
@@ -156,17 +148,15 @@
(type $struct (struct i32))
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
)
@@ -221,17 +211,15 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
)
@@ -246,15 +234,13 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 1337)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -265,15 +251,13 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 1337)
- (rtt.canon $struct)
)
)
(drop
@@ -292,17 +276,15 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
)
@@ -343,17 +325,15 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
)
@@ -400,24 +380,22 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (block (result f32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (f32.const 42)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
;; Fall though a 42 via a block.
(block (result f32)
(nop)
(f32.const 42)
)
- (rtt.canon $struct)
)
)
)
@@ -473,9 +451,8 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (ref.func $test)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -491,9 +468,8 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(ref.func $test)
- (rtt.canon $struct)
)
)
(drop
@@ -513,9 +489,6 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -538,8 +511,7 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_with_rtt $struct
- (i32.const 10)
+ (struct.new $struct
(unreachable)
)
)
@@ -568,17 +540,15 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
)
@@ -615,9 +585,8 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
@@ -627,9 +596,8 @@
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
(struct.set $struct 0
@@ -673,19 +641,17 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 10)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
)
)
@@ -722,31 +688,27 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
(drop
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 10)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
)
)
@@ -784,31 +746,27 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
(drop
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
)
)
@@ -844,31 +802,27 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
(drop
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
)
)
@@ -905,9 +859,8 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
@@ -915,18 +868,16 @@
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
(struct.set $struct 0
@@ -934,10 +885,9 @@
(i32.const 10)
)
(drop
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
)
)
@@ -975,21 +925,19 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 20)
(f64.const 3.14159)
(ref.null any)
- (rtt.canon $struct3)
)
)
)
@@ -1114,34 +1062,31 @@
;; CHECK: (func $create (type $anyref_=>_none) (param $any anyref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 20)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 999)
;; CHECK-NEXT: (f64.const 2.71828)
;; CHECK-NEXT: (f64.const 9.9999999)
;; CHECK-NEXT: (ref.null any)
;; CHECK-NEXT: (local.get $any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (param $any anyref)
(drop
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
(i32.const 20)
- (rtt.canon $struct1)
)
)
(drop
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(i32.const 999) ;; use a different value here
(f64.const 2.71828)
@@ -1149,7 +1094,6 @@
(ref.null any)
(local.get $any) ;; use a non-constant value here, which can never be
;; optimized.
- (rtt.canon $struct3)
)
)
)
@@ -1344,47 +1288,41 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct2
+ ;; CHECK-NEXT: (struct.new $struct2
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (rtt.canon $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
- (rtt.canon $struct1)
)
)
(drop
- (struct.new_with_rtt $struct2
+ (struct.new $struct2
(i32.const 9999) ;; use a different value here
(f64.const 0)
- (rtt.canon $struct2)
)
)
(drop
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(f64.const 0)
(ref.null any)
- (rtt.canon $struct3)
)
)
)
@@ -1447,16 +1385,14 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct2
+ ;; CHECK-NEXT: (struct.new $struct2
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (rtt.canon $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct2 0
@@ -1464,26 +1400,23 @@
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
- (rtt.canon $struct1)
)
)
(drop
- (struct.new_with_rtt $struct2
+ (struct.new $struct2
(i32.const 9999) ;; use a different value here
(f64.const 0)
- (rtt.canon $struct2)
)
)
(struct.set $struct2 0
@@ -1492,11 +1425,10 @@
(f64.const 0)
)
(drop
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(f64.const 0)
(ref.null any)
- (rtt.canon $struct3)
)
)
)
@@ -1547,7 +1479,7 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
@@ -1557,19 +1489,17 @@
;; CHECK-NEXT: (f64.const 2.71828)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 30)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.eqz (i32.const 10)) ;; not a constant (as far as this pass knows)
(f64.const 3.14159)
(i32.const 20)
(f64.abs (f64.const 2.71828)) ;; not a constant
(i32.const 30)
- (rtt.canon $struct)
)
)
)
@@ -1683,17 +1613,15 @@
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $C
+ ;; CHECK-NEXT: (struct.new $C
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $C)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create
(drop
- (struct.new_with_rtt $C
+ (struct.new $C
(i32.const 10)
- (rtt.canon $C)
)
)
)
@@ -1735,9 +1663,7 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
;; CHECK-NEXT: (ref.null $struct)
@@ -1763,9 +1689,7 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (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.
@@ -1795,9 +1719,7 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 1
;; CHECK-NEXT: (ref.null $struct)
@@ -1816,9 +1738,7 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
;; As this is not a copy, we cannot optimize struct.1's get lower down.
(struct.set $struct 1
@@ -1844,9 +1764,7 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
;; CHECK-NEXT: (ref.null $struct)
@@ -1867,9 +1785,7 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
;; As this is not a copy, we cannot optimize struct.0's get lower down.
(struct.set $struct 0
@@ -2182,4 +2098,3 @@
)
)
)
-
diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast
index a8e078468..ea4cce506 100644
--- a/test/lit/passes/dae-gc.wast
+++ b/test/lit/passes/dae-gc.wast
@@ -69,30 +69,28 @@
(unreachable)
)
)
- ;; a function that gets an rtt that is never used. we cannot create a local for
- ;; that parameter, as it is not defaultable, so do not remove the parameter.
- ;; CHECK: (func $get-rtt (param $0 (rtt ${}))
+ ;; A function that gets a non-nullable reference that is never used. We can
+ ;; still create a nullable local for that parameter.
+ ;; CHECK: (func $get-nonnull
+ ;; CHECK-NEXT: (local $0 (ref null ${}))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- ;; NOMNL: (func $get-rtt (type $rtt_${}_=>_none) (param $0 (rtt ${}))
+ ;; NOMNL: (func $get-nonnull (type $none_=>_none)
+ ;; NOMNL-NEXT: (local $0 (ref null ${}))
;; NOMNL-NEXT: (nop)
;; NOMNL-NEXT: )
- (func $get-rtt (param $0 (rtt ${}))
+ (func $get-nonnull (param $0 (ref ${}))
(nop)
)
- ;; CHECK: (func $send-rtt
- ;; CHECK-NEXT: (call $get-rtt
- ;; CHECK-NEXT: (rtt.canon ${})
- ;; CHECK-NEXT: )
+ ;; CHECK: (func $send-nonnull
+ ;; CHECK-NEXT: (call $get-nonnull)
;; CHECK-NEXT: )
- ;; NOMNL: (func $send-rtt (type $none_=>_none)
- ;; NOMNL-NEXT: (call $get-rtt
- ;; NOMNL-NEXT: (rtt.canon ${})
- ;; NOMNL-NEXT: )
+ ;; NOMNL: (func $send-nonnull (type $none_=>_none)
+ ;; NOMNL-NEXT: (call $get-nonnull)
;; NOMNL-NEXT: )
- (func $send-rtt
- (call $get-rtt
- (rtt.canon ${})
+ (func $send-nonnull
+ (call $get-nonnull
+ (struct.new ${})
)
)
)
diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast
index 41c7fc950..1bc0d2b73 100644
--- a/test/lit/passes/gto-removals.wast
+++ b/test/lit/passes/gto-removals.wast
@@ -399,8 +399,8 @@
(module
;; A new with side effects
- ;; CHECK: (type $struct (struct_subtype (field i32) (field (rtt $struct)) data))
- (type $struct (struct i32 f64 (ref any) (rtt $struct)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
+ (type $struct (struct i32 f64 (ref any)))
;; CHECK: (type $none_=>_none (func_subtype func))
@@ -425,11 +425,6 @@
;; CHECK-NEXT: (ref.null $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.get $struct 1
- ;; CHECK-NEXT: (ref.null $struct)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $gets (param $x (ref any))
;; Gets to keep certain fields alive.
@@ -438,11 +433,6 @@
(ref.null $struct)
)
)
- (drop
- (struct.get $struct 3
- (ref.null $struct)
- )
- )
)
;; CHECK: (func $new-side-effect (type $none_=>_none)
@@ -468,24 +458,20 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (local.get $0)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $new-side-effect
;; The 2nd&3rd fields here will be removed, since those fields have no
- ;; reads. They has side effects, though, so the operands will be saved in
- ;; locals. Note that we can't save the rtt.canon in locals, but it has
- ;; no effects, and we leave such arguments as they are.
- ;; Note also that one of the fields is non-nullable, and we need to use a
+ ;; reads. They have side effects, though, so the operands will be saved in
+ ;; locals. Note that one of the fields is non-nullable, and we need to use a
;; nullable local for it.
(drop
(struct.new $struct
(call $helper0 (i32.const 0))
(call $helper1 (i32.const 1))
(call $helper2 (i32.const 2))
- (rtt.canon $struct)
)
)
)
@@ -507,7 +493,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (global.get $imm-i32)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -522,7 +507,6 @@
(global.get $imm-i32)
(call $helper1 (i32.const 0))
(call $helper2 (i32.const 1))
- (rtt.canon $struct)
)
)
)
@@ -548,7 +532,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (local.get $0)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -561,7 +544,6 @@
(global.get $mut-i32)
(call $helper1 (i32.const 0))
(call $helper2 (i32.const 1))
- (rtt.canon $struct)
)
)
)
@@ -580,9 +562,6 @@
;; CHECK-NEXT: (i32.const 3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -594,7 +573,6 @@
(i32.const 2)
(unreachable)
(call $helper2 (i32.const 3))
- (rtt.canon $struct)
)
)
)
@@ -605,7 +583,6 @@
;; CHECK-NEXT: (call $helper0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -617,7 +594,6 @@
(call $helper0 (i32.const 0))
(f64.const 3.14159)
(local.get $any)
- (rtt.canon $struct)
)
)
)
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 19ca922f4..ddd10e7f9 100644
--- a/test/lit/passes/gufa-refs.wast
+++ b/test/lit/passes/gufa-refs.wast
@@ -2896,11 +2896,10 @@
;; they might appear as if no content were possible there, and we'd emit an
;; unreachable. That should not happen anywhere here.
(module
- ;; CHECK: (type $none_=>_none (func_subtype func))
-
- ;; CHECK: (type $A (struct_subtype data))
(type $A (struct_subtype data))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
;; CHECK: (type $i32_=>_none (func_subtype (param i32) func))
;; CHECK: (type $B (array_subtype (mut anyref) data))
@@ -3146,44 +3145,6 @@
)
)
- ;; CHECK: (func $refs-rtts (type $none_=>_none)
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (ref.null data)
- ;; CHECK-NEXT: (ref.null data)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $A))
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (ref.null $A)
- ;; CHECK-NEXT: (rtt.sub $A
- ;; CHECK-NEXT: (rtt.canon $A)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $A)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- (func $refs-rtts
- (drop
- (ref.eq
- (ref.null data)
- (ref.null data)
- )
- )
- (drop
- (ref.cast
- (ref.null $A)
- (rtt.sub $A
- (rtt.canon $A)
- )
- )
- )
- )
-
;; CHECK: (func $table (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (table.get $t
diff --git a/test/lit/passes/gufa-vs-cfp.wast b/test/lit/passes/gufa-vs-cfp.wast
index 38dbf72fd..9cb74fbe7 100644
--- a/test/lit/passes/gufa-vs-cfp.wast
+++ b/test/lit/passes/gufa-vs-cfp.wast
@@ -66,9 +66,7 @@
;; its reference is non-nullable).
(drop
(struct.get $struct 0
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
)
)
@@ -89,9 +87,8 @@
;; passed in, as opposed to being a default value as in the last testcase).
(drop
(struct.get $struct 0
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
)
@@ -112,9 +109,8 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (call $import)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -123,9 +119,8 @@
;; The value given is not a constant, and so we cannot optimize.
(drop
(struct.get $struct 0
- (struct.new_with_rtt $struct
+ (struct.new $struct
(call $import)
- (rtt.canon $struct)
)
)
)
@@ -142,15 +137,13 @@
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
;; CHECK: (func $get (type $none_=>_none)
@@ -204,15 +197,13 @@
)
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
)
@@ -226,34 +217,30 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 1337)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
;; (A better analysis could see that the first struct.new is dropped and its
;; value cannot reach this struct.get.)
(drop
(struct.get $struct 0
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 1337)
- (rtt.canon $struct)
)
)
)
@@ -269,15 +256,13 @@
;; CHECK: (type $none_=>_ref|$struct| (func_subtype (result (ref $struct)) func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
;; CHECK: (func $set (type $none_=>_none)
@@ -319,15 +304,13 @@
;; CHECK: (type $none_=>_ref|$struct| (func_subtype (result (ref $struct)) func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(f32.const 42)
- (rtt.canon $struct)
)
)
;; CHECK: (func $set (type $none_=>_none)
@@ -376,19 +359,17 @@
(import "a" "b" (func $import (result i32)))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (f32.const 42)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
;; Fall though a 42. The block can be optimized to a constant.
(block $named (result f32)
(nop)
(f32.const 42)
)
- (rtt.canon $struct)
)
)
;; CHECK: (func $set (type $none_=>_none)
@@ -453,9 +434,8 @@
(func $test
(drop
(struct.get $struct 0
- (struct.new_with_rtt $struct
+ (struct.new $struct
(ref.func $test)
- (rtt.canon $struct)
)
)
)
@@ -493,7 +473,7 @@
;; CHECK-NEXT: )
(func $test
(drop
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
(unreachable)
)
@@ -520,15 +500,13 @@
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
;; CHECK: (func $get (type $none_=>_none)
@@ -569,15 +547,13 @@
;; CHECK: (type $none_=>_ref|$struct| (func_subtype (result (ref $struct)) func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
@@ -631,9 +607,8 @@
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (local $ref (ref null $struct))
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $struct 0
@@ -659,9 +634,8 @@
(func $test
(local $ref (ref null $struct))
(local.set $ref
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
)
(struct.set $struct 0
@@ -700,10 +674,9 @@
(func $test
(drop
(struct.get $struct 0
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 10)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
)
)
@@ -730,14 +703,12 @@
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (select (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
@@ -751,14 +722,12 @@
(drop
(struct.get $struct 0
(select
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 10)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
(call $import)
)
@@ -787,14 +756,12 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
;; CHECK-NEXT: (select (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
@@ -805,14 +772,12 @@
(drop
(struct.get $struct 0
(select
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20) ;; this constant changed
(f64.const 3.14159)
- (rtt.canon $substruct)
)
(call $import)
)
@@ -846,14 +811,12 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast_static $substruct
;; CHECK-NEXT: (select (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
@@ -869,14 +832,12 @@
;; This cast is added, ensuring only a $substruct can reach the get.
(ref.cast_static $substruct
(select
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
(call $import)
)
@@ -905,14 +866,12 @@
;; CHECK-NEXT: (local $ref (ref null $struct))
;; CHECK-NEXT: (local.set $ref
;; CHECK-NEXT: (select (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
@@ -933,14 +892,12 @@
(local $ref (ref null $struct))
(local.set $ref
(select
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
(call $import)
)
@@ -981,14 +938,12 @@
;; CHECK-NEXT: (local $ref (ref null $struct))
;; CHECK-NEXT: (local.set $ref
;; CHECK-NEXT: (select (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_with_rtt $substruct
+ ;; CHECK-NEXT: (struct.new $substruct
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
- ;; CHECK-NEXT: (rtt.canon $substruct)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
@@ -1014,14 +969,12 @@
(local $ref (ref null $struct))
(local.set $ref
(select
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 10)
- (rtt.canon $struct)
)
- (struct.new_with_rtt $substruct
+ (struct.new $substruct
(i32.const 20)
(f64.const 3.14159)
- (rtt.canon $substruct)
)
(call $import)
)
@@ -1059,19 +1012,17 @@
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_ref|$struct3|) (result (ref $struct3))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (f64.const 3.14159)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct3))
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 20)
(f64.const 3.14159)
(ref.null any)
- (rtt.canon $struct3)
)
)
;; CHECK: (func $get (type $none_=>_none)
@@ -1209,33 +1160,30 @@
(import "a" "b" (func $import (result anyref)))
;; CHECK: (func $create1 (type $none_=>_ref|$struct1|) (result (ref $struct1))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 20)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create1 (result (ref $struct1))
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
(i32.const 20)
- (rtt.canon $struct1)
)
)
;; CHECK: (func $create3 (type $none_=>_ref|$struct3|) (result (ref $struct3))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 999)
;; CHECK-NEXT: (f64.const 2.71828)
;; CHECK-NEXT: (f64.const 9.9999999)
;; CHECK-NEXT: (ref.null any)
;; CHECK-NEXT: (call $import)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(i32.const 999) ;; use a different value here
(f64.const 2.71828)
@@ -1243,7 +1191,6 @@
(ref.null any)
(call $import) ;; use an unknown value here, which can never be
;; optimized.
- (rtt.canon $struct3)
)
)
@@ -1447,47 +1394,41 @@
(import "a" "b" (func $import (result i32)))
;; CHECK: (func $create1 (type $none_=>_ref|$struct1|) (result (ref $struct1))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create1 (result (ref $struct1))
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
- (rtt.canon $struct1)
)
)
;; CHECK: (func $create2 (type $none_=>_ref|$struct2|) (result (ref $struct2))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct2
+ ;; CHECK-NEXT: (struct.new $struct2
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (rtt.canon $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create2 (result (ref $struct2))
- (struct.new_with_rtt $struct2
+ (struct.new $struct2
(i32.const 9999) ;; use a different value here
(f64.const 0)
- (rtt.canon $struct2)
)
)
;; CHECK: (func $create3 (type $none_=>_ref|$struct3|) (result (ref $struct3))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(f64.const 0)
(ref.null any)
- (rtt.canon $struct3)
)
)
@@ -1758,47 +1699,41 @@
(import "a" "b" (func $import (result i32)))
;; CHECK: (func $create1 (type $none_=>_ref|$struct1|) (result (ref $struct1))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create1 (result (ref $struct1))
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
- (rtt.canon $struct1)
)
)
;; CHECK: (func $create2 (type $none_=>_ref|$struct2|) (result (ref $struct2))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct2
+ ;; CHECK-NEXT: (struct.new $struct2
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (rtt.canon $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create2 (result (ref $struct2))
- (struct.new_with_rtt $struct2
+ (struct.new $struct2
(i32.const 9999) ;; use a different value here
(f64.const 0)
- (rtt.canon $struct2)
)
)
;; CHECK: (func $create3 (type $none_=>_ref|$struct3|) (result (ref $struct3))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(f64.const 0)
(ref.null any)
- (rtt.canon $struct3)
)
)
@@ -1880,47 +1815,41 @@
(import "a" "b" (func $import (result i32)))
;; CHECK: (func $create1 (type $none_=>_ref|$struct1|) (result (ref $struct1))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct1
+ ;; CHECK-NEXT: (struct.new $struct1
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $struct1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create1 (result (ref $struct1))
- (struct.new_with_rtt $struct1
+ (struct.new $struct1
(i32.const 10)
- (rtt.canon $struct1)
)
)
;; CHECK: (func $create2 (type $none_=>_ref|$struct2|) (result (ref $struct2))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct2
+ ;; CHECK-NEXT: (struct.new $struct2
;; CHECK-NEXT: (i32.const 9999)
;; CHECK-NEXT: (f64.const 0)
- ;; CHECK-NEXT: (rtt.canon $struct2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create2 (result (ref $struct2))
- (struct.new_with_rtt $struct2
+ (struct.new $struct2
(i32.const 9999) ;; use a different value here
(f64.const 0)
- (rtt.canon $struct2)
)
)
;; CHECK: (func $create3 (type $none_=>_ref|$struct3|) (result (ref $struct3))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct3
+ ;; CHECK-NEXT: (struct.new $struct3
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: (ref.null any)
- ;; CHECK-NEXT: (rtt.canon $struct3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create3 (result (ref $struct3))
- (struct.new_with_rtt $struct3
+ (struct.new $struct3
(i32.const 10)
(f64.const 0)
(ref.null any)
- (rtt.canon $struct3)
)
)
@@ -1988,7 +1917,7 @@
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
@@ -1998,17 +1927,15 @@
;; CHECK-NEXT: (f64.const 2.71828)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 30)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.eqz (i32.const 10)) ;; not a constant (as far as this pass knows)
(f64.const 3.14159)
(i32.const 20)
(f64.abs (f64.const 2.71828)) ;; not a constant
(i32.const 30)
- (rtt.canon $struct)
)
)
;; CHECK: (func $get (type $none_=>_none)
@@ -2110,15 +2037,13 @@
;; CHECK: (type $none_=>_ref|$C| (func_subtype (result (ref $C)) func))
;; CHECK: (func $create-C (type $none_=>_ref|$C|) (result (ref $C))
- ;; CHECK-NEXT: (struct.new_with_rtt $C
+ ;; CHECK-NEXT: (struct.new $C
;; CHECK-NEXT: (i32.const 10)
- ;; CHECK-NEXT: (rtt.canon $C)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $create-C (result (ref $C))
- (struct.new_with_rtt $C
+ (struct.new $C
(i32.const 10)
- (rtt.canon $C)
)
)
;; CHECK: (func $set (type $none_=>_none)
@@ -2167,14 +2092,10 @@
;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (type $none_=>_ref|$struct|) (result (ref $struct))
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
(func $create (result (ref $struct))
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
;; CHECK: (func $test (type $none_=>_none)
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast
index ebe5d1db9..b7ed9bd0f 100644
--- a/test/lit/passes/heap2local.wast
+++ b/test/lit/passes/heap2local.wast
@@ -11,22 +11,20 @@
;; CHECK: (type $struct.recursive (struct (field (mut (ref null $struct.recursive)))))
- ;; CHECK: (type $struct.nonnullable (struct (field (ref $struct.A))))
+ ;; 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.nonnullable (struct_subtype (field (ref $struct.A)) data))
-
;; NOMNL: (type $struct.packed (struct_subtype (field (mut i8)) data))
(type $struct.packed (struct (field (mut i8))))
- ;; CHECK: (type $struct.nondefaultable (struct (field (rtt $struct.A))))
- ;; NOMNL: (type $struct.nondefaultable (struct_subtype (field (rtt $struct.A)) data))
- (type $struct.nondefaultable (struct (field (rtt $struct.A))))
+ ;; 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
@@ -40,9 +38,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -58,9 +53,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -69,9 +61,7 @@
;; Other passes can remove such a trivial case of an unused allocation, but
;; we still optimize it.
(drop
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
@@ -87,9 +77,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -106,9 +93,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -120,9 +104,7 @@
;; drop (and adding some unnecessary code to allocate the values, which we
;; depend on other passes to remove).
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
@@ -139,9 +121,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -162,9 +141,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -180,9 +156,7 @@
;; locals, and we read from the locals instead of the struct.get.
(drop
(struct.get $struct.A 0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
)
@@ -200,9 +174,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -223,9 +194,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -237,9 +205,7 @@
;; Similar to the above, but using a different field index.
(drop
(struct.get $struct.A 1
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
)
@@ -255,9 +221,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -276,9 +239,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -289,9 +249,7 @@
(func $one-set
;; A simple optimizable allocation only used in one set.
(struct.set $struct.A 0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
(i32.const 1)
)
)
@@ -299,18 +257,14 @@
;; CHECK: (func $packed
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get_u $struct.packed 0
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.packed
- ;; CHECK-NEXT: (rtt.canon $struct.packed)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.packed)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $packed (type $none_=>_none)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (struct.get_u $struct.packed 0
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.packed
- ;; NOMNL-NEXT: (rtt.canon $struct.packed)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.packed)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -318,9 +272,7 @@
;; We do not optimize packed structs yet.
(drop
(struct.get $struct.packed 0
- (struct.new_default_with_rtt $struct.packed
- (rtt.canon $struct.packed)
- )
+ (struct.new_default $struct.packed)
)
)
)
@@ -346,9 +298,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -377,9 +326,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (local.get $3)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -392,10 +338,9 @@
;; proper locals.
(drop
(struct.get $struct.A 0
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 2)
(f64.const 3.14159)
- (rtt.canon $struct.A)
)
)
)
@@ -412,9 +357,6 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -431,9 +373,6 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -444,43 +383,70 @@
;; remove it.
(drop
(struct.get $struct.A 0
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 2)
(unreachable)
- (rtt.canon $struct.A)
)
)
)
)
;; CHECK: (func $nondefaultable
+ ;; CHECK-NEXT: (local $0 (ref null $struct.A))
+ ;; CHECK-NEXT: (local $1 (ref null $struct.A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.get $struct.nondefaultable 0
- ;; CHECK-NEXT: (struct.new_with_rtt $struct.nondefaultable
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: (rtt.canon $struct.nondefaultable)
+ ;; CHECK-NEXT: (block (result (ref $struct.A))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result (ref null $struct.nondefaultable))
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.null $struct.nondefaultable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $nondefaultable (type $none_=>_none)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 (ref null $struct.A))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (struct.get $struct.nondefaultable 0
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct.nondefaultable
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: (rtt.canon $struct.nondefaultable)
+ ;; NOMNL-NEXT: (block (result (ref $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.nondefaultable))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.nondefaultable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $nondefaultable
;; We do not optimize structs with nondefaultable types that we cannot
- ;; handle, like rtts.
+ ;; handle.
+ ;; TODO: We should be able to handle this after #4824 is resolved.
(drop
(struct.get $struct.nondefaultable 0
- (struct.new_with_rtt $struct.nondefaultable
- (rtt.canon $struct.A)
- (rtt.canon $struct.nondefaultable)
+ (struct.new $struct.nondefaultable
+ (struct.new_default $struct.A)
)
)
)
@@ -498,9 +464,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -525,9 +488,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -546,9 +506,7 @@
;; to a local. The local.set should not prevent our optimization, and the
;; local.set can be turned into a drop.
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.set $struct.A 0
(local.get $ref)
@@ -568,9 +526,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -593,9 +548,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -609,9 +561,7 @@
(func $simple-one-local-get (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; A simple optimizable allocation only used in one get, via a local.
(struct.get $struct.A 1
@@ -640,9 +590,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -668,9 +615,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -687,9 +631,7 @@
(func $safe-to-drop (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; An extra drop does not let the allocation escape.
(drop
@@ -703,9 +645,7 @@
;; CHECK: (func $escape-via-call (result f64)
;; CHECK-NEXT: (local $ref (ref null $struct.A))
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $send-ref
;; CHECK-NEXT: (local.get $ref)
@@ -717,9 +657,7 @@
;; NOMNL: (func $escape-via-call (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $ref (ref null $struct.A))
;; NOMNL-NEXT: (local.set $ref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $send-ref
;; NOMNL-NEXT: (local.get $ref)
@@ -731,9 +669,7 @@
(func $escape-via-call (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; The allocation escapes into a call.
(call $send-ref
@@ -756,9 +692,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -788,9 +721,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -811,9 +741,7 @@
(func $safe-to-drop-multiflow (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; An extra drop + multiple flows through things do not stop us.
(drop
@@ -833,9 +761,7 @@
;; CHECK: (func $escape-after-multiflow (result f64)
;; CHECK-NEXT: (local $ref (ref null $struct.A))
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $send-ref
;; CHECK-NEXT: (block (result (ref null $struct.A))
@@ -851,9 +777,7 @@
;; NOMNL: (func $escape-after-multiflow (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $ref (ref null $struct.A))
;; NOMNL-NEXT: (local.set $ref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $send-ref
;; NOMNL-NEXT: (block (result (ref null $struct.A))
@@ -869,9 +793,7 @@
(func $escape-after-multiflow (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; An escape after multiple flows.
(call $send-ref
@@ -892,12 +814,8 @@
;; CHECK-NEXT: (local $ref (ref null $struct.A))
;; CHECK-NEXT: (local.set $ref
;; CHECK-NEXT: (select (result (ref $struct.A))
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -909,12 +827,8 @@
;; NOMNL-NEXT: (local $ref (ref null $struct.A))
;; NOMNL-NEXT: (local.set $ref
;; NOMNL-NEXT: (select (result (ref $struct.A))
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: (i32.const 1)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -928,12 +842,8 @@
;; to optimize it.
(local.set $ref
(select
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
+ (struct.new_default $struct.A)
(i32.const 1)
)
)
@@ -954,9 +864,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -982,9 +889,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1001,9 +905,7 @@
(func $local-copies (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; Copying our allocation through locals does not bother us.
(local.set $ref
@@ -1027,9 +929,6 @@
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1066,9 +965,6 @@
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1096,9 +992,7 @@
(local $ref (ref null $struct.A))
(local $ref-2 (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; Copying our allocation through locals does not bother us, even if it's
;; another local.
@@ -1129,9 +1023,6 @@
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1160,9 +1051,6 @@
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1182,9 +1070,7 @@
(func $local-copies-conditional (param $x i32) (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; Possibly copying our allocation through locals does not bother us. Note
;; that as a result of this the final local.get has two sets that send it
@@ -1211,9 +1097,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1241,9 +1124,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1262,9 +1142,7 @@
(func $block-value (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; Returning our allocation from a block does not bother us.
(struct.get $struct.A 1
@@ -1281,9 +1159,7 @@
;; CHECK: (func $non-exclusive-get (param $x i32) (result f64)
;; CHECK-NEXT: (local $ref (ref null $struct.A))
;; CHECK-NEXT: (local.set $ref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $x)
@@ -1298,9 +1174,7 @@
;; NOMNL: (func $non-exclusive-get (type $i32_=>_f64) (param $x i32) (result f64)
;; NOMNL-NEXT: (local $ref (ref null $struct.A))
;; NOMNL-NEXT: (local.set $ref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (if
;; NOMNL-NEXT: (local.get $x)
@@ -1315,9 +1189,7 @@
(func $non-exclusive-get (param $x i32) (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(if (local.get $x)
(local.set $ref
@@ -1343,9 +1215,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1363,9 +1232,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1376,9 +1242,7 @@
(struct.get $struct.A 0
;; A tee flows out the value, and we can optimize this allocation.
(local.tee $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
)
@@ -1391,9 +1255,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (ref.null $struct.recursive)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.recursive)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1409,9 +1270,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (ref.null $struct.recursive)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.recursive)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1424,9 +1282,7 @@
;; As above, but with a set, and also a recursive type.
(struct.set $struct.recursive 0
(local.tee $ref
- (struct.new_default_with_rtt $struct.recursive
- (rtt.canon $struct.recursive)
- )
+ (struct.new_default $struct.recursive)
)
(ref.null $struct.recursive)
)
@@ -1437,9 +1293,7 @@
;; CHECK-NEXT: (struct.set $struct.recursive 0
;; CHECK-NEXT: (ref.null $struct.recursive)
;; CHECK-NEXT: (local.tee $ref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.recursive
- ;; CHECK-NEXT: (rtt.canon $struct.recursive)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1448,9 +1302,7 @@
;; NOMNL-NEXT: (struct.set $struct.recursive 0
;; NOMNL-NEXT: (ref.null $struct.recursive)
;; NOMNL-NEXT: (local.tee $ref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.recursive
- ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.recursive)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1461,9 +1313,7 @@
;; As above, but operands reversed: the allocation is now the value, not
;; the reference, and so it escapes.
(local.tee $ref
- (struct.new_default_with_rtt $struct.recursive
- (rtt.canon $struct.recursive)
- )
+ (struct.new_default $struct.recursive)
)
)
)
@@ -1475,16 +1325,11 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref null $struct.recursive))
;; CHECK-NEXT: (local.set $2
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.recursive
- ;; CHECK-NEXT: (rtt.canon $struct.recursive)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.recursive)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1504,16 +1349,11 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
;; NOMNL-NEXT: (local.set $2
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.recursive
- ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.recursive)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.recursive)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1530,7 +1370,7 @@
(local $0 (ref null $struct.recursive))
(local.set $0
;; The outer allocation can be optimized, as it does not escape.
- (struct.new_with_rtt $struct.recursive
+ (struct.new $struct.recursive
;; The inner allocation should not prevent the outer one from being
;; optimized through some form of confusion.
;; After the outer one is optimized, the inner one can be optimized in
@@ -1538,10 +1378,7 @@
;; on other optimizations to actually remove the outer allocation (like
;; vacuum), and so it cannot be optimized. If we ran vaccum, and then
;; additional iterations, this might be handled.
- (struct.new_default_with_rtt $struct.recursive
- (rtt.canon $struct.recursive)
- )
- (rtt.canon $struct.recursive)
+ (struct.new_default $struct.recursive)
)
)
(drop
@@ -1555,9 +1392,7 @@
;; CHECK-NEXT: (local $ref (ref null $struct.A))
;; CHECK-NEXT: (struct.set $struct.A 0
;; CHECK-NEXT: (local.tee $ref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
@@ -1567,9 +1402,7 @@
;; NOMNL-NEXT: (local $ref (ref null $struct.A))
;; NOMNL-NEXT: (struct.set $struct.A 0
;; NOMNL-NEXT: (local.tee $ref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (i32.const 1)
;; NOMNL-NEXT: )
@@ -1579,9 +1412,7 @@
(local $ref (ref null $struct.A))
(struct.set $struct.A 0
(local.tee $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(i32.const 1)
)
@@ -1593,9 +1424,7 @@
;; CHECK-NEXT: (local $ref (ref null $struct.A))
;; CHECK-NEXT: (struct.set $struct.A 0
;; CHECK-NEXT: (local.tee $ref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
@@ -1607,9 +1436,7 @@
;; NOMNL-NEXT: (local $ref (ref null $struct.A))
;; NOMNL-NEXT: (struct.set $struct.A 0
;; NOMNL-NEXT: (local.tee $ref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (i32.const 1)
;; NOMNL-NEXT: )
@@ -1621,9 +1448,7 @@
(local $ref (ref null $struct.A))
(struct.set $struct.A 0
(local.tee $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(i32.const 1)
)
@@ -1639,7 +1464,7 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref $struct.A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.nonnullable))
+ ;; CHECK-NEXT: (block (result (ref null $struct.nondefaultable))
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: )
@@ -1648,10 +1473,7 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.nonnullable)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.null $struct.nonnullable)
+ ;; CHECK-NEXT: (ref.null $struct.nondefaultable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.as_non_null
@@ -1675,9 +1497,6 @@
;; NOMNL-NEXT: (local.get $2)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.nonnullable)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.nonnullable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1692,9 +1511,8 @@
;; An optimizable case where the type is non-nullable, which requires
;; special handling in locals.
(struct.get $struct.nonnullable 0
- (struct.new_with_rtt $struct.nonnullable
+ (struct.new $struct.nonnullable
(local.get $a)
- (rtt.canon $struct.nonnullable)
)
)
)
@@ -1721,9 +1539,6 @@
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (local.get $5)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1818,9 +1633,6 @@
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (local.get $5)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1900,10 +1712,9 @@
;; in various ways inside.
(loop $outer
(local.set $ref
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 2)
(f64.const 2.1828)
- (rtt.canon $struct.A)
)
)
(drop
@@ -1969,9 +1780,6 @@
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1988,9 +1796,6 @@
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2007,9 +1812,6 @@
;; CHECK-NEXT: (local.set $5
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2034,9 +1836,6 @@
;; NOMNL-NEXT: (local.set $1
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2053,9 +1852,6 @@
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2072,9 +1868,6 @@
;; NOMNL-NEXT: (local.set $5
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2086,23 +1879,17 @@
;; Multiple independent things we can optimize.
(drop
(struct.get $struct.A 0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
(drop
(struct.get $struct.A 0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
(drop
(struct.get $struct.A 1
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
)
@@ -2121,9 +1908,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2143,9 +1927,6 @@
;; CHECK-NEXT: (local.set $4
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2172,9 +1953,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2194,9 +1972,6 @@
;; NOMNL-NEXT: (local.set $4
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2214,9 +1989,7 @@
;; Multiple independent things we can optimize that use the same local
;; index, but they do not conflict in their live ranges.
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(drop
(struct.get $struct.A 0
@@ -2224,9 +1997,7 @@
)
)
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(drop
(struct.get $struct.A 0
@@ -2250,9 +2021,6 @@
;; CHECK-NEXT: (local.set $3
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2264,9 +2032,6 @@
;; CHECK-NEXT: (local.set $5
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2302,9 +2067,6 @@
;; NOMNL-NEXT: (local.set $3
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2316,9 +2078,6 @@
;; NOMNL-NEXT: (local.set $5
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2345,14 +2104,10 @@
;; Multiple independent things we can optimize that use different local
;; indexes, but whose lifetimes overlap. We should not be confused by that.
(local.set $ref1
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(local.set $ref2
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(drop
(struct.get $struct.A 0
@@ -2369,9 +2124,7 @@
;; CHECK: (func $get-through-block (result f64)
;; CHECK-NEXT: (local $0 (ref null $struct.A))
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $struct.A 1
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
@@ -2388,9 +2141,7 @@
;; NOMNL: (func $get-through-block (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $0 (ref null $struct.A))
;; NOMNL-NEXT: (local.set $0
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $struct.A 1
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
@@ -2407,9 +2158,7 @@
(func $get-through-block (result f64)
(local $0 (ref null $struct.A))
(local.set $0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.get $struct.A 1
(block $block (result (ref null $struct.A))
@@ -2431,9 +2180,7 @@
;; CHECK: (func $branch-to-block (result f64)
;; CHECK-NEXT: (local $0 (ref null $struct.A))
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $struct.A 1
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
@@ -2450,9 +2197,7 @@
;; NOMNL: (func $branch-to-block (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $0 (ref null $struct.A))
;; NOMNL-NEXT: (local.set $0
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $struct.A 1
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
@@ -2469,9 +2214,7 @@
(func $branch-to-block (result f64)
(local $0 (ref null $struct.A))
(local.set $0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.get $struct.A 1
(block $block (result (ref null $struct.A))
@@ -2500,9 +2243,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2535,9 +2275,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2561,9 +2298,7 @@
(func $branch-to-block-no-fallthrough (result f64)
(local $0 (ref null $struct.A))
(local.set $0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.get $struct.A 1
(block $block (result (ref null $struct.A))
@@ -2584,9 +2319,7 @@
;; CHECK: (func $two-branches (result f64)
;; CHECK-NEXT: (local $0 (ref null $struct.A))
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $struct.A 1
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
@@ -2611,9 +2344,7 @@
;; NOMNL: (func $two-branches (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $0 (ref null $struct.A))
;; NOMNL-NEXT: (local.set $0
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $struct.A 1
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
@@ -2638,9 +2369,7 @@
(func $two-branches (result f64)
(local $0 (ref null $struct.A))
(local.set $0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.get $struct.A 1
(block $block (result (ref null $struct.A))
@@ -2666,9 +2395,7 @@
;; CHECK: (func $two-branches-b (result f64)
;; CHECK-NEXT: (local $0 (ref null $struct.A))
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $struct.A 1
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
@@ -2693,9 +2420,7 @@
;; NOMNL: (func $two-branches-b (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $0 (ref null $struct.A))
;; NOMNL-NEXT: (local.set $0
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $struct.A 1
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
@@ -2720,9 +2445,7 @@
(func $two-branches-b (result f64)
(local $0 (ref null $struct.A))
(local.set $0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.get $struct.A 1
(block $block (result (ref null $struct.A))
@@ -2749,9 +2472,7 @@
;; CHECK: (func $br_if_flow (result f64)
;; CHECK-NEXT: (local $0 (ref null $struct.A))
;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct.A
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.get $struct.A 1
;; CHECK-NEXT: (block $block (result (ref null $struct.A))
@@ -2770,9 +2491,7 @@
;; NOMNL: (func $br_if_flow (type $none_=>_f64) (result f64)
;; NOMNL-NEXT: (local $0 (ref null $struct.A))
;; NOMNL-NEXT: (local.set $0
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (struct.get $struct.A 1
;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
@@ -2791,9 +2510,7 @@
(func $br_if_flow (result f64)
(local $0 (ref null $struct.A))
(local.set $0
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.get $struct.A 1
(block $block (result (ref null $struct.A))
@@ -2823,9 +2540,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2855,9 +2569,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2878,9 +2589,7 @@
(func $ref-as-non-null
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
(struct.set $struct.A 0
;; We can see that the input to this RefAsNonNull is always non-null, as
@@ -2911,9 +2620,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2939,9 +2645,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2958,9 +2661,7 @@
(func $ref-as-non-null-through-local (result i32)
(local $ref (ref null $struct.A))
(local.set $ref
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
;; Copy the allocation through a ref.as_non_null. This must not trap: it may
;; trap if we leave the ref.as_non_null there and also we do not assign
@@ -3001,9 +2702,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (local.get $4)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
@@ -3039,9 +2737,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (local.get $4)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (i32.const 0)
@@ -3062,10 +2757,9 @@
;; Our allocation flows into a br_if, which therefore has non-nullable
;; type, which we must update after optimizing.
(br_if $block
- (struct.new_with_rtt $struct.A
+ (struct.new $struct.A
(i32.const 42)
(f64.const 13.37)
- (rtt.canon $struct.A)
)
(i32.const 0)
)
@@ -3075,44 +2769,6 @@
)
)
- ;; CHECK: (func $simple-no-rtt
- ;; CHECK-NEXT: (local $0 i32)
- ;; CHECK-NEXT: (local $1 f64)
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
- ;; 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: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $simple-no-rtt (type $none_=>_none)
- ;; NOMNL-NEXT: (local $0 i32)
- ;; NOMNL-NEXT: (local $1 f64)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref null $struct.A))
- ;; 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: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- (func $simple-no-rtt
- (drop
- ;; This allocation has no rtt, so we have nothing to drop from it when
- ;; we optimize.
- (struct.new_default $struct.A)
- )
- )
-
;; CHECK: (func $pass-through-loop
;; CHECK-NEXT: (local $0 (ref null $struct.A))
;; CHECK-NEXT: (local $1 i32)
@@ -3129,9 +2785,6 @@
;; CHECK-NEXT: (local.set $2
;; CHECK-NEXT: (f64.const 0)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct.A)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -3153,9 +2806,6 @@
;; NOMNL-NEXT: (local.set $2
;; NOMNL-NEXT: (f64.const 0)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct.A)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $struct.A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -3172,9 +2822,7 @@
;; block).
(br_if $loop (i32.const 0))
;; The allocation that will be turned into locals.
- (struct.new_default_with_rtt $struct.A
- (rtt.canon $struct.A)
- )
+ (struct.new_default $struct.A)
)
)
)
diff --git a/test/lit/passes/inlining-optimizing.wast b/test/lit/passes/inlining-optimizing.wast
index ac29ba1f9..74748c6a4 100644
--- a/test/lit/passes/inlining-optimizing.wast
+++ b/test/lit/passes/inlining-optimizing.wast
@@ -30,12 +30,10 @@
(call $0)
(drop
(call_ref
- (ref.cast
+ (ref.cast_static $none_=>_i32
(ref.func $0)
- (rtt.canon $none_=>_i32)
)
)
)
)
)
-
diff --git a/test/lit/passes/inlining_all-features.wast b/test/lit/passes/inlining_all-features.wast
index 051201b23..3b2f3a458 100644
--- a/test/lit/passes/inlining_all-features.wast
+++ b/test/lit/passes/inlining_all-features.wast
@@ -208,41 +208,3 @@
)
)
)
-
-;; never inline an rtt parameter, as those cannot be handled as locals
-(module
- ;; CHECK: (type $struct (struct ))
- ;; NOMNL: (type $struct (struct_subtype data))
- (type $struct (struct))
- ;; CHECK: (type $rtt_$struct_=>_none (func (param (rtt $struct))))
-
- ;; CHECK: (type $none_=>_none (func))
-
- ;; CHECK: (func $0 (param $rtt (rtt $struct))
- ;; CHECK-NEXT: (nop)
- ;; CHECK-NEXT: )
- ;; NOMNL: (type $rtt_$struct_=>_none (func_subtype (param (rtt $struct)) func))
-
- ;; NOMNL: (type $none_=>_none (func_subtype func))
-
- ;; NOMNL: (func $0 (type $rtt_$struct_=>_none) (param $rtt (rtt $struct))
- ;; NOMNL-NEXT: (nop)
- ;; NOMNL-NEXT: )
- (func $0 (param $rtt (rtt $struct))
- )
- ;; CHECK: (func $1
- ;; CHECK-NEXT: (call $0
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $1 (type $none_=>_none)
- ;; NOMNL-NEXT: (call $0
- ;; NOMNL-NEXT: (rtt.canon $struct)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- (func $1
- (call $0
- (rtt.canon $struct)
- )
- )
-)
diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast
index 599bb9cc6..678400c7f 100644
--- a/test/lit/passes/inlining_splitting.wast
+++ b/test/lit/passes/inlining_splitting.wast
@@ -14,8 +14,6 @@
;; CHECK: (type $struct (struct ))
(type $struct (struct))
- ;; CHECK: (type $i32_rtt_$struct_=>_none (func (param i32 (rtt $struct))))
-
;; CHECK: (type $i64_i32_f64_=>_none (func (param i64 i32 f64)))
;; CHECK: (import "out" "func" (func $import))
@@ -203,19 +201,8 @@
(call $br-to-toplevel (i32.const 2))
)
- ;; CHECK: (func $nondefaultable-param (param $x i32) (param $y (rtt $struct))
- ;; CHECK-NEXT: (if
- ;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (return)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (loop $l
- ;; CHECK-NEXT: (call $import)
- ;; CHECK-NEXT: (br $l)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- (func $nondefaultable-param (param $x i32) (param $y (rtt $struct))
- ;; The RTT param here prevents us from even being inlined, even with
- ;; splitting.
+ (func $nondefaultable-param (param $x i32) (param $y (ref $struct))
+ ;; We can inline despite the non-initial, non-defaultable param.
(if
(local.get $x)
(return)
@@ -227,13 +214,30 @@
)
;; CHECK: (func $call-nondefaultable-param
- ;; CHECK-NEXT: (call $nondefaultable-param
- ;; CHECK-NEXT: (i32.const 0)
- ;; CHECK-NEXT: (rtt.canon $struct)
+ ;; CHECK-NEXT: (local $0 i32)
+ ;; CHECK-NEXT: (local $1 (ref null $struct))
+ ;; CHECK-NEXT: (block $__inlined_func$nondefaultable-param
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (struct.new_default $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (br $__inlined_func$nondefaultable-param)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (loop $l
+ ;; CHECK-NEXT: (call $import)
+ ;; CHECK-NEXT: (br $l)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (br $__inlined_func$nondefaultable-param)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $call-nondefaultable-param
- (call $nondefaultable-param (i32.const 0) (rtt.canon $struct))
+ (call $nondefaultable-param (i32.const 0) (struct.new $struct))
)
(func $many-params (param $x i64) (param $y i32) (param $z f64)
diff --git a/test/lit/passes/local-cse_all-features.wast b/test/lit/passes/local-cse_all-features.wast
index 8ff3bc253..ff0a746d4 100644
--- a/test/lit/passes/local-cse_all-features.wast
+++ b/test/lit/passes/local-cse_all-features.wast
@@ -187,29 +187,25 @@
;; CHECK: (func $creations
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $A
+ ;; CHECK-NEXT: (struct.new $A
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (struct.new_with_rtt $A
+ ;; CHECK-NEXT: (struct.new $A
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (array.new_with_rtt $B
+ ;; CHECK-NEXT: (array.new $B
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (array.new_with_rtt $B
+ ;; CHECK-NEXT: (array.new $B
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -217,29 +213,25 @@
;; Allocating GC data has no side effects, but each allocation is unique
;; and so we cannot replace separate allocations with a single one.
(drop
- (struct.new_with_rtt $A
+ (struct.new $A
(i32.const 1)
- (rtt.canon $A)
)
)
(drop
- (struct.new_with_rtt $A
+ (struct.new $A
(i32.const 1)
- (rtt.canon $A)
)
)
(drop
- (array.new_with_rtt $B
+ (array.new $B
(i32.const 1)
(i32.const 1)
- (rtt.canon $B)
)
)
(drop
- (array.new_with_rtt $B
+ (array.new $B
(i32.const 1)
(i32.const 1)
- (rtt.canon $B)
)
)
)
diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast
index b92e976bb..c3a607d07 100644
--- a/test/lit/passes/optimize-instructions-call_ref.wast
+++ b/test/lit/passes/optimize-instructions-call_ref.wast
@@ -163,9 +163,6 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $return-nothing)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $none_=>_i32)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -178,9 +175,8 @@
;; call_ref that returns nothing with a call that returns an i32. In fact, we
;; end up optimizing the cast into an unreachable.
(call_ref
- (ref.cast
+ (ref.cast_static $none_=>_i32
(ref.func $return-nothing)
- (rtt.canon $none_=>_i32)
)
)
)
diff --git a/test/lit/passes/optimize-instructions-gc-iit.wast b/test/lit/passes/optimize-instructions-gc-iit.wast
index 4117dce19..3f0c926d3 100644
--- a/test/lit/passes/optimize-instructions-gc-iit.wast
+++ b/test/lit/passes/optimize-instructions-gc-iit.wast
@@ -33,107 +33,65 @@
(func $foo)
- ;; CHECK: (func $ref-cast-iit (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other)) (param $parent-rtt (rtt $parent)) (param $child-rtt (rtt $child)) (param $other-rtt (rtt $other))
+ ;; CHECK: (func $ref-cast-iit (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref $parent))
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $parent-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (local.get $parent)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $parent)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref $child))
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $parent-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (local.get $child)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $child)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $child
;; CHECK-NEXT: (local.get $parent)
- ;; CHECK-NEXT: (local.get $child-rtt)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref $other))
+ ;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $child)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $other-rtt)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $ref-cast-iit (type $ref|$parent|_ref|$child|_ref|$other|_rtt_$parent_rtt_$child_rtt_$other_=>_none) (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other)) (param $parent-rtt (rtt $parent)) (param $child-rtt (rtt $child)) (param $other-rtt (rtt $other))
+ ;; NOMNL: (func $ref-cast-iit (type $ref|$parent|_ref|$child|_ref|$other|_=>_none) (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref $parent))
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (local.get $parent-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (local.get $parent)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $parent)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref $child))
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (local.get $parent-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (local.get $child)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $child)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $child
;; NOMNL-NEXT: (local.get $parent)
- ;; NOMNL-NEXT: (local.get $child-rtt)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref $other))
+ ;; NOMNL-NEXT: (block
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.get $child)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (local.get $other-rtt)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-TNH: (func $ref-cast-iit (type $ref|$parent|_ref|$child|_ref|$other|_rtt_$parent_rtt_$child_rtt_$other_=>_none) (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other)) (param $parent-rtt (rtt $parent)) (param $child-rtt (rtt $child)) (param $other-rtt (rtt $other))
+ ;; NOMNL-TNH: (func $ref-cast-iit (type $ref|$parent|_ref|$child|_ref|$other|_=>_none) (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other))
;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (block (result (ref $parent))
- ;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (local.get $parent-rtt)
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: (local.get $parent)
- ;; NOMNL-TNH-NEXT: )
+ ;; NOMNL-TNH-NEXT: (local.get $parent)
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (block (result (ref $child))
- ;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (local.get $parent-rtt)
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: (local.get $child)
- ;; NOMNL-TNH-NEXT: )
+ ;; NOMNL-TNH-NEXT: (local.get $child)
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (ref.cast
+ ;; NOMNL-TNH-NEXT: (ref.cast_static $child
;; NOMNL-TNH-NEXT: (local.get $parent)
- ;; NOMNL-TNH-NEXT: (local.get $child-rtt)
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (block (result (ref $other))
+ ;; NOMNL-TNH-NEXT: (block
;; NOMNL-TNH-NEXT: (drop
;; NOMNL-TNH-NEXT: (local.get $child)
;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (local.get $other-rtt)
- ;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: (unreachable)
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: )
@@ -143,174 +101,91 @@
(param $child (ref $child))
(param $other (ref $other))
- (param $parent-rtt (rtt $parent))
- (param $child-rtt (rtt $child))
- (param $other-rtt (rtt $other))
-
- ;; a cast of parent to an rtt of parent: assuming no traps as we do, we can
- ;; optimize this as the new type will be valid.
+ ;; a cast of parent to parent. We can optimize this as the new type will be
+ ;; valid.
(drop
- (ref.cast
+ (ref.cast_static $parent
(local.get $parent)
- (local.get $parent-rtt)
)
)
;; a cast of child to a supertype: again, we replace with a valid type.
(drop
- (ref.cast
+ (ref.cast_static $parent
(local.get $child)
- (local.get $parent-rtt)
)
)
;; a cast of parent to a subtype: we cannot replace the original heap type
;; $child with one that is not equal or more specific, like $parent, so we
;; cannot optimize here.
(drop
- (ref.cast
+ (ref.cast_static $child
(local.get $parent)
- (local.get $child-rtt)
)
)
;; a cast of child to an unrelated type: it will trap anyhow
(drop
- (ref.cast
+ (ref.cast_static $other
(local.get $child)
- (local.get $other-rtt)
)
)
)
- ;; CHECK: (func $ref-cast-iit-bad (param $parent (ref $parent)) (param $parent-rtt (rtt $parent))
- ;; CHECK-NEXT: (local $2 (ref null $parent))
+ ;; CHECK: (func $ref-cast-iit-bad (param $parent (ref $parent))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block (result (ref $parent))
- ;; CHECK-NEXT: (local.set $2
- ;; CHECK-NEXT: (block $block (result (ref $parent))
- ;; CHECK-NEXT: (call $foo)
- ;; CHECK-NEXT: (local.get $parent)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (block $block0 (result (rtt $parent))
- ;; CHECK-NEXT: (call $foo)
- ;; CHECK-NEXT: (local.get $parent-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (local.get $2)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (block $block (result (ref $parent))
+ ;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (local.get $parent)
- ;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $parent
;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: (local.get $parent-rtt)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $ref-cast-iit-bad (type $ref|$parent|_rtt_$parent_=>_none) (param $parent (ref $parent)) (param $parent-rtt (rtt $parent))
- ;; NOMNL-NEXT: (local $2 (ref null $parent))
+ ;; NOMNL: (func $ref-cast-iit-bad (type $ref|$parent|_=>_none) (param $parent (ref $parent))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block (result (ref $parent))
- ;; NOMNL-NEXT: (local.set $2
- ;; NOMNL-NEXT: (block $block (result (ref $parent))
- ;; NOMNL-NEXT: (call $foo)
- ;; NOMNL-NEXT: (local.get $parent)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (block $block0 (result (rtt $parent))
- ;; NOMNL-NEXT: (call $foo)
- ;; NOMNL-NEXT: (local.get $parent-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (local.get $2)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (block $block (result (ref $parent))
+ ;; NOMNL-NEXT: (call $foo)
;; NOMNL-NEXT: (local.get $parent)
- ;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $parent
;; NOMNL-NEXT: (unreachable)
- ;; NOMNL-NEXT: (local.get $parent-rtt)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-TNH: (func $ref-cast-iit-bad (type $ref|$parent|_rtt_$parent_=>_none) (param $parent (ref $parent)) (param $parent-rtt (rtt $parent))
- ;; NOMNL-TNH-NEXT: (local $2 (ref null $parent))
+ ;; NOMNL-TNH: (func $ref-cast-iit-bad (type $ref|$parent|_=>_none) (param $parent (ref $parent))
;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (block (result (ref $parent))
- ;; NOMNL-TNH-NEXT: (local.set $2
- ;; NOMNL-TNH-NEXT: (block $block (result (ref $parent))
- ;; NOMNL-TNH-NEXT: (call $foo)
- ;; NOMNL-TNH-NEXT: (local.get $parent)
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (block $block0 (result (rtt $parent))
- ;; NOMNL-TNH-NEXT: (call $foo)
- ;; NOMNL-TNH-NEXT: (local.get $parent-rtt)
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: (ref.as_non_null
- ;; NOMNL-TNH-NEXT: (local.get $2)
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: )
- ;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (ref.cast
+ ;; NOMNL-TNH-NEXT: (block $block (result (ref $parent))
+ ;; NOMNL-TNH-NEXT: (call $foo)
;; NOMNL-TNH-NEXT: (local.get $parent)
- ;; NOMNL-TNH-NEXT: (unreachable)
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: (drop
- ;; NOMNL-TNH-NEXT: (ref.cast
+ ;; NOMNL-TNH-NEXT: (ref.cast_static $parent
;; NOMNL-TNH-NEXT: (unreachable)
- ;; NOMNL-TNH-NEXT: (local.get $parent-rtt)
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: )
;; NOMNL-TNH-NEXT: )
(func $ref-cast-iit-bad
(param $parent (ref $parent))
- (param $parent-rtt (rtt $parent))
;; optimizing this cast away requires reordering.
(drop
- (ref.cast
+ (ref.cast_static $parent
(block (result (ref $parent))
(call $foo)
(local.get $parent)
)
- (block (result (rtt $parent))
- (call $foo)
- (local.get $parent-rtt)
- )
)
)
;; ignore unreachability
(drop
- (ref.cast
- (local.get $parent)
- (unreachable)
- )
- )
- (drop
- (ref.cast
+ (ref.cast_static $parent
(unreachable)
- (local.get $parent-rtt)
)
)
)
@@ -335,9 +210,8 @@
(drop
(ref.eq
(local.get $x)
- (ref.cast
+ (ref.cast_static $parent
(local.get $x)
- (rtt.canon $parent)
)
)
)
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast
index f53237f02..f6a1b5d09 100644
--- a/test/lit/passes/optimize-instructions-gc.wast
+++ b/test/lit/passes/optimize-instructions-gc.wast
@@ -18,24 +18,26 @@
;; NOMNL: (type $A (struct_subtype (field i32) data))
(type $A (struct (field i32)))
+ ;; CHECK: (type $B (struct (field i32) (field i32) (field f32)))
+
;; 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))
- ;; CHECK: (type $empty (struct ))
+ ;; NOMNL: (type $C (struct_subtype (field i32) (field i32) (field f64) $A))
+
;; NOMNL: (type $empty (struct_subtype data))
(type $empty (struct))
;; CHECK: (type $C (struct (field i32) (field i32) (field f64)))
- ;; NOMNL: (type $C (struct_subtype (field i32) (field i32) (field f64) $A))
(type $C (struct_subtype (field i32) (field i32) (field f64) $A))
;; CHECK: (import "env" "get-i32" (func $get-i32 (result i32)))
@@ -966,12 +968,8 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $struct)
+ ;; CHECK-NEXT: (struct.new_default $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -1003,12 +1001,8 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.eq
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct
- ;; NOMNL-NEXT: (rtt.canon $struct)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct
- ;; NOMNL-NEXT: (rtt.canon $struct)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $struct)
+ ;; NOMNL-NEXT: (struct.new_default $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
@@ -1042,12 +1036,8 @@
;; allocation prevents optimization
(drop
(ref.eq
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
+ (struct.new_default $struct)
)
)
;; but irrelevant allocations do not prevent optimization
@@ -1056,17 +1046,13 @@
(block (result eqref)
;; an allocation that does not trouble us
(drop
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
(local.get $x)
)
(block (result eqref)
(drop
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
;; add a nop to make the two inputs to ref.eq not structurally equal,
;; but in a way that does not matter (since only the value falling
@@ -1091,9 +1077,8 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1102,9 +1087,8 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.eq
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1115,9 +1099,8 @@
(drop
(ref.eq
(local.get $x)
- (ref.cast
+ (ref.cast_static $struct
(local.get $x)
- (rtt.canon $struct)
)
)
)
@@ -1126,132 +1109,117 @@
;; CHECK: (func $flip-cast-of-as-non-null (param $x anyref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get_u $struct $i8
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (ref.as_func
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (ref.as_data
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (ref.as_i31
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $flip-cast-of-as-non-null (type $anyref_=>_none) (param $x anyref)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.as_non_null
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (struct.get_u $struct $i8
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (ref.as_func
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (ref.as_data
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (ref.as_i31
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $flip-cast-of-as-non-null (param $x anyref)
(drop
- (ref.cast
+ (ref.cast_static $struct
;; this can be moved through the ref.cast outward.
(ref.as_non_null
(local.get $x)
)
- (rtt.canon $struct)
)
)
(drop
;; an example of how this helps: the struct.get will trap on null anyhow
(struct.get_u $struct 0
- (ref.cast
+ (ref.cast_static $struct
;; this can be moved through the ref.cast outward.
(ref.as_non_null
(local.get $x)
)
- (rtt.canon $struct)
)
)
)
;; other ref.as* operations are ignored for now
(drop
- (ref.cast
+ (ref.cast_static $struct
(ref.as_func
(local.get $x)
)
- (rtt.canon $struct)
)
)
(drop
- (ref.cast
+ (ref.cast_static $struct
(ref.as_data
(local.get $x)
)
- (rtt.canon $struct)
)
)
(drop
- (ref.cast
+ (ref.cast_static $struct
(ref.as_i31
(local.get $x)
)
- (rtt.canon $struct)
)
)
)
@@ -1461,48 +1429,46 @@
;; CHECK: (func $ref-cast-squared (param $x eqref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $ref-cast-squared (type $eqref_=>_none) (param $x eqref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $ref-cast-squared (param $x eqref)
;; Identical ref.casts can be folded together.
(drop
- (ref.cast
- (ref.cast
+ (ref.cast_static $struct
+ (ref.cast_static $struct
(local.get $x)
- (rtt.canon $struct)
)
- (rtt.canon $struct)
)
)
)
;; CHECK: (func $ref-cast-squared-fallthrough (param $x eqref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.tee $x
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $struct)
+ ;; CHECK-NEXT: (ref.cast_static $struct
+ ;; CHECK-NEXT: (local.tee $x
+ ;; CHECK-NEXT: (ref.cast_static $struct
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $ref-cast-squared-fallthrough (type $eqref_=>_none) (param $x eqref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (local.tee $x
- ;; NOMNL-NEXT: (ref.cast
- ;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: (ref.cast_static $struct
+ ;; NOMNL-NEXT: (local.tee $x
+ ;; NOMNL-NEXT: (ref.cast_static $struct
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -1510,128 +1476,68 @@
(func $ref-cast-squared-fallthrough (param $x eqref)
;; A fallthrough in the middle does not prevent this optimization.
(drop
- (ref.cast
+ (ref.cast_static $struct
(local.tee $x
- (ref.cast
+ (ref.cast_static $struct
(local.get $x)
- (rtt.canon $struct)
)
)
- (rtt.canon $struct)
)
)
)
;; CHECK: (func $ref-cast-cubed (param $x eqref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $ref-cast-cubed (type $eqref_=>_none) (param $x eqref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $ref-cast-cubed (param $x eqref)
;; Three and more also work.
(drop
- (ref.cast
- (ref.cast
- (ref.cast
+ (ref.cast_static $struct
+ (ref.cast_static $struct
+ (ref.cast_static $struct
(local.get $x)
- (rtt.canon $struct)
)
- (rtt.canon $struct)
)
- (rtt.canon $struct)
)
)
)
;; CHECK: (func $ref-cast-squared-different (param $x eqref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
+ ;; CHECK-NEXT: (ref.cast_static $struct
+ ;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $ref-cast-squared-different (type $eqref_=>_none) (param $x eqref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
+ ;; NOMNL-NEXT: (ref.cast_static $empty
;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (rtt.canon $empty)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $ref-cast-squared-different (param $x eqref)
;; Different casts cannot be folded.
(drop
- (ref.cast
- (ref.cast
- (local.get $x)
- (rtt.canon $empty)
- )
- (rtt.canon $struct)
- )
- )
- )
- ;; CHECK: (func $ref-cast-squared-effects (param $x eqref)
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (local.get $x)
- ;; CHECK-NEXT: (call $get-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (call $get-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $ref-cast-squared-effects (type $eqref_=>_none) (param $x eqref)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
- ;; NOMNL-NEXT: (ref.cast
- ;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (call $get-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (call $get-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- (func $ref-cast-squared-effects (param $x eqref)
- ;; The rtts are equal but have side effects, preventing optimization.
- (drop
- (ref.cast
- (ref.cast
+ (ref.cast_static $struct
+ (ref.cast_static $empty
(local.get $x)
- (call $get-rtt)
)
- (call $get-rtt)
)
)
)
- ;; Helper function for above.
- ;; CHECK: (func $get-rtt (result (rtt $empty))
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $get-rtt (type $none_=>_rtt_$empty) (result (rtt $empty))
- ;; NOMNL-NEXT: (unreachable)
- ;; NOMNL-NEXT: )
- (func $get-rtt (result (rtt $empty))
- (unreachable)
- )
-
;; CHECK: (func $ref-eq-null (param $x eqref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.is_null
@@ -2024,9 +1930,6 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $array)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2037,18 +1940,14 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.get $struct)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $array)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $incompatible-cast-of-non-null (param $struct (ref $struct))
(drop
- (ref.cast
+ (ref.cast_static $array
(local.get $struct)
- (rtt.canon $array)
)
)
)
@@ -2059,9 +1958,6 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.null $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $array)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $array)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2073,9 +1969,6 @@
;; CHECK-NEXT: (ref.null $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $array)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null $array)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2087,9 +1980,6 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (ref.null $struct)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $array)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $array)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2101,9 +1991,6 @@
;; NOMNL-NEXT: (ref.null $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $array)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (ref.null $array)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2111,45 +1998,40 @@
;; NOMNL-NEXT: )
(func $incompatible-cast-of-null
(drop
- (ref.cast
+ (ref.cast_static $array
(ref.null $struct)
- (rtt.canon $array)
)
)
(drop
- (ref.cast
+ (ref.cast_static $array
;; The fallthrough is null, but the node's child's type is non-nullable,
;; so we must add a ref.as_non_null on the outside to keep the type
;; identical.
(ref.as_non_null
(ref.null $struct)
)
- (rtt.canon $array)
)
)
)
;; CHECK: (func $incompatible-cast-of-unknown (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $array
;; CHECK-NEXT: (local.get $struct)
- ;; CHECK-NEXT: (rtt.canon $array)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $incompatible-cast-of-unknown (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $array
;; NOMNL-NEXT: (local.get $struct)
- ;; NOMNL-NEXT: (rtt.canon $array)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $incompatible-cast-of-unknown (param $struct (ref null $struct))
(drop
- (ref.cast
+ (ref.cast_static $array
(local.get $struct)
- (rtt.canon $array)
)
)
)
@@ -2160,9 +2042,6 @@
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $struct)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $array)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -2173,9 +2052,6 @@
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.get $struct)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $array)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2183,70 +2059,61 @@
(func $incompatible-test (param $struct (ref null $struct))
(drop
;; This test will definitely fail, so we can turn it into 0.
- (ref.test
+ (ref.test_static $array
(local.get $struct)
- (rtt.canon $array)
)
)
)
;; CHECK: (func $subtype-compatible (param $A (ref null $A)) (param $B (ref null $B))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.test
+ ;; CHECK-NEXT: (ref.test_static $B
;; CHECK-NEXT: (local.get $A)
- ;; CHECK-NEXT: (rtt.canon $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.test
+ ;; CHECK-NEXT: (ref.test_static $A
;; CHECK-NEXT: (local.get $B)
- ;; CHECK-NEXT: (rtt.canon $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $subtype-compatible (type $ref?|$A|_ref?|$B|_=>_none) (param $A (ref null $A)) (param $B (ref null $B))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.test
+ ;; NOMNL-NEXT: (ref.test_static $B
;; NOMNL-NEXT: (local.get $A)
- ;; NOMNL-NEXT: (rtt.canon $B)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.test
+ ;; NOMNL-NEXT: (ref.test_static $A
;; NOMNL-NEXT: (local.get $B)
- ;; NOMNL-NEXT: (rtt.canon $A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $subtype-compatible (param $A (ref null $A)) (param $B (ref null $B))
(drop
;; B is a subtype of A, so this can work.
- (ref.test
+ (ref.test_static $B
(local.get $A)
- (rtt.canon $B)
)
)
(drop
;; The other direction works too.
- (ref.test
+ (ref.test_static $A
(local.get $B)
- (rtt.canon $A)
)
)
)
;; CHECK: (func $ref.test-unreachable (param $A (ref null $A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.test
+ ;; CHECK-NEXT: (ref.test_static $A
;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: (rtt.canon $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $ref.test-unreachable (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.test
+ ;; NOMNL-NEXT: (ref.test_static $A
;; NOMNL-NEXT: (unreachable)
- ;; NOMNL-NEXT: (rtt.canon $A)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -2254,42 +2121,39 @@
(drop
;; We should ignore unreachable ref.tests and not try to compare their
;; HeapTypes.
- (ref.test
+ (ref.test_static $A
(unreachable)
- (rtt.canon $A)
)
)
)
;; CHECK: (func $consecutive-opts-with-unreachable (param $func funcref)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $struct
;; CHECK-NEXT: (block (result dataref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $consecutive-opts-with-unreachable (type $funcref_=>_none) (param $func funcref)
;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $struct
;; NOMNL-NEXT: (block (result dataref)
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (local.get $func)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $consecutive-opts-with-unreachable (param $func funcref)
(drop
- (ref.cast
+ (ref.cast_static $struct
;; Casting a funcref to data will definitely fail, so this will be
;; replaced with an unreachable. But it should be enclosed in a block of
;; the previous type, so that the outside ref.cast is not confused. This
@@ -2302,7 +2166,6 @@
(ref.as_data
(local.get $func)
)
- (rtt.canon $struct)
)
)
)
diff --git a/test/lit/passes/optimize-instructions-iit-eh.wast b/test/lit/passes/optimize-instructions-iit-eh.wast
index b297cb7df..ee6b78738 100644
--- a/test/lit/passes/optimize-instructions-iit-eh.wast
+++ b/test/lit/passes/optimize-instructions-iit-eh.wast
@@ -5,33 +5,17 @@
(module
;; CHECK: (type $struct.A (struct (field i32)))
(type $struct.A (struct i32))
- ;; CHECK: (global $g-struct.A (rtt $struct.A) (rtt.canon $struct.A))
-
;; CHECK: (tag $e (param (ref null $struct.A)))
(tag $e (param (ref null $struct.A)))
- (global $g-struct.A (rtt $struct.A) (rtt.canon $struct.A))
;; CHECK: (func $ref-cast-statically-removed
- ;; CHECK-NEXT: (local $0 (ref null $struct.A))
- ;; CHECK-NEXT: (local $1 (ref null $struct.A))
;; CHECK-NEXT: (try $try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch $e
- ;; CHECK-NEXT: (local.set $1
- ;; CHECK-NEXT: (pop (ref null $struct.A))
- ;; CHECK-NEXT: )
;; CHECK-NEXT: (throw $e
- ;; CHECK-NEXT: (block (result (ref null $struct.A))
- ;; CHECK-NEXT: (local.set $0
- ;; CHECK-NEXT: (local.get $1)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (global.get $g-struct.A)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (local.get $0)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (pop (ref null $struct.A))
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -41,15 +25,14 @@
(do)
(catch $e
(throw $e
- ;; Because --ignore-implicit-traps is given, this ref.cast is assumed
- ;; not to throw so this ref.cast can be statically removed. But that
- ;; creates a block around this, making 'pop' nested into it, which is
- ;; invalid. We fix this up at the end up OptimizeInstruction,
+ ;; Because --ignore-implicit-traps is given, this ref.cast_static is
+ ;; assumed not to throw so this ref.cast can be statically removed.
+ ;; But that creates a block around this, making 'pop' nested into it,
+ ;; which is invalid. We fix this up at the end up OptimizeInstruction,
;; assigning the 'pop' to a local at the start of this 'catch' body
;; and later using 'local.get' to get it.
- (ref.cast
+ (ref.cast_static $struct.A
(pop (ref null $struct.A))
- (global.get $g-struct.A)
)
)
)
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index 14347bd3c..161b1fe07 100644
--- a/test/lit/passes/precompute-gc.wast
+++ b/test/lit/passes/precompute-gc.wast
@@ -74,9 +74,8 @@
;; CHECK: (func $load-from-struct
;; CHECK-NEXT: (local $x (ref null $struct))
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $log
@@ -85,9 +84,8 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 2)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $log
@@ -108,9 +106,8 @@
;; NOMNL: (func $load-from-struct (type $none_=>_none)
;; NOMNL-NEXT: (local $x (ref null $struct))
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (struct.new $struct
;; NOMNL-NEXT: (i32.const 1)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $log
@@ -119,9 +116,8 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (struct.new $struct
;; NOMNL-NEXT: (i32.const 2)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $log
@@ -142,9 +138,8 @@
(func $load-from-struct
(local $x (ref null $struct))
(local.set $x
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 1)
- (rtt.canon $struct)
)
)
;; we don't precompute these, as we don't know if the GC data was modified
@@ -154,9 +149,8 @@
)
;; Assign a new struct
(local.set $x
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 2)
- (rtt.canon $struct)
)
)
(call $log
@@ -176,15 +170,13 @@
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $i)
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 2)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -199,15 +191,13 @@
;; NOMNL-NEXT: (if
;; NOMNL-NEXT: (local.get $i)
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (struct.new $struct
;; NOMNL-NEXT: (i32.const 1)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (struct.new $struct
;; NOMNL-NEXT: (i32.const 2)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -223,15 +213,13 @@
(if
(local.get $i)
(local.set $x
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 1)
- (rtt.canon $struct)
)
)
(local.set $x
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 2)
- (rtt.canon $struct)
)
)
)
@@ -277,9 +265,8 @@
;; CHECK: (func $load-from-struct-bad-escape
;; CHECK-NEXT: (local $x (ref null $struct))
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $modify-gc-heap
@@ -294,9 +281,8 @@
;; NOMNL: (func $load-from-struct-bad-escape (type $none_=>_none)
;; NOMNL-NEXT: (local $x (ref null $struct))
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (struct.new $struct
;; NOMNL-NEXT: (i32.const 1)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (call $modify-gc-heap
@@ -311,9 +297,8 @@
(func $load-from-struct-bad-escape (export "test")
(local $x (ref null $struct))
(local.set $x
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 1)
- (rtt.canon $struct)
)
)
(call $modify-gc-heap
@@ -431,9 +416,8 @@
;; CHECK-NEXT: (local $y (ref null $struct))
;; CHECK-NEXT: (local $tempresult i32)
;; CHECK-NEXT: (local.set $x
- ;; CHECK-NEXT: (struct.new_with_rtt $struct
+ ;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (i32.const 1)
- ;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $y
@@ -449,9 +433,8 @@
;; NOMNL-NEXT: (local $y (ref null $struct))
;; NOMNL-NEXT: (local $tempresult i32)
;; NOMNL-NEXT: (local.set $x
- ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (struct.new $struct
;; NOMNL-NEXT: (i32.const 1)
- ;; NOMNL-NEXT: (rtt.canon $struct)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $y
@@ -467,9 +450,8 @@
(local $y (ref null $struct))
(local $tempresult i32)
(local.set $x
- (struct.new_with_rtt $struct
+ (struct.new $struct
(i32.const 1)
- (rtt.canon $struct)
)
)
(local.set $y
@@ -492,9 +474,7 @@
;; CHECK-NEXT: (local.set $tempresult
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (local.tee $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $tempref)
;; CHECK-NEXT: )
@@ -507,9 +487,7 @@
;; NOMNL-NEXT: (local.set $tempresult
;; NOMNL-NEXT: (ref.eq
;; NOMNL-NEXT: (local.tee $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.get $tempref)
;; NOMNL-NEXT: )
@@ -524,9 +502,7 @@
(ref.eq
;; allocate one struct
(local.tee $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
(local.get $tempref)
)
@@ -561,12 +537,8 @@
(local.set $tempresult
;; allocate two different structs
(ref.eq
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
+ (struct.new $empty)
)
)
(local.get $tempresult)
@@ -577,9 +549,7 @@
;; CHECK-NEXT: (local $tempref (ref null $empty))
;; CHECK-NEXT: (local.set $tempresult
;; CHECK-NEXT: (ref.eq
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: (local.get $input)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -590,9 +560,7 @@
;; NOMNL-NEXT: (local $tempref (ref null $empty))
;; NOMNL-NEXT: (local.set $tempresult
;; NOMNL-NEXT: (ref.eq
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: (local.get $input)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
@@ -605,9 +573,7 @@
;; allocate a struct and compare it to a param, which we know nothing about,
;; so we can infer nothing here at all.
(ref.eq
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
(local.get $input)
)
)
@@ -684,9 +650,7 @@
;; CHECK-NEXT: (local $tempref (ref null $empty))
;; CHECK-NEXT: (local $stashedref (ref null $empty))
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $stashedref
;; CHECK-NEXT: (local.get $tempref)
@@ -696,9 +660,7 @@
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $tempresult
@@ -714,9 +676,7 @@
;; NOMNL-NEXT: (local $tempref (ref null $empty))
;; NOMNL-NEXT: (local $stashedref (ref null $empty))
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $stashedref
;; NOMNL-NEXT: (local.get $tempref)
@@ -726,9 +686,7 @@
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $tempresult
@@ -744,9 +702,7 @@
(local $tempref (ref null $empty))
(local $stashedref (ref null $empty))
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
(local.set $stashedref
(local.get $tempref)
@@ -758,9 +714,7 @@
(i32.const 0)
)
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
)
(local.set $tempresult
@@ -777,9 +731,7 @@
;; CHECK-NEXT: (local $tempref (ref null $empty))
;; CHECK-NEXT: (local $stashedref (ref null $empty))
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $stashedref
;; CHECK-NEXT: (local.get $tempref)
@@ -792,9 +744,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: (br_if $loop
;; CHECK-NEXT: (call $helper
@@ -808,9 +758,7 @@
;; NOMNL-NEXT: (local $tempref (ref null $empty))
;; NOMNL-NEXT: (local $stashedref (ref null $empty))
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $stashedref
;; NOMNL-NEXT: (local.get $tempref)
@@ -823,9 +771,7 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (br_if $loop
;; NOMNL-NEXT: (call $helper
@@ -839,9 +785,7 @@
(local $tempref (ref null $empty))
(local $stashedref (ref null $empty))
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
(local.set $stashedref
(local.get $tempref)
@@ -856,9 +800,7 @@
)
)
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
(br_if $loop
(call $helper
@@ -873,9 +815,7 @@
;; CHECK-NEXT: (local $tempref (ref null $empty))
;; CHECK-NEXT: (local $stashedref (ref null $empty))
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $stashedref
;; CHECK-NEXT: (local.get $tempref)
@@ -896,9 +836,7 @@
;; NOMNL-NEXT: (local $tempref (ref null $empty))
;; NOMNL-NEXT: (local $stashedref (ref null $empty))
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $stashedref
;; NOMNL-NEXT: (local.get $tempref)
@@ -921,9 +859,7 @@
;; As above, but remove the new in the loop, so that each loop iteration does
;; in fact have the ref locals identical, and we can precompute a 1.
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
(local.set $stashedref
(local.get $tempref)
@@ -949,9 +885,7 @@
;; CHECK-NEXT: (local $stashedref (ref null $empty))
;; CHECK-NEXT: (loop $loop
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $stashedref
;; CHECK-NEXT: (local.get $tempref)
@@ -972,9 +906,7 @@
;; NOMNL-NEXT: (local $stashedref (ref null $empty))
;; NOMNL-NEXT: (loop $loop
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $stashedref
;; NOMNL-NEXT: (local.get $tempref)
@@ -997,9 +929,7 @@
;; Another example of a loop where we can optimize. Here the new is inside
;; the loop.
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
(local.set $stashedref
(local.get $tempref)
@@ -1028,9 +958,7 @@
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $tempref
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new_default $empty)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $stashedref
@@ -1059,9 +987,7 @@
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $tempref
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default $empty)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (local.set $stashedref
@@ -1094,9 +1020,7 @@
(i32.const 0)
)
(local.set $tempref
- (struct.new_with_rtt $empty
- (rtt.canon $empty)
- )
+ (struct.new $empty)
)
)
(local.set $stashedref
@@ -1155,9 +1079,8 @@
;; ref.cast instruction has, that is, the value is a null of type $B). So this
;; is an odd cast that "works".
(local.set $temp
- (ref.cast
+ (ref.cast_static $B
(ref.null $A)
- (rtt.canon $B)
)
)
(drop
@@ -1202,9 +1125,8 @@
;; As above, but with a tuple.
(local.set $temp
(tuple.make
- (ref.cast
+ (ref.cast_static $B
(ref.null $A)
- (rtt.canon $B)
)
(i32.const 10)
)
@@ -1230,9 +1152,8 @@
;; CHECK: (func $odd-cast-and-get-non-null (param $temp (ref $func-return-i32))
;; CHECK-NEXT: (local.set $temp
- ;; CHECK-NEXT: (ref.cast
+ ;; CHECK-NEXT: (ref.cast_static $func-return-i32
;; CHECK-NEXT: (ref.func $receive-f64)
- ;; CHECK-NEXT: (rtt.canon $func-return-i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
@@ -1243,9 +1164,8 @@
;; CHECK-NEXT: )
;; NOMNL: (func $odd-cast-and-get-non-null (type $ref|$func-return-i32|_=>_none) (param $temp (ref $func-return-i32))
;; NOMNL-NEXT: (local.set $temp
- ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.cast_static $func-return-i32
;; NOMNL-NEXT: (ref.func $receive-f64)
- ;; NOMNL-NEXT: (rtt.canon $func-return-i32)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
@@ -1257,9 +1177,8 @@
(func $odd-cast-and-get-non-null (param $temp (ref $func-return-i32))
;; Try to cast a function to an incompatible type.
(local.set $temp
- (ref.cast
+ (ref.cast_static $func-return-i32
(ref.func $receive-f64)
- (rtt.canon $func-return-i32)
)
)
(drop
@@ -1271,51 +1190,6 @@
)
)
- ;; Regression test checking that breaking RTTs are interpreted correctly.
- ;; CHECK: (func $cast-breaking-rtt
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (ref.cast
- ;; CHECK-NEXT: (struct.new_default $struct)
- ;; CHECK-NEXT: (call $unreachable-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (call $unreachable-rtt)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $cast-breaking-rtt (type $none_=>_none)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast
- ;; NOMNL-NEXT: (ref.cast
- ;; NOMNL-NEXT: (struct.new_default $struct)
- ;; NOMNL-NEXT: (call $unreachable-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (call $unreachable-rtt)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- (func $cast-breaking-rtt
- (drop
- (ref.cast
- (ref.cast
- (struct.new_default $struct)
- (call $unreachable-rtt)
- )
- (call $unreachable-rtt)
- )
- )
- )
-
- ;; CHECK: (func $unreachable-rtt (result (rtt $struct))
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $unreachable-rtt (type $none_=>_rtt_$struct) (result (rtt $struct))
- ;; NOMNL-NEXT: (unreachable)
- ;; NOMNL-NEXT: )
- (func $unreachable-rtt (result (rtt $struct))
- (unreachable)
- )
-
;; CHECK: (func $new_block_unreachable (result anyref)
;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
;; CHECK-NEXT: (drop
@@ -1323,9 +1197,6 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $new_block_unreachable (type $none_=>_anyref) (result anyref)
@@ -1335,67 +1206,20 @@
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (rtt.canon $struct)
- ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $new_block_unreachable (result anyref)
- (struct.new_with_rtt $struct
+ (struct.new $struct
;; The value is a block with an unreachable. precompute will get rid of the
;; block, after which fuzz-exec should not crash - this is a regression test
;; for us being careful in how we execute an unreachable struct.new
(block $label$1 (result i32)
(unreachable)
)
- (rtt.canon $struct)
- )
- )
-
- ;; CHECK: (func $br_on_cast-on-creation-rtt (result (ref $empty))
- ;; CHECK-NEXT: (block $label (result (ref $empty))
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (br_on_cast $label
- ;; CHECK-NEXT: (struct.new_default_with_rtt $empty
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $empty)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; NOMNL: (func $br_on_cast-on-creation-rtt (type $none_=>_ref|$empty|) (result (ref $empty))
- ;; NOMNL-NEXT: (block $label (result (ref $empty))
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (br_on_cast $label
- ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (rtt.canon $empty)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (unreachable)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- (func $br_on_cast-on-creation-rtt (result (ref $empty))
- (block $label (result (ref $empty))
- (drop
- ;; The br_on_cast will read the GC data created from struct.new, which must
- ;; emit it properly, including with an RTT which it will read from (since
- ;; this instructions uses an RTT).
- (br_on_cast $label
- (struct.new_default_with_rtt $empty
- (rtt.canon $empty)
- )
- (rtt.canon $empty)
- )
- )
- (unreachable)
)
)
- ;; CHECK: (func $br_on_cast-on-creation-nortt (result (ref $empty))
+ ;; CHECK: (func $br_on_cast-on-creation (result (ref $empty))
;; CHECK-NEXT: (block $label (result (ref $empty))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (br_on_cast_static $label $empty
@@ -1405,7 +1229,7 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $br_on_cast-on-creation-nortt (type $none_=>_ref|$empty|) (result (ref $empty))
+ ;; NOMNL: (func $br_on_cast-on-creation (type $none_=>_ref|$empty|) (result (ref $empty))
;; NOMNL-NEXT: (block $label (result (ref $empty))
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (br_on_cast_static $label $empty
@@ -1415,10 +1239,9 @@
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
- (func $br_on_cast-on-creation-nortt (result (ref $empty))
+ (func $br_on_cast-on-creation (result (ref $empty))
(block $label (result (ref $empty))
(drop
- ;; As above, but with no RTTs.
(br_on_cast_static $label $empty
(struct.new_default $empty)
)
diff --git a/test/lit/passes/remove-unused-brs-gc.wast b/test/lit/passes/remove-unused-brs-gc.wast
index 33aa08af5..eb5baa846 100644
--- a/test/lit/passes/remove-unused-brs-gc.wast
+++ b/test/lit/passes/remove-unused-brs-gc.wast
@@ -184,38 +184,6 @@
)
)
- ;; CHECK: (func $br_on_cast_dynamic (result (ref $struct))
- ;; CHECK-NEXT: (local $temp (ref null $struct))
- ;; CHECK-NEXT: (block $block (result (ref $struct))
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (br_on_cast $block
- ;; CHECK-NEXT: (struct.new_default_with_rtt $struct
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (rtt.canon $struct)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
- (func $br_on_cast_dynamic (result (ref $struct))
- (local $temp (ref null $struct))
- (block $block (result (ref $struct))
- (drop
- ;; This dynamic cast happens to be optimizable since we see both sides use
- ;; rtt.canon, but we do not inspect things that closely, and leave such
- ;; dynamic casts to runtime.
- (br_on_cast $block
- (struct.new_with_rtt $struct
- (rtt.canon $struct)
- )
- (rtt.canon $struct)
- )
- )
- (unreachable)
- )
- )
-
;; CHECK: (func $casts-are-costly (param $x i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (if (result i32)
diff --git a/test/lit/passes/roundtrip-gc-types.wast b/test/lit/passes/roundtrip-gc-types.wast
index 24d0ef40c..acbfea3a8 100644
--- a/test/lit/passes/roundtrip-gc-types.wast
+++ b/test/lit/passes/roundtrip-gc-types.wast
@@ -10,29 +10,24 @@
;; CHECK: (type $A (struct (field (ref $C))))
;; NOMNL: (type $A (struct_subtype (field (ref $C)) data))
(type $A (struct (field (ref $C))))
- ;; CHECK: (type $D (struct (field (ref $C)) (field (ref $A))))
-
;; CHECK: (type $C (struct (field (mut (ref $B)))))
;; CHECK: (type $B (func (param (ref $A)) (result (ref $B))))
- ;; NOMNL: (type $D (struct_subtype (field (ref $C)) (field (ref $A)) $A))
-
;; NOMNL: (type $C (struct_subtype (field (mut (ref $B))) data))
;; NOMNL: (type $B (func_subtype (param (ref $A)) (result (ref $B)) func))
(type $B (func (param (ref $A)) (result (ref $B))))
(type $C (struct (field (mut (ref $B)))))
+ ;; CHECK: (type $D (struct (field (ref $C)) (field (ref $A))))
+ ;; NOMNL: (type $D (struct_subtype (field (ref $C)) (field (ref $A)) $A))
(type $D (struct_subtype (field (ref $C)) (field (ref $A)) $A))
- ;; CHECK: (global $g0 (rtt 0 $A) (rtt.canon $A))
- ;; NOMNL: (global $g0 (rtt 0 $A) (rtt.canon $A))
- (global $g0 (rtt 0 $A) (rtt.canon $A))
- ;; CHECK: (global $g1 (rtt 1 $D) (rtt.sub $D
- ;; CHECK-NEXT: (global.get $g0)
- ;; CHECK-NEXT: ))
- ;; NOMNL: (global $g1 (rtt 1 $D) (rtt.sub $D
- ;; NOMNL-NEXT: (global.get $g0)
- ;; NOMNL-NEXT: ))
- (global $g1 (rtt 1 $D) (rtt.sub $D
- (global.get $g0)
- ))
+ ;; CHECK: (func $use-types (param $0 (ref $A)) (param $1 (ref $D))
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ ;; NOMNL: (func $use-types (type $ref|$A|_ref|$D|_=>_none) (param $0 (ref $A)) (param $1 (ref $D))
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
+ (func $use-types (param (ref $A) (ref $D))
+ (nop)
+ )
)
diff --git a/test/lit/passes/roundtrip-gc.wast b/test/lit/passes/roundtrip-gc.wast
index 2fb5d57b2..cc38de819 100644
--- a/test/lit/passes/roundtrip-gc.wast
+++ b/test/lit/passes/roundtrip-gc.wast
@@ -9,7 +9,7 @@
(export "export" (func $test))
;; CHECK: (func $test
;; CHECK-NEXT: (call $help
- ;; CHECK-NEXT: (rtt.canon $\7bi32\7d)
+ ;; CHECK-NEXT: (struct.new_default $\7bi32\7d)
;; CHECK-NEXT: (block $label$1 (result i32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (i32.const 1)
@@ -18,7 +18,7 @@
;; CHECK-NEXT: )
;; NOMNL: (func $test (type $none_=>_none)
;; NOMNL-NEXT: (call $help
- ;; NOMNL-NEXT: (rtt.canon $\7bi32\7d)
+ ;; NOMNL-NEXT: (struct.new_default $\7bi32\7d)
;; NOMNL-NEXT: (block $label$1 (result i32)
;; NOMNL-NEXT: (nop)
;; NOMNL-NEXT: (i32.const 1)
@@ -27,25 +27,27 @@
;; NOMNL-NEXT: )
(func $test
(call $help
- (rtt.canon ${i32})
+ (struct.new_default ${i32})
;; Stack IR optimizations can remove this block, leaving a nop in an odd
;; "stacky" location. On load, we would normally use a local to work around
- ;; that, creating a block to contain the rtt before us and the nop, and then
- ;; returning the local. But we can't use a local for an rtt, so we should not
- ;; optimize this sort of thing in stack IR.
+ ;; that, creating a block to contain the non-nullable reference before us and
+ ;; the nop, and then returning the local. But we can't use a local for a
+ ;; non-nullable reference, so we should not optimize this sort of thing in
+ ;; stack IR.
+ ;; TODO: This shouldn't be true after #4824 is resolved.
(block (result i32)
(nop)
(i32.const 1)
)
)
)
- ;; CHECK: (func $help (param $3 (rtt $\7bi32\7d)) (param $4 i32)
+ ;; CHECK: (func $help (param $3 (ref $\7bi32\7d)) (param $4 i32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- ;; NOMNL: (func $help (type $rtt_$\7bi32\7d_i32_=>_none) (param $3 (rtt $\7bi32\7d)) (param $4 i32)
+ ;; NOMNL: (func $help (type $ref|$\7bi32\7d|_i32_=>_none) (param $3 (ref $\7bi32\7d)) (param $4 i32)
;; NOMNL-NEXT: (nop)
;; NOMNL-NEXT: )
- (func $help (param $3 (rtt ${i32})) (param $4 i32)
+ (func $help (param $3 (ref ${i32})) (param $4 i32)
(nop)
)
)
diff --git a/test/lit/passes/vacuum-gc.wast b/test/lit/passes/vacuum-gc.wast
index 71f0e39c2..57b298443 100644
--- a/test/lit/passes/vacuum-gc.wast
+++ b/test/lit/passes/vacuum-gc.wast
@@ -51,39 +51,31 @@
)
)
- ;; CHECK: (func $vacuum-rtt-with-depth
+ ;; CHECK: (func $vacuum-nonnull
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- (func $vacuum-rtt-with-depth
+ (func $vacuum-nonnull
(drop
- (if (result (rtt 1 ${}))
+ (if (result (ref ${}))
(i32.const 1)
;; This block's result is not used. As a consequence vacuum will try to
- ;; generate a replacement zero for the block's fallthrough value. An rtt
- ;; with depth is a problem for that, since we can't just create an
- ;; rtt.canon - we'd need to add some rtt.subs, and it's not clear that we'd
- ;; be improving code size while doing so, hence we do not allow making a
- ;; zero of that type. Vacuum should not error on trying to do so. And
- ;; the end result of this function should simply be empty, as everything
- ;; here can be vacuumed away.
- (block (result (rtt 1 ${}))
- (rtt.sub ${}
- (rtt.canon ${})
- )
+ ;; generate a replacement zero for the block's fallthrough value. A
+ ;; non-nullable reference is a problem for that, since we don't want to
+ ;; synthesize and allocate a new struct value. Vacuum should not error
+ ;; on this case, though. Instead, the end result of this function should
+ ;; simply be empty, as everything here can be vacuumed away.
+ (block (result (ref ${}))
+ (struct.new ${})
)
(unreachable)
)
)
)
- ;; CHECK: (func $drop-i31.get (param $ref (ref null i31)) (param $ref-nn i31ref)
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (i31.get_s
- ;; CHECK-NEXT: (local.get $ref)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: )
+ ;; CHECK: (func $drop-i31.get (param $ref i31ref) (param $ref-nn i31ref)
+ ;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- (func $drop-i31.get (param $ref (ref null i31)) (param $ref-nn (ref i31))
+ (func $drop-i31.get (param $ref i31ref) (param $ref-nn (ref i31))
;; A nullable get might trap, so only the second item can be removed.
(drop
(i31.get_s
diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt
index 14ef78a8c..410bf37c1 100644
--- a/test/passes/Oz_fuzz-exec_all-features.txt
+++ b/test/passes/Oz_fuzz-exec_all-features.txt
@@ -9,18 +9,8 @@
[LoggingExternalInterface logging 128]
[LoggingExternalInterface logging -128]
[LoggingExternalInterface logging 42]
-[fuzz-exec] calling rtts
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
[fuzz-exec] calling br_on_cast
[LoggingExternalInterface logging 3]
-[trap unreachable]
[fuzz-exec] calling br_on_failed_cast-1
[LoggingExternalInterface logging 1]
[fuzz-exec] calling br_on_failed_cast-2
@@ -44,12 +34,10 @@
[fuzz-exec] calling ref-as-func-of-data
[trap not a func]
[fuzz-exec] calling ref-as-func-of-func
-[fuzz-exec] calling rtt-and-cast-on-func
+[fuzz-exec] calling cast-on-func
[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 2]
[LoggingExternalInterface logging 1337]
-[LoggingExternalInterface logging 3]
+[LoggingExternalInterface logging 1]
[trap cast error]
[fuzz-exec] calling array-alloc-failure
[host limit allocation failure]
@@ -63,10 +51,6 @@
[LoggingExternalInterface logging 99]
[LoggingExternalInterface logging 0]
[LoggingExternalInterface logging 10]
-[fuzz-exec] calling rtt_Fresh
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
[fuzz-exec] calling array.init
[LoggingExternalInterface logging 2]
[LoggingExternalInterface logging 42]
@@ -79,7 +63,7 @@
[LoggingExternalInterface logging 0]
[LoggingExternalInterface logging 1]
[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 0]
+[LoggingExternalInterface logging 1]
[fuzz-exec] calling static-br_on_cast
[LoggingExternalInterface logging 3]
[fuzz-exec] calling static-br_on_cast_fail
@@ -87,41 +71,38 @@
(module
(type $void_func (func))
(type $bytes (array (mut i8)))
- (type $extendedstruct (struct (field (mut i32)) (field f64)))
(type $struct (struct (field (mut i32))))
(type $i32_=>_none (func (param i32)))
+ (type $extendedstruct (struct (field (mut i32)) (field f64)))
(type $anyref_=>_none (func (param anyref)))
(type $int_func (func (result i32)))
(import "fuzzing-support" "log-i32" (func $log (param i32)))
- (global $rtt (mut (rtt $extendedstruct)) (rtt.canon $extendedstruct))
(export "structs" (func $0))
(export "arrays" (func $1))
- (export "rtts" (func $2))
- (export "br_on_cast" (func $3))
- (export "br_on_failed_cast-1" (func $4))
- (export "br_on_failed_cast-2" (func $5))
- (export "cast-null-anyref-to-gc" (func $6))
- (export "br_on_data" (func $8))
- (export "br_on_non_data-null" (func $9))
- (export "br_on_non_data-data" (func $10))
- (export "br_on_non_data-other" (func $9))
- (export "br-on_non_null" (func $9))
- (export "br-on_non_null-2" (func $13))
- (export "ref-as-data-of-func" (func $14))
- (export "ref-as-data-of-data" (func $9))
- (export "ref-as-func-of-data" (func $14))
- (export "ref-as-func-of-func" (func $9))
- (export "rtt-and-cast-on-func" (func $19))
- (export "array-alloc-failure" (func $9))
- (export "init-array-packed" (func $21))
- (export "cast-func-to-struct" (func $14))
- (export "array-copy" (func $24))
- (export "rtt_Fresh" (func $25))
- (export "array.init" (func $26))
- (export "array.init-packed" (func $27))
- (export "static-casts" (func $28))
- (export "static-br_on_cast" (func $29))
- (export "static-br_on_cast_fail" (func $30))
+ (export "br_on_cast" (func $2))
+ (export "br_on_failed_cast-1" (func $3))
+ (export "br_on_failed_cast-2" (func $4))
+ (export "cast-null-anyref-to-gc" (func $5))
+ (export "br_on_data" (func $7))
+ (export "br_on_non_data-null" (func $8))
+ (export "br_on_non_data-data" (func $9))
+ (export "br_on_non_data-other" (func $8))
+ (export "br-on_non_null" (func $8))
+ (export "br-on_non_null-2" (func $12))
+ (export "ref-as-data-of-func" (func $13))
+ (export "ref-as-data-of-data" (func $8))
+ (export "ref-as-func-of-data" (func $13))
+ (export "ref-as-func-of-func" (func $8))
+ (export "cast-on-func" (func $18))
+ (export "array-alloc-failure" (func $8))
+ (export "init-array-packed" (func $20))
+ (export "cast-func-to-struct" (func $13))
+ (export "array-copy" (func $23))
+ (export "array.init" (func $24))
+ (export "array.init-packed" (func $25))
+ (export "static-casts" (func $26))
+ (export "static-br_on_cast" (func $2))
+ (export "static-br_on_cast_fail" (func $28))
(func $0 (; has Stack IR ;)
(local $0 i32)
(call $log
@@ -144,10 +125,9 @@
(call $log
(array.len $bytes
(local.tee $0
- (array.new_with_rtt $bytes
+ (array.new $bytes
(i32.const 42)
(i32.const 50)
- (rtt.canon $bytes)
)
)
)
@@ -184,42 +164,13 @@
)
(func $2 (; has Stack IR ;)
(call $log
- (i32.const 1)
- )
- (call $log
- (i32.const 0)
- )
- (call $log
- (i32.const 0)
- )
- (call $log
- (i32.const 1)
- )
- (call $log
- (i32.const 0)
- )
- (call $log
- (i32.const 1)
- )
- (call $log
- (i32.const 0)
- )
- (call $log
- (i32.const 1)
- )
- )
- (func $3 (; has Stack IR ;)
- (call $log
(i32.const 3)
)
- (unreachable)
)
- (func $4 (; has Stack IR ;)
+ (func $3 (; has Stack IR ;)
(local $0 (ref null $struct))
(local.set $0
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
(drop
(block $any (result anyref)
@@ -227,9 +178,8 @@
(i32.const 1)
)
(drop
- (br_on_cast_fail $any
+ (br_on_cast_static_fail $any $extendedstruct
(local.get $0)
- (rtt.canon $extendedstruct)
)
)
(call $log
@@ -239,7 +189,7 @@
)
)
)
- (func $5 (; has Stack IR ;)
+ (func $4 (; has Stack IR ;)
(call $log
(i32.const 1)
)
@@ -247,12 +197,12 @@
(i32.const 999)
)
)
- (func $6 (; has Stack IR ;)
+ (func $5 (; has Stack IR ;)
(call $log
(i32.const 0)
)
)
- (func $8 (; has Stack IR ;) (param $0 anyref)
+ (func $7 (; has Stack IR ;) (param $0 anyref)
(drop
(block $data (result dataref)
(drop
@@ -263,21 +213,19 @@
(call $log
(i32.const 1)
)
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
)
)
- (func $9 (; has Stack IR ;)
+ (func $8 (; has Stack IR ;)
(nop)
)
- (func $10 (; has Stack IR ;)
+ (func $9 (; has Stack IR ;)
(call $log
(i32.const 1)
)
)
- (func $13 (; has Stack IR ;)
+ (func $12 (; has Stack IR ;)
(drop
(block
(call $log
@@ -287,47 +235,39 @@
)
)
)
- (func $14 (; has Stack IR ;)
+ (func $13 (; has Stack IR ;)
(drop
(unreachable)
)
)
- (func $19 (; has Stack IR ;)
+ (func $18 (; has Stack IR ;)
(call $log
(i32.const 0)
)
(call $log
- (i32.const 1)
- )
- (call $log
- (i32.const 2)
- )
- (call $log
(i32.const 1337)
)
(call $log
- (i32.const 3)
+ (i32.const 1)
)
(unreachable)
)
- (func $21 (; has Stack IR ;) (result i32)
+ (func $20 (; has Stack IR ;) (result i32)
(array.get_u $bytes
- (array.new_with_rtt $bytes
+ (array.new $bytes
(i32.const -43)
(i32.const 50)
- (rtt.canon $bytes)
)
(i32.const 10)
)
)
- (func $24 (; has Stack IR ;)
+ (func $23 (; has Stack IR ;)
(local $0 (ref null $bytes))
(local $1 (ref null $bytes))
(array.set $bytes
(local.tee $1
- (array.new_default_with_rtt $bytes
+ (array.new_default $bytes
(i32.const 200)
- (rtt.canon $bytes)
)
)
(i32.const 42)
@@ -336,10 +276,9 @@
(call $log
(array.get_u $bytes
(local.tee $0
- (array.new_with_rtt $bytes
+ (array.new $bytes
(i32.const 10)
(i32.const 100)
- (rtt.canon $bytes)
)
)
(i32.const 10)
@@ -377,36 +316,14 @@
)
)
)
- (func $25 (; has Stack IR ;)
- (call $log
- (i32.const 1)
- )
- (call $log
- (i32.const 0)
- )
- (global.set $rtt
- (rtt.fresh_sub $extendedstruct
- (rtt.canon $struct)
- )
- )
- (call $log
- (ref.test
- (struct.new_default_with_rtt $extendedstruct
- (global.get $rtt)
- )
- (global.get $rtt)
- )
- )
- )
- (func $26 (; has Stack IR ;)
+ (func $24 (; has Stack IR ;)
(local $0 (ref null $bytes))
(call $log
(array.len $bytes
(local.tee $0
- (array.init $bytes
+ (array.init_static $bytes
(i32.const 42)
(i32.const 50)
- (rtt.canon $bytes)
)
)
)
@@ -424,18 +341,17 @@
)
)
)
- (func $27 (; has Stack IR ;)
+ (func $25 (; has Stack IR ;)
(call $log
(array.get_u $bytes
- (array.init $bytes
+ (array.init_static $bytes
(i32.const -11512)
- (rtt.canon $bytes)
)
(i32.const 0)
)
)
)
- (func $28 (; has Stack IR ;)
+ (func $26 (; has Stack IR ;)
(call $log
(i32.const 1)
)
@@ -455,12 +371,7 @@
(i32.const 1)
)
)
- (func $29 (; has Stack IR ;)
- (call $log
- (i32.const 3)
- )
- )
- (func $30 (; has Stack IR ;)
+ (func $28 (; has Stack IR ;)
(call $log
(i32.const -2)
)
@@ -477,18 +388,8 @@
[LoggingExternalInterface logging 128]
[LoggingExternalInterface logging -128]
[LoggingExternalInterface logging 42]
-[fuzz-exec] calling rtts
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
[fuzz-exec] calling br_on_cast
[LoggingExternalInterface logging 3]
-[trap unreachable]
[fuzz-exec] calling br_on_failed_cast-1
[LoggingExternalInterface logging 1]
[fuzz-exec] calling br_on_failed_cast-2
@@ -512,12 +413,10 @@
[fuzz-exec] calling ref-as-func-of-data
[trap unreachable]
[fuzz-exec] calling ref-as-func-of-func
-[fuzz-exec] calling rtt-and-cast-on-func
+[fuzz-exec] calling cast-on-func
[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 2]
[LoggingExternalInterface logging 1337]
-[LoggingExternalInterface logging 3]
+[LoggingExternalInterface logging 1]
[trap unreachable]
[fuzz-exec] calling array-alloc-failure
[fuzz-exec] calling init-array-packed
@@ -530,10 +429,6 @@
[LoggingExternalInterface logging 99]
[LoggingExternalInterface logging 0]
[LoggingExternalInterface logging 10]
-[fuzz-exec] calling rtt_Fresh
-[LoggingExternalInterface logging 1]
-[LoggingExternalInterface logging 0]
-[LoggingExternalInterface logging 1]
[fuzz-exec] calling array.init
[LoggingExternalInterface logging 2]
[LoggingExternalInterface logging 42]
diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast
index 7ab9116dd..c8ad3700a 100644
--- a/test/passes/Oz_fuzz-exec_all-features.wast
+++ b/test/passes/Oz_fuzz-exec_all-features.wast
@@ -8,15 +8,11 @@
(import "fuzzing-support" "log-i32" (func $log (param i32)))
- (global $rtt (mut (rtt $extendedstruct)) (rtt.canon $extendedstruct))
-
(func "structs"
(local $x (ref null $struct))
(local $y (ref null $struct))
(local.set $x
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
;; The value is initialized to 0
;; Note: We cannot optimize these to constants without either immutability or
@@ -49,10 +45,9 @@
(func "arrays"
(local $x (ref null $bytes))
(local.set $x
- (array.new_with_rtt $bytes
+ (array.new $bytes
(i32.const 42) ;; value to splat into the array
(i32.const 50) ;; size
- (rtt.canon $bytes)
)
)
;; The length should be 50
@@ -77,78 +72,11 @@
(array.get_s $bytes (local.get $x) (i32.const 20))
)
)
- (func "rtts"
- (local $any anyref)
- ;; Casting null returns null.
- (call $log (ref.is_null
- (ref.cast (ref.null $struct) (rtt.canon $struct))
- ))
- ;; Testing null returns 0.
- (call $log
- (ref.test (ref.null $struct) (rtt.canon $struct))
- )
- ;; Testing something completely wrong (struct vs array) returns 0.
- (call $log
- (ref.test
- (array.new_with_rtt $bytes
- (i32.const 20)
- (i32.const 10)
- (rtt.canon $bytes)
- )
- (rtt.canon $struct)
- )
- )
- ;; Testing a thing with the same RTT returns 1.
- (call $log
- (ref.test
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
- (rtt.canon $struct)
- )
- )
- ;; A bad downcast returns 0: we create a struct, which is not a extendedstruct.
- (call $log
- (ref.test
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
- (rtt.canon $extendedstruct)
- )
- )
- ;; Create a extendedstruct with RTT y, and upcast statically to anyref.
- (local.set $any
- (struct.new_default_with_rtt $extendedstruct
- (rtt.sub $extendedstruct (rtt.canon $struct))
- )
- )
- ;; Casting to y, the exact same RTT, works.
- (call $log
- (ref.test
- (local.get $any)
- (rtt.sub $extendedstruct (rtt.canon $struct))
- )
- )
- ;; Casting to z, another RTT of the same data type, fails.
- (call $log
- (ref.test
- (local.get $any)
- (rtt.canon $extendedstruct)
- )
- )
- ;; Casting to x, the parent of y, works.
- (call $log
- (ref.test
- (local.get $any)
- (rtt.canon $struct)
- )
- )
- )
(func "br_on_cast"
(local $any anyref)
;; create a simple $struct, store it in an anyref
(local.set $any
- (struct.new_default_with_rtt $struct (rtt.canon $struct))
+ (struct.new_default $struct)
)
(drop
(block $block (result ($ref $struct))
@@ -156,12 +84,11 @@
(block $extendedblock (result (ref $extendedstruct))
(drop
;; second, try to cast our simple $struct to what it is, which will work
- (br_on_cast $block
+ (br_on_cast_static $block $struct
;; first, try to cast our simple $struct to an extended, which will fail
- (br_on_cast $extendedblock
- (local.get $any) (rtt.canon $extendedstruct)
+ (br_on_cast_static $extendedblock $extendedstruct
+ (local.get $any)
)
- (rtt.canon $struct)
)
)
(call $log (i32.const -1)) ;; we should never get here
@@ -173,20 +100,12 @@
)
)
(call $log (i32.const 3)) ;; we should get here
- (drop
- (block $never (result (ref $extendedstruct))
- ;; an untaken br_on_cast, with unreachable rtt - so we cannot use the
- ;; RTT in binaryen IR to find the cast type.
- (br_on_cast $never (ref.null $struct) (unreachable))
- (unreachable)
- )
- )
)
(func "br_on_failed_cast-1"
(local $any anyref)
;; create a simple $struct, store it in an anyref
(local.set $any
- (struct.new_default_with_rtt $struct (rtt.canon $struct))
+ (struct.new_default $struct)
)
(drop
(block $any (result (ref null any))
@@ -194,9 +113,8 @@
(drop
;; try to cast our simple $struct to an extended, which will fail, and
;; so we will branch, skipping the next logging.
- (br_on_cast_fail $any
+ (br_on_cast_static_fail $any $extendedstruct
(local.get $any)
- (rtt.canon $extendedstruct)
)
)
(call $log (i32.const 999)) ;; we should skip this
@@ -208,7 +126,7 @@
(local $any anyref)
;; create an $extendedstruct, store it in an anyref
(local.set $any
- (struct.new_default_with_rtt $extendedstruct (rtt.canon $extendedstruct))
+ (struct.new_default $extendedstruct)
)
(drop
(block $any (result (ref null any))
@@ -216,9 +134,8 @@
(drop
;; try to cast our simple $struct to an extended, which will succeed, and
;; so we will continue to the next logging.
- (br_on_cast_fail $any
+ (br_on_cast_static_fail $any $extendedstruct
(local.get $any)
- (rtt.canon $extendedstruct)
)
)
(call $log (i32.const 999))
@@ -231,16 +148,13 @@
;; array or a struct, so our casting code should not assume it is. it is ok
;; to try to cast it, and the result should be 0.
(call $log
- (ref.test
+ (ref.test_static $struct
(ref.null any)
- (rtt.canon $struct)
)
)
)
(func $get_data (result dataref)
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
(func "br_on_data" (param $x anyref)
(local $y anyref)
@@ -272,9 +186,7 @@
(local $x anyref)
;; set x to valid data
(local.set $x
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
(drop
(block $any (result anyref)
@@ -336,9 +248,7 @@
(func "ref-as-data-of-data"
(drop
(ref.as_data
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
)
)
@@ -346,9 +256,7 @@
(drop
;; This should trap.
(ref.as_func
- (struct.new_default_with_rtt $struct
- (rtt.canon $struct)
- )
+ (struct.new_default $struct)
)
)
)
@@ -362,43 +270,33 @@
(func $a-void-func
(call $log (i32.const 1337))
)
- (func "rtt-and-cast-on-func"
+ (func "cast-on-func"
(call $log (i32.const 0))
- (drop
- (rtt.canon $void_func)
- )
- (call $log (i32.const 1))
- (drop
- (rtt.canon $int_func)
- )
- (call $log (i32.const 2))
;; a valid cast
(call_ref
- (ref.cast (ref.func $a-void-func) (rtt.canon $void_func))
+ (ref.cast_static $void_func (ref.func $a-void-func))
)
- (call $log (i32.const 3))
+ (call $log (i32.const 1))
;; an invalid cast
(drop (call_ref
- (ref.cast (ref.func $a-void-func) (rtt.canon $int_func))
+ (ref.cast_static $int_func (ref.func $a-void-func))
))
;; will never be reached
- (call $log (i32.const 4))
+ (call $log (i32.const 2))
)
(func "array-alloc-failure"
(drop
- (array.new_default_with_rtt $bytes
+ (array.new_default $bytes
(i32.const -1) ;; un-allocatable size (4GB * sizeof(Literal))
- (rtt.canon $bytes)
)
)
)
(func "init-array-packed" (result i32)
(local $x (ref null $bytes))
(local.set $x
- (array.new_with_rtt $bytes
+ (array.new $bytes
(i32.const -43) ;; initialize the i8 values with a negative i32
(i32.const 50)
- (rtt.canon $bytes)
)
)
;; read the value, which should be -43 & 255 ==> 213
@@ -413,9 +311,8 @@
(func "cast-func-to-struct"
(drop
;; An impossible cast of a function to a struct, which should fail.
- (ref.cast
+ (ref.cast_static $struct
(ref.func $call-target)
- (rtt.canon $struct)
)
)
)
@@ -424,17 +321,15 @@
(local $y (ref null $bytes))
;; Create an array of 10's, of size 100.
(local.set $x
- (array.new_with_rtt $bytes
+ (array.new $bytes
(i32.const 10)
(i32.const 100)
- (rtt.canon $bytes)
)
)
;; Create an array of zeros of size 200, and also set one index there.
(local.set $y
- (array.new_default_with_rtt $bytes
+ (array.new_default $bytes
(i32.const 200)
- (rtt.canon $bytes)
)
)
(array.set $bytes
@@ -467,55 +362,12 @@
(array.get_u $bytes (local.get $x) (i32.const 12))
)
)
- (func "rtt_Fresh"
- ;; Casting to the same sequence of rtt.subs works.
- (call $log
- (ref.test
- (struct.new_default_with_rtt $extendedstruct
- (rtt.sub $extendedstruct
- (rtt.canon $struct)
- )
- )
- (rtt.sub $extendedstruct
- (rtt.canon $struct)
- )
- )
- )
- ;; But not with fresh!
- (call $log
- (ref.test
- (struct.new_default_with_rtt $extendedstruct
- (rtt.sub $extendedstruct
- (rtt.canon $struct)
- )
- )
- (rtt.fresh_sub $extendedstruct
- (rtt.canon $struct)
- )
- )
- )
- ;; Casts with fresh succeed, if we use the same fresh rtt.
- (global.set $rtt
- (rtt.fresh_sub $extendedstruct
- (rtt.canon $struct)
- )
- )
- (call $log
- (ref.test
- (struct.new_default_with_rtt $extendedstruct
- (global.get $rtt)
- )
- (global.get $rtt)
- )
- )
- )
(func "array.init"
(local $x (ref null $bytes))
(local.set $x
- (array.init $bytes
+ (array.init_static $bytes
(i32.const 42) ;; first value
(i32.const 50) ;; second value
- (rtt.canon $bytes)
)
)
;; The length should be 2
@@ -534,9 +386,8 @@
(func "array.init-packed"
(local $x (ref null $bytes))
(local.set $x
- (array.init $bytes
+ (array.init_static $bytes
(i32.const -11512)
- (rtt.canon $bytes)
)
)
;; The value should be be -11512 & 255 => 8
@@ -574,9 +425,7 @@
(struct.new_default $struct)
)
)
- ;; Casting to a supertype does not work because the canonical RTT for the
- ;; subtype is not a sub-rtt of the canonical RTT of the supertype in
- ;; structural mode.
+ ;; Casting to a supertype works.
(call $log
(ref.test_static $struct
(struct.new_default $extendedstruct)
@@ -641,9 +490,8 @@
;; opts the unused value is removed so there is no trap, and a value is
;; returned, which should not confuse the fuzzer.
(drop
- (array.new_default_with_rtt $[mut:i8]
+ (array.new_default $[mut:i8]
(i32.const -1)
- (rtt.canon $[mut:i8])
)
)
(i32.const 0)
diff --git a/test/passes/remove-unused-brs_all-features.txt b/test/passes/remove-unused-brs_all-features.txt
index abfcc3e76..631c4ffe3 100644
--- a/test/passes/remove-unused-brs_all-features.txt
+++ b/test/passes/remove-unused-brs_all-features.txt
@@ -13,12 +13,10 @@
(func $foo (result (ref null $struct))
(if (result (ref null $struct))
(i32.const 1)
- (struct.new_with_rtt $struct
- (array.new_default_with_rtt $vector
+ (struct.new $struct
+ (array.new_default $vector
(i32.const 1)
- (rtt.canon $vector)
)
- (rtt.canon $struct)
)
(ref.null $struct)
)
@@ -88,18 +86,16 @@
(block $data (result (ref $vector))
(drop
(br $data
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 1)
- (rtt.canon $vector)
)
)
)
(call $log
(i32.const 5)
)
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 2)
- (rtt.canon $vector)
)
)
)
@@ -160,9 +156,8 @@
(drop
(block $func (result funcref)
(drop
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 2)
- (rtt.canon $vector)
)
)
(ref.null func)
@@ -181,9 +176,8 @@
(drop
(block $i31 (result (ref null i31))
(drop
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 2)
- (rtt.canon $vector)
)
)
(ref.null i31)
diff --git a/test/passes/remove-unused-brs_all-features.wast b/test/passes/remove-unused-brs_all-features.wast
index 9614f7f5c..56a6ab98f 100644
--- a/test/passes/remove-unused-brs_all-features.wast
+++ b/test/passes/remove-unused-brs_all-features.wast
@@ -5,14 +5,12 @@
(func $foo (result (ref null $struct))
(if (result (ref null $struct))
(i32.const 1)
- (struct.new_with_rtt $struct
+ (struct.new $struct
;; regression test for computing the cost of an array.new_default, which
;; lacks the optional field "init"
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 1)
- (rtt.canon $vector)
)
- (rtt.canon $struct)
)
(ref.null $struct)
)
@@ -81,16 +79,14 @@
;; a non-null data reference means we always take the br
(drop
(br_on_data $data
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 1)
- (rtt.canon $vector)
)
)
)
(call $log (i32.const 5))
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 2)
- (rtt.canon $vector)
)
)
)
@@ -147,9 +143,8 @@
(block $func (result (ref null func))
(drop
(br_on_func $func
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 2)
- (rtt.canon $vector)
)
)
)
@@ -171,9 +166,8 @@
(block $i31 (result (ref null i31))
(drop
(br_on_i31 $i31
- (array.new_default_with_rtt $vector
+ (array.new_default $vector
(i32.const 2)
- (rtt.canon $vector)
)
)
)
diff --git a/test/passes/vacuum_all-features.wast b/test/passes/vacuum_all-features.wast
index 8a6d52022..1dbb6e39b 100644
--- a/test/passes/vacuum_all-features.wast
+++ b/test/passes/vacuum_all-features.wast
@@ -805,9 +805,7 @@
;; nullable reference type and we don't have a type to put in its place, so
;; don't try to replace it. (later operations will remove all the body of
;; this function; this test verifies we don't crash along the way)
- (struct.new_default_with_rtt $A
- (rtt.canon $A)
- )
+ (struct.new_default $A)
)
)
)
diff --git a/test/spec/array.wast b/test/spec/array.wast
index 243431319..fd151669e 100644
--- a/test/spec/array.wast
+++ b/test/spec/array.wast
@@ -1,5 +1,3 @@
-;; XXX BINARYEN: rename array.new_default => array.new_default_with_rtt
-
;; Type syntax
(module
@@ -13,8 +11,6 @@
(type (array (ref data)))
(type (array (ref 0)))
(type (array (ref null 1)))
- (type (array (rtt 1)))
- (type (array (rtt 10 1)))
(type (array (mut i8)))
(type (array (mut i16)))
(type (array (mut i32)))
@@ -25,8 +21,6 @@
(type (array (mut (ref data))))
(type (array (mut (ref 0))))
(type (array (mut (ref null i31))))
- (type (array (mut (rtt 0))))
- (type (array (mut (rtt 10 0))))
)
@@ -70,7 +64,7 @@
)
(func (export "get") (param $i i32) (result f32)
(call $get (local.get $i)
- (array.new_default_with_rtt $vec (i32.const 3) (rtt.canon $vec))
+ (array.new_default $vec (i32.const 3))
)
)
@@ -80,7 +74,7 @@
)
(func (export "set_get") (param $i i32) (param $y f32) (result f32)
(call $set_get (local.get $i)
- (array.new_default_with_rtt $mvec (i32.const 3) (rtt.canon $mvec))
+ (array.new_default $mvec (i32.const 3))
(local.get $y)
)
)
@@ -89,7 +83,7 @@
(array.len $vec (local.get $v))
)
(func (export "len") (result i32)
- (call $len (array.new_default_with_rtt $vec (i32.const 3) (rtt.canon $vec)))
+ (call $len (array.new_default $vec (i32.const 3)))
)
)
@@ -130,16 +124,8 @@
(module
(type $t (array i32))
(func (export "array.new-null")
- (local (ref null (rtt $t))) (drop (array.new_default_with_rtt $t (i32.const 1) (i32.const 3) (local.get 0)))
- )
- )
- "type mismatch"
-)
-(assert_invalid
- (module
- (type $t (array (mut i32)))
- (func (export "array.new_default_with_rtt-null")
- (local (ref null (rtt $t))) (drop (array.new_default_with_rtt $t (i32.const 3) (local.get 0)))
+ (local i64)
+ (drop (array.new_default $t (local.get 0)))
)
)
"type mismatch"
diff --git a/test/spec/ref_cast.wast b/test/spec/ref_cast.wast
index 8712e5954..1af96d9d4 100644
--- a/test/spec/ref_cast.wast
+++ b/test/spec/ref_cast.wast
@@ -6,15 +6,6 @@
(type $t2' (struct (field i32) (field i32)))
(type $t3 (struct (field i32) (field i32)))
- (global $t0 (rtt $t0) (rtt.canon $t0))
- (global $t0' (rtt $t0) (rtt.canon $t0))
- (global $t1 (rtt $t1) (rtt.sub $t1 (global.get $t0)))
- (global $t1' (rtt $t1') (rtt.sub $t1' (global.get $t0)))
- (global $t2 (rtt $t2) (rtt.sub $t2 (global.get $t1)))
- (global $t2' (rtt $t2') (rtt.sub $t2' (global.get $t1')))
- (global $t3 (rtt $t3) (rtt.sub $t3 (global.get $t0)))
- (global $t4 (rtt $t3) (rtt.sub $t3 (rtt.sub $t0 (global.get $t0))))
-
(global $tab.0 (mut (ref null data)) (ref.null data))
(global $tab.1 (mut (ref null data)) (ref.null data))
(global $tab.2 (mut (ref null data)) (ref.null data))
@@ -25,62 +16,55 @@
(global $tab.12 (mut (ref null data)) (ref.null data))
(func $init
- (global.set $tab.0 (struct.new_default_with_rtt $t0 (global.get $t0)))
- (global.set $tab.10 (struct.new_default_with_rtt $t0 (global.get $t0')))
- (global.set $tab.1 (struct.new_default_with_rtt $t1 (global.get $t1)))
- (global.set $tab.11 (struct.new_default_with_rtt $t1' (global.get $t1')))
- (global.set $tab.2 (struct.new_default_with_rtt $t2 (global.get $t2)))
- (global.set $tab.12 (struct.new_default_with_rtt $t2' (global.get $t2')))
- (global.set $tab.3 (struct.new_default_with_rtt $t3 (global.get $t3)))
- (global.set $tab.4 (struct.new_default_with_rtt $t3 (global.get $t4)))
+ (global.set $tab.0 (struct.new_default $t0))
+ (global.set $tab.10 (struct.new_default $t0))
+ (global.set $tab.1 (struct.new_default $t1))
+ (global.set $tab.11 (struct.new_default $t1'))
+ (global.set $tab.2 (struct.new_default $t2))
+ (global.set $tab.12 (struct.new_default $t2'))
+ (global.set $tab.3 (struct.new_default $t3))
+ (global.set $tab.4 (struct.new_default $t3))
)
(func (export "test-sub")
(call $init)
- (drop (ref.cast (ref.null data) (global.get $t0)))
- (drop (ref.cast (global.get $tab.0) (global.get $t0)))
- (drop (ref.cast (global.get $tab.1) (global.get $t0)))
- (drop (ref.cast (global.get $tab.2) (global.get $t0)))
- (drop (ref.cast (global.get $tab.3) (global.get $t0)))
- (drop (ref.cast (global.get $tab.4) (global.get $t0)))
+ (drop (ref.cast_static $t0 (ref.null data)))
+ (drop (ref.cast_static $t0 (global.get $tab.0)))
+ (drop (ref.cast_static $t0 (global.get $tab.1)))
+ (drop (ref.cast_static $t0 (global.get $tab.2)))
+ (drop (ref.cast_static $t0 (global.get $tab.3)))
+ (drop (ref.cast_static $t0 (global.get $tab.4)))
- (drop (ref.cast (ref.null data) (global.get $t0)))
- (drop (ref.cast (global.get $tab.1) (global.get $t1)))
- (drop (ref.cast (global.get $tab.2) (global.get $t1)))
+ (drop (ref.cast_static $t0 (ref.null data)))
+ (drop (ref.cast_static $t1 (global.get $tab.1)))
+ (drop (ref.cast_static $t1 (global.get $tab.2)))
- (drop (ref.cast (ref.null data) (global.get $t0)))
- (drop (ref.cast (global.get $tab.2) (global.get $t2)))
+ (drop (ref.cast_static $t0 (ref.null data)))
+ (drop (ref.cast_static $t2 (global.get $tab.2)))
- (drop (ref.cast (ref.null data) (global.get $t0)))
- (drop (ref.cast (global.get $tab.3) (global.get $t3)))
+ (drop (ref.cast_static $t0 (ref.null data)))
+ (drop (ref.cast_static $t3 (global.get $tab.3)))
- (drop (ref.cast (ref.null data) (global.get $t0)))
- (drop (ref.cast (global.get $tab.4) (global.get $t4)))
+ (drop (ref.cast_static $t0 (ref.null data)))
)
(func (export "test-canon")
(call $init)
- (drop (ref.cast (global.get $tab.0) (global.get $t0')))
- (drop (ref.cast (global.get $tab.1) (global.get $t0')))
- (drop (ref.cast (global.get $tab.2) (global.get $t0')))
- (drop (ref.cast (global.get $tab.3) (global.get $t0')))
- (drop (ref.cast (global.get $tab.4) (global.get $t0')))
-
- (drop (ref.cast (global.get $tab.10) (global.get $t0)))
- (drop (ref.cast (global.get $tab.11) (global.get $t0)))
- (drop (ref.cast (global.get $tab.12) (global.get $t0)))
+ (drop (ref.cast_static $t0 (global.get $tab.10)))
+ (drop (ref.cast_static $t0 (global.get $tab.11)))
+ (drop (ref.cast_static $t0 (global.get $tab.12)))
- (drop (ref.cast (global.get $tab.1) (global.get $t1')))
- (drop (ref.cast (global.get $tab.2) (global.get $t1')))
+ (drop (ref.cast_static $t1' (global.get $tab.1)))
+ (drop (ref.cast_static $t1' (global.get $tab.2)))
- (drop (ref.cast (global.get $tab.11) (global.get $t1)))
- (drop (ref.cast (global.get $tab.12) (global.get $t1)))
+ (drop (ref.cast_static $t1 (global.get $tab.11)))
+ (drop (ref.cast_static $t1 (global.get $tab.12)))
- (drop (ref.cast (global.get $tab.2) (global.get $t2')))
+ (drop (ref.cast_static $t2' (global.get $tab.2)))
- (drop (ref.cast (global.get $tab.12) (global.get $t2)))
+ (drop (ref.cast_static $t2 (global.get $tab.12)))
)
)
diff --git a/test/spec/struct.wast b/test/spec/struct.wast
index bac4d4520..5bc8e2f2e 100644
--- a/test/spec/struct.wast
+++ b/test/spec/struct.wast
@@ -28,7 +28,7 @@
(struct.get $vec 0 (local.get $v))
)
(func (export "get_0") (result f32)
- (call $get_0 (struct.new_default_with_rtt $vec (rtt.canon $vec)))
+ (call $get_0 (struct.new_default $vec))
)
(func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32)
@@ -36,7 +36,7 @@
(struct.get $vec $y (local.get $v))
)
(func (export "set_get_y") (param $y f32) (result f32)
- (call $set_get_y (struct.new_default_with_rtt $vec (rtt.canon $vec)) (local.get $y))
+ (call $set_get_y (struct.new_default $vec) (local.get $y))
)
(func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32)
@@ -44,7 +44,7 @@
(struct.get $vec $y (local.get $v))
)
(func (export "set_get_1") (param $y f32) (result f32)
- (call $set_get_1 (struct.new_default_with_rtt $vec (rtt.canon $vec)) (local.get $y))
+ (call $set_get_1 (struct.new_default $vec) (local.get $y))
)
)
@@ -82,29 +82,12 @@
(module
(type $t (struct (field i32) (field (mut i32))))
(func (export "struct.new-null")
- (local (ref null (rtt $t))) (drop (struct.new $t (i32.const 1) (i32.const 2) (local.get 0)))
+ (local i64)
+ (drop (struct.new $t (i32.const 1) (i32.const 2) (local.get 0)))
)
)
"type mismatch"
)
-(assert_invalid
- (module
- (type $t (struct (field i32) (field (mut i32))))
- (func (export "struct.new_default-null")
- (local (ref null (rtt $t))) (drop (struct.new_default_with_rtt $t (local.get 0)))
- )
- )
- "type mismatch"
-)
-
-(assert_invalid
- (module
- (type $A (struct (field i32)))
- (type $B (struct (field i64)))
- (global $glob (rtt $A) (rtt.sub $A (rtt.canon $B)))
- )
- "invalid rtt"
-)
(assert_invalid
(module
@@ -112,7 +95,7 @@
(func $test
(drop
;; too many arguments
- (struct.new_with_rtt $vec (i32.const 1) (i32.const 2) (rtt.canon $vec))
+ (struct.new $vec (i32.const 1) (i32.const 2))
)
)
)
@@ -125,7 +108,7 @@
(func $test
(drop
;; too few arguments
- (struct.new_with_rtt $vec (i32.const 1) (rtt.canon $vec))
+ (struct.new $vec (i32.const 1))
)
)
)