summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rwxr-xr-xscripts/fuzz_opt.py16
-rwxr-xr-xscripts/gen-s-parser.py1
-rw-r--r--src/asmjs/asm_v_wasm.cpp3
-rw-r--r--src/binaryen-c.cpp6
-rw-r--r--src/binaryen-c.h2
-rw-r--r--src/gen-s-parser.inc18
-rw-r--r--src/ir/abstract.h2
-rw-r--r--src/js/binaryen.js-post.js8
-rw-r--r--src/literal.h1
-rw-r--r--src/parsing.h1
-rw-r--r--src/passes/ConstHoisting.cpp3
-rw-r--r--src/passes/FuncCastEmulation.cpp6
-rw-r--r--src/passes/InstrumentLocals.cpp26
-rw-r--r--src/shell-interface.h1
-rw-r--r--src/tools/fuzzing.h33
-rw-r--r--src/tools/spec-wrapper.h3
-rw-r--r--src/tools/tool-options.h1
-rw-r--r--src/tools/wasm-reduce.cpp5
-rw-r--r--src/wasm-binary.h9
-rw-r--r--src/wasm-builder.h2
-rw-r--r--src/wasm-features.h7
-rw-r--r--src/wasm-interpreter.h2
-rw-r--r--src/wasm-type.h15
-rw-r--r--src/wasm/literal.cpp14
-rw-r--r--src/wasm/wasm-binary.cpp8
-rw-r--r--src/wasm/wasm-s-parser.cpp3
-rw-r--r--src/wasm/wasm-stack.cpp3
-rw-r--r--src/wasm/wasm-type.cpp34
-rw-r--r--src/wasm/wasm-validator.cpp17
-rw-r--r--src/wasm/wasm.cpp1
-rw-r--r--test/binaryen.js/event.js4
-rw-r--r--test/binaryen.js/kitchen-sink.js4
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt5
-rw-r--r--test/example/c-api-kitchen-sink.c7
-rw-r--r--test/example/c-api-kitchen-sink.txt4
-rw-r--r--test/example/typeinfo.cpp16
-rw-r--r--test/example/typeinfo.txt2
-rw-r--r--test/passes/flatten_all-features.txt48
-rw-r--r--test/passes/flatten_all-features.wast27
-rw-r--r--test/passes/flatten_local-cse_all-features.txt49
-rw-r--r--test/passes/flatten_local-cse_all-features.wast51
-rw-r--r--test/passes/instrument-locals_all-features.txt3
-rw-r--r--test/passes/merge-locals_all-features.txt12
-rw-r--r--test/passes/merge-locals_all-features.wast26
-rw-r--r--test/passes/optimize-instructions_all-features.txt4
-rw-r--r--test/passes/optimize-instructions_all-features.wast15
-rw-r--r--test/passes/simplify-locals_all-features.txt13
-rw-r--r--test/passes/simplify-locals_all-features.wast33
-rw-r--r--test/passes/simplify-locals_all-features_disable-exception-handling.txt13
-rw-r--r--test/passes/simplify-locals_all-features_disable-exception-handling.wast33
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.txt1
-rw-r--r--test/passes/translate-to-fuzz_all-features.txt1088
-rw-r--r--test/reference-types.wast818
-rw-r--r--test/reference-types.wast.from-wast622
-rw-r--r--test/reference-types.wast.fromBinary591
-rw-r--r--test/reference-types.wast.fromBinary.noDebugInfo639
-rw-r--r--test/unit/input/anyref_target_feature.wasmbin0 -> 60 bytes
-rwxr-xr-xtest/unit/input/exception_handling_target_feature.wasmbin89 -> 106 bytes
-rw-r--r--test/unit/test_features.py44
60 files changed, 3497 insertions, 930 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 555fa7003..80534dab8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,10 @@ Current Trunk
-------------
- Remove asm2wasm, which supported Emscripten's fastcomp backend, after fastcomp
was removed.
+- The new feature flag `--enable-anyref` enables just the `anyref` type incl.
+ basic subtyping of `externref`, `funcref` and `exnref` (if enabled).
+- Enabling the exception handling or anyref features without also enabling
+ reference types is a validation error now.
v96
---
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py
index bf1f7f409..4df552b99 100755
--- a/scripts/fuzz_opt.py
+++ b/scripts/fuzz_opt.py
@@ -111,6 +111,8 @@ def randomize_feature_opts():
for possible in POSSIBLE_FEATURE_OPTS:
if random.random() < 0.5:
FEATURE_OPTS.append(possible)
+ if possible in IMPLIED_FEATURE_OPTS:
+ FEATURE_OPTS.extend(IMPLIED_FEATURE_OPTS[possible])
print('randomized feature opts:', ' '.join(FEATURE_OPTS))
@@ -402,7 +404,7 @@ class CompareVMs(TestCaseHandler):
if random.random() < 0.5:
return False
# wasm2c doesn't support most features
- return all([x in FEATURE_OPTS for x in ['--disable-exception-handling', '--disable-simd', '--disable-threads', '--disable-bulk-memory', '--disable-nontrapping-float-to-int', '--disable-tail-call', '--disable-sign-ext', '--disable-reference-types', '--disable-multivalue']])
+ return all([x in FEATURE_OPTS for x in ['--disable-exception-handling', '--disable-simd', '--disable-threads', '--disable-bulk-memory', '--disable-nontrapping-float-to-int', '--disable-tail-call', '--disable-sign-ext', '--disable-reference-types', '--disable-multivalue', '--disable-anyref']])
def run(self, wasm):
run([in_bin('wasm-opt'), wasm, '--emit-wasm2c-wrapper=main.c'] + FEATURE_OPTS)
@@ -502,7 +504,7 @@ class CompareVMs(TestCaseHandler):
compare(before[vm], after[vm], 'CompareVMs between before and after: ' + vm.name)
def can_run_on_feature_opts(self, feature_opts):
- return all([x in feature_opts for x in ['--disable-simd', '--disable-reference-types', '--disable-exception-handling', '--disable-multivalue']])
+ return all([x in feature_opts for x in ['--disable-simd', '--disable-reference-types', '--disable-exception-handling', '--disable-multivalue', '--disable-anyref']])
# Check for determinism - the same command must have the same output.
@@ -633,7 +635,7 @@ class Wasm2JS(TestCaseHandler):
return run_vm([shared.NODEJS, js_file, 'a.wasm'])
def can_run_on_feature_opts(self, feature_opts):
- return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-threads', '--disable-bulk-memory', '--disable-nontrapping-float-to-int', '--disable-tail-call', '--disable-sign-ext', '--disable-reference-types', '--disable-multivalue']])
+ return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-threads', '--disable-bulk-memory', '--disable-nontrapping-float-to-int', '--disable-tail-call', '--disable-sign-ext', '--disable-reference-types', '--disable-multivalue', '--disable-anyref']])
class Asyncify(TestCaseHandler):
@@ -687,7 +689,7 @@ class Asyncify(TestCaseHandler):
compare(before, after_asyncify, 'Asyncify (before/after_asyncify)')
def can_run_on_feature_opts(self, feature_opts):
- return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-tail-call', '--disable-reference-types', '--disable-multivalue']])
+ return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-tail-call', '--disable-reference-types', '--disable-multivalue', '--disable-anyref']])
# The global list of all test case handlers
@@ -870,6 +872,12 @@ def randomize_opt_flags():
POSSIBLE_FEATURE_OPTS = run([in_bin('wasm-opt'), '--print-features', in_binaryen('test', 'hello_world.wat')] + CONSTANT_FEATURE_OPTS).replace('--enable', '--disable').strip().split('\n')
print('POSSIBLE_FEATURE_OPTS:', POSSIBLE_FEATURE_OPTS)
+# some features depend on other features, so if a required feature is
+# disabled, its dependent features need to be disabled as well.
+IMPLIED_FEATURE_OPTS = {
+ '--disable-reference-types': ['--disable-exception-handling', '--disable-anyref']
+}
+
if __name__ == '__main__':
# if we are given a seed, run exactly that one testcase. otherwise,
# run new ones until we fail
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index f105e6407..5e49c8614 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -51,6 +51,7 @@ instructions = [
("funcref.pop", "makePop(Type::funcref)"),
("externref.pop", "makePop(Type::externref)"),
("exnref.pop", "makePop(Type::exnref)"),
+ ("anyref.pop", "makePop(Type::anyref)"),
("i32.load", "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
("i64.load", "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
("f32.load", "makeLoad(s, Type::f32, /*isAtomic=*/false)"),
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp
index ddcb27d3d..8d2894f13 100644
--- a/src/asmjs/asm_v_wasm.cpp
+++ b/src/asmjs/asm_v_wasm.cpp
@@ -57,6 +57,7 @@ AsmType wasmToAsmType(Type type) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
assert(false && "reference types are not supported by asm2wasm");
case Type::none:
return ASM_NONE;
@@ -85,6 +86,8 @@ char getSig(Type type) {
return 'X';
case Type::exnref:
return 'E';
+ case Type::anyref:
+ return 'A';
case Type::none:
return 'v';
case Type::unreachable:
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 9b2da350d..e11b762dd 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -73,6 +73,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
break;
case Type::externref:
case Type::exnref:
+ case Type::anyref:
assert(x.isNull());
break;
case Type::none:
@@ -98,6 +99,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
return Literal::makeFunc(x.func);
case Type::externref:
case Type::exnref:
+ case Type::anyref:
return Literal::makeNull(Type(x.type));
case Type::none:
case Type::unreachable:
@@ -133,6 +135,7 @@ BinaryenType BinaryenTypeVec128(void) { return Type::v128; }
BinaryenType BinaryenTypeFuncref(void) { return Type::funcref; }
BinaryenType BinaryenTypeExternref(void) { return Type::externref; }
BinaryenType BinaryenTypeExnref(void) { return Type::exnref; }
+BinaryenType BinaryenTypeAnyref(void) { return Type::anyref; }
BinaryenType BinaryenTypeUnreachable(void) { return Type::unreachable; }
BinaryenType BinaryenTypeAuto(void) { return uintptr_t(-1); }
@@ -324,6 +327,9 @@ BinaryenFeatures BinaryenFeatureReferenceTypes(void) {
BinaryenFeatures BinaryenFeatureMultivalue(void) {
return static_cast<BinaryenFeatures>(FeatureSet::Multivalue);
}
+BinaryenFeatures BinaryenFeatureAnyref(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Anyref);
+}
BinaryenFeatures BinaryenFeatureAll(void) {
return static_cast<BinaryenFeatures>(FeatureSet::All);
}
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index beaf72499..e622419ac 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -101,6 +101,7 @@ BINARYEN_API BinaryenType BinaryenTypeVec128(void);
BINARYEN_API BinaryenType BinaryenTypeFuncref(void);
BINARYEN_API BinaryenType BinaryenTypeExternref(void);
BINARYEN_API BinaryenType BinaryenTypeExnref(void);
+BINARYEN_API BinaryenType BinaryenTypeAnyref(void);
BINARYEN_API BinaryenType BinaryenTypeUnreachable(void);
// Not a real type. Used as the last parameter to BinaryenBlock to let
// the API figure out the type instead of providing one.
@@ -196,6 +197,7 @@ BINARYEN_API BinaryenFeatures BinaryenFeatureExceptionHandling(void);
BINARYEN_API BinaryenFeatures BinaryenFeatureTailCall(void);
BINARYEN_API BinaryenFeatures BinaryenFeatureReferenceTypes(void);
BINARYEN_API BinaryenFeatures BinaryenFeatureMultivalue(void);
+BINARYEN_API BinaryenFeatures BinaryenFeatureAnyref(void);
BINARYEN_API BinaryenFeatures BinaryenFeatureAll(void);
// Modules
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 97ba15c32..4b02b09c2 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -8,13 +8,21 @@ char op[27] = {'\0'};
strncpy(op, s[0]->c_str(), 26);
switch (op[0]) {
case 'a': {
- switch (op[7]) {
- case 'f':
- if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); }
- goto parse_error;
+ switch (op[1]) {
case 'n':
- if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); }
+ if (strcmp(op, "anyref.pop") == 0) { return makePop(Type::anyref); }
goto parse_error;
+ case 't': {
+ switch (op[7]) {
+ case 'f':
+ if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); }
+ goto parse_error;
+ case 'n':
+ if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
diff --git a/src/ir/abstract.h b/src/ir/abstract.h
index b00537bf5..5f1fd393e 100644
--- a/src/ir/abstract.h
+++ b/src/ir/abstract.h
@@ -104,6 +104,7 @@ inline UnaryOp getUnary(Type type, Op op) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable: {
return InvalidUnary;
@@ -268,6 +269,7 @@ inline BinaryOp getBinary(Type type, Op op) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable: {
return InvalidBinary;
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 66de10848..fd121b8af 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -36,6 +36,7 @@ function initializeConstants() {
['funcref', 'Funcref'],
['externref', 'Externref'],
['exnref', 'Exnref'],
+ ['anyref', 'Anyref'],
['unreachable', 'Unreachable'],
['auto', 'Auto']
].forEach(entry => {
@@ -120,6 +121,7 @@ function initializeConstants() {
'TailCall',
'ReferenceTypes',
'Multivalue',
+ 'Anyref',
'All'
].forEach(name => {
Module['Features'][name] = Module['_BinaryenFeature' + name]();
@@ -2063,6 +2065,12 @@ function wrapModule(module, self = {}) {
}
};
+ self['anyref'] = {
+ 'pop'() {
+ return Module['_BinaryenPop'](module, Module['anyref']);
+ }
+ };
+
self['ref'] = {
'null'(type) {
return Module['_BinaryenRefNull'](module, type);
diff --git a/src/literal.h b/src/literal.h
index 1b3949d21..981f5b6d4 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -579,6 +579,7 @@ template<> struct less<wasm::Literal> {
case wasm::Type::funcref:
case wasm::Type::externref:
case wasm::Type::exnref:
+ case wasm::Type::anyref:
case wasm::Type::none:
case wasm::Type::unreachable:
return false;
diff --git a/src/parsing.h b/src/parsing.h
index 663b901fd..d809cbedd 100644
--- a/src/parsing.h
+++ b/src/parsing.h
@@ -266,6 +266,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
WASM_UNREACHABLE("unexpected const type");
case Type::none:
case Type::unreachable: {
diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp
index e3583d3bb..3b34751ff 100644
--- a/src/passes/ConstHoisting.cpp
+++ b/src/passes/ConstHoisting.cpp
@@ -96,7 +96,8 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::exnref: {
+ case Type::exnref:
+ case Type::anyref: {
return false;
}
case Type::none:
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 160895f23..101834790 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -67,7 +67,8 @@ static Expression* toABI(Expression* value, Module* module) {
}
case Type::funcref:
case Type::externref:
- case Type::exnref: {
+ case Type::exnref:
+ case Type::anyref: {
WASM_UNREACHABLE("reference types cannot be converted to i64");
}
case Type::none: {
@@ -110,7 +111,8 @@ static Expression* fromABI(Expression* value, Type type, Module* module) {
}
case Type::funcref:
case Type::externref:
- case Type::exnref: {
+ case Type::exnref:
+ case Type::anyref: {
WASM_UNREACHABLE("reference types cannot be converted from i64");
}
case Type::none: {
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp
index ee288c103..b1ce5f05e 100644
--- a/src/passes/InstrumentLocals.cpp
+++ b/src/passes/InstrumentLocals.cpp
@@ -59,6 +59,7 @@ Name get_f64("get_f64");
Name get_funcref("get_funcref");
Name get_externref("get_externref");
Name get_exnref("get_exnref");
+Name get_anyref("get_anyref");
Name get_v128("get_v128");
Name set_i32("set_i32");
@@ -68,6 +69,7 @@ Name set_f64("set_f64");
Name set_funcref("set_funcref");
Name set_externref("set_externref");
Name set_exnref("set_exnref");
+Name set_anyref("set_anyref");
Name set_v128("set_v128");
struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
@@ -99,6 +101,9 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
case Type::exnref:
import = get_exnref;
break;
+ case Type::anyref:
+ import = get_anyref;
+ break;
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -145,6 +150,9 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
case Type::exnref:
import = set_exnref;
break;
+ case Type::anyref:
+ import = set_anyref;
+ break;
case Type::unreachable:
return; // nothing to do here
case Type::none:
@@ -184,12 +192,18 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
set_externref,
{Type::i32, Type::i32, Type::externref},
Type::externref);
- }
- if (curr->features.hasExceptionHandling()) {
- addImport(
- curr, get_exnref, {Type::i32, Type::i32, Type::exnref}, Type::exnref);
- addImport(
- curr, set_exnref, {Type::i32, Type::i32, Type::exnref}, Type::exnref);
+ if (curr->features.hasExceptionHandling()) {
+ addImport(
+ curr, get_exnref, {Type::i32, Type::i32, Type::exnref}, Type::exnref);
+ addImport(
+ curr, set_exnref, {Type::i32, Type::i32, Type::exnref}, Type::exnref);
+ }
+ if (curr->features.hasAnyref()) {
+ addImport(
+ curr, get_anyref, {Type::i32, Type::i32, Type::anyref}, Type::anyref);
+ addImport(
+ curr, set_anyref, {Type::i32, Type::i32, Type::anyref}, Type::anyref);
+ }
}
if (curr->features.hasSIMD()) {
addImport(curr, get_v128, {Type::i32, Type::i32, Type::v128}, Type::v128);
diff --git a/src/shell-interface.h b/src/shell-interface.h
index 92f562b48..ae86d13ec 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -118,6 +118,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
globals[import->name] = {Literal::makeNull(import->type)};
break;
case Type::none:
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index ef7844c60..9768b63c4 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -315,7 +315,20 @@ private:
}
SmallVector<Type, 2> options;
options.push_back(type); // includes itself
- // TODO (GC): subtyping
+ TODO_SINGLE_COMPOUND(type);
+ switch (type.getBasic()) {
+ case Type::anyref:
+ if (wasm.features.hasReferenceTypes()) {
+ options.push_back(Type::funcref);
+ options.push_back(Type::externref);
+ if (wasm.features.hasExceptionHandling()) {
+ options.push_back(Type::exnref);
+ }
+ }
+ break;
+ default:
+ break;
+ }
return pick(options);
}
@@ -1349,6 +1362,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -1452,6 +1466,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -1580,6 +1595,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -1624,6 +1640,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1691,6 +1708,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1717,6 +1735,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1826,6 +1845,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
return makeTrivial(type);
case Type::none:
case Type::unreachable:
@@ -1970,6 +1990,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -2206,6 +2227,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -2412,6 +2434,7 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -2592,6 +2615,9 @@ private:
if (wasm.features.hasExceptionHandling()) {
options.push_back(Type::exnref);
}
+ if (wasm.features.hasAnyref()) {
+ options.push_back(Type::anyref);
+ }
return builder.makeRefIsNull(make(pick(options)));
}
@@ -2657,7 +2683,8 @@ private:
.add(FeatureSet::SIMD, Type::v128)
.add(FeatureSet::ReferenceTypes, Type::funcref, Type::externref)
.add(FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling,
- Type::exnref));
+ Type::exnref)
+ .add(FeatureSet::ReferenceTypes | FeatureSet::Anyref, Type::anyref));
}
Type getSingleConcreteType() { return pick(getSingleConcreteTypes()); }
@@ -2697,7 +2724,7 @@ private:
// - funcref cannot be logged because referenced functions can be inlined or
// removed during optimization
- // - there's no point in logging externref because it is opaque
+ // - there's no point in logging externref or anyref because these are opaque
// - don't bother logging tuples
std::vector<Type> getLoggableTypes() {
return items(
diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h
index c073a994c..200571fd0 100644
--- a/src/tools/spec-wrapper.h
+++ b/src/tools/spec-wrapper.h
@@ -58,6 +58,9 @@ static std::string generateSpecWrapper(Module& wasm) {
case Type::exnref:
ret += "(ref.null exn)";
break;
+ case Type::anyref:
+ ret += "(ref.null any)";
+ break;
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h
index f04b95304..082e95549 100644
--- a/src/tools/tool-options.h
+++ b/src/tools/tool-options.h
@@ -87,6 +87,7 @@ struct ToolOptions : public Options {
.addFeature(FeatureSet::TailCall, "tail call operations")
.addFeature(FeatureSet::ReferenceTypes, "reference types")
.addFeature(FeatureSet::Multivalue, "multivalue functions")
+ .addFeature(FeatureSet::Anyref, "anyref type (without GC)")
.add("--no-validation",
"-n",
"Disables validation, assumes inputs are correct",
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 1a7c3544d..7410ff91e 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -598,6 +598,7 @@ struct Reducer
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -623,6 +624,7 @@ struct Reducer
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -648,6 +650,7 @@ struct Reducer
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -673,6 +676,7 @@ struct Reducer
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -684,6 +688,7 @@ struct Reducer
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 865a882df..33f78ce7f 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -347,6 +347,8 @@ enum EncodedType {
funcref = -0x10, // 0x70
// opaque host reference type
externref = -0x11, // 0x6f
+ // any reference type
+ anyref = -0x12, // 0x6e
// exception reference type
exnref = -0x18, // 0x68
// func_type form
@@ -358,6 +360,7 @@ enum EncodedType {
enum EncodedHeapType {
func = -0x10, // 0x70
extern_ = -0x11, // 0x6f
+ any = -0x12, // 0x6e
exn = -0x18, // 0x68
};
@@ -380,6 +383,7 @@ extern const char* ExceptionHandlingFeature;
extern const char* TailCallFeature;
extern const char* ReferenceTypesFeature;
extern const char* MultivalueFeature;
+extern const char* AnyrefFeature;
enum Subsection {
NameFunction = 1,
@@ -975,6 +979,9 @@ inline S32LEB binaryType(Type type) {
case Type::exnref:
ret = BinaryConsts::EncodedType::exnref;
break;
+ case Type::anyref:
+ ret = BinaryConsts::EncodedType::anyref;
+ break;
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
}
@@ -994,6 +1001,8 @@ inline S32LEB binaryHeapType(HeapType type) {
ret = BinaryConsts::EncodedHeapType::exn;
break;
case HeapType::AnyKind:
+ ret = BinaryConsts::EncodedHeapType::any;
+ break;
case HeapType::EqKind:
case HeapType::I31Kind:
case HeapType::SignatureKind:
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 1ce3a507c..6c1923482 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -631,6 +631,7 @@ public:
return makeRefNull(value.type);
case Type::externref:
case Type::exnref: // TODO: ExceptionPackage?
+ case Type::anyref:
assert(value.isNull());
return makeRefNull(value.type);
default:
@@ -825,6 +826,7 @@ public:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
return ExpressionManipulator::refNull(curr, curr->type);
case Type::none:
return ExpressionManipulator::nop(curr);
diff --git a/src/wasm-features.h b/src/wasm-features.h
index c35ff0442..5d05b6284 100644
--- a/src/wasm-features.h
+++ b/src/wasm-features.h
@@ -36,7 +36,8 @@ struct FeatureSet {
TailCall = 1 << 7,
ReferenceTypes = 1 << 8,
Multivalue = 1 << 9,
- All = (1 << 10) - 1
+ Anyref = 1 << 10,
+ All = (1 << 11) - 1
};
static std::string toString(Feature f) {
@@ -61,6 +62,8 @@ struct FeatureSet {
return "reference-types";
case Multivalue:
return "multivalue";
+ case Anyref:
+ return "anyref";
default:
WASM_UNREACHABLE("unexpected feature");
}
@@ -84,6 +87,7 @@ struct FeatureSet {
bool hasTailCall() const { return (features & TailCall) != 0; }
bool hasReferenceTypes() const { return (features & ReferenceTypes) != 0; }
bool hasMultivalue() const { return (features & Multivalue) != 0; }
+ bool hasAnyref() const { return (features & Anyref) != 0; }
bool hasAll() const { return (features & All) != 0; }
void makeMVP() { features = MVP; }
@@ -100,6 +104,7 @@ struct FeatureSet {
void setTailCall(bool v = true) { set(TailCall, v); }
void setReferenceTypes(bool v = true) { set(ReferenceTypes, v); }
void setMultivalue(bool v = true) { set(Multivalue, v); }
+ void setAnyref(bool v = true) { set(Anyref, v); }
void setAll(bool v = true) { features = v ? All : MVP; }
void enable(const FeatureSet& other) { features |= other.features; }
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 44cac9d49..361545a2c 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1647,6 +1647,7 @@ public:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1703,6 +1704,7 @@ public:
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 384cc589f..f3973068f 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -50,7 +50,8 @@ public:
funcref,
externref,
exnref,
- _last_basic_id = exnref
+ anyref,
+ _last_basic_id = anyref
};
Type() = default;
@@ -88,11 +89,11 @@ public:
// │ v128 ║ x │ │ x │ x │ V │ ┘
// ├─ Aliases ───╫───┼───┼───┼───┤───────┤
// │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref
- // │ externref ║ x │ │ x │ x │ f? n │ │ f_unc, n_ullable
- // │ anyref ║ x │ │ x │ x │ f? n │ │ ┐
- // │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC)
+ // │ externref ║ x │ │ x │ x │ f? n │ │ f_unc
+ // │ exnref ║ x │ │ x │ x │ n │ │ n_ullable
+ // │ anyref ║ x │ │ x │ x │ f? n │ │
+ // │ eqref ║ x │ │ x │ x │ n │ │ ┐ TODO (GC)
// │ i31ref ║ x │ │ x │ x │ │ │ ┘
- // │ exnref ║ x │ │ x │ x │ n │ │
// ├─ Compound ──╫───┼───┼───┼───┤───────┤ │
// │ Ref ║ │ x │ x │ x │ f? n? │◄┘
// │ Tuple ║ │ x │ │ x │ │
@@ -330,11 +331,11 @@ struct HeapType {
enum Kind {
FuncKind,
ExternKind,
+ ExnKind,
AnyKind,
EqKind,
I31Kind,
- ExnKind,
- _last_basic_kind = ExnKind,
+ _last_basic_kind = I31Kind,
SignatureKind,
StructKind,
ArrayKind,
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index ffb98abe4..39a4cea3c 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -69,6 +69,7 @@ Literal::Literal(const Literal& other) : type(other.type) {
case Type::none:
break;
case Type::externref:
+ case Type::anyref:
break; // null
case Type::funcref:
case Type::exnref:
@@ -221,6 +222,7 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
break;
case Type::externref:
case Type::exnref:
+ case Type::anyref:
if (isNull()) {
break;
}
@@ -384,6 +386,10 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
o << "exnref(" << literal.getExceptionPackage() << ")";
}
break;
+ case Type::anyref:
+ assert(literal.isNull() && "TODO: non-null anyref values");
+ o << "anyref(null)";
+ break;
case Type::externref:
assert(literal.isNull() && "TODO: non-null externref values");
o << "externref(null)";
@@ -612,6 +618,7 @@ Literal Literal::eqz() const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -633,6 +640,7 @@ Literal Literal::neg() const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -654,6 +662,7 @@ Literal Literal::abs() const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -758,6 +767,7 @@ Literal Literal::add(const Literal& other) const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -779,6 +789,7 @@ Literal Literal::sub(const Literal& other) const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -896,6 +907,7 @@ Literal Literal::mul(const Literal& other) const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1141,6 +1153,7 @@ Literal Literal::eq(const Literal& other) const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1162,6 +1175,7 @@ Literal Literal::ne(const Literal& other) const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index b78d6b86b..de82f0656 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -691,6 +691,8 @@ void WasmBinaryWriter::writeFeaturesSection() {
return BinaryConsts::UserSections::ReferenceTypesFeature;
case FeatureSet::Multivalue:
return BinaryConsts::UserSections::MultivalueFeature;
+ case FeatureSet::Anyref:
+ return BinaryConsts::UserSections::AnyrefFeature;
default:
WASM_UNREACHABLE("unexpected feature flag");
}
@@ -1138,6 +1140,8 @@ Type WasmBinaryBuilder::getType() {
return Type::externref;
case BinaryConsts::EncodedType::exnref:
return Type::exnref;
+ case BinaryConsts::EncodedType::anyref:
+ return Type::anyref;
default:
throwError("invalid wasm type: " + std::to_string(type));
}
@@ -1160,6 +1164,8 @@ HeapType WasmBinaryBuilder::getHeapType() {
return HeapType::ExternKind;
case BinaryConsts::EncodedHeapType::exn:
return HeapType::ExnKind;
+ case BinaryConsts::EncodedHeapType::any:
+ return HeapType::AnyKind;
default:
throwError("invalid wasm heap type: " + std::to_string(type));
}
@@ -2203,6 +2209,8 @@ void WasmBinaryBuilder::readFeatures(size_t payloadLen) {
wasm.features.setReferenceTypes();
} else if (name == BinaryConsts::UserSections::MultivalueFeature) {
wasm.features.setMultivalue();
+ } else if (name == BinaryConsts::UserSections::AnyrefFeature) {
+ wasm.features.setAnyref();
}
}
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index bac5f958c..e4a33c034 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -874,6 +874,9 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
if (strncmp(str, "exnref", 6) == 0 && (prefix || str[6] == 0)) {
return Type::exnref;
}
+ if (strncmp(str, "anyref", 6) == 0 && (prefix || str[6] == 0)) {
+ return Type::anyref;
+ }
if (allowError) {
return Type::none;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index aee5079c2..64622e814 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -191,6 +191,7 @@ void BinaryInstWriter::visitLoad(Load* curr) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
WASM_UNREACHABLE("unexpected type");
}
@@ -292,6 +293,7 @@ void BinaryInstWriter::visitStore(Store* curr) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -694,6 +696,7 @@ void BinaryInstWriter::visitConst(Const* curr) {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 729cc88f5..0c49e8dcc 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -256,12 +256,13 @@ std::unordered_map<TypeInfo, uintptr_t> indices = {
{TypeInfo(HeapType(HeapType::FuncKind), true), Type::funcref},
{TypeInfo({Type::externref}), Type::externref},
{TypeInfo(HeapType(HeapType::ExternKind), true), Type::externref},
+ {TypeInfo({Type::exnref}), Type::exnref},
+ {TypeInfo(HeapType(HeapType::ExnKind), true), Type::exnref},
+ {TypeInfo({Type::anyref}), Type::anyref},
+ {TypeInfo(HeapType(HeapType::AnyKind), true), Type::anyref},
// TODO (GC): Add canonical ids
- // * `(ref null any) == anyref`
// * `(ref null eq) == eqref`
// * `(ref i31) == i31ref`
- {TypeInfo({Type::exnref}), Type::exnref},
- {TypeInfo(HeapType(HeapType::ExnKind), true), Type::exnref},
};
} // anonymous namespace
@@ -340,7 +341,7 @@ bool Type::isTuple() const {
bool Type::isRef() const {
if (isBasic()) {
- return id >= funcref && id <= exnref;
+ return id >= funcref && id <= anyref;
} else {
return getTypeInfo(*this)->isRef();
}
@@ -366,7 +367,7 @@ bool Type::isException() const {
bool Type::isNullable() const {
if (isBasic()) {
- return id >= funcref && id <= exnref;
+ return id >= funcref && id <= anyref;
} else {
return getTypeInfo(*this)->isNullable();
}
@@ -407,6 +408,7 @@ unsigned Type::getByteSize() const {
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
case Type::unreachable:
break;
@@ -451,6 +453,8 @@ FeatureSet Type::getFeatures() const {
return FeatureSet::ReferenceTypes;
case Type::exnref:
return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling;
+ case Type::anyref:
+ return FeatureSet::ReferenceTypes | FeatureSet::Anyref;
default:
return FeatureSet::MVP;
}
@@ -478,6 +482,8 @@ HeapType Type::getHeapType() const {
return HeapType::ExternKind;
case exnref:
return HeapType::ExnKind;
+ case anyref:
+ return HeapType::AnyKind;
default:
break;
}
@@ -502,10 +508,12 @@ Type Type::get(unsigned byteSize, bool float_) {
}
bool Type::isSubType(Type left, Type right) {
- // TODO (GC): subtyping, currently checks for equality only
if (left == right) {
return true;
}
+ if (left.isRef() && right.isRef()) {
+ return right == Type::anyref;
+ }
if (left.isTuple() && right.isTuple()) {
if (left.size() != right.size()) {
return false;
@@ -533,6 +541,17 @@ Type Type::getLeastUpperBound(Type a, Type b) {
if (a.size() != b.size()) {
return Type::none; // a poison value that must not be consumed
}
+ if (a.isRef()) {
+ if (b.isRef()) {
+ // The LUB of two different reference types is anyref, which may or may
+ // not be a valid type depending on whether the anyref feature is enabled.
+ // When anyref is disabled, it is possible for the finalization of invalid
+ // code to introduce a use of anyref via this function, but that is not a
+ // problem because it will be caught and rejected by validation.
+ return Type::anyref;
+ }
+ return Type::none;
+ }
if (a.isTuple()) {
TypeList types;
types.resize(a.size());
@@ -732,6 +751,9 @@ std::ostream& operator<<(std::ostream& os, Type type) {
case Type::exnref:
os << "exnref";
break;
+ case Type::anyref:
+ os << "anyref";
+ break;
}
} else {
os << *getTypeInfo(type);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index c6d679a24..80c54abed 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1363,6 +1363,7 @@ void FunctionValidator::validateMemBytes(uint8_t bytes,
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
WASM_UNREACHABLE("unexpected type");
}
@@ -2176,6 +2177,7 @@ void FunctionValidator::validateAlignment(
case Type::funcref:
case Type::externref:
case Type::exnref:
+ case Type::anyref:
case Type::none:
WASM_UNREACHABLE("invalid type");
}
@@ -2475,6 +2477,20 @@ static void validateModule(Module& module, ValidationInfo& info) {
}
}
+static void validateFeatures(Module& module, ValidationInfo& info) {
+ if (module.features.hasAnyref()) {
+ info.shouldBeTrue(module.features.hasReferenceTypes(),
+ module.features,
+ "--enable-anyref requires --enable-reference-types");
+ }
+ if (module.features.hasExceptionHandling()) { // implies exnref
+ info.shouldBeTrue(
+ module.features.hasReferenceTypes(),
+ module.features,
+ "--enable-exception-handling requires --enable-reference-types");
+ }
+}
+
// TODO: If we want the validator to be part of libwasm rather than libpasses,
// then Using PassRunner::getPassDebug causes a circular dependence. We should
// fix that, perhaps by moving some of the pass infrastructure into libsupport.
@@ -2495,6 +2511,7 @@ bool WasmValidator::validate(Module& module, Flags flags) {
validateTable(module, info);
validateEvents(module, info);
validateModule(module, info);
+ validateFeatures(module, info);
}
// validate additional internal IR details when in pass-debug mode
if (PassRunner::getPassDebug()) {
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index fe7c1b229..31e05f42e 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -45,6 +45,7 @@ const char* SIMD128Feature = "simd128";
const char* TailCallFeature = "tail-call";
const char* ReferenceTypesFeature = "reference-types";
const char* MultivalueFeature = "multivalue";
+const char* AnyrefFeature = "anyref";
} // namespace UserSections
} // namespace BinaryConsts
diff --git a/test/binaryen.js/event.js b/test/binaryen.js/event.js
index 64d7659b8..f705edc38 100644
--- a/test/binaryen.js/event.js
+++ b/test/binaryen.js/event.js
@@ -7,7 +7,9 @@ function cleanInfo(info) {
}
var module = new binaryen.Module();
-module.setFeatures(binaryen.Features.ExceptionHandling | binaryen.Features.Multivalue);
+module.setFeatures(binaryen.Features.ReferenceTypes |
+ binaryen.Features.ExceptionHandling |
+ binaryen.Features.Multivalue);
var pairType = binaryen.createType([binaryen.i32, binaryen.f32]);
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index e82090858..b90890466 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -77,6 +77,9 @@ function test_types() {
console.log(" // BinaryenTypeExnref: " + binaryen.exnref);
console.log(" //", binaryen.expandType(binaryen.exnref).join(","));
+ console.log(" // BinaryenTypeAnyref: " + binaryen.anyref);
+ console.log(" //", binaryen.expandType(binaryen.anyref).join(","));
+
console.log(" // BinaryenTypeAuto: " + binaryen.auto);
var i32_pair = binaryen.createType([binaryen.i32, binaryen.i32]);
@@ -103,6 +106,7 @@ function test_features() {
console.log("Features.TailCall: " + binaryen.Features.TailCall);
console.log("Features.ReferenceTypes: " + binaryen.Features.ReferenceTypes);
console.log("Features.Multivalue: " + binaryen.Features.Multivalue);
+ console.log("Features.Anyref: " + binaryen.Features.Anyref);
console.log("Features.All: " + binaryen.Features.All);
}
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index 917525eeb..52b15f8ff 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -18,6 +18,8 @@
// 8
// BinaryenTypeExnref: 9
// 9
+ // BinaryenTypeAnyref: 10
+ // 10
// BinaryenTypeAuto: -1
// 2,2
// 2,2
@@ -33,7 +35,8 @@ Features.ExceptionHandling: 64
Features.TailCall: 128
Features.ReferenceTypes: 256
Features.Multivalue: 512
-Features.All: 1023
+Features.Anyref: 1024
+Features.All: 2047
InvalidId: 0
BlockId: 1
IfId: 2
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index b0a3ad302..e242cfc8e 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -211,6 +211,12 @@ void test_types() {
BinaryenTypeExpand(exnref, &valueType);
assert(valueType == exnref);
+ BinaryenType anyref = BinaryenTypeAnyref();
+ printf(" // BinaryenTypeAnyref: %d\n", anyref);
+ assert(BinaryenTypeArity(anyref) == 1);
+ BinaryenTypeExpand(anyref, &valueType);
+ assert(valueType == anyref);
+
printf(" // BinaryenTypeAuto: %d\n", BinaryenTypeAuto());
BinaryenType pair[] = {i32, i32};
@@ -241,6 +247,7 @@ void test_features() {
printf("BinaryenFeatureTailCall: %d\n", BinaryenFeatureTailCall());
printf("BinaryenFeatureReferenceTypes: %d\n", BinaryenFeatureReferenceTypes());
printf("BinaryenFeatureMultivalue: %d\n", BinaryenFeatureMultivalue());
+ printf("BinaryenFeatureAnyref: %d\n", BinaryenFeatureAnyref());
printf("BinaryenFeatureAll: %d\n", BinaryenFeatureAll());
}
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index 288174b99..c5958ff1d 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -8,6 +8,7 @@
// BinaryenTypeFuncref: 7
// BinaryenTypeExternref: 8
// BinaryenTypeExnref: 9
+ // BinaryenTypeAnyref: 10
// BinaryenTypeAuto: -1
BinaryenFeatureMVP: 0
BinaryenFeatureAtomics: 1
@@ -20,7 +21,8 @@ BinaryenFeatureExceptionHandling: 64
BinaryenFeatureTailCall: 128
BinaryenFeatureReferenceTypes: 256
BinaryenFeatureMultivalue: 512
-BinaryenFeatureAll: 1023
+BinaryenFeatureAnyref: 1024
+BinaryenFeatureAll: 2047
(f32.neg
(f32.const -33.61199951171875)
)
diff --git a/test/example/typeinfo.cpp b/test/example/typeinfo.cpp
index ac01c6a1b..345bc0788 100644
--- a/test/example/typeinfo.cpp
+++ b/test/example/typeinfo.cpp
@@ -21,8 +21,15 @@ void test_compound() {
HeapType sameExtern(HeapType::ExternKind);
assert(Type(extern_, false).getID() == Type(sameExtern, false).getID());
+ HeapType exn(HeapType::ExnKind);
+ assert(Type(exn, true).getID() == Type::exnref);
+ assert(Type(exn, false).getID() == Type(exn, false).getID());
+ assert(Type(exn, false).getID() != Type(exn, true).getID());
+ HeapType sameExn(HeapType::ExnKind);
+ assert(Type(exn, false).getID() == Type(sameExn, false).getID());
+
HeapType any(HeapType::AnyKind);
- // assert(Type(any, true).getID() == Type::anyref);
+ assert(Type(any, true).getID() == Type::anyref);
assert(Type(any, false).getID() == Type(any, false).getID());
assert(Type(any, false).getID() != Type(any, true).getID());
HeapType sameAny(HeapType::AnyKind);
@@ -41,13 +48,6 @@ void test_compound() {
assert(Type(i31, false).getID() != Type(i31, true).getID());
HeapType sameI31(HeapType::I31Kind);
assert(Type(i31, false).getID() == Type(sameI31, false).getID());
-
- HeapType exn(HeapType::ExnKind);
- assert(Type(exn, true).getID() == Type::exnref);
- assert(Type(exn, false).getID() == Type(exn, false).getID());
- assert(Type(exn, false).getID() != Type(exn, true).getID());
- HeapType sameExn(HeapType::ExnKind);
- assert(Type(exn, false).getID() == Type(sameExn, false).getID());
}
{
Signature signature(Type::i32, Type::none);
diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt
index 95706d5e2..539f305db 100644
--- a/test/example/typeinfo.txt
+++ b/test/example/typeinfo.txt
@@ -6,7 +6,7 @@ extern
externref
(ref extern)
any
-(ref null any)
+anyref
(ref any)
eq
(ref null eq)
diff --git a/test/passes/flatten_all-features.txt b/test/passes/flatten_all-features.txt
index 896dc4ed0..e3d2ca55e 100644
--- a/test/passes/flatten_all-features.txt
+++ b/test/passes/flatten_all-features.txt
@@ -5,6 +5,7 @@
(type $i32_=>_i32 (func (param i32) (result i32)))
(type $none_=>_f32 (func (result f32)))
(type $i64_i64_=>_i64 (func (param i64 i64) (result i64)))
+ (type $none_=>_anyref (func (result anyref)))
(memory $0 10)
(table $0 1 1 funcref)
(elem (i32.const 0) $call-me)
@@ -2375,6 +2376,53 @@
)
(unreachable)
)
+ (func $subtype (result anyref)
+ (local $0 externref)
+ (local $1 anyref)
+ (local $2 externref)
+ (local $3 externref)
+ (local $4 externref)
+ (local $5 externref)
+ (local $6 externref)
+ (local $7 anyref)
+ (block $label0
+ (block $block
+ (local.set $1
+ (ref.null extern)
+ )
+ (local.set $2
+ (ref.null extern)
+ )
+ (br_if $label0
+ (i32.const 0)
+ )
+ (local.set $3
+ (local.get $2)
+ )
+ (local.set $0
+ (local.get $3)
+ )
+ (local.set $4
+ (local.get $0)
+ )
+ (local.set $5
+ (local.get $4)
+ )
+ )
+ (local.set $6
+ (local.get $5)
+ )
+ (local.set $1
+ (local.get $6)
+ )
+ )
+ (local.set $7
+ (local.get $1)
+ )
+ (return
+ (local.get $7)
+ )
+ )
)
(module
(type $i64_f32_=>_none (func (param i64 f32)))
diff --git a/test/passes/flatten_all-features.wast b/test/passes/flatten_all-features.wast
index 68bd7a64b..14da24a74 100644
--- a/test/passes/flatten_all-features.wast
+++ b/test/passes/flatten_all-features.wast
@@ -1020,7 +1020,6 @@
(return (i32.sub (i32.const 1) (i32.const 2)))
)
- ;; TODO (GC)
;; subtypes
;; br_if leaves a value on the stack if not taken, which later can be the last
@@ -1028,19 +1027,19 @@
;; targets an outer branch whose return type is a supertype of the br_if's
;; value type, we need the value to be set into two locals: one with the outer
;; block's type, and one with its value type.
- ;; (func $subtype (result externref)
- ;; (local $0 anyref)
- ;; (block $label0 (result externref)
- ;; (block (result anyref)
- ;; (local.tee $0
- ;; (br_if $label0
- ;; (ref.null extern)
- ;; (i32.const 0)
- ;; )
- ;; )
- ;; )
- ;; )
- ;; )
+ (func $subtype (result anyref)
+ (local $0 externref)
+ (block $label0 (result anyref)
+ (block (result externref)
+ (local.tee $0
+ (br_if $label0
+ (ref.null extern)
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ )
)
(module
(func $0 (param $0 i64) (param $1 f32)
diff --git a/test/passes/flatten_local-cse_all-features.txt b/test/passes/flatten_local-cse_all-features.txt
index 201a6f793..ad051c5e2 100644
--- a/test/passes/flatten_local-cse_all-features.txt
+++ b/test/passes/flatten_local-cse_all-features.txt
@@ -764,3 +764,52 @@
)
)
)
+(module
+ (type $none_=>_none (func))
+ (type $none_=>_anyref (func (result anyref)))
+ (func $subtype-test (result anyref)
+ (local $0 funcref)
+ (local $1 funcref)
+ (local $2 anyref)
+ (local $3 anyref)
+ (block
+ (nop)
+ (loop $label$1
+ (local.set $0
+ (ref.null func)
+ )
+ )
+ (local.set $1
+ (local.get $0)
+ )
+ (local.set $2
+ (local.get $0)
+ )
+ )
+ (local.set $3
+ (local.get $2)
+ )
+ (return
+ (local.get $2)
+ )
+ )
+ (func $test
+ (local $0 anyref)
+ (local $1 funcref)
+ (local $2 funcref)
+ (block $label$1
+ (local.set $0
+ (ref.null func)
+ )
+ (local.set $1
+ (ref.null func)
+ )
+ )
+ (local.set $2
+ (local.get $1)
+ )
+ (drop
+ (local.get $1)
+ )
+ )
+)
diff --git a/test/passes/flatten_local-cse_all-features.wast b/test/passes/flatten_local-cse_all-features.wast
index 05fbcb2ac..660f56c1e 100644
--- a/test/passes/flatten_local-cse_all-features.wast
+++ b/test/passes/flatten_local-cse_all-features.wast
@@ -288,30 +288,29 @@
)
)
-;; TODO (GC)
-;; (module
-;; ;; After --flatten, there will be a series of chain copies between multiple
-;; ;; locals, but some of the locals will be funcref type and others anyref
-;; ;; type. We cannot make locals of different types a common subexpression.
-;; (func $subtype-test (result anyref)
-;; (nop)
-;; (loop $label$1 (result funcref)
-;; (ref.null func)
-;; )
-;; )
+(module
+ ;; After --flatten, there will be a series of chain copies between multiple
+ ;; locals, but some of the locals will be funcref type and others anyref
+ ;; type. We cannot make locals of different types a common subexpression.
+ (func $subtype-test (result anyref)
+ (nop)
+ (loop $label$1 (result funcref)
+ (ref.null func)
+ )
+ )
-;; (func $test
-;; (local $0 anyref)
-;; (drop
-;; (block $label$1 (result funcref)
-;; (local.set $0
-;; (ref.null func)
-;; )
-;; ;; After --flatten, this will be assigned to a local of funcref type. After
-;; ;; --local-cse, even if we set (ref.null) to local $0 above, this should not
-;; ;; be replaced with $0, because it is of type anyref.
-;; (ref.null func)
-;; )
-;; )
-;; )
-;; )
+ (func $test
+ (local $0 anyref)
+ (drop
+ (block $label$1 (result funcref)
+ (local.set $0
+ (ref.null func)
+ )
+ ;; After --flatten, this will be assigned to a local of funcref type. After
+ ;; --local-cse, even if we set (ref.null func) to local $0 above, this
+ ;; should not be replaced with $0, because it is of type anyref.
+ (ref.null func)
+ )
+ )
+ )
+)
diff --git a/test/passes/instrument-locals_all-features.txt b/test/passes/instrument-locals_all-features.txt
index 91e71a48d..cb46cb3ef 100644
--- a/test/passes/instrument-locals_all-features.txt
+++ b/test/passes/instrument-locals_all-features.txt
@@ -7,6 +7,7 @@
(type $i32_i32_funcref_=>_funcref (func (param i32 i32 funcref) (result funcref)))
(type $i32_i32_externref_=>_externref (func (param i32 i32 externref) (result externref)))
(type $i32_i32_exnref_=>_exnref (func (param i32 i32 exnref) (result exnref)))
+ (type $i32_i32_anyref_=>_anyref (func (param i32 i32 anyref) (result anyref)))
(type $none_=>_none (func))
(import "env" "get_i32" (func $get_i32 (param i32 i32 i32) (result i32)))
(import "env" "get_i64" (func $get_i64 (param i32 i32 i64) (result i64)))
@@ -22,6 +23,8 @@
(import "env" "set_externref" (func $set_externref (param i32 i32 externref) (result externref)))
(import "env" "get_exnref" (func $get_exnref (param i32 i32 exnref) (result exnref)))
(import "env" "set_exnref" (func $set_exnref (param i32 i32 exnref) (result exnref)))
+ (import "env" "get_anyref" (func $get_anyref (param i32 i32 anyref) (result anyref)))
+ (import "env" "set_anyref" (func $set_anyref (param i32 i32 anyref) (result anyref)))
(import "env" "get_v128" (func $get_v128 (param i32 i32 v128) (result v128)))
(import "env" "set_v128" (func $set_v128 (param i32 i32 v128) (result v128)))
(func $test
diff --git a/test/passes/merge-locals_all-features.txt b/test/passes/merge-locals_all-features.txt
index 15039b4ce..0ba98f09a 100644
--- a/test/passes/merge-locals_all-features.txt
+++ b/test/passes/merge-locals_all-features.txt
@@ -1,6 +1,7 @@
(module
(type $i32_i32_=>_none (func (param i32 i32)))
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
+ (type $none_=>_none (func))
(type $i32_i32_i32_=>_none (func (param i32 i32 i32)))
(type $i32_f32_f32_=>_i64 (func (param i32 f32 f32) (result i64)))
(global $global$0 (mut i32) (i32.const 10))
@@ -456,4 +457,15 @@
)
)
)
+ (func $subtype-test
+ (local $0 anyref)
+ (local $1 funcref)
+ (local $2 funcref)
+ (local.set $0
+ (local.get $1)
+ )
+ (local.set $2
+ (local.get $1)
+ )
+ )
)
diff --git a/test/passes/merge-locals_all-features.wast b/test/passes/merge-locals_all-features.wast
index c12a02426..1cdac26ec 100644
--- a/test/passes/merge-locals_all-features.wast
+++ b/test/passes/merge-locals_all-features.wast
@@ -375,18 +375,16 @@
)
)
)
- ;; TODO (GC)
- ;; (func $subtype-test
- ;; (local $0 anyref)
- ;; (local $1 funcref)
- ;; (local $2 funcref)
- ;; (local.set $0
- ;; (local.get $1)
- ;; )
- ;; (local.set $2
- ;; ;; This should NOT become $0, because types of $0 and $1 are different
- ;; (local.get $1)
- ;; )
- ;; )
+ (func $subtype-test
+ (local $0 anyref)
+ (local $1 funcref)
+ (local $2 funcref)
+ (local.set $0
+ (local.get $1)
+ )
+ (local.set $2
+ ;; This should NOT become $0, because types of $0 and $1 are different
+ (local.get $1)
+ )
+ )
)
-
diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt
index 5677624cb..6ff608ab7 100644
--- a/test/passes/optimize-instructions_all-features.txt
+++ b/test/passes/optimize-instructions_all-features.txt
@@ -14,6 +14,7 @@
(type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64)))
(type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32)))
(type $none_=>_f64 (func (result f64)))
+ (type $none_=>_anyref (func (result anyref)))
(memory $0 0)
(export "load-off-2" (func $load-off-2))
(func $f (param $i1 i32) (param $i2 i64)
@@ -3711,6 +3712,9 @@
(unreachable)
)
)
+ (func $if-arms-subtype (result anyref)
+ (ref.null extern)
+ )
(func $optimize-boolean-context (param $x i32) (param $y i32)
(if
(local.get $x)
diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast
index 37d0d7618..aafb6c9d8 100644
--- a/test/passes/optimize-instructions_all-features.wast
+++ b/test/passes/optimize-instructions_all-features.wast
@@ -4207,15 +4207,14 @@
(unreachable)
)
)
- ;; TODO (GC)
;; Tests when if arms are subtype of if's type
- ;; (func $if-arms-subtype (result anyref)
- ;; (if (result anyref)
- ;; (i32.const 0)
- ;; (ref.null extern)
- ;; (ref.null func)
- ;; )
- ;; )
+ (func $if-arms-subtype (result anyref)
+ (if (result anyref)
+ (i32.const 0)
+ (ref.null extern)
+ (ref.null func)
+ )
+ )
(func $optimize-boolean-context (param $x i32) (param $y i32)
;; 0 - x ==> x
(if
diff --git a/test/passes/simplify-locals_all-features.txt b/test/passes/simplify-locals_all-features.txt
index f461a7580..e04b8fb7a 100644
--- a/test/passes/simplify-locals_all-features.txt
+++ b/test/passes/simplify-locals_all-features.txt
@@ -1882,6 +1882,19 @@
)
)
(module
+ (type $none_=>_anyref (func (result anyref)))
+ (func $subtype-test (result anyref)
+ (local $0 externref)
+ (local $1 anyref)
+ (local $2 anyref)
+ (block $block
+ (nop)
+ )
+ (nop)
+ (local.get $0)
+ )
+)
+(module
(type $none_=>_none (func))
(type $i32_exnref_=>_none (func (param i32 exnref)))
(type $exnref_=>_none (func (param exnref)))
diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast
index b32da3df8..0a51e5371 100644
--- a/test/passes/simplify-locals_all-features.wast
+++ b/test/passes/simplify-locals_all-features.wast
@@ -1655,23 +1655,22 @@
)
)
)
-;; TODO (GC)
-;; (module
-;; (func $subtype-test (result anyref)
-;; (local $0 anyref)
-;; (local $1 externref)
-;; (local $2 externref)
-;; (block
-;; (local.set $1
-;; (local.get $0)
-;; )
-;; )
-;; (local.set $2
-;; (local.get $1)
-;; )
-;; (local.get $1)
-;; )
-;; )
+(module
+ (func $subtype-test (result anyref)
+ (local $0 externref)
+ (local $1 anyref)
+ (local $2 anyref)
+ (block
+ (local.set $1
+ (local.get $0)
+ )
+ )
+ (local.set $2
+ (local.get $1)
+ )
+ (local.get $1)
+ )
+)
(module
(event $event$0 (attr 0) (param))
(func $unoptimizable-br_on_exn-block (result exnref) (local $0 exnref)
diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.txt b/test/passes/simplify-locals_all-features_disable-exception-handling.txt
index b01941639..7215bfadf 100644
--- a/test/passes/simplify-locals_all-features_disable-exception-handling.txt
+++ b/test/passes/simplify-locals_all-features_disable-exception-handling.txt
@@ -1875,3 +1875,16 @@
)
)
)
+(module
+ (type $none_=>_anyref (func (result anyref)))
+ (func $subtype-test (result anyref)
+ (local $0 funcref)
+ (local $1 anyref)
+ (local $2 anyref)
+ (block $block
+ (nop)
+ )
+ (nop)
+ (local.get $0)
+ )
+)
diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.wast b/test/passes/simplify-locals_all-features_disable-exception-handling.wast
index c0f279cd0..f9806641c 100644
--- a/test/passes/simplify-locals_all-features_disable-exception-handling.wast
+++ b/test/passes/simplify-locals_all-features_disable-exception-handling.wast
@@ -1655,20 +1655,19 @@
)
)
)
-;; TODO (GC)
-;; (module
-;; (func $subtype-test (result anyref)
-;; (local $0 funcref)
-;; (local $1 anyref)
-;; (local $2 anyref)
-;; (block
-;; (local.set $1
-;; (local.get $0)
-;; )
-;; )
-;; (local.set $2
-;; (local.get $1)
-;; )
-;; (local.get $1)
-;; )
-;; )
+(module
+ (func $subtype-test (result anyref)
+ (local $0 funcref)
+ (local $1 anyref)
+ (local $2 anyref)
+ (block
+ (local.set $1
+ (local.get $0)
+ )
+ )
+ (local.set $2
+ (local.get $1)
+ )
+ (local.get $1)
+ )
+)
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
index d54c7bb4e..80e8d6bc7 100644
--- a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
@@ -8,6 +8,7 @@
--enable-tail-call
--enable-reference-types
--enable-multivalue
+--enable-anyref
(module
(type $none_=>_v128_externref (func (result v128 externref)))
(func $foo (result v128 externref)
diff --git a/test/passes/translate-to-fuzz_all-features.txt b/test/passes/translate-to-fuzz_all-features.txt
index ab9a5b946..4b7ec462a 100644
--- a/test/passes/translate-to-fuzz_all-features.txt
+++ b/test/passes/translate-to-fuzz_all-features.txt
@@ -1,20 +1,18 @@
(module
(type $none_=>_none (func))
+ (type $f32_=>_none (func (param f32)))
+ (type $exnref_=>_none (func (param exnref)))
+ (type $none_=>_i32_anyref_externref (func (result i32 anyref externref)))
+ (type $none_=>_externref_anyref_anyref_anyref (func (result externref anyref anyref anyref)))
(type $i32_=>_none (func (param i32)))
- (type $none_=>_funcref_exnref_i32_externref (func (result funcref exnref i32 externref)))
- (type $i32_funcref_f64_v128_i32_=>_none (func (param i32 funcref f64 v128 i32)))
(type $i64_=>_none (func (param i64)))
- (type $f32_=>_none (func (param f32)))
(type $f64_=>_none (func (param f64)))
+ (type $f64_i32_i64_f64_v128_=>_none (func (param f64 i32 i64 f64 v128)))
(type $v128_=>_none (func (param v128)))
- (type $exnref_=>_none (func (param exnref)))
(type $none_=>_i32 (func (result i32)))
- (type $i32_v128_f64_i32_=>_i32 (func (param i32 v128 f64 i32) (result i32)))
- (type $none_=>_i64 (func (result i64)))
- (type $none_=>_f32 (func (result f32)))
- (type $i64_f32_=>_f64 (func (param i64 f32) (result f64)))
+ (type $anyref_funcref_externref_=>_f32 (func (param anyref funcref externref) (result f32)))
(type $none_=>_v128 (func (result v128)))
- (type $none_=>_funcref (func (result funcref)))
+ (type $none_=>_anyref (func (result anyref)))
(import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
(import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))
(import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))
@@ -23,31 +21,29 @@
(import "fuzzing-support" "log-exnref" (func $log-exnref (param exnref)))
(memory $0 (shared 1 1))
(data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3")
- (table $0 5 5 funcref)
- (elem (i32.const 0) $func_9 $func_10 $func_12 $func_12 $func_14)
- (global $global$5 (mut exnref) (ref.null exn))
- (global $global$4 (mut f64) (f64.const 13))
- (global $global$3 (mut f32) (f32.const 16448))
- (global $global$2 (mut (v128 i32 i32 f64 exnref exnref)) (tuple.make
- (v128.const i32x4 0x4d5affff 0x055b007b 0xff830011 0xffee0040)
- (i32.const -32767)
- (i32.const 44)
- (f64.const 1797693134862315708145274e284)
+ (table $0 2 funcref)
+ (elem (i32.const 0) $func_7 $func_11)
+ (global $global$5 (mut f32) (f32.const 74))
+ (global $global$4 (mut exnref) (ref.null exn))
+ (global $global$3 (mut i32) (i32.const 1263230471))
+ (global $global$2 (mut i32) (i32.const -131072))
+ (global $global$1 (mut (funcref exnref exnref externref anyref f64)) (tuple.make
+ (ref.null func)
(ref.null exn)
(ref.null exn)
+ (ref.null extern)
+ (ref.null any)
+ (f64.const 1.1754943508222875e-38)
))
- (global $global$1 (mut exnref) (ref.null exn))
(global $hangLimit (mut i32) (i32.const 10))
- (event $event$0 (attr 0) (param i32))
+ (event $event$0 (attr 0) (param exnref))
+ (event $event$1 (attr 0) (param f32))
(export "hashMemory" (func $hashMemory))
(export "memory" (memory $0))
+ (export "func_7" (func $func_7))
(export "func_7_invoker" (func $func_7_invoker))
- (export "func_9" (func $func_9))
- (export "func_10_invoker" (func $func_10_invoker))
- (export "func_12" (func $func_12))
- (export "func_12_invoker" (func $func_12_invoker))
- (export "func_16_invoker" (func $func_16_invoker))
- (export "func_19" (func $func_19))
+ (export "func_10" (func $func_10))
+ (export "func_11_invoker" (func $func_11_invoker))
(export "hangLimitInitializer" (func $hangLimitInitializer))
(func $hashMemory (result i32)
(local $0 i32)
@@ -280,14 +276,17 @@
)
(local.get $0)
)
- (func $func_7 (param $0 i32) (param $1 v128) (param $2 f64) (param $3 i32) (result i32)
+ (func $func_7 (result anyref)
+ (local $0 i64)
+ (local $1 i64)
+ (local $2 anyref)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (i32.const 4883)
+ (ref.null any)
)
)
(global.set $hangLimit
@@ -297,65 +296,26 @@
)
)
)
- (local.tee $3
- (local.tee $0
- (local.get $3)
- )
- )
+ (ref.null any)
)
(func $func_7_invoker
(drop
- (call $func_7
- (i32.const -119)
- (v128.const i32x4 0x00000000 0x40410000 0x00000000 0x3ff00000)
- (f64.const 3.433897990215153e-220)
- (i32.const 255)
- )
+ (call $func_7)
+ )
+ (drop
+ (call $func_7)
)
(call $log-i32
(call $hashMemory)
)
- )
- (func $func_9 (result funcref)
- (local $0 i64)
- (local $1 i64)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (ref.func $log-f32)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
+ (drop
+ (call $func_7)
)
- (block $label$0
- (f64.store offset=22 align=2
- (i32.and
- (i32.const -65535)
- (i32.const 15)
- )
- (f64.const 8589934593)
- )
- (return
- (ref.func $log-exnref)
- )
+ (call $log-i32
+ (call $hashMemory)
)
)
- (func $func_10 (result funcref exnref i32 externref)
- (local $0 i64)
- (local $1 exnref)
- (local $2 f32)
- (local $3 externref)
- (local $4 externref)
- (local $5 f32)
- (local $6 i64)
+ (func $func_9 (result externref anyref anyref anyref)
(block
(if
(i32.eqz
@@ -363,10 +323,10 @@
)
(return
(tuple.make
- (ref.func $func_10)
- (ref.null exn)
- (i32.const 0)
(ref.null extern)
+ (ref.null any)
+ (ref.null any)
+ (ref.null any)
)
)
)
@@ -378,22 +338,14 @@
)
)
(tuple.make
- (ref.func $log-v128)
- (ref.null exn)
- (i32.const 26155)
(ref.null extern)
+ (ref.null any)
+ (ref.null any)
+ (ref.null any)
)
)
- (func $func_10_invoker
- (drop
- (call $func_10)
- )
- (call $log-i32
- (call $hashMemory)
- )
- )
- (func $func_12
- (local $0 exnref)
+ (func $func_10 (param $0 f64) (param $1 i32) (param $2 i64) (param $3 f64) (param $4 v128)
+ (local $5 exnref)
(block
(if
(i32.eqz
@@ -408,56 +360,478 @@
)
)
)
- (call $log-i32
- (i32.const 1)
- )
- )
- (func $func_12_invoker
- (call $func_12)
- )
- (func $func_14 (result v128)
- (local $0 i32)
- (local $1 f32)
- (local $2 f32)
- (local $3 externref)
- (local $4 exnref)
- (local $5 f64)
- (local $6 i64)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (v128.const i32x4 0x5ea21f0a 0x52800ae0 0x002a5300 0xe4010058)
- )
+ (block $label$0
+ (call $log-i32
+ (call $hashMemory)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
+ (call $log-f32
+ (i32.load offset=4 align=2
+ (i32.and
+ (local.tee $1
+ (block $label$1
+ (call $log-i32
+ (block $label$2 (result i32)
+ (loop $label$3
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block $label$4
+ (call $log-f32
+ (global.get $global$5)
+ )
+ (if
+ (local.tee $1
+ (local.get $1)
+ )
+ (block $label$5
+ (call $log-f64
+ (f64.reinterpret_i64
+ (local.tee $2
+ (block $label$6
+ (call $log-f32
+ (f32.min
+ (f32.const -1)
+ (f32.demote_f64
+ (f64.copysign
+ (f64.const 28)
+ (local.get $3)
+ )
+ )
+ )
+ )
+ (br $label$5)
+ )
+ )
+ )
+ )
+ (call $log-i32
+ (br_if $label$2
+ (global.get $global$3)
+ (f64.lt
+ (f64.min
+ (tuple.extract 0
+ (tuple.make
+ (f64.const 16240)
+ (ref.null any)
+ )
+ )
+ (f64.const -9223372036854775808)
+ )
+ (f64x2.extract_lane 1
+ (local.get $4)
+ )
+ )
+ )
+ )
+ )
+ (block $label$7
+ (local.set $0
+ (loop $label$8 (result f64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result f64)
+ (block $label$9
+ (call $log-v128
+ (local.get $4)
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ )
+ (br_if $label$8
+ (i32.eqz
+ (local.tee $1
+ (i32.const 977223545)
+ )
+ )
+ )
+ (local.get $3)
+ )
+ )
+ )
+ (call $log-f32
+ (f32.const 2147483648)
+ )
+ )
+ )
+ )
+ (br_if $label$3
+ (br_if $label$2
+ (select
+ (i32.const 4612)
+ (local.get $1)
+ (local.get $1)
+ )
+ (if
+ (i32.eqz
+ (i64.le_s
+ (local.get $2)
+ (local.get $2)
+ )
+ )
+ (block $label$10
+ (br $label$3)
+ )
+ (local.tee $1
+ (if
+ (if (result i32)
+ (i32.const -16)
+ (block
+ (select
+ (if (result i32)
+ (i32.popcnt
+ (call $hashMemory)
+ )
+ (block $label$15 (result i32)
+ (call $log-f32
+ (f32.const 1291)
+ )
+ (global.get $global$3)
+ )
+ (block $label$16
+ (call $log-i64
+ (i64.const 1304720377604164420)
+ )
+ (br $label$3)
+ )
+ )
+ (block $label$17
+ (call $log-v128
+ (i32x4.ne
+ (local.get $4)
+ (v128.const i32x4 0xffe3e76d 0x41dfffff 0xd70a3d70 0x3ffb70a3)
+ )
+ )
+ (br $label$3)
+ )
+ (if (result i32)
+ (block $label$11 (result i32)
+ (nop)
+ (i32.const 127)
+ )
+ (block $label$12 (result i32)
+ (call $log-v128
+ (if (result v128)
+ (f32.ge
+ (f32.const -nan:0x7fffed)
+ (f32.mul
+ (f32.const -nan:0x7ffffc)
+ (f32.const -nan:0x7ffffc)
+ )
+ )
+ (v128.const i32x4 0x110b0c03 0x241c171e 0xffffffe9 0xffffffff)
+ (local.tee $4
+ (local.tee $4
+ (v128.const i32x4 0x00000000 0xfe000000 0xffffffff 0x00000fff)
+ )
+ )
+ )
+ )
+ (br_if $label$12
+ (local.get $1)
+ (local.get $1)
+ )
+ )
+ (block $label$13 (result i32)
+ (v128.store offset=4 align=1
+ (i32.and
+ (local.get $1)
+ (i32.const 15)
+ )
+ (loop $label$14 (result v128)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (i64x2.splat
+ (i64.const 32767)
+ )
+ )
+ )
+ (local.get $1)
+ )
+ )
+ )
+ (drop
+ (i32.atomic.load offset=4
+ (i32.and
+ (i64.lt_u
+ (local.get $2)
+ (local.tee $2
+ (i64.extend_i32_u
+ (local.get $1)
+ )
+ )
+ )
+ (i32.const 15)
+ )
+ )
+ )
+ )
+ (block $label$18 (result i32)
+ (call $log-i32
+ (br_if $label$18
+ (local.tee $1
+ (br_if $label$18
+ (ref.is_null
+ (ref.null exn)
+ )
+ (i32.eqz
+ (i32.const 1997038858)
+ )
+ )
+ )
+ (i32.eqz
+ (i8x16.extract_lane_u 3
+ (tuple.extract 1
+ (tuple.make
+ (f64.const 2)
+ (select
+ (local.get $4)
+ (v128.const i32x4 0x5b800000 0x4e800000 0x53000000 0x5f800000)
+ (i32.const -255)
+ )
+ (ref.null any)
+ (ref.null func)
+ (f32x4.extract_lane 1
+ (local.get $4)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (br $label$3)
+ )
+ )
+ (block $label$19
+ (loop $label$20
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$21
+ (call $log-f64
+ (local.tee $0
+ (local.tee $0
+ (local.get $3)
+ )
+ )
+ )
+ (call $log-i32
+ (local.get $1)
+ )
+ )
+ )
+ (br $label$3)
+ )
+ (block $label$22
+ (call $log-v128
+ (local.tee $4
+ (loop $label$23 (result v128)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result v128)
+ (block $label$24
+ (call $log-i64
+ (local.tee $2
+ (i64.const 576460752303423488)
+ )
+ )
+ (loop $label$25
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block $label$26
+ (local.set $5
+ (local.get $5)
+ )
+ (call $log-v128
+ (v128.const i32x4 0x00000014 0xffff8000 0x00000800 0xffffffe5)
+ )
+ )
+ (br_if $label$25
+ (i32.eqz
+ (local.get $1)
+ )
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ )
+ )
+ )
+ (br_if $label$23
+ (i32.eqz
+ (loop $label$27 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result i32)
+ (call $log-f32
+ (loop $label$28 (result f32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (f32.const 1)
+ )
+ )
+ (br_if $label$27
+ (i32.eqz
+ (i32.atomic.load16_u offset=1
+ (i32.and
+ (i32.const -11)
+ (i32.const 15)
+ )
+ )
+ )
+ )
+ (if (result i32)
+ (i32.const 358420504)
+ (local.get $1)
+ (block $label$29 (result i32)
+ (nop)
+ (local.get $1)
+ )
+ )
+ )
+ )
+ )
+ )
+ (local.get $4)
+ )
+ )
+ )
+ )
+ (br $label$3)
+ )
+ )
+ )
+ )
+ )
+ )
+ (v128.store offset=22
+ (i32.and
+ (global.get $global$3)
+ (i32.const 15)
+ )
+ (local.get $4)
+ )
+ )
+ )
+ (block $label$31
+ (return)
+ )
+ )
+ )
+ (return)
+ )
+ )
+ (i32.const 15)
+ )
)
)
)
- (v128.const i32x4 0x1d00ff00 0x2a255500 0x01fbf800 0x0a000002)
)
- (func $func_15 (result i64)
- (local $0 f32)
- (local $1 funcref)
- (local $2 f32)
- (local $3 i32)
- (local $4 f32)
- (local $5 v128)
- (local $6 f64)
- (local $7 funcref)
- (local $8 externref)
+ (func $func_11 (param $0 anyref) (param $1 funcref) (param $2 externref) (result f32)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (i64.const -2097152)
+ (f32.const 510.8139953613281)
)
)
(global.set $hangLimit
@@ -467,27 +841,39 @@
)
)
)
- (block $label$0
- (nop)
- (return
- (i64.const -61)
+ (f32.const 4503599627370496)
+ )
+ (func $func_11_invoker
+ (drop
+ (call $func_11
+ (ref.null any)
+ (ref.func $func_7)
+ (ref.null extern)
)
)
+ (drop
+ (call $func_11
+ (ref.null any)
+ (ref.func $log-f64)
+ (ref.null extern)
+ )
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
)
- (func $func_16 (param $0 i32) (param $1 funcref) (param $2 f64) (param $3 v128) (param $4 i32)
- (local $5 (i32 f64))
- (local $6 i64)
- (local $7 (i32 i64))
- (local $8 i32)
- (local $9 funcref)
- (local $10 f32)
- (local $11 (i64 v128 f32))
+ (func $func_13 (result v128)
+ (local $0 i32)
+ (local $1 exnref)
+ (local $2 f64)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
- (return)
+ (return
+ (v128.const i32x4 0x016d0001 0x7a01017f 0x7901016d 0x00800056)
+ )
)
(global.set $hangLimit
(i32.sub
@@ -496,36 +882,27 @@
)
)
)
- (nop)
- )
- (func $func_16_invoker
- (call $func_16
- (i32.const -19)
- (ref.func $hashMemory)
- (f64.const -2305843009213693952)
- (v128.const i32x4 0x2b27212f 0x322e2366 0x0000343b 0x00000000)
- (i32.const 24)
- )
- (call $func_16
- (i32.const 2147483646)
- (ref.null func)
- (f64.const 23348)
- (v128.const i32x4 0x0000007c 0x00000000 0x00000000 0xc0000000)
- (i32.const 521672456)
+ (tuple.extract 0
+ (tuple.make
+ (v128.const i32x4 0x41430000 0x00405556 0x2020ffdd 0x0005080a)
+ (i32.const 32768)
+ )
)
)
- (func $func_18 (param $0 i64) (param $1 f32) (result f64)
- (local $2 (f64 f64 i32))
- (local $3 i64)
- (local $4 f32)
- (local $5 externref)
+ (func $func_14 (result i32 anyref externref)
+ (local $0 i64)
+ (local $1 i32)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (f64.const -1073741824)
+ (tuple.make
+ (i32.const -91)
+ (ref.null any)
+ (ref.null extern)
+ )
)
)
(global.set $hangLimit
@@ -535,45 +912,25 @@
)
)
)
- (select
- (f64.const 35184372088832)
- (f64x2.extract_lane 0
- (v128.const i32x4 0x55800000 0x4f800000 0x3def9db2 0x4e6dcc9d)
- )
- (loop $label$0 (result i32)
- (block
+ (block $label$0
+ (f64.store offset=2
+ (select
+ (local.get $1)
+ (local.get $1)
(if
(i32.eqz
- (global.get $hangLimit)
- )
- (return
- (f64.const 4294967213)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block (result i32)
- (block $label$1
- (call_indirect (type $none_=>_none)
- (i32.const 2)
- )
- (nop)
- )
- (br_if $label$0
- (i32.eqz
- (loop $label$2 (result i32)
+ (loop $label$6 (result i32)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (f64.const 8589934591.815)
+ (tuple.make
+ (i32.const -16383)
+ (ref.null any)
+ (ref.null extern)
+ )
)
)
(global.set $hangLimit
@@ -584,156 +941,257 @@
)
)
(block (result i32)
- (block $label$15
- (memory.copy
- (i32.and
- (i32.const -8192)
- (i32.const 15)
- )
- (i32.and
- (i8x16.extract_lane_s 1
- (v128.const i32x4 0x3329287c 0x00007fff 0x00000002 0x00002966)
+ (nop)
+ (br_if $label$6
+ (i32.eqz
+ (i32x4.extract_lane 0
+ (v128.load offset=2 align=4
+ (i16x8.extract_lane_u 5
+ (if (result v128)
+ (local.get $1)
+ (block $label$7 (result v128)
+ (nop)
+ (v128.const i32x4 0xffff8001 0xffffffff 0x4d2b4835 0x00000000)
+ )
+ (block $label$8 (result v128)
+ (block $label$9
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (nop)
+ )
+ (v128.const i32x4 0x0d756b0d 0x0d0f0301 0x60626c7f 0x07092727)
+ )
+ )
+ )
)
- (i32.const 15)
)
- (i32.atomic.rmw8.add_u offset=1
- (i32.and
- (i32.const -93)
- (i32.const 15)
+ )
+ )
+ (block $label$10 (result i32)
+ (loop $label$11
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (tuple.make
+ (i32.const 622862719)
+ (ref.null any)
+ (ref.null extern)
+ )
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
- (i32.const 26)
)
- )
- (br_if $label$15
- (i32.eqz
- (i32.const 169416729)
+ (block
+ (br_if $label$6
+ (loop $label$12 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (tuple.make
+ (i32.const 0)
+ (ref.null any)
+ (ref.null extern)
+ )
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$13 (result i32)
+ (data.drop 0)
+ (i32.const 2)
+ )
+ )
+ )
+ (br_if $label$11
+ (local.get $1)
+ )
+ (loop $label$14
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (tuple.make
+ (i32.const 25948)
+ (ref.null any)
+ (ref.null extern)
+ )
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (f32.store offset=4 align=2
+ (i32.and
+ (i32.atomic.rmw8.or_u offset=4
+ (i32.and
+ (i32.const 13)
+ (i32.const 15)
+ )
+ (atomic.notify offset=22
+ (i32.and
+ (local.get $1)
+ (i32.const 15)
+ )
+ (br_if $label$10
+ (local.get $1)
+ (i32.eqz
+ (local.get $1)
+ )
+ )
+ )
+ )
+ (i32.const 15)
+ )
+ (f32.const 18446744073709551615)
+ )
+ )
)
)
- )
- (br_if $label$2
- (i32.const 1397565735)
- )
- (tuple.extract 1
- (tuple.make
- (f64.const -2.2250738585072014e-308)
- (i32.const -86)
- )
+ (br $label$6)
)
)
)
)
- )
- (if (result i32)
- (if (result i32)
- (i32.const -33)
- (i32.trunc_f32_s
- (f32.load offset=4 align=1
- (i32.const 1347440720)
+ (block $label$16
+ (nop)
+ (return
+ (tuple.make
+ (i32.const 33554433)
+ (ref.null any)
+ (ref.null extern)
)
)
- (i32.const -83)
)
- (block $label$12 (result i32)
- (nop)
- (i32.const -5)
+ (block $label$17
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (return
+ (tuple.make
+ (i32.const 0)
+ (ref.null any)
+ (ref.null extern)
+ )
+ )
)
- (if (result i32)
- (i32.eqz
- (i32.load offset=3 align=1
- (i32.and
- (block $label$23
- (nop)
+ )
+ )
+ (f64x2.extract_lane 0
+ (v128.const i32x4 0x14171109 0x0109440d 0x10031007 0x021d1401)
+ )
+ )
+ (if
+ (local.tee $1
+ (local.tee $1
+ (block $label$18 (result i32)
+ (call $log-f64
+ (loop $label$19 (result f64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
(return
- (f64.const -1)
+ (tuple.make
+ (i32.const -10)
+ (ref.null any)
+ (ref.null extern)
+ )
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
)
)
- (i32.const 15)
)
- )
- )
- (block $label$13 (result i32)
- (call $log-i32
- (i32.load offset=4 align=1
- (i32.and
- (i32.const 2049)
- (block $label$24
- (global.set $global$4
- (f64.const 3.475623083072852e-234)
+ (block (result f64)
+ (block $label$20
+ (call $log-f32
+ (block $label$21
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (br $label$19)
)
- (return
- (f64.const -2147483647.157)
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ )
+ (br_if $label$19
+ (i32.eqz
+ (ref.is_null
+ (ref.null extern)
)
)
)
+ (f64.const 4294967278)
)
)
- (block $label$14
- (call $log-i64
- (local.get $0)
- )
- (nop)
- )
- (f32.gt
- (f32.sqrt
- (local.tee $4
- (local.get $1)
- )
- )
- (f32.const 512.2849731445312)
+ )
+ (i32.atomic.load16_u offset=3
+ (i32.and
+ (local.get $1)
+ (i32.const 15)
)
)
- (i32.const 0)
)
)
)
- )
- )
- )
- (func $func_19 (result f32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (f32.const 8589934592)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
+ (block $label$1
+ (return
+ (tuple.make
+ (i32.const -131072)
+ (ref.null any)
+ (ref.null extern)
+ )
+ )
)
- )
- )
- (f32.load offset=4 align=2
- (i32.and
- (i32.popcnt
- (ref.is_null
- (block $label$0 (result exnref)
- (nop)
- (call $log-f32
- (f32.convert_i64_s
- (i32.atomic.rmw.cmpxchg offset=22
- (i32.and
- (block $label$1
- (atomic.fence)
- (return
- (f32.const -512.8049926757812)
- )
- )
- (i32.const 15)
- )
- (i64.const -28)
- (i64.const -524289)
- )
- )
+ (block $label$2
+ (i32.atomic.store16 offset=4
+ (i32.and
+ (local.tee $1
+ (local.get $1)
)
- (ref.null exn)
+ (i32.const 15)
+ )
+ (local.tee $1
+ (i32.const 843005738)
+ )
+ )
+ (return
+ (tuple.make
+ (i32.const -8388607)
+ (ref.null any)
+ (ref.null extern)
)
)
)
- (i32.const 15)
)
)
)
diff --git a/test/reference-types.wast b/test/reference-types.wast
index 80755124e..ad0f908ce 100644
--- a/test/reference-types.wast
+++ b/test/reference-types.wast
@@ -1,22 +1,24 @@
;; reftype :: externref | funcref | exnref
-;; TODO (GC): the subtyping relationship has been removed from the current
-;; proposal so the relevant test cases have been disabled. Once `anyref` becomes
-;; enabled, these tests can be uncommented again.
+;; NOTE: the subtyping relationship has been removed from the reference-types proposal but an
+;; `--enable-anyref` feature flag is present in Binaryen that we use below to test subtyping.
+;;
+;; reftype :: reftype | anyref
+;; reftype <: anyref
(module
(type $sig_externref (func (param externref)))
(type $sig_funcref (func (param funcref)))
(type $sig_exnref (func (param exnref)))
- ;; (type $sig_anyref (func (param anyref)))
+ (type $sig_anyref (func (param anyref)))
(func $take_externref (param externref))
(func $take_funcref (param funcref))
(func $take_exnref (param exnref))
- ;; (func $take_anyref (param anyref))
+ (func $take_anyref (param anyref))
(func $foo)
- (table funcref (elem $take_externref $take_funcref $take_exnref)) ;; $take_anyref
+ (table funcref (elem $take_externref $take_funcref $take_exnref $take_anyref))
(import "env" "import_func" (func $import_func (param externref) (result funcref)))
(import "env" "import_global" (global $import_global externref))
@@ -28,19 +30,19 @@
(global $global_funcref (mut funcref) (ref.null func))
(global $global_funcref_func (mut funcref) (ref.func $foo))
(global $global_exnref (mut exnref) (ref.null exn))
- ;; (global $global_anyref (mut anyref) (ref.null any))
+ (global $global_anyref (mut anyref) (ref.null any))
;; Test subtype relationship in global initializer expressions
- ;; (global $global_anyref2 (mut anyref) (ref.null extern))
- ;; (global $global_anyref3 (mut anyref) (ref.null func))
- ;; (global $global_anyref4 (mut anyref) (ref.func $foo))
- ;; (global $global_anyref5 (mut anyref) (ref.null exn))
+ (global $global_anyref2 (mut anyref) (ref.null extern))
+ (global $global_anyref3 (mut anyref) (ref.null func))
+ (global $global_anyref4 (mut anyref) (ref.func $foo))
+ (global $global_anyref5 (mut anyref) (ref.null exn))
(func $test
(local $local_externref externref)
(local $local_funcref funcref)
(local $local_exnref exnref)
- ;; (local $local_anyref anyref)
+ (local $local_anyref anyref)
;; Test types for local.get/set
(local.set $local_externref (local.get $local_externref))
@@ -53,21 +55,21 @@
(local.set $local_exnref (local.get $local_exnref))
(local.set $local_exnref (global.get $global_exnref))
(local.set $local_exnref (ref.null exn))
- ;; (local.set $local_anyref (local.get $local_anyref))
- ;; (local.set $local_anyref (global.get $global_anyref))
- ;; (local.set $local_anyref (ref.null any))
+ (local.set $local_anyref (local.get $local_anyref))
+ (local.set $local_anyref (global.get $global_anyref))
+ (local.set $local_anyref (ref.null any))
;; Test subtype relationship for local.set
- ;; (local.set $local_anyref (local.get $local_externref))
- ;; (local.set $local_anyref (global.get $global_externref))
- ;; (local.set $local_anyref (ref.null extern))
- ;; (local.set $local_anyref (local.get $local_funcref))
- ;; (local.set $local_anyref (global.get $global_funcref))
- ;; (local.set $local_anyref (ref.null func))
- ;; (local.set $local_anyref (ref.func $foo))
- ;; (local.set $local_anyref (local.get $local_exnref))
- ;; (local.set $local_anyref (global.get $global_exnref))
- ;; (local.set $local_anyref (ref.null exn))
+ (local.set $local_anyref (local.get $local_externref))
+ (local.set $local_anyref (global.get $global_externref))
+ (local.set $local_anyref (ref.null extern))
+ (local.set $local_anyref (local.get $local_funcref))
+ (local.set $local_anyref (global.get $global_funcref))
+ (local.set $local_anyref (ref.null func))
+ (local.set $local_anyref (ref.func $foo))
+ (local.set $local_anyref (local.get $local_exnref))
+ (local.set $local_anyref (global.get $global_exnref))
+ (local.set $local_anyref (ref.null exn))
;; Test types for global.get/set
(global.set $global_externref (global.get $global_externref))
@@ -80,21 +82,21 @@
(global.set $global_exnref (global.get $global_exnref))
(global.set $global_exnref (local.get $local_exnref))
(global.set $global_exnref (ref.null exn))
- ;; (global.set $global_anyref (global.get $global_anyref))
- ;; (global.set $global_anyref (local.get $local_anyref))
- ;; (global.set $global_anyref (ref.null any))
+ (global.set $global_anyref (global.get $global_anyref))
+ (global.set $global_anyref (local.get $local_anyref))
+ (global.set $global_anyref (ref.null any))
;; Test subtype relationship for global.set
- ;; (global.set $global_anyref (global.get $global_externref))
- ;; (global.set $global_anyref (local.get $local_externref))
- ;; (global.set $global_anyref (ref.null extern))
- ;; (global.set $global_anyref (global.get $global_funcref))
- ;; (global.set $global_anyref (local.get $local_funcref))
- ;; (global.set $global_anyref (ref.null func))
- ;; (global.set $global_anyref (ref.func $foo))
- ;; (global.set $global_anyref (global.get $global_exnref))
- ;; (global.set $global_anyref (local.get $local_exnref))
- ;; (global.set $global_anyref (ref.null exn))
+ (global.set $global_anyref (global.get $global_externref))
+ (global.set $global_anyref (local.get $local_externref))
+ (global.set $global_anyref (ref.null extern))
+ (global.set $global_anyref (global.get $global_funcref))
+ (global.set $global_anyref (local.get $local_funcref))
+ (global.set $global_anyref (ref.null func))
+ (global.set $global_anyref (ref.func $foo))
+ (global.set $global_anyref (global.get $global_exnref))
+ (global.set $global_anyref (local.get $local_exnref))
+ (global.set $global_anyref (ref.null exn))
;; Test function call params
(call $take_externref (local.get $local_externref))
@@ -107,21 +109,21 @@
(call $take_exnref (local.get $local_exnref))
(call $take_exnref (global.get $global_exnref))
(call $take_exnref (ref.null exn))
- ;; (call $take_anyref (local.get $local_anyref))
- ;; (call $take_anyref (global.get $global_anyref))
- ;; (call $take_anyref (ref.null any))
+ (call $take_anyref (local.get $local_anyref))
+ (call $take_anyref (global.get $global_anyref))
+ (call $take_anyref (ref.null any))
;; Test subtype relationship for function call params
- ;; (call $take_anyref (local.get $local_externref))
- ;; (call $take_anyref (global.get $global_externref))
- ;; (call $take_anyref (ref.null extern))
- ;; (call $take_anyref (local.get $local_funcref))
- ;; (call $take_anyref (global.get $global_funcref))
- ;; (call $take_anyref (ref.null func))
- ;; (call $take_anyref (ref.func $foo))
- ;; (call $take_anyref (local.get $local_exnref))
- ;; (call $take_anyref (global.get $global_exnref))
- ;; (call $take_anyref (ref.null exn))
+ (call $take_anyref (local.get $local_externref))
+ (call $take_anyref (global.get $global_externref))
+ (call $take_anyref (ref.null extern))
+ (call $take_anyref (local.get $local_funcref))
+ (call $take_anyref (global.get $global_funcref))
+ (call $take_anyref (ref.null func))
+ (call $take_anyref (ref.func $foo))
+ (call $take_anyref (local.get $local_exnref))
+ (call $take_anyref (global.get $global_exnref))
+ (call $take_anyref (ref.null exn))
;; Test call_indirect params
(call_indirect (type $sig_externref) (local.get $local_externref) (i32.const 0))
@@ -134,21 +136,21 @@
(call_indirect (type $sig_exnref) (local.get $local_exnref) (i32.const 2))
(call_indirect (type $sig_exnref) (global.get $global_exnref) (i32.const 2))
(call_indirect (type $sig_exnref) (ref.null exn) (i32.const 2))
- ;; (call_indirect (type $sig_anyref) (local.get $local_anyref) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (global.get $global_anyref) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (ref.null any) (i32.const 3))
+ (call_indirect (type $sig_anyref) (local.get $local_anyref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (global.get $global_anyref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (ref.null any) (i32.const 3))
;; Test subtype relationship for call_indirect params
- ;; (call_indirect (type $sig_anyref) (local.get $local_externref) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (global.get $global_externref) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (ref.null extern) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (local.get $local_funcref) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (global.get $global_funcref) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (ref.null func) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (ref.func $foo) (i32.const 3))
- ;; (call_indirect (type $sig_anyref) (local.get $local_exnref) (i32.const 3)
- ;; (call_indirect (type $sig_anyref) (global.get $global_exnref) (i32.const 3)
- ;; (call_indirect (type $sig_anyref) (ref.null exn) (i32.const 3))
+ (call_indirect (type $sig_anyref) (local.get $local_externref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (global.get $global_externref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (ref.null extern) (i32.const 3))
+ (call_indirect (type $sig_anyref) (local.get $local_funcref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (global.get $global_funcref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (ref.null func) (i32.const 3))
+ (call_indirect (type $sig_anyref) (ref.func $foo) (i32.const 3))
+ (call_indirect (type $sig_anyref) (local.get $local_exnref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (global.get $global_exnref) (i32.const 3))
+ (call_indirect (type $sig_anyref) (ref.null exn) (i32.const 3))
;; Test block return type
(drop
@@ -201,58 +203,58 @@
(br_if 0 (ref.null exn) (i32.const 1))
)
)
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (local.get $local_anyref) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (global.get $global_anyref) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (ref.null any) (i32.const 1))
- ;; )
- ;; )
+ (drop
+ (block (result anyref)
+ (br_if 0 (local.get $local_anyref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (global.get $global_anyref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (ref.null any) (i32.const 1))
+ )
+ )
;; Test subtype relationship for block return type
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (local.get $local_externref) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (local.get $local_funcref) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (local.get $local_exnref) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (ref.null extern) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (ref.null func) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (ref.func $foo) (i32.const 1))
- ;; )
- ;; )
- ;; (drop
- ;; (block (result anyref)
- ;; (br_if 0 (ref.null exn) (i32.const 1))
- ;; )
- ;; )
+ (drop
+ (block (result anyref)
+ (br_if 0 (local.get $local_externref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (local.get $local_funcref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (local.get $local_exnref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (ref.null extern) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (ref.null func) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (ref.func $foo) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result anyref)
+ (br_if 0 (ref.null exn) (i32.const 1))
+ )
+ )
;; Test loop return type
(drop
@@ -305,73 +307,73 @@
(ref.null exn)
)
)
- ;; (drop
- ;; (loop (result anyref)
- ;; (local.get $local_anyref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (global.get $global_anyref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (ref.null any)
- ;; )
- ;; )
+ (drop
+ (loop (result anyref)
+ (local.get $local_anyref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (global.get $global_anyref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (ref.null any)
+ )
+ )
;; Test subtype relationship for loop return type
- ;; (drop
- ;; (loop (result anyref)
- ;; (local.get $local_externref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (global.get $global_externref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (ref.null extern)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (local.get $local_funcref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (global.get $global_funcref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (ref.null func)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (ref.func $foo)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (local.get $local_exnref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (global.get $global_exnref)
- ;; )
- ;; )
- ;; (drop
- ;; (loop (result anyref)
- ;; (ref.null exn)
- ;; )
- ;; )
+ (drop
+ (loop (result anyref)
+ (local.get $local_externref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (global.get $global_externref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (local.get $local_funcref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (global.get $global_funcref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (ref.null func)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (ref.func $foo)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (local.get $local_exnref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (global.get $global_exnref)
+ )
+ )
+ (drop
+ (loop (result anyref)
+ (ref.null exn)
+ )
+ )
;; Test if return type
(drop
@@ -395,64 +397,64 @@
(ref.null exn)
)
)
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (local.get $local_anyref)
- ;; (ref.null any)
- ;; )
- ;; )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_anyref)
+ (ref.null any)
+ )
+ )
;; Test subtype relationship for if return type
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (local.get $local_externref)
- ;; (local.get $local_funcref)
- ;; )
- ;; )
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (local.get $local_externref)
- ;; (local.get $local_exnref)
- ;; )
- ;; )
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (local.get $local_funcref)
- ;; (local.get $local_exnref)
- ;; )
- ;; )
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (ref.null extern)
- ;; (ref.null func)
- ;; )
- ;; )
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (ref.null extern)
- ;; (ref.null exn)
- ;; )
- ;; )
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (ref.null func)
- ;; (ref.null exn)
- ;; )
- ;; )
- ;; (drop
- ;; (if (result anyref)
- ;; (i32.const 1)
- ;; (ref.func $foo)
- ;; (ref.null extern)
- ;; )
- ;; )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_externref)
+ (local.get $local_funcref)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_externref)
+ (local.get $local_exnref)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_funcref)
+ (local.get $local_exnref)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null func)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null func)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.func $foo)
+ (ref.null extern)
+ )
+ )
;; Test try return type
(drop
@@ -489,70 +491,70 @@
)
;; Test subtype relationship for try return type
- ;; (drop
- ;; (try (result anyref)
- ;; (do
- ;; (local.get $local_externref)
- ;; )
- ;; (catch
- ;; (drop (exnref.pop))
- ;; (ref.func $foo)
- ;; )
- ;; )
- ;; )
- ;; (drop
- ;; (try (result anyref)
- ;; (do
- ;; (local.get $local_externref)
- ;; )
- ;; (catch
- ;; (exnref.pop)
- ;; )
- ;; )
- ;; )
- ;; (drop
- ;; (try (result anyref)
- ;; (do
- ;; (ref.func $foo)
- ;; )
- ;; (catch
- ;; (drop (exnref.pop))
- ;; (local.get $local_externref)
- ;; )
- ;; )
- ;; )
- ;; (drop
- ;; (try (result anyref)
- ;; (do
- ;; (ref.func $foo)
- ;; )
- ;; (catch
- ;; (exnref.pop)
- ;; )
- ;; )
- ;; )
- ;; (drop
- ;; (try (result anyref)
- ;; (do
- ;; (ref.null exn)
- ;; )
- ;; (catch
- ;; (drop (exnref.pop))
- ;; (local.get $local_externref)
- ;; )
- ;; )
- ;; )
- ;; (drop
- ;; (try (result anyref)
- ;; (do
- ;; (ref.null exn)
- ;; )
- ;; (catch
- ;; (drop (exnref.pop))
- ;; (ref.func $foo)
- ;; )
- ;; )
- ;; )
+ (drop
+ (try (result anyref)
+ (do
+ (local.get $local_externref)
+ )
+ (catch
+ (drop (exnref.pop))
+ (ref.func $foo)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (local.get $local_externref)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $foo)
+ )
+ (catch
+ (drop (exnref.pop))
+ (local.get $local_externref)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $foo)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop (exnref.pop))
+ (local.get $local_externref)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop (exnref.pop))
+ (ref.func $foo)
+ )
+ )
+ )
;; Test typed select
(drop
@@ -585,48 +587,48 @@
)
;; Test subtype relationship for typed select
- ;; (drop
- ;; (select (result anyref)
- ;; (local.get $local_externref)
- ;; (local.get $local_funcref)
- ;; (i32.const 1)
- ;; )
- ;; )
- ;; (drop
- ;; (select (result anyref)
- ;; (local.get $local_externref)
- ;; (local.get $local_exnref)
- ;; (i32.const 1)
- ;; )
- ;; )
- ;; (drop
- ;; (select (result anyref)
- ;; (local.get $local_funcref)
- ;; (local.get $local_externref)
- ;; (i32.const 1)
- ;; )
- ;; )
- ;; (drop
- ;; (select (result anyref)
- ;; (local.get $local_funcref)
- ;; (local.get $local_exnref)
- ;; (i32.const 1)
- ;; )
- ;; )
- ;; (drop
- ;; (select (result anyref)
- ;; (local.get $local_exnref)
- ;; (local.get $local_externref)
- ;; (i32.const 1)
- ;; )
- ;; )
- ;; (drop
- ;; (select (result anyref)
- ;; (local.get $local_exnref)
- ;; (local.get $local_funcref)
- ;; (i32.const 1)
- ;; )
- ;; )
+ (drop
+ (select (result anyref)
+ (local.get $local_externref)
+ (local.get $local_funcref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_externref)
+ (local.get $local_exnref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_funcref)
+ (local.get $local_externref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_funcref)
+ (local.get $local_exnref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_exnref)
+ (local.get $local_externref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_exnref)
+ (local.get $local_funcref)
+ (i32.const 1)
+ )
+ )
;; ref.is_null takes any reference types
(drop (ref.is_null (local.get $local_externref)))
@@ -639,9 +641,9 @@
(drop (ref.is_null (local.get $local_exnref)))
(drop (ref.is_null (global.get $global_exnref)))
(drop (ref.is_null (ref.null exn)))
- ;; (drop (ref.is_null (local.get $local_anyref)))
- ;; (drop (ref.is_null (global.get $global_anyref)))
- ;; (drop (ref.is_null (ref.null any)))
+ (drop (ref.is_null (local.get $local_anyref)))
+ (drop (ref.is_null (global.get $global_anyref)))
+ (drop (ref.is_null (ref.null any)))
)
;; Test function return type
@@ -678,51 +680,51 @@
(func $return_exnref_null (result exnref)
(ref.null exn)
)
- ;; (func $return_anyref_local (result anyref)
- ;; (local $local_anyref anyref)
- ;; (local.get $local_anyref)
- ;; )
- ;; (func $return_anyref_global (result anyref)
- ;; (global.get $global_anyref)
- ;; )
- ;; (func $return_anyref_null (result anyref)
- ;; (ref.null any)
- ;; )
+ (func $return_anyref_local (result anyref)
+ (local $local_anyref anyref)
+ (local.get $local_anyref)
+ )
+ (func $return_anyref_global (result anyref)
+ (global.get $global_anyref)
+ )
+ (func $return_anyref_null (result anyref)
+ (ref.null any)
+ )
;; Test subtype relationship in function return type
- ;; (func $return_anyref2 (result anyref)
- ;; (local $local_externref externref)
- ;; (local.get $local_externref)
- ;; )
- ;; (func $return_anyref3 (result anyref)
- ;; (global.get $global_externref)
- ;; )
- ;; (func $return_anyref4 (result anyref)
- ;; (ref.null extern)
- ;; )
- ;; (func $return_anyref5 (result anyref)
- ;; (local $local_funcref funcref)
- ;; (local.get $local_funcref)
- ;; )
- ;; (func $return_anyref6 (result anyref)
- ;; (global.get $global_funcref)
- ;; )
- ;; (func $return_anyref7 (result anyref)
- ;; (ref.null func)
- ;; )
- ;; (func $return_anyref8 (result anyref)
- ;; (ref.func $foo)
- ;; )
- ;; (func $return_anyref9 (result anyref)
- ;; (local $local_exnnref exnref)
- ;; (local.get $local_exnref)
- ;; )
- ;; (func $return_anyref10 (result anyref)
- ;; (global.get $global_exnref)
- ;; )
- ;; (func $return_anyref11 (result anyref)
- ;; (ref.null exn)
- ;; )
+ (func $return_anyref2 (result anyref)
+ (local $local_externref externref)
+ (local.get $local_externref)
+ )
+ (func $return_anyref3 (result anyref)
+ (global.get $global_externref)
+ )
+ (func $return_anyref4 (result anyref)
+ (ref.null extern)
+ )
+ (func $return_anyref5 (result anyref)
+ (local $local_funcref funcref)
+ (local.get $local_funcref)
+ )
+ (func $return_anyref6 (result anyref)
+ (global.get $global_funcref)
+ )
+ (func $return_anyref7 (result anyref)
+ (ref.null func)
+ )
+ (func $return_anyref8 (result anyref)
+ (ref.func $foo)
+ )
+ (func $return_anyref9 (result anyref)
+ (local $local_exnref exnref)
+ (local.get $local_exnref)
+ )
+ (func $return_anyref10 (result anyref)
+ (global.get $global_exnref)
+ )
+ (func $return_anyref11 (result anyref)
+ (ref.null exn)
+ )
;; Test returns
(func $returns_externref (result externref)
@@ -744,27 +746,27 @@
(return (global.get $global_exnref))
(return (ref.null exn))
)
- ;; (func $returns_anyref (result anyref)
- ;; (local $local_anyref anyref)
- ;; (return (local.get $local_anyref))
- ;; (return (global.get $global_anyref))
- ;; (return (ref.null any))
- ;; )
+ (func $returns_anyref (result anyref)
+ (local $local_anyref anyref)
+ (return (local.get $local_anyref))
+ (return (global.get $global_anyref))
+ (return (ref.null any))
+ )
;; Test subtype relationship in returns
- ;; (func $returns_anyref2 (result anyref)
- ;; (local $local_externref externref)
- ;; (local $local_funcref funcref)
- ;; (local $local_exnref exnref)
- ;; (return (local.get $local_externref))
- ;; (return (global.get $global_externref))
- ;; (return (ref.null extern))
- ;; (return (local.get $local_funcref))
- ;; (return (global.get $global_funcref))
- ;; (return (ref.func $foo))
- ;; (return (ref.null func))
- ;; (return (local.get $local_exnref))
- ;; (return (global.get $global_exnref))
- ;; (return (ref.null exn))
- ;; )
+ (func $returns_anyref2 (result anyref)
+ (local $local_externref externref)
+ (local $local_funcref funcref)
+ (local $local_exnref exnref)
+ (return (local.get $local_externref))
+ (return (global.get $global_externref))
+ (return (ref.null extern))
+ (return (local.get $local_funcref))
+ (return (global.get $global_funcref))
+ (return (ref.func $foo))
+ (return (ref.null func))
+ (return (local.get $local_exnref))
+ (return (global.get $global_exnref))
+ (return (ref.null exn))
+ )
)
diff --git a/test/reference-types.wast.from-wast b/test/reference-types.wast.from-wast
index ac9660531..4e82da60d 100644
--- a/test/reference-types.wast.from-wast
+++ b/test/reference-types.wast.from-wast
@@ -1,4 +1,6 @@
(module
+ (type $none_=>_anyref (func (result anyref)))
+ (type $anyref_=>_none (func (param anyref)))
(type $funcref_=>_none (func (param funcref)))
(type $none_=>_funcref (func (result funcref)))
(type $externref_=>_none (func (param externref)))
@@ -9,12 +11,17 @@
(type $externref_=>_funcref (func (param externref) (result funcref)))
(import "env" "import_global" (global $import_global externref))
(import "env" "import_func" (func $import_func (param externref) (result funcref)))
- (table $0 3 3 funcref)
- (elem (i32.const 0) $take_externref $take_funcref $take_exnref)
+ (table $0 4 4 funcref)
+ (elem (i32.const 0) $take_externref $take_funcref $take_exnref $take_anyref)
(global $global_externref (mut externref) (ref.null extern))
(global $global_funcref (mut funcref) (ref.null func))
(global $global_funcref_func (mut funcref) (ref.func $foo))
(global $global_exnref (mut exnref) (ref.null exn))
+ (global $global_anyref (mut anyref) (ref.null any))
+ (global $global_anyref2 (mut anyref) (ref.null extern))
+ (global $global_anyref3 (mut anyref) (ref.null func))
+ (global $global_anyref4 (mut anyref) (ref.func $foo))
+ (global $global_anyref5 (mut anyref) (ref.null exn))
(export "export_func" (func $import_func))
(export "export_global" (global $import_global))
(func $take_externref (param $0 externref)
@@ -26,6 +33,9 @@
(func $take_exnref (param $0 exnref)
(nop)
)
+ (func $take_anyref (param $0 anyref)
+ (nop)
+ )
(func $foo
(nop)
)
@@ -33,6 +43,7 @@
(local $local_externref externref)
(local $local_funcref funcref)
(local $local_exnref exnref)
+ (local $local_anyref anyref)
(local.set $local_externref
(local.get $local_externref)
)
@@ -63,6 +74,45 @@
(local.set $local_exnref
(ref.null exn)
)
+ (local.set $local_anyref
+ (local.get $local_anyref)
+ )
+ (local.set $local_anyref
+ (global.get $global_anyref)
+ )
+ (local.set $local_anyref
+ (ref.null any)
+ )
+ (local.set $local_anyref
+ (local.get $local_externref)
+ )
+ (local.set $local_anyref
+ (global.get $global_externref)
+ )
+ (local.set $local_anyref
+ (ref.null extern)
+ )
+ (local.set $local_anyref
+ (local.get $local_funcref)
+ )
+ (local.set $local_anyref
+ (global.get $global_funcref)
+ )
+ (local.set $local_anyref
+ (ref.null func)
+ )
+ (local.set $local_anyref
+ (ref.func $foo)
+ )
+ (local.set $local_anyref
+ (local.get $local_exnref)
+ )
+ (local.set $local_anyref
+ (global.get $global_exnref)
+ )
+ (local.set $local_anyref
+ (ref.null exn)
+ )
(global.set $global_externref
(global.get $global_externref)
)
@@ -93,6 +143,45 @@
(global.set $global_exnref
(ref.null exn)
)
+ (global.set $global_anyref
+ (global.get $global_anyref)
+ )
+ (global.set $global_anyref
+ (local.get $local_anyref)
+ )
+ (global.set $global_anyref
+ (ref.null any)
+ )
+ (global.set $global_anyref
+ (global.get $global_externref)
+ )
+ (global.set $global_anyref
+ (local.get $local_externref)
+ )
+ (global.set $global_anyref
+ (ref.null extern)
+ )
+ (global.set $global_anyref
+ (global.get $global_funcref)
+ )
+ (global.set $global_anyref
+ (local.get $local_funcref)
+ )
+ (global.set $global_anyref
+ (ref.null func)
+ )
+ (global.set $global_anyref
+ (ref.func $foo)
+ )
+ (global.set $global_anyref
+ (global.get $global_exnref)
+ )
+ (global.set $global_anyref
+ (local.get $local_exnref)
+ )
+ (global.set $global_anyref
+ (ref.null exn)
+ )
(call $take_externref
(local.get $local_externref)
)
@@ -123,6 +212,45 @@
(call $take_exnref
(ref.null exn)
)
+ (call $take_anyref
+ (local.get $local_anyref)
+ )
+ (call $take_anyref
+ (global.get $global_anyref)
+ )
+ (call $take_anyref
+ (ref.null any)
+ )
+ (call $take_anyref
+ (local.get $local_externref)
+ )
+ (call $take_anyref
+ (global.get $global_externref)
+ )
+ (call $take_anyref
+ (ref.null extern)
+ )
+ (call $take_anyref
+ (local.get $local_funcref)
+ )
+ (call $take_anyref
+ (global.get $global_funcref)
+ )
+ (call $take_anyref
+ (ref.null func)
+ )
+ (call $take_anyref
+ (ref.func $foo)
+ )
+ (call $take_anyref
+ (local.get $local_exnref)
+ )
+ (call $take_anyref
+ (global.get $global_exnref)
+ )
+ (call $take_anyref
+ (ref.null exn)
+ )
(call_indirect (type $externref_=>_none)
(local.get $local_externref)
(i32.const 0)
@@ -163,6 +291,58 @@
(ref.null exn)
(i32.const 2)
)
+ (call_indirect (type $anyref_=>_none)
+ (local.get $local_anyref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global_anyref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null any)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $local_externref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global_externref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null extern)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $local_funcref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global_funcref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null func)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.func $foo)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $local_exnref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global_exnref)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null exn)
+ (i32.const 3)
+ )
(drop
(block $block (result externref)
(br_if $block
@@ -244,52 +424,197 @@
)
)
(drop
+ (block $block9 (result anyref)
+ (br_if $block9
+ (local.get $local_anyref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block10 (result anyref)
+ (br_if $block10
+ (global.get $global_anyref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block11 (result anyref)
+ (br_if $block11
+ (ref.null any)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block12 (result anyref)
+ (br_if $block12
+ (local.get $local_externref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block13 (result anyref)
+ (br_if $block13
+ (local.get $local_funcref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block14 (result anyref)
+ (br_if $block14
+ (local.get $local_exnref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block15 (result anyref)
+ (br_if $block15
+ (ref.null extern)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block16 (result anyref)
+ (br_if $block16
+ (ref.null func)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block17 (result anyref)
+ (br_if $block17
+ (ref.func $foo)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block18 (result anyref)
+ (br_if $block18
+ (ref.null exn)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
(loop $loop-in (result externref)
(local.get $local_externref)
)
)
(drop
- (loop $loop-in9 (result externref)
+ (loop $loop-in19 (result externref)
(global.get $global_externref)
)
)
(drop
- (loop $loop-in10 (result externref)
+ (loop $loop-in20 (result externref)
(ref.null extern)
)
)
(drop
- (loop $loop-in11 (result funcref)
+ (loop $loop-in21 (result funcref)
(local.get $local_funcref)
)
)
(drop
- (loop $loop-in12 (result funcref)
+ (loop $loop-in22 (result funcref)
(global.get $global_funcref)
)
)
(drop
- (loop $loop-in13 (result funcref)
+ (loop $loop-in23 (result funcref)
(ref.null func)
)
)
(drop
- (loop $loop-in14 (result funcref)
+ (loop $loop-in24 (result funcref)
(ref.func $foo)
)
)
(drop
- (loop $loop-in15 (result exnref)
+ (loop $loop-in25 (result exnref)
(local.get $local_exnref)
)
)
(drop
- (loop $loop-in16 (result exnref)
+ (loop $loop-in26 (result exnref)
(global.get $global_exnref)
)
)
(drop
- (loop $loop-in17 (result exnref)
+ (loop $loop-in27 (result exnref)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (loop $loop-in28 (result anyref)
+ (local.get $local_anyref)
+ )
+ )
+ (drop
+ (loop $loop-in29 (result anyref)
+ (global.get $global_anyref)
+ )
+ )
+ (drop
+ (loop $loop-in30 (result anyref)
+ (ref.null any)
+ )
+ )
+ (drop
+ (loop $loop-in31 (result anyref)
+ (local.get $local_externref)
+ )
+ )
+ (drop
+ (loop $loop-in32 (result anyref)
+ (global.get $global_externref)
+ )
+ )
+ (drop
+ (loop $loop-in33 (result anyref)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (loop $loop-in34 (result anyref)
+ (local.get $local_funcref)
+ )
+ )
+ (drop
+ (loop $loop-in35 (result anyref)
+ (global.get $global_funcref)
+ )
+ )
+ (drop
+ (loop $loop-in36 (result anyref)
+ (ref.null func)
+ )
+ )
+ (drop
+ (loop $loop-in37 (result anyref)
+ (ref.func $foo)
+ )
+ )
+ (drop
+ (loop $loop-in38 (result anyref)
+ (local.get $local_exnref)
+ )
+ )
+ (drop
+ (loop $loop-in39 (result anyref)
+ (global.get $global_exnref)
+ )
+ )
+ (drop
+ (loop $loop-in40 (result anyref)
(ref.null exn)
)
)
@@ -315,6 +640,62 @@
)
)
(drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_anyref)
+ (ref.null any)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_externref)
+ (local.get $local_funcref)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_externref)
+ (local.get $local_exnref)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $local_funcref)
+ (local.get $local_exnref)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null func)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null func)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.func $foo)
+ (ref.null extern)
+ )
+ )
+ (drop
(try (result externref)
(do
(local.get $local_externref)
@@ -351,6 +732,78 @@
)
)
(drop
+ (try (result anyref)
+ (do
+ (local.get $local_externref)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (ref.func $foo)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (local.get $local_externref)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $foo)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (local.get $local_externref)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $foo)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (local.get $local_externref)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (ref.func $foo)
+ )
+ )
+ )
+ (drop
(select (result externref)
(local.get $local_externref)
(ref.null extern)
@@ -379,6 +832,48 @@
)
)
(drop
+ (select (result anyref)
+ (local.get $local_externref)
+ (local.get $local_funcref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_externref)
+ (local.get $local_exnref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_funcref)
+ (local.get $local_externref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_funcref)
+ (local.get $local_exnref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_exnref)
+ (local.get $local_externref)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $local_exnref)
+ (local.get $local_funcref)
+ (i32.const 1)
+ )
+ )
+ (drop
(ref.is_null
(local.get $local_externref)
)
@@ -428,6 +923,21 @@
(ref.null exn)
)
)
+ (drop
+ (ref.is_null
+ (local.get $local_anyref)
+ )
+ )
+ (drop
+ (ref.is_null
+ (global.get $global_anyref)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null any)
+ )
+ )
)
(func $return_externref_local (result externref)
(local $local_externref externref)
@@ -462,6 +972,49 @@
(func $return_exnref_null (result exnref)
(ref.null exn)
)
+ (func $return_anyref_local (result anyref)
+ (local $local_anyref anyref)
+ (local.get $local_anyref)
+ )
+ (func $return_anyref_global (result anyref)
+ (global.get $global_anyref)
+ )
+ (func $return_anyref_null (result anyref)
+ (ref.null any)
+ )
+ (func $return_anyref2 (result anyref)
+ (local $local_externref externref)
+ (local.get $local_externref)
+ )
+ (func $return_anyref3 (result anyref)
+ (global.get $global_externref)
+ )
+ (func $return_anyref4 (result anyref)
+ (ref.null extern)
+ )
+ (func $return_anyref5 (result anyref)
+ (local $local_funcref funcref)
+ (local.get $local_funcref)
+ )
+ (func $return_anyref6 (result anyref)
+ (global.get $global_funcref)
+ )
+ (func $return_anyref7 (result anyref)
+ (ref.null func)
+ )
+ (func $return_anyref8 (result anyref)
+ (ref.func $foo)
+ )
+ (func $return_anyref9 (result anyref)
+ (local $local_exnref exnref)
+ (local.get $local_exnref)
+ )
+ (func $return_anyref10 (result anyref)
+ (global.get $global_exnref)
+ )
+ (func $return_anyref11 (result anyref)
+ (ref.null exn)
+ )
(func $returns_externref (result externref)
(local $local_externref externref)
(return
@@ -501,4 +1054,51 @@
(ref.null exn)
)
)
+ (func $returns_anyref (result anyref)
+ (local $local_anyref anyref)
+ (return
+ (local.get $local_anyref)
+ )
+ (return
+ (global.get $global_anyref)
+ )
+ (return
+ (ref.null any)
+ )
+ )
+ (func $returns_anyref2 (result anyref)
+ (local $local_externref externref)
+ (local $local_funcref funcref)
+ (local $local_exnref exnref)
+ (return
+ (local.get $local_externref)
+ )
+ (return
+ (global.get $global_externref)
+ )
+ (return
+ (ref.null extern)
+ )
+ (return
+ (local.get $local_funcref)
+ )
+ (return
+ (global.get $global_funcref)
+ )
+ (return
+ (ref.func $foo)
+ )
+ (return
+ (ref.null func)
+ )
+ (return
+ (local.get $local_exnref)
+ )
+ (return
+ (global.get $global_exnref)
+ )
+ (return
+ (ref.null exn)
+ )
+ )
)
diff --git a/test/reference-types.wast.fromBinary b/test/reference-types.wast.fromBinary
index f4a958d99..c266e725a 100644
--- a/test/reference-types.wast.fromBinary
+++ b/test/reference-types.wast.fromBinary
@@ -1,4 +1,6 @@
(module
+ (type $none_=>_anyref (func (result anyref)))
+ (type $anyref_=>_none (func (param anyref)))
(type $funcref_=>_none (func (param funcref)))
(type $none_=>_funcref (func (result funcref)))
(type $externref_=>_none (func (param externref)))
@@ -9,12 +11,17 @@
(type $externref_=>_funcref (func (param externref) (result funcref)))
(import "env" "import_global" (global $gimport$1 externref))
(import "env" "import_func" (func $import_func (param externref) (result funcref)))
- (table $0 3 3 funcref)
- (elem (i32.const 0) $take_externref $take_funcref $take_exnref)
+ (table $0 4 4 funcref)
+ (elem (i32.const 0) $take_externref $take_funcref $take_exnref $take_anyref)
(global $global$0 (mut externref) (ref.null extern))
(global $global$1 (mut funcref) (ref.null func))
(global $global$2 (mut funcref) (ref.func $foo))
(global $global$3 (mut exnref) (ref.null exn))
+ (global $global$4 (mut anyref) (ref.null any))
+ (global $global$5 (mut anyref) (ref.null extern))
+ (global $global$6 (mut anyref) (ref.null func))
+ (global $global$7 (mut anyref) (ref.func $foo))
+ (global $global$8 (mut anyref) (ref.null exn))
(export "export_func" (func $import_func))
(export "export_global" (global $gimport$1))
(func $take_externref (param $0 externref)
@@ -26,6 +33,9 @@
(func $take_exnref (param $0 exnref)
(nop)
)
+ (func $take_anyref (param $0 anyref)
+ (nop)
+ )
(func $foo
(nop)
)
@@ -33,6 +43,7 @@
(local $0 funcref)
(local $1 externref)
(local $2 exnref)
+ (local $3 anyref)
(local.set $1
(local.get $1)
)
@@ -63,6 +74,45 @@
(local.set $2
(ref.null exn)
)
+ (local.set $3
+ (local.get $3)
+ )
+ (local.set $3
+ (global.get $global$4)
+ )
+ (local.set $3
+ (ref.null any)
+ )
+ (local.set $3
+ (local.get $1)
+ )
+ (local.set $3
+ (global.get $global$0)
+ )
+ (local.set $3
+ (ref.null extern)
+ )
+ (local.set $3
+ (local.get $0)
+ )
+ (local.set $3
+ (global.get $global$1)
+ )
+ (local.set $3
+ (ref.null func)
+ )
+ (local.set $3
+ (ref.func $foo)
+ )
+ (local.set $3
+ (local.get $2)
+ )
+ (local.set $3
+ (global.get $global$3)
+ )
+ (local.set $3
+ (ref.null exn)
+ )
(global.set $global$0
(global.get $global$0)
)
@@ -93,6 +143,45 @@
(global.set $global$3
(ref.null exn)
)
+ (global.set $global$4
+ (global.get $global$4)
+ )
+ (global.set $global$4
+ (local.get $3)
+ )
+ (global.set $global$4
+ (ref.null any)
+ )
+ (global.set $global$4
+ (global.get $global$0)
+ )
+ (global.set $global$4
+ (local.get $1)
+ )
+ (global.set $global$4
+ (ref.null extern)
+ )
+ (global.set $global$4
+ (global.get $global$1)
+ )
+ (global.set $global$4
+ (local.get $0)
+ )
+ (global.set $global$4
+ (ref.null func)
+ )
+ (global.set $global$4
+ (ref.func $foo)
+ )
+ (global.set $global$4
+ (global.get $global$3)
+ )
+ (global.set $global$4
+ (local.get $2)
+ )
+ (global.set $global$4
+ (ref.null exn)
+ )
(call $take_externref
(local.get $1)
)
@@ -123,6 +212,45 @@
(call $take_exnref
(ref.null exn)
)
+ (call $take_anyref
+ (local.get $3)
+ )
+ (call $take_anyref
+ (global.get $global$4)
+ )
+ (call $take_anyref
+ (ref.null any)
+ )
+ (call $take_anyref
+ (local.get $1)
+ )
+ (call $take_anyref
+ (global.get $global$0)
+ )
+ (call $take_anyref
+ (ref.null extern)
+ )
+ (call $take_anyref
+ (local.get $0)
+ )
+ (call $take_anyref
+ (global.get $global$1)
+ )
+ (call $take_anyref
+ (ref.null func)
+ )
+ (call $take_anyref
+ (ref.func $foo)
+ )
+ (call $take_anyref
+ (local.get $2)
+ )
+ (call $take_anyref
+ (global.get $global$3)
+ )
+ (call $take_anyref
+ (ref.null exn)
+ )
(call_indirect (type $externref_=>_none)
(local.get $1)
(i32.const 0)
@@ -163,6 +291,58 @@
(ref.null exn)
(i32.const 2)
)
+ (call_indirect (type $anyref_=>_none)
+ (local.get $3)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$4)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null any)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $1)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$0)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null extern)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $0)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$1)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null func)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.func $foo)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $2)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$3)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null exn)
+ (i32.const 3)
+ )
(drop
(block $label$1 (result externref)
(br_if $label$1
@@ -244,52 +424,197 @@
)
)
(drop
- (loop $label$11 (result externref)
+ (block $label$11 (result anyref)
+ (br_if $label$11
+ (local.get $3)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$12 (result anyref)
+ (br_if $label$12
+ (global.get $global$4)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$13 (result anyref)
+ (br_if $label$13
+ (ref.null any)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$14 (result anyref)
+ (br_if $label$14
+ (local.get $1)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$15 (result anyref)
+ (br_if $label$15
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$16 (result anyref)
+ (br_if $label$16
+ (local.get $2)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$17 (result anyref)
+ (br_if $label$17
+ (ref.null extern)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$18 (result anyref)
+ (br_if $label$18
+ (ref.null func)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$19 (result anyref)
+ (br_if $label$19
+ (ref.func $foo)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$20 (result anyref)
+ (br_if $label$20
+ (ref.null exn)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (loop $label$21 (result externref)
+ (local.get $1)
+ )
+ )
+ (drop
+ (loop $label$22 (result externref)
+ (global.get $global$0)
+ )
+ )
+ (drop
+ (loop $label$23 (result externref)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (loop $label$24 (result funcref)
+ (local.get $0)
+ )
+ )
+ (drop
+ (loop $label$25 (result funcref)
+ (global.get $global$1)
+ )
+ )
+ (drop
+ (loop $label$26 (result funcref)
+ (ref.null func)
+ )
+ )
+ (drop
+ (loop $label$27 (result funcref)
+ (ref.func $foo)
+ )
+ )
+ (drop
+ (loop $label$28 (result exnref)
+ (local.get $2)
+ )
+ )
+ (drop
+ (loop $label$29 (result exnref)
+ (global.get $global$3)
+ )
+ )
+ (drop
+ (loop $label$30 (result exnref)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (loop $label$31 (result anyref)
+ (local.get $3)
+ )
+ )
+ (drop
+ (loop $label$32 (result anyref)
+ (global.get $global$4)
+ )
+ )
+ (drop
+ (loop $label$33 (result anyref)
+ (ref.null any)
+ )
+ )
+ (drop
+ (loop $label$34 (result anyref)
(local.get $1)
)
)
(drop
- (loop $label$12 (result externref)
+ (loop $label$35 (result anyref)
(global.get $global$0)
)
)
(drop
- (loop $label$13 (result externref)
+ (loop $label$36 (result anyref)
(ref.null extern)
)
)
(drop
- (loop $label$14 (result funcref)
+ (loop $label$37 (result anyref)
(local.get $0)
)
)
(drop
- (loop $label$15 (result funcref)
+ (loop $label$38 (result anyref)
(global.get $global$1)
)
)
(drop
- (loop $label$16 (result funcref)
+ (loop $label$39 (result anyref)
(ref.null func)
)
)
(drop
- (loop $label$17 (result funcref)
+ (loop $label$40 (result anyref)
(ref.func $foo)
)
)
(drop
- (loop $label$18 (result exnref)
+ (loop $label$41 (result anyref)
(local.get $2)
)
)
(drop
- (loop $label$19 (result exnref)
+ (loop $label$42 (result anyref)
(global.get $global$3)
)
)
(drop
- (loop $label$20 (result exnref)
+ (loop $label$43 (result anyref)
(ref.null exn)
)
)
@@ -315,6 +640,62 @@
)
)
(drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $3)
+ (ref.null any)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $1)
+ (local.get $0)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $1)
+ (local.get $2)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $0)
+ (local.get $2)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null func)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null func)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.func $foo)
+ (ref.null extern)
+ )
+ )
+ (drop
(try (result externref)
(do
(local.get $1)
@@ -351,6 +732,78 @@
)
)
(drop
+ (try (result anyref)
+ (do
+ (local.get $1)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (ref.func $foo)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (local.get $1)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $foo)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (local.get $1)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $foo)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (local.get $1)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (ref.func $foo)
+ )
+ )
+ )
+ (drop
(select (result externref)
(local.get $1)
(ref.null extern)
@@ -379,6 +832,48 @@
)
)
(drop
+ (select (result anyref)
+ (local.get $1)
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $1)
+ (local.get $2)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $0)
+ (local.get $1)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $0)
+ (local.get $2)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $2)
+ (local.get $1)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $2)
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (drop
(ref.is_null
(local.get $1)
)
@@ -428,6 +923,21 @@
(ref.null exn)
)
)
+ (drop
+ (ref.is_null
+ (local.get $3)
+ )
+ )
+ (drop
+ (ref.is_null
+ (global.get $global$4)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null any)
+ )
+ )
)
(func $return_externref_local (result externref)
(local $0 externref)
@@ -462,6 +972,49 @@
(func $return_exnref_null (result exnref)
(ref.null exn)
)
+ (func $return_anyref_local (result anyref)
+ (local $0 anyref)
+ (local.get $0)
+ )
+ (func $return_anyref_global (result anyref)
+ (global.get $global$4)
+ )
+ (func $return_anyref_null (result anyref)
+ (ref.null any)
+ )
+ (func $return_anyref2 (result anyref)
+ (local $0 externref)
+ (local.get $0)
+ )
+ (func $return_anyref3 (result anyref)
+ (global.get $global$0)
+ )
+ (func $return_anyref4 (result anyref)
+ (ref.null extern)
+ )
+ (func $return_anyref5 (result anyref)
+ (local $0 funcref)
+ (local.get $0)
+ )
+ (func $return_anyref6 (result anyref)
+ (global.get $global$1)
+ )
+ (func $return_anyref7 (result anyref)
+ (ref.null func)
+ )
+ (func $return_anyref8 (result anyref)
+ (ref.func $foo)
+ )
+ (func $return_anyref9 (result anyref)
+ (local $0 exnref)
+ (local.get $0)
+ )
+ (func $return_anyref10 (result anyref)
+ (global.get $global$3)
+ )
+ (func $return_anyref11 (result anyref)
+ (ref.null exn)
+ )
(func $returns_externref (result externref)
(local $0 externref)
(return
@@ -480,5 +1033,19 @@
(local.get $0)
)
)
+ (func $returns_anyref (result anyref)
+ (local $0 anyref)
+ (return
+ (local.get $0)
+ )
+ )
+ (func $returns_anyref2 (result anyref)
+ (local $0 funcref)
+ (local $1 externref)
+ (local $2 exnref)
+ (return
+ (local.get $1)
+ )
+ )
)
diff --git a/test/reference-types.wast.fromBinary.noDebugInfo b/test/reference-types.wast.fromBinary.noDebugInfo
index f0282f1e2..e1d18827e 100644
--- a/test/reference-types.wast.fromBinary.noDebugInfo
+++ b/test/reference-types.wast.fromBinary.noDebugInfo
@@ -1,4 +1,6 @@
(module
+ (type $none_=>_anyref (func (result anyref)))
+ (type $anyref_=>_none (func (param anyref)))
(type $funcref_=>_none (func (param funcref)))
(type $none_=>_funcref (func (result funcref)))
(type $externref_=>_none (func (param externref)))
@@ -9,12 +11,17 @@
(type $externref_=>_funcref (func (param externref) (result funcref)))
(import "env" "import_global" (global $gimport$1 externref))
(import "env" "import_func" (func $fimport$0 (param externref) (result funcref)))
- (table $0 3 3 funcref)
- (elem (i32.const 0) $0 $1 $2)
+ (table $0 4 4 funcref)
+ (elem (i32.const 0) $0 $1 $2 $3)
(global $global$0 (mut externref) (ref.null extern))
(global $global$1 (mut funcref) (ref.null func))
- (global $global$2 (mut funcref) (ref.func $3))
+ (global $global$2 (mut funcref) (ref.func $4))
(global $global$3 (mut exnref) (ref.null exn))
+ (global $global$4 (mut anyref) (ref.null any))
+ (global $global$5 (mut anyref) (ref.null extern))
+ (global $global$6 (mut anyref) (ref.null func))
+ (global $global$7 (mut anyref) (ref.func $4))
+ (global $global$8 (mut anyref) (ref.null exn))
(export "export_func" (func $fimport$0))
(export "export_global" (global $gimport$1))
(func $0 (param $0 externref)
@@ -26,13 +33,17 @@
(func $2 (param $0 exnref)
(nop)
)
- (func $3
+ (func $3 (param $0 anyref)
(nop)
)
(func $4
+ (nop)
+ )
+ (func $5
(local $0 funcref)
(local $1 externref)
(local $2 exnref)
+ (local $3 anyref)
(local.set $1
(local.get $1)
)
@@ -52,7 +63,7 @@
(ref.null func)
)
(local.set $0
- (ref.func $3)
+ (ref.func $4)
)
(local.set $2
(local.get $2)
@@ -63,6 +74,45 @@
(local.set $2
(ref.null exn)
)
+ (local.set $3
+ (local.get $3)
+ )
+ (local.set $3
+ (global.get $global$4)
+ )
+ (local.set $3
+ (ref.null any)
+ )
+ (local.set $3
+ (local.get $1)
+ )
+ (local.set $3
+ (global.get $global$0)
+ )
+ (local.set $3
+ (ref.null extern)
+ )
+ (local.set $3
+ (local.get $0)
+ )
+ (local.set $3
+ (global.get $global$1)
+ )
+ (local.set $3
+ (ref.null func)
+ )
+ (local.set $3
+ (ref.func $4)
+ )
+ (local.set $3
+ (local.get $2)
+ )
+ (local.set $3
+ (global.get $global$3)
+ )
+ (local.set $3
+ (ref.null exn)
+ )
(global.set $global$0
(global.get $global$0)
)
@@ -82,7 +132,7 @@
(ref.null func)
)
(global.set $global$1
- (ref.func $3)
+ (ref.func $4)
)
(global.set $global$3
(global.get $global$3)
@@ -93,6 +143,45 @@
(global.set $global$3
(ref.null exn)
)
+ (global.set $global$4
+ (global.get $global$4)
+ )
+ (global.set $global$4
+ (local.get $3)
+ )
+ (global.set $global$4
+ (ref.null any)
+ )
+ (global.set $global$4
+ (global.get $global$0)
+ )
+ (global.set $global$4
+ (local.get $1)
+ )
+ (global.set $global$4
+ (ref.null extern)
+ )
+ (global.set $global$4
+ (global.get $global$1)
+ )
+ (global.set $global$4
+ (local.get $0)
+ )
+ (global.set $global$4
+ (ref.null func)
+ )
+ (global.set $global$4
+ (ref.func $4)
+ )
+ (global.set $global$4
+ (global.get $global$3)
+ )
+ (global.set $global$4
+ (local.get $2)
+ )
+ (global.set $global$4
+ (ref.null exn)
+ )
(call $0
(local.get $1)
)
@@ -112,7 +201,7 @@
(ref.null func)
)
(call $1
- (ref.func $3)
+ (ref.func $4)
)
(call $2
(local.get $2)
@@ -123,6 +212,45 @@
(call $2
(ref.null exn)
)
+ (call $3
+ (local.get $3)
+ )
+ (call $3
+ (global.get $global$4)
+ )
+ (call $3
+ (ref.null any)
+ )
+ (call $3
+ (local.get $1)
+ )
+ (call $3
+ (global.get $global$0)
+ )
+ (call $3
+ (ref.null extern)
+ )
+ (call $3
+ (local.get $0)
+ )
+ (call $3
+ (global.get $global$1)
+ )
+ (call $3
+ (ref.null func)
+ )
+ (call $3
+ (ref.func $4)
+ )
+ (call $3
+ (local.get $2)
+ )
+ (call $3
+ (global.get $global$3)
+ )
+ (call $3
+ (ref.null exn)
+ )
(call_indirect (type $externref_=>_none)
(local.get $1)
(i32.const 0)
@@ -148,7 +276,7 @@
(i32.const 1)
)
(call_indirect (type $funcref_=>_none)
- (ref.func $3)
+ (ref.func $4)
(i32.const 1)
)
(call_indirect (type $exnref_=>_none)
@@ -163,6 +291,58 @@
(ref.null exn)
(i32.const 2)
)
+ (call_indirect (type $anyref_=>_none)
+ (local.get $3)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$4)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null any)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $1)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$0)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null extern)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $0)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$1)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null func)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.func $4)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (local.get $2)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (global.get $global$3)
+ (i32.const 3)
+ )
+ (call_indirect (type $anyref_=>_none)
+ (ref.null exn)
+ (i32.const 3)
+ )
(drop
(block $label$1 (result externref)
(br_if $label$1
@@ -214,7 +394,7 @@
(drop
(block $label$7 (result funcref)
(br_if $label$7
- (ref.func $3)
+ (ref.func $4)
(i32.const 1)
)
)
@@ -244,52 +424,197 @@
)
)
(drop
- (loop $label$11 (result externref)
+ (block $label$11 (result anyref)
+ (br_if $label$11
+ (local.get $3)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$12 (result anyref)
+ (br_if $label$12
+ (global.get $global$4)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$13 (result anyref)
+ (br_if $label$13
+ (ref.null any)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$14 (result anyref)
+ (br_if $label$14
+ (local.get $1)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$15 (result anyref)
+ (br_if $label$15
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$16 (result anyref)
+ (br_if $label$16
+ (local.get $2)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$17 (result anyref)
+ (br_if $label$17
+ (ref.null extern)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$18 (result anyref)
+ (br_if $label$18
+ (ref.null func)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$19 (result anyref)
+ (br_if $label$19
+ (ref.func $4)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $label$20 (result anyref)
+ (br_if $label$20
+ (ref.null exn)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (loop $label$21 (result externref)
+ (local.get $1)
+ )
+ )
+ (drop
+ (loop $label$22 (result externref)
+ (global.get $global$0)
+ )
+ )
+ (drop
+ (loop $label$23 (result externref)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (loop $label$24 (result funcref)
+ (local.get $0)
+ )
+ )
+ (drop
+ (loop $label$25 (result funcref)
+ (global.get $global$1)
+ )
+ )
+ (drop
+ (loop $label$26 (result funcref)
+ (ref.null func)
+ )
+ )
+ (drop
+ (loop $label$27 (result funcref)
+ (ref.func $4)
+ )
+ )
+ (drop
+ (loop $label$28 (result exnref)
+ (local.get $2)
+ )
+ )
+ (drop
+ (loop $label$29 (result exnref)
+ (global.get $global$3)
+ )
+ )
+ (drop
+ (loop $label$30 (result exnref)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (loop $label$31 (result anyref)
+ (local.get $3)
+ )
+ )
+ (drop
+ (loop $label$32 (result anyref)
+ (global.get $global$4)
+ )
+ )
+ (drop
+ (loop $label$33 (result anyref)
+ (ref.null any)
+ )
+ )
+ (drop
+ (loop $label$34 (result anyref)
(local.get $1)
)
)
(drop
- (loop $label$12 (result externref)
+ (loop $label$35 (result anyref)
(global.get $global$0)
)
)
(drop
- (loop $label$13 (result externref)
+ (loop $label$36 (result anyref)
(ref.null extern)
)
)
(drop
- (loop $label$14 (result funcref)
+ (loop $label$37 (result anyref)
(local.get $0)
)
)
(drop
- (loop $label$15 (result funcref)
+ (loop $label$38 (result anyref)
(global.get $global$1)
)
)
(drop
- (loop $label$16 (result funcref)
+ (loop $label$39 (result anyref)
(ref.null func)
)
)
(drop
- (loop $label$17 (result funcref)
- (ref.func $3)
+ (loop $label$40 (result anyref)
+ (ref.func $4)
)
)
(drop
- (loop $label$18 (result exnref)
+ (loop $label$41 (result anyref)
(local.get $2)
)
)
(drop
- (loop $label$19 (result exnref)
+ (loop $label$42 (result anyref)
(global.get $global$3)
)
)
(drop
- (loop $label$20 (result exnref)
+ (loop $label$43 (result anyref)
(ref.null exn)
)
)
@@ -315,6 +640,62 @@
)
)
(drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $3)
+ (ref.null any)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $1)
+ (local.get $0)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $1)
+ (local.get $2)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (local.get $0)
+ (local.get $2)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null func)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null extern)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.null func)
+ (ref.null exn)
+ )
+ )
+ (drop
+ (if (result anyref)
+ (i32.const 1)
+ (ref.func $4)
+ (ref.null extern)
+ )
+ )
+ (drop
(try (result externref)
(do
(local.get $1)
@@ -330,7 +711,7 @@
(drop
(try (result funcref)
(do
- (ref.func $3)
+ (ref.func $4)
)
(catch
(drop
@@ -351,6 +732,78 @@
)
)
(drop
+ (try (result anyref)
+ (do
+ (local.get $1)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (ref.func $4)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (local.get $1)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $4)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (local.get $1)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.func $4)
+ )
+ (catch
+ (exnref.pop)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (local.get $1)
+ )
+ )
+ )
+ (drop
+ (try (result anyref)
+ (do
+ (ref.null exn)
+ )
+ (catch
+ (drop
+ (exnref.pop)
+ )
+ (ref.func $4)
+ )
+ )
+ )
+ (drop
(select (result externref)
(local.get $1)
(ref.null extern)
@@ -379,6 +832,48 @@
)
)
(drop
+ (select (result anyref)
+ (local.get $1)
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $1)
+ (local.get $2)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $0)
+ (local.get $1)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $0)
+ (local.get $2)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $2)
+ (local.get $1)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (select (result anyref)
+ (local.get $2)
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (drop
(ref.is_null
(local.get $1)
)
@@ -410,7 +905,7 @@
)
(drop
(ref.is_null
- (ref.func $3)
+ (ref.func $4)
)
)
(drop
@@ -428,57 +923,129 @@
(ref.null exn)
)
)
+ (drop
+ (ref.is_null
+ (local.get $3)
+ )
+ )
+ (drop
+ (ref.is_null
+ (global.get $global$4)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null any)
+ )
+ )
+ )
+ (func $6 (result externref)
+ (local $0 externref)
+ (local.get $0)
+ )
+ (func $7 (result externref)
+ (global.get $global$0)
+ )
+ (func $8 (result externref)
+ (ref.null extern)
+ )
+ (func $9 (result funcref)
+ (local $0 funcref)
+ (local.get $0)
+ )
+ (func $10 (result funcref)
+ (global.get $global$1)
+ )
+ (func $11 (result funcref)
+ (ref.null func)
+ )
+ (func $12 (result funcref)
+ (ref.func $4)
+ )
+ (func $13 (result exnref)
+ (local $0 exnref)
+ (local.get $0)
+ )
+ (func $14 (result exnref)
+ (global.get $global$3)
+ )
+ (func $15 (result exnref)
+ (ref.null exn)
+ )
+ (func $16 (result anyref)
+ (local $0 anyref)
+ (local.get $0)
+ )
+ (func $17 (result anyref)
+ (global.get $global$4)
+ )
+ (func $18 (result anyref)
+ (ref.null any)
)
- (func $5 (result externref)
+ (func $19 (result anyref)
(local $0 externref)
(local.get $0)
)
- (func $6 (result externref)
+ (func $20 (result anyref)
(global.get $global$0)
)
- (func $7 (result externref)
+ (func $21 (result anyref)
(ref.null extern)
)
- (func $8 (result funcref)
+ (func $22 (result anyref)
(local $0 funcref)
(local.get $0)
)
- (func $9 (result funcref)
+ (func $23 (result anyref)
(global.get $global$1)
)
- (func $10 (result funcref)
+ (func $24 (result anyref)
(ref.null func)
)
- (func $11 (result funcref)
- (ref.func $3)
+ (func $25 (result anyref)
+ (ref.func $4)
)
- (func $12 (result exnref)
+ (func $26 (result anyref)
(local $0 exnref)
(local.get $0)
)
- (func $13 (result exnref)
+ (func $27 (result anyref)
(global.get $global$3)
)
- (func $14 (result exnref)
+ (func $28 (result anyref)
(ref.null exn)
)
- (func $15 (result externref)
+ (func $29 (result externref)
(local $0 externref)
(return
(local.get $0)
)
)
- (func $16 (result funcref)
+ (func $30 (result funcref)
(local $0 funcref)
(return
(local.get $0)
)
)
- (func $17 (result exnref)
+ (func $31 (result exnref)
(local $0 exnref)
(return
(local.get $0)
)
)
+ (func $32 (result anyref)
+ (local $0 anyref)
+ (return
+ (local.get $0)
+ )
+ )
+ (func $33 (result anyref)
+ (local $0 funcref)
+ (local $1 externref)
+ (local $2 exnref)
+ (return
+ (local.get $1)
+ )
+ )
)
diff --git a/test/unit/input/anyref_target_feature.wasm b/test/unit/input/anyref_target_feature.wasm
new file mode 100644
index 000000000..88c61ebc2
--- /dev/null
+++ b/test/unit/input/anyref_target_feature.wasm
Binary files differ
diff --git a/test/unit/input/exception_handling_target_feature.wasm b/test/unit/input/exception_handling_target_feature.wasm
index 487aaf679..996cd2142 100755
--- a/test/unit/input/exception_handling_target_feature.wasm
+++ b/test/unit/input/exception_handling_target_feature.wasm
Binary files differ
diff --git a/test/unit/test_features.py b/test/unit/test_features.py
index 506fd8809..2b5b00469 100644
--- a/test/unit/test_features.py
+++ b/test/unit/test_features.py
@@ -42,8 +42,17 @@ class FeatureValidationTest(utils.BinaryenTestCase):
self.check_feature(module, error, '--enable-reference-types')
def check_multivalue(self, module, error):
+ self.check_feature(module, error, '--enable-multivalue')
+
+ def check_multivalue_exception_handling(self, module, error):
self.check_feature(module, error, '--enable-multivalue',
- ['--enable-exception-handling'])
+ ['--enable-exception-handling',
+ '--enable-reference-types'])
+
+ def check_anyref(self, module, error):
+ # Anyref handling implies reference types
+ self.check_feature(module, error, '--enable-anyref',
+ ['--enable-reference-types'])
def test_v128_signature(self):
module = '''
@@ -228,8 +237,8 @@ class FeatureValidationTest(utils.BinaryenTestCase):
(event $foo (attr 0) (param i32 i64))
)
'''
- self.check_multivalue(module, 'Multivalue event type ' +
- '(multivalue is not enabled)')
+ self.check_multivalue_exception_handling(module, 'Multivalue event type ' +
+ '(multivalue is not enabled)')
def test_multivalue_block(self):
module = '''
@@ -249,6 +258,24 @@ class FeatureValidationTest(utils.BinaryenTestCase):
self.check_multivalue(module, 'Multivalue block type ' +
'(multivalue is not enabled)')
+ def test_anyref_global(self):
+ module = '''
+ (module
+ (global $foo anyref (ref.null any))
+ )
+ '''
+ self.check_anyref(module, 'all used types should be allowed')
+
+ def test_anyref_local(self):
+ module = '''
+ (module
+ (func $foo
+ (local $0 anyref)
+ )
+ )
+ '''
+ self.check_anyref(module, 'all used types should be allowed')
+
class TargetFeaturesSectionTest(utils.BinaryenTestCase):
def test_atomics(self):
@@ -303,9 +330,15 @@ class TargetFeaturesSectionTest(utils.BinaryenTestCase):
def test_exception_handling(self):
filename = 'exception_handling_target_feature.wasm'
self.roundtrip(filename)
- self.check_features(filename, ['exception-handling'])
+ self.check_features(filename, ['exception-handling', 'reference-types'])
self.assertIn('throw', self.disassemble(filename))
+ def test_anyref(self):
+ filename = 'anyref_target_feature.wasm'
+ self.roundtrip(filename)
+ self.check_features(filename, ['reference-types', 'anyref'])
+ self.assertIn('anyref', self.disassemble(filename))
+
def test_incompatible_features(self):
path = self.input_path('signext_target_feature.wasm')
p = shared.run_process(
@@ -353,5 +386,6 @@ class TargetFeaturesSectionTest(utils.BinaryenTestCase):
'--enable-exception-handling',
'--enable-tail-call',
'--enable-reference-types',
- '--enable-multivalue'
+ '--enable-multivalue',
+ '--enable-anyref'
], p2.stdout.splitlines())