diff options
Diffstat (limited to 'src/wasm/literal.cpp')
-rw-r--r-- | src/wasm/literal.cpp | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 6b63d2ca5..a7c14fdb6 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -220,11 +220,9 @@ double Literal::getFloat() const { void Literal::getBits(uint8_t (&buf)[16]) const { memset(buf, 0, 16); - TODO_SINGLE_COMPOUND(type); switch (type.getBasic()) { case Type::i32: case Type::f32: - case Type::i31ref: memcpy(buf, &i32, sizeof(i32)); break; case Type::i64: @@ -234,19 +232,14 @@ void Literal::getBits(uint8_t (&buf)[16]) const { case Type::v128: memcpy(buf, &v128, sizeof(v128)); break; - // TODO: investigate changing bits returned for reference types. currently, - // `null` values and even non-`null` functions return all zeroes, but only - // to avoid introducing a functional change. + case Type::none: + case Type::unreachable: case Type::funcref: - break; case Type::externref: case Type::exnref: case Type::anyref: case Type::eqref: - assert(isNull() && "unexpected non-null reference type literal"); - break; - case Type::none: - case Type::unreachable: + case Type::i31ref: WASM_UNREACHABLE("invalid type"); } } @@ -255,23 +248,51 @@ bool Literal::operator==(const Literal& other) const { if (type != other.type) { return false; } - if (type == Type::none) { - return true; - } - if (isNull() || other.isNull()) { - return isNull() == other.isNull(); - } - if (type.isFunction()) { - return func == other.func; - } - if (type.isException()) { - assert(exn != nullptr && other.exn != nullptr); - return *exn == *other.exn; + auto compareRef = [&]() { + assert(type.isRef()); + if (isNull() || other.isNull()) { + return isNull() == other.isNull(); + } + if (type.isFunction()) { + assert(func.is() && other.func.is()); + return func == other.func; + } + if (type.isException()) { + assert(exn != nullptr && other.exn != nullptr); + return *exn == *other.exn; + } + // other non-null reference type literals cannot represent concrete values, + // i.e. there is no concrete externref, anyref or eqref other than null. + WASM_UNREACHABLE("unexpected type"); + }; + if (type.isBasic()) { + switch (type.getBasic()) { + case Type::none: + return true; // special voided literal + case Type::i32: + case Type::f32: + case Type::i31ref: + return i32 == other.i32; + case Type::i64: + case Type::f64: + return i64 == other.i64; + case Type::v128: + return memcmp(v128, other.v128, 16) == 0; + case Type::funcref: + case Type::externref: + case Type::exnref: + case Type::anyref: + case Type::eqref: + return compareRef(); + case Type::unreachable: + break; + } + } else if (type.isRef()) { + return compareRef(); + } else if (type.isRtt()) { + WASM_UNREACHABLE("TODO: rtt literals"); } - uint8_t bits[16], other_bits[16]; - getBits(bits); - other.getBits(other_bits); - return memcmp(bits, other_bits, 16) == 0; + WASM_UNREACHABLE("unexpected type"); } bool Literal::operator!=(const Literal& other) const { |