summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asmjs/asm_v_wasm.cpp6
-rw-r--r--src/binaryen-c.cpp10
-rw-r--r--src/binaryen-c.h2
-rw-r--r--src/ir/abstract.h4
-rw-r--r--src/js/binaryen.js-post.js14
-rw-r--r--src/literal.h2
-rw-r--r--src/parsing.h2
-rw-r--r--src/passes/ConstHoisting.cpp4
-rw-r--r--src/passes/FuncCastEmulation.cpp8
-rw-r--r--src/passes/InstrumentLocals.cpp24
-rw-r--r--src/shell-interface.h3
-rw-r--r--src/tools/fuzzing.h37
-rw-r--r--src/tools/spec-wrapper.h5
-rw-r--r--src/tools/wasm-reduce.cpp10
-rw-r--r--src/wasm-binary.h18
-rw-r--r--src/wasm-builder.h8
-rw-r--r--src/wasm-interpreter.h4
-rw-r--r--src/wasm-type.h4
-rw-r--r--src/wasm/literal.cpp42
-rw-r--r--src/wasm/wasm-binary.cpp12
-rw-r--r--src/wasm/wasm-s-parser.cpp6
-rw-r--r--src/wasm/wasm-stack.cpp6
-rw-r--r--src/wasm/wasm-type.cpp32
-rw-r--r--src/wasm/wasm-validator.cpp4
-rw-r--r--test/binaryen.js/kitchen-sink.js11
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt30
-rw-r--r--test/example/c-api-kitchen-sink.c12
-rw-r--r--test/example/c-api-kitchen-sink.txt2
-rw-r--r--test/example/typeinfo.txt4
-rw-r--r--test/passes/instrument-locals_all-features.txt6
-rw-r--r--test/passes/translate-to-fuzz_all-features.txt1323
-rw-r--r--test/unit/input/gc_target_feature.wasmbin56 -> 61 bytes
-rw-r--r--test/unit/test_features.py22
33 files changed, 990 insertions, 687 deletions
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp
index 8d2894f13..e7b4d6edd 100644
--- a/src/asmjs/asm_v_wasm.cpp
+++ b/src/asmjs/asm_v_wasm.cpp
@@ -58,6 +58,8 @@ AsmType wasmToAsmType(Type type) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
assert(false && "reference types are not supported by asm2wasm");
case Type::none:
return ASM_NONE;
@@ -88,6 +90,10 @@ char getSig(Type type) {
return 'E';
case Type::anyref:
return 'A';
+ case Type::eqref:
+ return 'Q';
+ case Type::i31ref:
+ return 'I';
case Type::none:
return 'v';
case Type::unreachable:
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 1c938faab..2f1d3f5ff 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -74,8 +74,11 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
case Type::externref:
case Type::exnref:
case Type::anyref:
- assert(x.isNull());
+ case Type::eqref:
+ assert(x.isNull() && "unexpected non-null reference type literal");
break;
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -100,7 +103,10 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
return Literal::makeNull(Type(x.type));
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -136,6 +142,8 @@ 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 BinaryenTypeEqref(void) { return Type::eqref; }
+BinaryenType BinaryenTypeI31ref(void) { return Type::i31ref; }
BinaryenType BinaryenTypeUnreachable(void) { return Type::unreachable; }
BinaryenType BinaryenTypeAuto(void) { return uintptr_t(-1); }
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index f368ad122..3a3be4608 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -102,6 +102,8 @@ BINARYEN_API BinaryenType BinaryenTypeFuncref(void);
BINARYEN_API BinaryenType BinaryenTypeExternref(void);
BINARYEN_API BinaryenType BinaryenTypeExnref(void);
BINARYEN_API BinaryenType BinaryenTypeAnyref(void);
+BINARYEN_API BinaryenType BinaryenTypeEqref(void);
+BINARYEN_API BinaryenType BinaryenTypeI31ref(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.
diff --git a/src/ir/abstract.h b/src/ir/abstract.h
index ce5b6b008..ac67a59b3 100644
--- a/src/ir/abstract.h
+++ b/src/ir/abstract.h
@@ -103,6 +103,8 @@ inline UnaryOp getUnary(Type type, Op op) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable: {
return InvalidUnary;
@@ -266,6 +268,8 @@ inline BinaryOp getBinary(Type type, Op op) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
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 87a6bacda..4703abc54 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -37,6 +37,8 @@ function initializeConstants() {
['externref', 'Externref'],
['exnref', 'Exnref'],
['anyref', 'Anyref'],
+ ['eqref', 'Eqref'],
+ ['i31ref', 'I31ref'],
['unreachable', 'Unreachable'],
['auto', 'Auto']
].forEach(entry => {
@@ -2070,6 +2072,18 @@ function wrapModule(module, self = {}) {
}
};
+ self['eqref'] = {
+ 'pop'() {
+ return Module['_BinaryenPop'](module, Module['eqref']);
+ }
+ };
+
+ self['i31ref'] = {
+ 'pop'() {
+ return Module['_BinaryenPop'](module, Module['i31ref']);
+ }
+ };
+
self['ref'] = {
'null'(type) {
return Module['_BinaryenRefNull'](module, type);
diff --git a/src/literal.h b/src/literal.h
index c617f56f0..698063cbe 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -595,6 +595,8 @@ template<> struct less<wasm::Literal> {
case wasm::Type::externref:
case wasm::Type::exnref:
case wasm::Type::anyref:
+ case wasm::Type::eqref:
+ case wasm::Type::i31ref:
case wasm::Type::none:
case wasm::Type::unreachable:
return false;
diff --git a/src/parsing.h b/src/parsing.h
index d809cbedd..bdc3e63b7 100644
--- a/src/parsing.h
+++ b/src/parsing.h
@@ -267,6 +267,8 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
WASM_UNREACHABLE("unexpected const type");
case Type::none:
case Type::unreachable: {
diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp
index 3b34751ff..a972c05fb 100644
--- a/src/passes/ConstHoisting.cpp
+++ b/src/passes/ConstHoisting.cpp
@@ -97,7 +97,9 @@ private:
case Type::funcref:
case Type::externref:
case Type::exnref:
- case Type::anyref: {
+ case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref: {
return false;
}
case Type::none:
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 101834790..6f5e9d611 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -68,7 +68,9 @@ static Expression* toABI(Expression* value, Module* module) {
case Type::funcref:
case Type::externref:
case Type::exnref:
- case Type::anyref: {
+ case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref: {
WASM_UNREACHABLE("reference types cannot be converted to i64");
}
case Type::none: {
@@ -112,7 +114,9 @@ static Expression* fromABI(Expression* value, Type type, Module* module) {
case Type::funcref:
case Type::externref:
case Type::exnref:
- case Type::anyref: {
+ case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref: {
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 f9c26d788..8803a7811 100644
--- a/src/passes/InstrumentLocals.cpp
+++ b/src/passes/InstrumentLocals.cpp
@@ -60,6 +60,8 @@ Name get_funcref("get_funcref");
Name get_externref("get_externref");
Name get_exnref("get_exnref");
Name get_anyref("get_anyref");
+Name get_eqref("get_eqref");
+Name get_i31ref("get_i31ref");
Name get_v128("get_v128");
Name set_i32("set_i32");
@@ -70,6 +72,8 @@ Name set_funcref("set_funcref");
Name set_externref("set_externref");
Name set_exnref("set_exnref");
Name set_anyref("set_anyref");
+Name set_eqref("set_eqref");
+Name set_i31ref("set_i31ref");
Name set_v128("set_v128");
struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
@@ -104,6 +108,12 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
case Type::anyref:
import = get_anyref;
break;
+ case Type::eqref:
+ import = get_eqref;
+ break;
+ case Type::i31ref:
+ import = get_i31ref;
+ break;
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -153,6 +163,12 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
case Type::anyref:
import = set_anyref;
break;
+ case Type::eqref:
+ import = set_eqref;
+ break;
+ case Type::i31ref:
+ import = set_i31ref;
+ break;
case Type::unreachable:
return; // nothing to do here
case Type::none:
@@ -203,6 +219,14 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
curr, get_anyref, {Type::i32, Type::i32, Type::anyref}, Type::anyref);
addImport(
curr, set_anyref, {Type::i32, Type::i32, Type::anyref}, Type::anyref);
+ addImport(
+ curr, get_eqref, {Type::i32, Type::i32, Type::eqref}, Type::eqref);
+ addImport(
+ curr, set_eqref, {Type::i32, Type::i32, Type::eqref}, Type::eqref);
+ addImport(
+ curr, get_i31ref, {Type::i32, Type::i32, Type::i31ref}, Type::i31ref);
+ addImport(
+ curr, set_i31ref, {Type::i32, Type::i32, Type::i31ref}, Type::i31ref);
}
}
if (curr->features.hasSIMD()) {
diff --git a/src/shell-interface.h b/src/shell-interface.h
index ae86d13ec..8d35905ee 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -119,8 +119,11 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
globals[import->name] = {Literal::makeNull(import->type)};
break;
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index e6cc4e444..0783588cd 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -324,6 +324,15 @@ private:
if (wasm.features.hasExceptionHandling()) {
options.push_back(Type::exnref);
}
+ if (wasm.features.hasGC()) {
+ options.push_back(Type::eqref);
+ // TODO: i31ref
+ }
+ }
+ break;
+ case Type::eqref:
+ if (wasm.features.hasGC()) {
+ // TODO: i31ref
}
break;
default:
@@ -1362,6 +1371,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -1466,6 +1477,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -1595,6 +1608,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -1640,6 +1655,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1708,6 +1725,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1735,6 +1754,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1845,6 +1866,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
return makeTrivial(type);
case Type::none:
case Type::unreachable:
@@ -1990,6 +2013,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -2227,6 +2252,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -2434,6 +2461,8 @@ private:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -2674,7 +2703,9 @@ private:
.add(FeatureSet::ReferenceTypes, Type::funcref, Type::externref)
.add(FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling,
Type::exnref)
- .add(FeatureSet::ReferenceTypes | FeatureSet::GC, Type::anyref));
+ .add(FeatureSet::ReferenceTypes | FeatureSet::GC,
+ Type::anyref,
+ Type::eqref)); // TODO: i31ref
}
Type getSingleConcreteType() { return pick(getSingleConcreteTypes()); }
@@ -2685,7 +2716,9 @@ private:
.add(FeatureSet::ReferenceTypes, Type::funcref, Type::externref)
.add(FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling,
Type::exnref)
- .add(FeatureSet::ReferenceTypes | FeatureSet::GC, Type::anyref));
+ .add(FeatureSet::ReferenceTypes | FeatureSet::GC,
+ Type::anyref,
+ Type::eqref)); // TODO: i31ref
}
Type getReferenceType() { return pick(getReferenceTypes()); }
diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h
index 200571fd0..5a61d72b6 100644
--- a/src/tools/spec-wrapper.h
+++ b/src/tools/spec-wrapper.h
@@ -61,6 +61,11 @@ static std::string generateSpecWrapper(Module& wasm) {
case Type::anyref:
ret += "(ref.null any)";
break;
+ case Type::eqref:
+ ret += "(ref.null eq)";
+ break;
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 7410ff91e..7a81007dc 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -599,6 +599,8 @@ struct Reducer
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -625,6 +627,8 @@ struct Reducer
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -651,6 +655,8 @@ struct Reducer
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -677,6 +683,8 @@ struct Reducer
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
@@ -689,6 +697,8 @@ struct Reducer
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
continue; // not implemented yet
case Type::none:
case Type::unreachable:
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 7666fa842..39980ee04 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -346,6 +346,10 @@ enum EncodedType {
externref = -0x11, // 0x6f
// any reference type
anyref = -0x12, // 0x6e
+ // comparable reference type
+ eqref = -0x13, // 0x6d
+ // integer reference type
+ i31ref = -0x16, // 0x6a
// exception reference type
exnref = -0x18, // 0x68
// func_type form
@@ -358,6 +362,8 @@ enum EncodedHeapType {
func = -0x10, // 0x70
extern_ = -0x11, // 0x6f
any = -0x12, // 0x6e
+ eq = -0x13, // 0x6d
+ i31 = -0x17, // 0x69, != i31ref
exn = -0x18, // 0x68
};
@@ -981,6 +987,12 @@ inline S32LEB binaryType(Type type) {
case Type::anyref:
ret = BinaryConsts::EncodedType::anyref;
break;
+ case Type::eqref:
+ ret = BinaryConsts::EncodedType::eqref;
+ break;
+ case Type::i31ref:
+ ret = BinaryConsts::EncodedType::i31ref;
+ break;
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
}
@@ -1003,11 +1015,15 @@ inline S32LEB binaryHeapType(HeapType type) {
ret = BinaryConsts::EncodedHeapType::any;
break;
case HeapType::EqKind:
+ ret = BinaryConsts::EncodedHeapType::eq;
+ break;
case HeapType::I31Kind:
+ ret = BinaryConsts::EncodedHeapType::i31;
+ break;
case HeapType::SignatureKind:
case HeapType::StructKind:
case HeapType::ArrayKind:
- WASM_UNREACHABLE("TODO: GC types");
+ WASM_UNREACHABLE("TODO: compound GC types");
}
return S32LEB(ret); // TODO: Actually encoded as s33
}
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index b35fde376..737dad16a 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -645,8 +645,11 @@ public:
case Type::externref:
case Type::exnref: // TODO: ExceptionPackage?
case Type::anyref:
- assert(value.isNull());
+ case Type::eqref:
+ assert(value.isNull() && "unexpected non-null reference type literal");
return makeRefNull(value.type);
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
default:
assert(value.type.isNumber());
return makeConst(value);
@@ -840,7 +843,10 @@ public:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
return ExpressionManipulator::refNull(curr, curr->type);
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::none:
return ExpressionManipulator::nop(curr);
case Type::unreachable:
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 51cc24d01..69d6ff771 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1653,6 +1653,8 @@ public:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1710,6 +1712,8 @@ public:
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
diff --git a/src/wasm-type.h b/src/wasm-type.h
index f3973068f..4a55d7b33 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -51,7 +51,9 @@ public:
externref,
exnref,
anyref,
- _last_basic_id = anyref
+ eqref,
+ i31ref,
+ _last_basic_id = i31ref,
};
Type() = default;
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 39a4cea3c..4a89b5cd1 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -70,7 +70,10 @@ Literal::Literal(const Literal& other) : type(other.type) {
break;
case Type::externref:
case Type::anyref:
+ case Type::eqref:
break; // null
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::funcref:
case Type::exnref:
case Type::unreachable:
@@ -223,10 +226,11 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
case Type::externref:
case Type::exnref:
case Type::anyref:
- if (isNull()) {
- break;
- }
- // falls through
+ case Type::eqref:
+ assert(isNull() && "unexpected non-null reference type literal");
+ break;
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -379,6 +383,10 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
o << "funcref(" << literal.getFunc() << ")";
}
break;
+ case Type::externref:
+ assert(literal.isNull() && "unexpected non-null externref literal");
+ o << "externref(null)";
+ break;
case Type::exnref:
if (literal.isNull()) {
o << "exnref(null)";
@@ -387,13 +395,15 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
}
break;
case Type::anyref:
- assert(literal.isNull() && "TODO: non-null anyref values");
+ assert(literal.isNull() && "unexpected non-null anyref literal");
o << "anyref(null)";
break;
- case Type::externref:
- assert(literal.isNull() && "TODO: non-null externref values");
- o << "externref(null)";
+ case Type::eqref:
+ assert(literal.isNull() && "unexpected non-null eqref literal");
+ o << "eqref(null)";
break;
+ case Type::i31ref:
+ WASM_UNREACHABLE("TODO: i31ref");
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
}
@@ -619,6 +629,8 @@ Literal Literal::eqz() const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -641,6 +653,8 @@ Literal Literal::neg() const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -663,6 +677,8 @@ Literal Literal::abs() const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -768,6 +784,8 @@ Literal Literal::add(const Literal& other) const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -790,6 +808,8 @@ Literal Literal::sub(const Literal& other) const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -908,6 +928,8 @@ Literal Literal::mul(const Literal& other) const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1154,6 +1176,8 @@ Literal Literal::eq(const Literal& other) const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -1176,6 +1200,8 @@ Literal Literal::ne(const Literal& other) const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
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 18a66fb2c..a6299c892 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1206,10 +1206,14 @@ Type WasmBinaryBuilder::getType() {
return Type::exnref;
case BinaryConsts::EncodedType::anyref:
return Type::anyref;
+ case BinaryConsts::EncodedType::eqref:
+ return Type::eqref;
+ case BinaryConsts::EncodedType::i31ref:
+ return Type::i31ref;
default:
throwError("invalid wasm type: " + std::to_string(type));
}
- WASM_UNREACHABLE("unexpeced type");
+ WASM_UNREACHABLE("unexpected type");
}
HeapType WasmBinaryBuilder::getHeapType() {
@@ -1230,10 +1234,14 @@ HeapType WasmBinaryBuilder::getHeapType() {
return HeapType::ExnKind;
case BinaryConsts::EncodedHeapType::any:
return HeapType::AnyKind;
+ case BinaryConsts::EncodedHeapType::eq:
+ return HeapType::EqKind;
+ case BinaryConsts::EncodedHeapType::i31:
+ return HeapType::I31Kind;
default:
throwError("invalid wasm heap type: " + std::to_string(type));
}
- WASM_UNREACHABLE("unexpeced type");
+ WASM_UNREACHABLE("unexpected type");
}
Type WasmBinaryBuilder::getConcreteType() {
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 8bbcc9ac0..2aa60979f 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -875,6 +875,12 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
if (strncmp(str, "anyref", 6) == 0 && (prefix || str[6] == 0)) {
return Type::anyref;
}
+ if (strncmp(str, "eqref", 5) == 0 && (prefix || str[5] == 0)) {
+ return Type::eqref;
+ }
+ if (strncmp(str, "i31ref", 6) == 0 && (prefix || str[6] == 0)) {
+ return Type::i31ref;
+ }
if (allowError) {
return Type::none;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 30816546a..66f9e02dd 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -192,6 +192,8 @@ void BinaryInstWriter::visitLoad(Load* curr) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
WASM_UNREACHABLE("unexpected type");
}
@@ -294,6 +296,8 @@ void BinaryInstWriter::visitStore(Store* curr) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -697,6 +701,8 @@ void BinaryInstWriter::visitConst(Const* curr) {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
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 d88b7b027..cf68d92e9 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -260,9 +260,10 @@ std::unordered_map<TypeInfo, uintptr_t> indices = {
{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 eq) == eqref`
- // * `(ref i31) == i31ref`
+ {TypeInfo({Type::eqref}), Type::eqref},
+ {TypeInfo(HeapType(HeapType::EqKind), true), Type::eqref},
+ {TypeInfo({Type::i31ref}), Type::i31ref},
+ {TypeInfo(HeapType(HeapType::I31Kind), false), Type::i31ref},
};
} // anonymous namespace
@@ -341,7 +342,7 @@ bool Type::isTuple() const {
bool Type::isRef() const {
if (isBasic()) {
- return id >= funcref && id <= anyref;
+ return id >= funcref && id <= i31ref;
} else {
return getTypeInfo(*this)->isRef();
}
@@ -367,7 +368,7 @@ bool Type::isException() const {
bool Type::isNullable() const {
if (isBasic()) {
- return id >= funcref && id <= anyref;
+ return id >= funcref && id <= eqref; // except i31ref
} else {
return getTypeInfo(*this)->isNullable();
}
@@ -409,6 +410,8 @@ unsigned Type::getByteSize() const {
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
case Type::unreachable:
break;
@@ -454,6 +457,8 @@ FeatureSet Type::getFeatures() const {
case Type::exnref:
return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling;
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
return FeatureSet::ReferenceTypes | FeatureSet::GC;
default:
return FeatureSet::MVP;
@@ -484,6 +489,10 @@ HeapType Type::getHeapType() const {
return HeapType::ExnKind;
case anyref:
return HeapType::AnyKind;
+ case eqref:
+ return HeapType::EqKind;
+ case i31ref:
+ return HeapType::I31Kind;
default:
break;
}
@@ -512,7 +521,8 @@ bool Type::isSubType(Type left, Type right) {
return true;
}
if (left.isRef() && right.isRef()) {
- return right == Type::anyref;
+ return right == Type::anyref ||
+ (left == Type::i31ref && right == Type::eqref);
}
if (left.isTuple() && right.isTuple()) {
if (left.size() != right.size()) {
@@ -543,6 +553,10 @@ Type Type::getLeastUpperBound(Type a, Type b) {
}
if (a.isRef()) {
if (b.isRef()) {
+ if ((a == Type::i31ref && b == Type::eqref) ||
+ (a == Type::eqref && b == Type::i31ref)) {
+ return Type::eqref;
+ }
// 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
@@ -754,6 +768,12 @@ std::ostream& operator<<(std::ostream& os, Type type) {
case Type::anyref:
os << "anyref";
break;
+ case Type::eqref:
+ os << "eqref";
+ break;
+ case Type::i31ref:
+ os << "i31ref";
+ break;
}
} else {
os << *getTypeInfo(type);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 505753c88..16ba60d72 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1396,6 +1396,8 @@ void FunctionValidator::validateMemBytes(uint8_t bytes,
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
WASM_UNREACHABLE("unexpected type");
}
@@ -2204,6 +2206,8 @@ void FunctionValidator::validateAlignment(
case Type::externref:
case Type::exnref:
case Type::anyref:
+ case Type::eqref:
+ case Type::i31ref:
case Type::none:
WASM_UNREACHABLE("invalid type");
}
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index d985b39aa..342315682 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -80,6 +80,12 @@ function test_types() {
console.log(" // BinaryenTypeAnyref: " + binaryen.anyref);
console.log(" //", binaryen.expandType(binaryen.anyref).join(","));
+ console.log(" // BinaryenTypeEqref: " + binaryen.eqref);
+ console.log(" //", binaryen.expandType(binaryen.eqref).join(","));
+
+ console.log(" // BinaryenTypeI31ref: " + binaryen.i31ref);
+ console.log(" //", binaryen.expandType(binaryen.i31ref).join(","));
+
console.log(" // BinaryenTypeAuto: " + binaryen.auto);
var i32_pair = binaryen.createType([binaryen.i32, binaryen.i32]);
@@ -570,9 +576,12 @@ function test_core() {
module.f32.pop(),
module.f64.pop(),
module.v128.pop(),
- module.externref.pop(),
module.funcref.pop(),
+ module.externref.pop(),
module.exnref.pop(),
+ module.anyref.pop(),
+ module.eqref.pop(),
+ module.i31ref.pop(),
// Memory
module.memory.size(),
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index 6bd8329e0..413a2236c 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -20,6 +20,10 @@
// 9
// BinaryenTypeAnyref: 10
// 10
+ // BinaryenTypeEqref: 11
+ // 11
+ // BinaryenTypeI31ref: 12
+ // 12
// BinaryenTypeAuto: -1
// 2,2
// 2,2
@@ -1912,15 +1916,24 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
(pop v128)
)
(drop
- (pop externref)
+ (pop funcref)
)
(drop
- (pop funcref)
+ (pop externref)
)
(drop
(pop exnref)
)
(drop
+ (pop anyref)
+ )
+ (drop
+ (pop eqref)
+ )
+ (drop
+ (pop i31ref)
+ )
+ (drop
(memory.size)
)
(drop
@@ -3760,15 +3773,24 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
(pop v128)
)
(drop
- (pop externref)
+ (pop funcref)
)
(drop
- (pop funcref)
+ (pop externref)
)
(drop
(pop exnref)
)
(drop
+ (pop anyref)
+ )
+ (drop
+ (pop eqref)
+ )
+ (drop
+ (pop i31ref)
+ )
+ (drop
(memory.size)
)
(drop
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index f619e6db5..442394e12 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -217,6 +217,18 @@ void test_types() {
BinaryenTypeExpand(anyref, &valueType);
assert(valueType == anyref);
+ BinaryenType eqref = BinaryenTypeEqref();
+ printf(" // BinaryenTypeEqref: %d\n", eqref);
+ assert(BinaryenTypeArity(eqref) == 1);
+ BinaryenTypeExpand(eqref, &valueType);
+ assert(valueType == eqref);
+
+ BinaryenType i31ref = BinaryenTypeI31ref();
+ printf(" // BinaryenTypeI31ref: %d\n", i31ref);
+ assert(BinaryenTypeArity(i31ref) == 1);
+ BinaryenTypeExpand(i31ref, &valueType);
+ assert(valueType == i31ref);
+
printf(" // BinaryenTypeAuto: %d\n", BinaryenTypeAuto());
BinaryenType pair[] = {i32, i32};
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index 807730e27..405848140 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -9,6 +9,8 @@
// BinaryenTypeExternref: 8
// BinaryenTypeExnref: 9
// BinaryenTypeAnyref: 10
+ // BinaryenTypeEqref: 11
+ // BinaryenTypeI31ref: 12
// BinaryenTypeAuto: -1
BinaryenFeatureMVP: 0
BinaryenFeatureAtomics: 1
diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt
index 539f305db..4ba628925 100644
--- a/test/example/typeinfo.txt
+++ b/test/example/typeinfo.txt
@@ -9,11 +9,11 @@ any
anyref
(ref any)
eq
-(ref null eq)
+eqref
(ref eq)
i31
(ref null i31)
-(ref i31)
+i31ref
exn
exnref
(ref exn)
diff --git a/test/passes/instrument-locals_all-features.txt b/test/passes/instrument-locals_all-features.txt
index 8943c2d56..a606813cb 100644
--- a/test/passes/instrument-locals_all-features.txt
+++ b/test/passes/instrument-locals_all-features.txt
@@ -8,6 +8,8 @@
(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 $i32_i32_eqref_=>_eqref (func (param i32 i32 eqref) (result eqref)))
+ (type $i32_i32_i31ref_=>_i31ref (func (param i32 i32 i31ref) (result i31ref)))
(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)))
@@ -25,6 +27,10 @@
(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_eqref" (func $get_eqref (param i32 i32 eqref) (result eqref)))
+ (import "env" "set_eqref" (func $set_eqref (param i32 i32 eqref) (result eqref)))
+ (import "env" "get_i31ref" (func $get_i31ref (param i32 i32 i31ref) (result i31ref)))
+ (import "env" "set_i31ref" (func $set_i31ref (param i32 i32 i31ref) (result i31ref)))
(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/translate-to-fuzz_all-features.txt b/test/passes/translate-to-fuzz_all-features.txt
index 80552e2d5..b03dbbb20 100644
--- a/test/passes/translate-to-fuzz_all-features.txt
+++ b/test/passes/translate-to-fuzz_all-features.txt
@@ -1,18 +1,24 @@
(module
- (type $none_=>_none (func))
- (type $none_=>_i32_anyref_externref (func (result i32 anyref externref)))
(type $f32_=>_none (func (param f32)))
- (type $exnref_=>_none (func (param exnref)))
- (type $none_=>_externref_anyref_anyref_anyref (func (result externref anyref anyref anyref)))
+ (type $none_=>_none (func))
+ (type $none_=>_f32_i64_funcref (func (result f32 i64 funcref)))
(type $i32_=>_none (func (param i32)))
+ (type $i32_f64_=>_none (func (param i32 f64)))
(type $i64_=>_none (func (param i64)))
(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 $anyref_funcref_externref_=>_f32 (func (param anyref funcref externref) (result f32)))
- (type $none_=>_v128 (func (result v128)))
- (type $none_=>_anyref (func (result anyref)))
+ (type $funcref_anyref_=>_f64 (func (param funcref anyref) (result f64)))
+ (type $anyref_eqref_=>_f64 (func (param anyref eqref) (result f64)))
+ (type $funcref_f64_=>_v128 (func (param funcref f64) (result v128)))
+ (type $none_=>_funcref (func (result funcref)))
+ (type $v128_=>_funcref (func (param v128) (result funcref)))
+ (type $v128_anyref_f32_=>_funcref (func (param v128 anyref f32) (result funcref)))
+ (type $externref_i32_v128_i64_=>_externref (func (param externref i32 v128 i64) (result externref)))
+ (type $f32_eqref_=>_anyref (func (param f32 eqref) (result anyref)))
+ (type $none_=>_eqref_eqref_eqref_eqref_eqref (func (result eqref eqref eqref eqref eqref)))
+ (type $exnref_=>_eqref_eqref_eqref_eqref_eqref (func (param exnref) (result eqref eqref eqref eqref eqref)))
(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)))
@@ -21,29 +27,31 @@
(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 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
+ (table $0 12 12 funcref)
+ (elem (i32.const 0) $func_7 $func_7 $func_8 $func_8 $func_9 $func_9 $func_9 $func_13 $func_13 $func_13 $func_17 $func_19)
+ (global $global$5 (mut eqref) (ref.null eq))
+ (global $global$4 (mut externref) (ref.null extern))
+ (global $global$3 (mut exnref) (ref.null exn))
+ (global $global$2 (mut funcref) (ref.null func))
+ (global $global$1 (mut (v128 funcref i64 anyref eqref exnref)) (tuple.make
+ (v128.const i32x4 0x0c0d0c62 0x48060d0d 0x000000ff 0x00000000)
(ref.null func)
- (ref.null exn)
- (ref.null exn)
- (ref.null extern)
+ (i64.const -2199023255552)
(ref.null any)
- (f64.const 1.1754943508222875e-38)
+ (ref.null eq)
+ (ref.null exn)
))
(global $hangLimit (mut i32) (i32.const 10))
- (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_10" (func $func_10))
- (export "func_11_invoker" (func $func_11_invoker))
+ (export "func_9" (func $func_9))
+ (export "func_10_invoker" (func $func_10_invoker))
+ (export "func_12" (func $func_12))
+ (export "func_13_invoker" (func $func_13_invoker))
+ (export "func_17" (func $func_17))
+ (export "func_19" (func $func_19))
+ (export "func_19_invoker" (func $func_19_invoker))
+ (export "func_21" (func $func_21))
(export "hangLimitInitializer" (func $hangLimitInitializer))
(func $hashMemory (result i32)
(local $0 i32)
@@ -276,18 +284,20 @@
)
(local.get $0)
)
- (func $func_7 (result anyref)
- (local $0 i64)
- (local $1 i64)
- (local $2 anyref)
+ (func $func_7 (param $0 f32)
+ (local $1 (anyref externref))
+ (local $2 i32)
+ (local $3 i64)
+ (local $4 funcref)
+ (local $5 v128)
+ (local $6 (funcref anyref f32 i32 exnref))
+ (local $7 i32)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
- (return
- (ref.null any)
- )
+ (return)
)
(global.set $hangLimit
(i32.sub
@@ -296,38 +306,87 @@
)
)
)
- (ref.null any)
- )
- (func $func_7_invoker
- (drop
- (call $func_7)
- )
- (drop
- (call $func_7)
- )
- (call $log-i32
- (call $hashMemory)
- )
- (drop
- (call $func_7)
- )
- (call $log-i32
- (call $hashMemory)
+ (block $label$0
+ (call $log-f64
+ (if (result f64)
+ (i32.eqz
+ (i32.const 32768)
+ )
+ (block $label$1 (result f64)
+ (br_if $label$0
+ (i32.eqz
+ (loop $label$2 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$3 (result i32)
+ (nop)
+ (local.tee $7
+ (local.tee $2
+ (local.tee $7
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.get $7)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (call $log-exnref
+ (ref.null exn)
+ )
+ (f64.const 11839)
+ )
+ (block $label$4 (result f64)
+ (nop)
+ (f64.nearest
+ (f64.const 1.6005841300030413e-215)
+ )
+ )
+ )
+ )
+ (call $log-exnref
+ (ref.null exn)
+ )
)
)
- (func $func_9 (result externref anyref anyref anyref)
+ (func $func_8 (param $0 funcref) (param $1 anyref) (result f64)
+ (local $2 i64)
+ (local $3 (f64 i32 anyref i64 exnref))
+ (local $4 v128)
+ (local $5 (v128 f32 exnref))
+ (local $6 f32)
+ (local $7 i32)
+ (local $8 (funcref eqref))
+ (local $9 i64)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (tuple.make
- (ref.null extern)
- (ref.null any)
- (ref.null any)
- (ref.null any)
- )
+ (f64.const 4806734720588042541890704e256)
)
)
(global.set $hangLimit
@@ -337,15 +396,11 @@
)
)
)
- (tuple.make
- (ref.null extern)
- (ref.null any)
- (ref.null any)
- (ref.null any)
- )
+ (f64.const 9223372036854775808)
)
- (func $func_10 (param $0 f64) (param $1 i32) (param $2 i64) (param $3 f64) (param $4 v128)
- (local $5 exnref)
+ (func $func_9 (param $0 i32) (param $1 f64)
+ (local $2 i32)
+ (local $3 funcref)
(block
(if
(i32.eqz
@@ -361,17 +416,29 @@
)
)
(block $label$0
- (call $log-i32
- (call $hashMemory)
- )
- (call $log-f32
- (i32.load offset=4 align=2
- (i32.and
- (local.tee $1
+ (f32.store offset=3 align=2
+ (i32.and
+ (local.get $0)
+ (i32.const 15)
+ )
+ (if (result f32)
+ (local.tee $2
+ (local.tee $2
(block $label$1
- (call $log-i32
- (block $label$2 (result i32)
- (loop $label$3
+ (call_indirect (type $f32_=>_none)
+ (f32.div
+ (f32.const 4189)
+ (f32.const 1396855168)
+ )
+ (i32.atomic.rmw8.cmpxchg_u offset=3
+ (i32.and
+ (call $hashMemory)
+ (i32.const 15)
+ )
+ (local.tee $0
+ (local.get $2)
+ )
+ (loop $label$3 (result i32)
(block
(if
(i32.eqz
@@ -386,452 +453,221 @@
)
)
)
- (block
- (block $label$4
- (call $log-f32
- (global.get $global$5)
- )
+ (loop $label$4 (result i32)
+ (block
(if
- (local.tee $1
- (local.get $1)
+ (i32.eqz
+ (global.get $hangLimit)
)
- (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)
- )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$5 (result i32)
+ (v128.store offset=22 align=8
+ (i32.and
+ (i32.load16_u offset=4 align=1
+ (i32.and
+ (ref.is_null
+ (ref.null extern)
)
+ (i32.const 15)
)
)
+ (i32.const 15)
)
- (block $label$7
- (local.set $0
- (loop $label$8 (result f64)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ (i16x8.ne
+ (i16x8.gt_u
+ (select
+ (if (result v128)
+ (i32.eqz
+ (i32.const 2147483647)
+ )
+ (block $label$8 (result v128)
+ (nop)
+ (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
+ (block $label$9 (result v128)
+ (if (result v128)
+ (i32.const -96)
+ (v128.const i32x4 0xffffff99 0xffffffff 0x00000000 0x40648000)
+ (v128.const i32x4 0x00005f01 0x0000b03f 0x644b1d80 0x4fb2ff39)
)
)
)
- (block (result f64)
- (block $label$9
- (call $log-v128
- (local.get $4)
- )
- (call $log-i32
- (call $hashMemory)
+ (v128.const i32x4 0x00000000 0x40eff640 0x00000000 0xc1300000)
+ (local.tee $0
+ (if (result i32)
+ (local.tee $0
+ (local.get $0)
)
- )
- (br_if $label$8
- (i32.eqz
- (local.tee $1
- (i32.const 977223545)
+ (block $label$6 (result i32)
+ (local.set $0
+ (local.get $2)
)
- )
- )
- (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)
+ (if (result i32)
+ (i32.eqz
+ (local.get $2)
)
- )
- (br $label$3)
- )
- (if (result i32)
- (block $label$11 (result i32)
- (nop)
(i32.const 127)
+ (i32.const -128)
)
- (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)
- )
+ (i32.const 26)
+ (i32.const -32768)
)
)
- (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$7
+ (atomic.fence)
+ (br $label$3)
)
)
- (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)
+ )
+ )
+ (tuple.extract 4
+ (tuple.make
+ (ref.null extern)
+ (i32.const 126)
+ (f32.const 2.5923033978570846e-30)
+ (i64.const 6796583934299212805)
+ (v128.const i32x4 0x00000008 0x00000000 0x000000fe 0x00000000)
+ )
+ )
+ )
+ (v128.const i32x4 0x0057ff7f 0x00470000 0x00014359 0x007f3028)
+ )
+ )
+ (atomic.notify offset=3
+ (i32.and
+ (if (result i32)
+ (i32.eqz
+ (f32.ge
+ (f32.sqrt
+ (f32.const -0.1029999852180481)
+ )
+ (f32x4.extract_lane 0
+ (v128.const i32x4 0x080a617e 0xcf000000 0xda800000 0xc20c0000)
)
)
- (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)
+ )
+ (select
+ (local.tee $0
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.get $2)
)
)
)
- (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)
+ (local.get $2)
+ (i32.const 0)
+ )
+ (local.tee $0
+ (br_if $label$5
+ (f64.gt
+ (select
+ (local.get $1)
+ (if (result f64)
+ (i32.eqz
+ (local.get $2)
)
+ (local.get $1)
+ (f64.const 2.5823598491911832e-236)
)
+ (local.get $0)
)
+ (local.get $1)
)
- (br $label$3)
+ (i32.const 609887560)
)
)
)
+ (i32.const 15)
+ )
+ (i64.eq
+ (tuple.extract 0
+ (tuple.make
+ (i64.const 82)
+ (i32.const 0)
+ )
+ )
+ (i64.const 2147483646)
)
)
)
- (v128.store offset=22
- (i32.and
- (global.get $global$3)
- (i32.const 15)
- )
- (local.get $4)
- )
)
)
- (block $label$31
- (return)
- )
)
)
- (return)
+ (br $label$0)
+ )
+ )
+ )
+ (f32.demote_f64
+ (block $label$2
+ (call_indirect (type $f32_=>_none)
+ (f32.div
+ (f32.const 4189)
+ (f32.const 1396855168)
+ )
+ (i32.atomic.rmw8.cmpxchg_u offset=3
+ (i32.and
+ (call $hashMemory)
+ (i32.const 15)
+ )
+ (local.tee $0
+ (local.get $2)
+ )
+ (i32.const -94)
+ )
)
+ (br $label$0)
)
- (i32.const 15)
)
+ (f32.const -2147483648)
+ )
+ )
+ (call_indirect (type $f32_=>_none)
+ (f32.sqrt
+ (f32.const -0.1029999852180481)
+ )
+ (i32.atomic.rmw8.cmpxchg_u offset=3
+ (i32.and
+ (call $hashMemory)
+ (i32.const 2147483647)
+ )
+ (local.tee $0
+ (local.get $2)
+ )
+ (i32.const 536870912)
)
)
)
)
- (func $func_11 (param $0 anyref) (param $1 funcref) (param $2 externref) (result f32)
+ (func $func_10 (result f32 i64 funcref)
+ (local $0 i64)
+ (local $1 (exnref exnref exnref exnref f32))
+ (local $2 externref)
+ (local $3 (v128 funcref))
+ (local $4 externref)
+ (local $5 (i32 f32))
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (f32.const 510.8139953613281)
+ (tuple.make
+ (f32.const 2047.8480224609375)
+ (i64.const -127)
+ (ref.null func)
+ )
)
)
(global.set $hangLimit
@@ -841,38 +677,50 @@
)
)
)
- (f32.const 4503599627370496)
+ (block $label$0 (result f32 i64 funcref)
+ (call $log-f64
+ (f64.const 1.44)
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (tuple.make
+ (f32.const 527435904)
+ (i64.const 2147483648)
+ (ref.null func)
+ )
+ )
)
- (func $func_11_invoker
+ (func $func_10_invoker
(drop
- (call $func_11
- (ref.null any)
- (ref.func $func_7)
- (ref.null extern)
- )
+ (call $func_10)
+ )
+ (call $log-i32
+ (call $hashMemory)
)
(drop
- (call $func_11
- (ref.null any)
- (ref.func $log-f64)
- (ref.null extern)
- )
+ (call $func_10)
)
(call $log-i32
(call $hashMemory)
)
)
- (func $func_13 (result v128)
- (local $0 i32)
- (local $1 exnref)
- (local $2 f64)
+ (func $func_12 (result funcref)
+ (local $0 anyref)
+ (local $1 eqref)
+ (local $2 i64)
+ (local $3 (anyref exnref i64 i32 anyref v128))
+ (local $4 externref)
+ (local $5 anyref)
+ (local $6 f32)
+ (local $7 v128)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (v128.const i32x4 0x016d0001 0x7a01017f 0x7901016d 0x00800056)
+ (ref.func $func_10)
)
)
(global.set $hangLimit
@@ -882,29 +730,270 @@
)
)
)
- (tuple.extract 0
- (tuple.make
- (v128.const i32x4 0x41430000 0x00405556 0x2020ffdd 0x0005080a)
- (i32.const 32768)
+ (ref.null func)
+ )
+ (func $func_13 (param $0 exnref) (result eqref eqref eqref eqref eqref)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (tuple.make
+ (ref.null eq)
+ (ref.null eq)
+ (ref.null eq)
+ (ref.null eq)
+ (ref.null eq)
+ )
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$0
+ (return
+ (tuple.make
+ (ref.null eq)
+ (ref.null eq)
+ (ref.null eq)
+ (ref.null eq)
+ (ref.null eq)
+ )
)
)
)
- (func $func_14 (result i32 anyref externref)
- (local $0 i64)
- (local $1 i32)
+ (func $func_13_invoker
+ (drop
+ (call $func_13
+ (ref.null exn)
+ )
+ )
+ )
+ (func $func_15 (param $0 anyref) (param $1 eqref) (result f64)
+ (local $2 (f64 eqref funcref i32))
+ (local $3 v128)
+ (local $4 i64)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (tuple.make
- (i32.const 127)
- (ref.null any)
- (ref.null extern)
+ (f64.const 303201560)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (f64.const 1.8039635330443502e-221)
+ )
+ (func $func_16 (param $0 funcref) (param $1 f64) (result v128)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (v128.const i32x4 0x00000000 0x41400000 0x00000000 0x40458000)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$0
+ (if
+ (i32.const 10793)
+ (call_indirect (type $f32_=>_none)
+ (f32.const 3402823466385288598117041e14)
+ (i32.const 0)
+ )
+ (block $label$1
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (call $log-f32
+ (loop $label$2 (result f32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (v128.const i32x4 0x41700000 0x5f000000 0x3f800000 0x41a00000)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result f32)
+ (block $label$3
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (call $log-v128
+ (loop $label$4 (result v128)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (v128.const i32x4 0x152dffff 0x8000ffa4 0x1f484608 0x02193720)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$5 (result v128)
+ (call $log-i32
+ (i32.const -1)
+ )
+ (v128.const i32x4 0x00020000 0xff8000b0 0xffb40001 0xffff5657)
+ )
+ )
+ )
+ )
+ (br_if $label$2
+ (if (result i32)
+ (i32.eqz
+ (f32.ge
+ (f32.const 3402823466385288598117041e14)
+ (f32.const 3402823466385288598117041e14)
+ )
+ )
+ (i32.const 0)
+ (i32.const -65537)
+ )
+ )
+ (f32.const 0.004999999888241291)
+ )
+ )
)
)
)
+ (return
+ (v128.const i32x4 0x1b145c08 0xffffffe0 0x00400000 0x00000052)
+ )
+ )
+ )
+ (func $func_17 (param $0 v128) (param $1 anyref) (param $2 f32) (result funcref)
+ (local $3 i64)
+ (local $4 (externref i32))
+ (local $5 i32)
+ (local $6 f64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (ref.func $log-exnref)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (ref.null func)
+ )
+ (func $func_18 (param $0 externref) (param $1 i32) (param $2 v128) (param $3 i64) (result externref)
+ (local $4 funcref)
+ (local $5 eqref)
+ (local $6 eqref)
+ (local $7 (f64 funcref f64 i32))
+ (local $8 externref)
+ (local $9 i32)
+ (local $10 i64)
+ (local $11 eqref)
+ (local $12 externref)
+ (local $13 funcref)
+ (local $14 f64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (local.get $8)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$0 (result externref)
+ (nop)
+ (local.get $0)
+ )
+ )
+ (func $func_19 (param $0 f32) (param $1 eqref) (result anyref)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (ref.null any)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (ref.null any)
+ )
+ (func $func_19_invoker
+ (drop
+ (call $func_19
+ (f32.const 58)
+ (ref.null eq)
+ )
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ )
+ (func $func_21 (param $0 v128) (result funcref)
+ (local $1 i64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (ref.func $hashMemory)
+ )
+ )
(global.set $hangLimit
(i32.sub
(global.get $hangLimit)
@@ -912,25 +1001,28 @@
)
)
)
- (block $label$0 (result i32 anyref externref)
- (f64.store offset=2
- (select
- (local.get $1)
- (local.get $1)
- (if
- (i32.eqz
- (loop $label$6 (result i32)
+ (block $label$0 (result funcref)
+ (drop
+ (tuple.make
+ (ref.null exn)
+ (ref.null eq)
+ (i32.const 26)
+ (v128.const i32x4 0x1715037b 0x00000027 0x000007ff 0xf8000000)
+ (f64.const 9.532824124368358e-130)
+ )
+ )
+ (block $label$1
+ (block $label$2
+ (local.tee $1
+ (i64.shr_s
+ (loop $label$3 (result i64)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (tuple.make
- (i32.const 40)
- (ref.null any)
- (ref.null extern)
- )
+ (ref.func $log-f32)
)
)
(global.set $hangLimit
@@ -940,173 +1032,96 @@
)
)
)
- (block (result i32)
+ (block (result i64)
(nop)
- (br_if $label$6
+ (br_if $label$3
(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 -32766)
)
)
- (block $label$10 (result i32)
- (loop $label$11
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (tuple.make
- (i32.const 1499027801)
- (ref.null any)
- (ref.null extern)
- )
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (i64.trunc_f32_s
+ (f32.min
+ (f32.load offset=3
+ (i32.and
+ (i32.const 454758683)
+ (i32.const 15)
)
)
- (block
- (br_if $label$6
- (loop $label$12 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (tuple.make
- (i32.const -90)
- (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 -88)
- (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)
- )
+ (f32.const 1023.5869750976562)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eqz
+ (i32.const 2049)
+ )
+ (block $label$4
+ (nop)
+ (br $label$1)
+ )
+ (block $label$5
+ (i64.store16 offset=2
+ (i32.and
+ (block $label$6 (result i32)
+ (call $log-i64
+ (i64.const 1949228928397086024)
)
+ (i32.const 2)
)
+ (i32.const 15)
)
- (br $label$6)
+ (local.get $1)
)
+ (br $label$2)
)
)
)
- (block $label$16
- (nop)
- (return
- (tuple.make
- (i32.const 33554433)
- (ref.null any)
- (ref.null extern)
+ )
+ (nop)
+ )
+ (block $label$7
+ (nop)
+ )
+ )
+ (call $func_21
+ (if (result v128)
+ (i32.eqz
+ (i32.const 760829235)
+ )
+ (block $label$8
+ (return
+ (ref.null func)
+ )
+ )
+ (loop $label$9 (result v128)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (ref.func $func_19)
)
)
- )
- (block $label$17
- (call $log-i32
- (call $hashMemory)
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
- (return
- (tuple.make
- (i32.const 0)
- (ref.null any)
- (ref.null extern)
+ )
+ (block (result v128)
+ (nop)
+ (br_if $label$9
+ (ref.is_null
+ (global.get $global$2)
)
)
+ (local.get $0)
)
)
)
- (f64x2.extract_lane 0
- (v128.const i32x4 0x14171109 0x0109440d 0x10031007 0x021d1401)
- )
- )
- (tuple.make
- (i32.const 65534)
- (ref.null any)
- (ref.null extern)
)
)
)
diff --git a/test/unit/input/gc_target_feature.wasm b/test/unit/input/gc_target_feature.wasm
index cd094ca3a..ccabbc16e 100644
--- a/test/unit/input/gc_target_feature.wasm
+++ b/test/unit/input/gc_target_feature.wasm
Binary files differ
diff --git a/test/unit/test_features.py b/test/unit/test_features.py
index 4a82f8cc2..a44d58bbd 100644
--- a/test/unit/test_features.py
+++ b/test/unit/test_features.py
@@ -276,6 +276,24 @@ class FeatureValidationTest(utils.BinaryenTestCase):
'''
self.check_gc(module, 'all used types should be allowed')
+ def test_eqref_global(self):
+ module = '''
+ (module
+ (global $foo eqref (ref.null eq))
+ )
+ '''
+ self.check_gc(module, 'all used types should be allowed')
+
+ def test_eqref_local(self):
+ module = '''
+ (module
+ (func $foo
+ (local $0 eqref)
+ )
+ )
+ '''
+ self.check_gc(module, 'all used types should be allowed')
+
class TargetFeaturesSectionTest(utils.BinaryenTestCase):
def test_atomics(self):
@@ -337,7 +355,9 @@ class TargetFeaturesSectionTest(utils.BinaryenTestCase):
filename = 'gc_target_feature.wasm'
self.roundtrip(filename)
self.check_features(filename, ['reference-types', 'gc'])
- self.assertIn('anyref', self.disassemble(filename))
+ disassembly = self.disassemble(filename)
+ self.assertIn('anyref', disassembly)
+ self.assertIn('eqref', disassembly)
def test_incompatible_features(self):
path = self.input_path('signext_target_feature.wasm')