summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-10-28 18:37:09 -0700
committerGitHub <noreply@github.com>2021-10-28 18:37:09 -0700
commit5b3cc376af95daba7da944842babe47b2b2197d2 (patch)
tree7d974299a443c103f60af7d565a29a98e19e593d /src
parent25264f7be10ebead4c464a218bf32a2456bb1cd9 (diff)
downloadbinaryen-5b3cc376af95daba7da944842babe47b2b2197d2.tar.gz
binaryen-5b3cc376af95daba7da944842babe47b2b2197d2.tar.bz2
binaryen-5b3cc376af95daba7da944842babe47b2b2197d2.zip
[NFC] Use std::variant in GCData (#4289)
This helps prevent bugs where we assume that the GCData has either a HeapType or Rtt without checking. Indeed, one such bug is found and fixed.
Diffstat (limited to 'src')
-rw-r--r--src/literal.h13
-rw-r--r--src/wasm-interpreter.h5
-rw-r--r--src/wasm/literal.cpp4
3 files changed, 15 insertions, 7 deletions
diff --git a/src/literal.h b/src/literal.h
index 6f2267752..ce3f80902 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -19,6 +19,7 @@
#include <array>
#include <iostream>
+#include <variant>
#include "compiler-support.h"
#include "support/hash.h"
@@ -700,13 +701,17 @@ std::ostream& operator<<(std::ostream& o, wasm::Literals literals);
// instead we have a static type.
struct GCData {
// Either the RTT or the type must be present, but not both.
- Literal rtt;
- HeapType type;
+ std::variant<Literal, HeapType> typeInfo;
Literals values;
- GCData(HeapType type, Literals values) : type(type), values(values) {}
- GCData(Literal rtt, Literals values) : rtt(rtt), values(values) {}
+ GCData(HeapType type, Literals values) : typeInfo(type), values(values) {}
+ GCData(Literal rtt, Literals values) : typeInfo(rtt), values(values) {}
+
+ bool hasRtt() { return std::get_if<Literal>(&typeInfo); }
+ bool hasHeapType() { return std::get_if<HeapType>(&typeInfo); }
+ Literal getRtt() { return std::get<Literal>(typeInfo); }
+ HeapType getHeapType() { return std::get<HeapType>(typeInfo); }
};
struct RttSuper {
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 205c9f8cd..61a08c14f 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1487,8 +1487,9 @@ public:
// GC data store an RTT in each instance.
assert(cast.originalRef.isData());
auto gcData = cast.originalRef.getGCData();
+ assert(bool(curr->rtt) == gcData->hasRtt());
if (curr->rtt) {
- Literal seenRtt = gcData->rtt;
+ auto seenRtt = gcData->getRtt();
if (!seenRtt.isSubRtt(intendedRtt)) {
cast.outcome = cast.Failure;
return cast;
@@ -1496,7 +1497,7 @@ public:
cast.castRef =
Literal(gcData, Type(intendedRtt.type.getHeapType(), NonNullable));
} else {
- auto seenType = gcData->type;
+ auto seenType = gcData->getHeapType();
if (!HeapType::isSubType(seenType, curr->intendedType)) {
cast.outcome = cast.Failure;
return cast;
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 8beae78bd..131a6d443 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -495,7 +495,9 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
if (literal.isData()) {
auto data = literal.getGCData();
if (data) {
- o << "[ref " << data->rtt << ' ' << data->values << ']';
+ o << "[ref ";
+ std::visit([&](auto& info) { o << info; }, data->typeInfo);
+ o << ' ' << data->values << ']';
} else {
o << "[ref null " << literal.type << ']';
}