summaryrefslogtreecommitdiff
path: root/src/literal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/literal.h')
-rw-r--r--src/literal.h67
1 files changed, 60 insertions, 7 deletions
diff --git a/src/literal.h b/src/literal.h
index ce245d940..c0e43eb88 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -215,6 +215,7 @@ public:
int64_t getInteger() const;
uint64_t getUnsigned() const;
double getFloat() const;
+ // Obtains the bits of a basic value typed literal.
void getBits(uint8_t (&buf)[16]) const;
// Equality checks for the type and the bits, so a nan float would
// be compared bitwise (which means that a Literal containing a nan
@@ -562,14 +563,66 @@ std::ostream& operator<<(std::ostream& o, const ExceptionPackage& exn);
namespace std {
template<> struct hash<wasm::Literal> {
size_t operator()(const wasm::Literal& a) const {
- uint8_t bytes[16];
- a.getBits(bytes);
- int64_t chunks[2];
- memcpy(chunks, bytes, sizeof(chunks));
auto digest = wasm::hash(a.type.getID());
- wasm::rehash(digest, chunks[0]);
- wasm::rehash(digest, chunks[1]);
- return digest;
+ auto hashRef = [&]() {
+ assert(a.type.isRef());
+ if (a.isNull()) {
+ return digest;
+ }
+ if (a.type.isFunction()) {
+ wasm::rehash(digest, a.getFunc());
+ return digest;
+ }
+ if (a.type.isException()) {
+ auto exn = a.getExceptionPackage();
+ wasm::rehash(digest, exn.event);
+ wasm::rehash(digest, exn.values);
+ return digest;
+ }
+ // 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 (a.type.isBasic()) {
+ switch (a.type.getBasic()) {
+ case wasm::Type::i32:
+ wasm::rehash(digest, a.geti32());
+ return digest;
+ case wasm::Type::f32:
+ wasm::rehash(digest, a.reinterpreti32());
+ return digest;
+ case wasm::Type::i64:
+ wasm::rehash(digest, a.geti64());
+ return digest;
+ case wasm::Type::f64:
+ wasm::rehash(digest, a.reinterpreti64());
+ return digest;
+ case wasm::Type::v128:
+ uint64_t chunks[2];
+ memcpy(&chunks, a.getv128Ptr(), 16);
+ wasm::rehash(digest, chunks[0]);
+ wasm::rehash(digest, chunks[1]);
+ return digest;
+ case wasm::Type::funcref:
+ case wasm::Type::externref:
+ case wasm::Type::exnref:
+ case wasm::Type::anyref:
+ case wasm::Type::eqref:
+ return hashRef();
+ case wasm::Type::i31ref:
+ wasm::rehash(digest, a.geti31(true));
+ return digest;
+ case wasm::Type::none:
+ case wasm::Type::unreachable:
+ break;
+ }
+ } else if (a.type.isRef()) {
+ return hashRef();
+ } else if (a.type.isRtt()) {
+ WASM_UNREACHABLE("TODO: rtt literals");
+ }
+ WASM_UNREACHABLE("unexpected type");
}
};
template<> struct hash<wasm::Literals> {