diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/literal.cpp | 21 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 5 |
3 files changed, 28 insertions, 7 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 131a6d443..4753e5ca1 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -38,8 +38,7 @@ Literal::Literal(Type type) : type(type) { if (isData()) { new (&gcData) std::shared_ptr<GCData>(); } else if (type.isRtt()) { - // Allocate a new RttSupers (with no data). - new (&rttSupers) auto(std::make_unique<RttSupers>()); + new (this) Literal(Literal::makeCanonicalRtt(type.getHeapType())); } else { memset(&v128, 0, 16); } @@ -148,6 +147,18 @@ Literal& Literal::operator=(const Literal& other) { return *this; } +Literal Literal::makeCanonicalRtt(HeapType type) { + auto supers = std::make_unique<RttSupers>(); + std::optional<HeapType> supertype; + for (auto curr = type; (supertype = curr.getSuperType()); curr = *supertype) { + supers->emplace_back(*supertype); + } + // We want the highest types to be first. + std::reverse(supers->begin(), supers->end()); + size_t depth = supers->size(); + return Literal(std::move(supers), Type(Rtt(depth, type))); +} + template<typename LaneT, int Lanes> static void extractBytes(uint8_t (&dest)[16], const LaneArray<Lanes>& lanes) { std::array<uint8_t, 16> bytes; @@ -495,9 +506,7 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { if (literal.isData()) { auto data = literal.getGCData(); if (data) { - o << "[ref "; - std::visit([&](auto& info) { o << info; }, data->typeInfo); - o << ' ' << data->values << ']'; + o << "[ref " << data->rtt << ' ' << data->values << ']'; } else { o << "[ref null " << literal.type << ']'; } @@ -2560,7 +2569,7 @@ bool Literal::isSubRtt(const Literal& other) const { // we have the same amount of supers, and must be completely identical to // other. if (otherSupers.size() < supers.size()) { - return other.type == supers[otherSupers.size()].type; + return other.type.getHeapType() == supers[otherSupers.size()].type; } else { return other.type == type; } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 94c6e96c6..002b401b5 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1217,6 +1217,15 @@ std::optional<HeapType> HeapType::getSuperType() const { return {}; } +size_t HeapType::getDepth() const { + size_t depth = 0; + std::optional<HeapType> super; + for (auto curr = *this; (super = curr.getSuperType()); curr = *super) { + ++depth; + } + return depth; +} + bool HeapType::isNominal() const { if (isBasic()) { return false; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index f8669961c..bb0e99cc2 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2361,7 +2361,10 @@ void FunctionValidator::visitRttCanon(RttCanon* curr) { getModule()->features.hasGC(), curr, "rtt.canon requires gc to be enabled"); shouldBeTrue(curr->type.isRtt(), curr, "rtt.canon must have RTT type"); auto rtt = curr->type.getRtt(); - shouldBeEqual(rtt.depth, Index(0), curr, "rtt.canon has a depth of 0"); + shouldBeEqual(rtt.depth, + Index(curr->type.getHeapType().getDepth()), + curr, + "rtt.canon must have the depth of its heap type"); } void FunctionValidator::visitRttSub(RttSub* curr) { |