summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/literal.cpp9
-rw-r--r--test/spec/ref_eq.wast11
2 files changed, 17 insertions, 3 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index c7a9ca844..8beae78bd 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -338,14 +338,17 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
}
bool Literal::operator==(const Literal& other) const {
+ // The types must be identical, unless both are references - in that case,
+ // nulls of different types *do* compare equal.
+ if (type.isRef() && other.type.isRef() && (isNull() || other.isNull())) {
+ return isNull() && other.isNull();
+ }
if (type != other.type) {
return false;
}
auto compareRef = [&]() {
assert(type.isRef());
- if (isNull() || other.isNull()) {
- return isNull() == other.isNull();
- }
+ // Note that we've already handled nulls earlier.
if (type.isFunction()) {
assert(func.is() && other.func.is());
return func == other.func;
diff --git a/test/spec/ref_eq.wast b/test/spec/ref_eq.wast
new file mode 100644
index 000000000..f170bcc06
--- /dev/null
+++ b/test/spec/ref_eq.wast
@@ -0,0 +1,11 @@
+(module
+ (func $compare (export "compare") (param $x eqref) (param $y eqref) (result i32)
+ (ref.eq
+ (local.get $x)
+ (local.get $y)
+ )
+ )
+)
+
+;; All nulls compare equal, regardless of their type.
+(assert_return (invoke "compare" (ref.null data) (ref.null eq)) (i32.const 1))