summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/literal.cpp74
-rw-r--r--src/wasm/wasm-binary.cpp122
-rw-r--r--src/wasm/wasm-s-parser.cpp127
-rw-r--r--src/wasm/wasm-stack.cpp79
-rw-r--r--src/wasm/wasm-type.cpp149
-rw-r--r--src/wasm/wasm-validator.cpp143
-rw-r--r--src/wasm/wasm.cpp66
-rw-r--r--src/wasm/wat-parser.cpp44
8 files changed, 50 insertions, 754 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index b8a6c7e7a..05f9d93d5 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -53,8 +53,6 @@ Literal::Literal(Type type) : type(type) {
if (isData()) {
assert(!type.isNonNullable());
new (&gcData) std::shared_ptr<GCData>();
- } else if (type.isRtt()) {
- new (this) Literal(Literal::makeCanonicalRtt(type.getHeapType()));
} else {
// For anything else, zero out all the union data.
memset(&v128, 0, 16);
@@ -71,11 +69,6 @@ Literal::Literal(std::shared_ptr<GCData> gcData, HeapType type)
assert(isData());
}
-Literal::Literal(std::unique_ptr<RttSupers>&& rttSupers, Type type)
- : rttSupers(std::move(rttSupers)), type(type) {
- assert(type.isRtt());
-}
-
Literal::Literal(const Literal& other) : type(other.type) {
if (type.isBasic()) {
switch (type.getBasic()) {
@@ -104,11 +97,6 @@ Literal::Literal(const Literal& other) : type(other.type) {
func = other.func;
return;
}
- if (type.isRtt()) {
- // Allocate a new RttSupers with a copy of the other's data.
- new (&rttSupers) auto(std::make_unique<RttSupers>(*other.rttSupers));
- return;
- }
if (type.isRef()) {
auto heapType = type.getHeapType();
if (heapType.isBasic()) {
@@ -136,11 +124,8 @@ Literal::~Literal() {
if (type.isBasic()) {
return;
}
-
if (isData()) {
gcData.~shared_ptr();
- } else if (type.isRtt()) {
- rttSupers.~unique_ptr();
}
}
@@ -152,18 +137,6 @@ 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;
@@ -228,8 +201,6 @@ Literal Literal::makeZero(Type type) {
assert(type.isSingle());
if (type.isRef()) {
return makeNull(type.getHeapType());
- } else if (type.isRtt()) {
- return Literal(type);
} else {
return makeFromInt32(0, type);
}
@@ -257,11 +228,6 @@ std::shared_ptr<GCData> Literal::getGCData() const {
return gcData;
}
-const RttSupers& Literal::getRttSupers() const {
- assert(type.isRtt());
- return *rttSupers;
-}
-
Literal Literal::castToF32() {
assert(type == Type::i32);
Literal ret(Type::f32);
@@ -383,8 +349,6 @@ bool Literal::operator==(const Literal& other) const {
// other non-null reference type literals cannot represent concrete values,
// i.e. there is no concrete anyref or eqref other than null.
WASM_UNREACHABLE("unexpected type");
- } else if (type.isRtt()) {
- return *rttSupers == *other.rttSupers;
}
WASM_UNREACHABLE("unexpected type");
}
@@ -494,7 +458,7 @@ 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 " << data->type << ' ' << data->values << ']';
} else {
o << "[ref null " << literal.type << ']';
}
@@ -524,15 +488,6 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
WASM_UNREACHABLE("type should have been handled above");
}
}
- } else if (literal.type.isRtt()) {
- o << "[rtt ";
- for (auto& super : literal.getRttSupers()) {
- o << super.type << " :> ";
- if (super.freshPtr) {
- o << " (fresh)";
- }
- }
- o << literal.type << ']';
} else {
TODO_SINGLE_COMPOUND(literal.type);
switch (literal.type.getBasic()) {
@@ -2564,31 +2519,4 @@ Literal Literal::relaxedFmsF64x2(const Literal& left,
return ternary<2, &Literal::getLanesF64x2, &Literal::fms>(*this, left, right);
}
-bool Literal::isSubRtt(const Literal& other) const {
- assert(type.isRtt() && other.type.isRtt());
- // For this literal to be a sub-rtt of the other rtt, the supers must be a
- // superset. That is, if other is a->b->c then we should be a->b->c as well
- // with possibly ->d->.. added. The rttSupers array represents those chains,
- // but only the supers, which means the last item in the chain is simply the
- // type of the literal.
- const auto& supers = getRttSupers();
- const auto& otherSupers = other.getRttSupers();
- if (otherSupers.size() > supers.size()) {
- return false;
- }
- for (Index i = 0; i < otherSupers.size(); i++) {
- if (supers[i] != otherSupers[i]) {
- return false;
- }
- }
- // If we have more supers than other, compare that extra super. Otherwise,
- // we have the same amount of supers, and must be completely identical to
- // other.
- if (otherSupers.size() < supers.size()) {
- return other.type.getHeapType() == supers[otherSupers.size()].type;
- } else {
- return other.type == type;
- }
-}
-
} // namespace wasm
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 4e8e3f0d7..b74ef017b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1383,17 +1383,6 @@ void WasmBinaryWriter::writeType(Type type) {
writeHeapType(type.getHeapType());
return;
}
- if (type.isRtt()) {
- auto rtt = type.getRtt();
- if (rtt.hasDepth()) {
- o << S32LEB(BinaryConsts::EncodedType::rtt_n);
- o << U32LEB(rtt.depth);
- } else {
- o << S32LEB(BinaryConsts::EncodedType::rtt);
- }
- writeIndexedHeapType(rtt.heapType);
- return;
- }
int ret = 0;
TODO_SINGLE_COMPOUND(type);
switch (type.getBasic()) {
@@ -1877,14 +1866,6 @@ Type WasmBinaryBuilder::getType(int initial) {
return Type(getHeapType(), Nullable);
case BinaryConsts::EncodedType::nonnullable:
return Type(getHeapType(), NonNullable);
- case BinaryConsts::EncodedType::rtt_n: {
- auto depth = getU32LEB();
- auto heapType = getIndexedHeapType();
- return Type(Rtt(depth, heapType));
- }
- case BinaryConsts::EncodedType::rtt: {
- return Type(Rtt(getIndexedHeapType()));
- }
default:
throwError("invalid wasm type: " + std::to_string(initial));
}
@@ -2029,16 +2010,6 @@ void WasmBinaryBuilder::readTypes() {
}
return builder.getTempRefType(builder[size_t(htCode)], nullability);
}
- case BinaryConsts::EncodedType::rtt_n:
- case BinaryConsts::EncodedType::rtt: {
- auto depth = typeCode == BinaryConsts::EncodedType::rtt ? Rtt::NoDepth
- : getU32LEB();
- auto htCode = getU32LEB();
- if (size_t(htCode) >= builder.size()) {
- throwError("invalid type index: " + std::to_string(htCode));
- }
- return builder.getTempRttType(Rtt(depth, builder[htCode]));
- }
default:
throwError("unexpected type index: " + std::to_string(typeCode));
}
@@ -3875,12 +3846,6 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitBrOn(curr, opcode)) {
break;
}
- if (maybeVisitRttCanon(curr, opcode)) {
- break;
- }
- if (maybeVisitRttSub(curr, opcode)) {
- break;
- }
if (maybeVisitStructNew(curr, opcode)) {
break;
}
@@ -6793,12 +6758,7 @@ bool WasmBinaryBuilder::maybeVisitI31Get(Expression*& out, uint32_t code) {
}
bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::RefTest) {
- auto* rtt = popNonVoidExpression();
- auto* ref = popNonVoidExpression();
- out = Builder(wasm).makeRefTest(ref, rtt);
- return true;
- } else if (code == BinaryConsts::RefTestStatic) {
+ if (code == BinaryConsts::RefTestStatic) {
auto intendedType = getIndexedHeapType();
auto* ref = popNonVoidExpression();
out = Builder(wasm).makeRefTest(ref, intendedType);
@@ -6808,13 +6768,8 @@ bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) {
}
bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::RefCast) {
- auto* rtt = popNonVoidExpression();
- auto* ref = popNonVoidExpression();
- out = Builder(wasm).makeRefCast(ref, rtt);
- return true;
- } else if (code == BinaryConsts::RefCastStatic ||
- code == BinaryConsts::RefCastNopStatic) {
+ if (code == BinaryConsts::RefCastStatic ||
+ code == BinaryConsts::RefCastNopStatic) {
auto intendedType = getIndexedHeapType();
auto* ref = popNonVoidExpression();
auto safety =
@@ -6834,11 +6789,9 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) {
case BinaryConsts::BrOnNonNull:
op = BrOnNonNull;
break;
- case BinaryConsts::BrOnCast:
case BinaryConsts::BrOnCastStatic:
op = BrOnCast;
break;
- case BinaryConsts::BrOnCastFail:
case BinaryConsts::BrOnCastStaticFail:
op = BrOnCastFail;
break;
@@ -6871,35 +6824,8 @@ bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) {
out = Builder(wasm).makeBrOn(op, name, ref, intendedType);
return true;
}
- Expression* rtt = nullptr;
- if (op == BrOnCast || op == BrOnCastFail) {
- rtt = popNonVoidExpression();
- }
auto* ref = popNonVoidExpression();
- out = ValidatingBuilder(wasm, pos).validateAndMakeBrOn(op, name, ref, rtt);
- return true;
-}
-
-bool WasmBinaryBuilder::maybeVisitRttCanon(Expression*& out, uint32_t code) {
- if (code != BinaryConsts::RttCanon) {
- return false;
- }
- auto heapType = getIndexedHeapType();
- out = Builder(wasm).makeRttCanon(heapType);
- return true;
-}
-
-bool WasmBinaryBuilder::maybeVisitRttSub(Expression*& out, uint32_t code) {
- if (code != BinaryConsts::RttSub && code != BinaryConsts::RttFreshSub) {
- return false;
- }
- auto targetHeapType = getIndexedHeapType();
- auto* parent = popNonVoidExpression();
- if (code == BinaryConsts::RttSub) {
- out = Builder(wasm).makeRttSub(targetHeapType, parent);
- } else {
- out = Builder(wasm).makeRttFreshSub(targetHeapType, parent);
- }
+ out = ValidatingBuilder(wasm, pos).validateAndMakeBrOn(op, name, ref);
return true;
}
@@ -6917,21 +6843,6 @@ bool WasmBinaryBuilder::maybeVisitStructNew(Expression*& out, uint32_t code) {
}
out = Builder(wasm).makeStructNew(heapType, operands);
return true;
- } else if (code == BinaryConsts::StructNewWithRtt ||
- code == BinaryConsts::StructNewDefaultWithRtt) {
- auto heapType = getIndexedHeapType();
- auto* rtt = popNonVoidExpression();
- validateHeapTypeUsingChild(rtt, heapType);
- std::vector<Expression*> operands;
- if (code == BinaryConsts::StructNewWithRtt) {
- auto numOperands = heapType.getStruct().fields.size();
- operands.resize(numOperands);
- for (Index i = 0; i < numOperands; i++) {
- operands[numOperands - i - 1] = popNonVoidExpression();
- }
- }
- out = Builder(wasm).makeStructNew(rtt, operands);
- return true;
}
return false;
}
@@ -6987,18 +6898,6 @@ bool WasmBinaryBuilder::maybeVisitArrayNew(Expression*& out, uint32_t code) {
}
out = Builder(wasm).makeArrayNew(heapType, size, init);
return true;
- } else if (code == BinaryConsts::ArrayNewWithRtt ||
- code == BinaryConsts::ArrayNewDefaultWithRtt) {
- auto heapType = getIndexedHeapType();
- auto* rtt = popNonVoidExpression();
- validateHeapTypeUsingChild(rtt, heapType);
- auto* size = popNonVoidExpression();
- Expression* init = nullptr;
- if (code == BinaryConsts::ArrayNewWithRtt) {
- init = popNonVoidExpression();
- }
- out = Builder(wasm).makeArrayNew(rtt, size, init);
- return true;
}
return false;
}
@@ -7013,17 +6912,6 @@ bool WasmBinaryBuilder::maybeVisitArrayInit(Expression*& out, uint32_t code) {
}
out = Builder(wasm).makeArrayInit(heapType, values);
return true;
- } else if (code == BinaryConsts::ArrayInit) {
- auto heapType = getIndexedHeapType();
- auto size = getU32LEB();
- auto* rtt = popNonVoidExpression();
- validateHeapTypeUsingChild(rtt, heapType);
- std::vector<Expression*> values(size);
- for (size_t i = 0; i < size; i++) {
- values[size - i - 1] = popNonVoidExpression();
- }
- out = Builder(wasm).makeArrayInit(rtt, values);
- return true;
}
return false;
}
@@ -7370,7 +7258,7 @@ void WasmBinaryBuilder::validateHeapTypeUsingChild(Expression* child,
if (child->type == Type::unreachable) {
return;
}
- if ((!child->type.isRef() && !child->type.isRtt()) ||
+ if (!child->type.isRef() ||
!HeapType::isSubType(child->type.getHeapType(), heapType)) {
throwError("bad heap type: expected " + heapType.toString() +
" but found " + child->type.toString());
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 38ec788ba..f13091c91 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -54,7 +54,7 @@ namespace wasm {
static Name STRUCT("struct"), FIELD("field"), ARRAY("array"),
FUNC_SUBTYPE("func_subtype"), STRUCT_SUBTYPE("struct_subtype"),
ARRAY_SUBTYPE("array_subtype"), EXTENDS("extends"), REC("rec"), I8("i8"),
- I16("i16"), RTT("rtt"), DECLARE("declare"), ITEM("item"), OFFSET("offset");
+ I16("i16"), DECLARE("declare"), ITEM("item"), OFFSET("offset");
static Address getAddress(const Element* s) { return atoll(s->c_str()); }
@@ -752,46 +752,11 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
}
};
- auto parseRttType = [&](Element& elem) -> Type {
- // '(' 'rtt' depth? typeidx ')'
- uint32_t depth;
- Element* idx;
- switch (elem.size()) {
- default:
- throw ParseException(
- "unexpected number of rtt parameters", elem.line, elem.col);
- case 2:
- depth = Rtt::NoDepth;
- idx = elem[1];
- break;
- case 3:
- if (!String::isNumber(elem[1]->c_str())) {
- throw ParseException(
- "invalid rtt depth", elem[1]->line, elem[1]->col);
- }
- depth = atoi(elem[1]->c_str());
- idx = elem[2];
- break;
- }
- if (idx->dollared()) {
- HeapType type = builder[typeIndices[idx->c_str()]];
- return builder.getTempRttType(Rtt(depth, type));
- } else if (String::isNumber(idx->c_str())) {
- size_t index = atoi(idx->c_str());
- if (index < numTypes) {
- return builder.getTempRttType(Rtt(depth, builder[index]));
- }
- }
- throw ParseException("invalid type index", idx->line, idx->col);
- };
-
auto parseValType = [&](Element& elem) {
if (elem.isStr()) {
return stringToType(elem.c_str());
} else if (*elem[0] == REF) {
return parseRefType(elem);
- } else if (*elem[0] == RTT) {
- return parseRttType(elem);
} else {
throw ParseException("unknown valtype kind", elem[0]->line, elem[0]->col);
}
@@ -1281,18 +1246,6 @@ Type SExpressionWasmBuilder::elementToType(Element& s) {
}
return Type(parseHeapType(*s[i]), nullable);
}
- if (elementStartsWith(s, RTT)) {
- // It's an RTT, something like (rtt N $typename) or just (rtt $typename)
- // if there is no depth.
- if (s[1]->dollared()) {
- auto heapType = parseHeapType(*s[1]);
- return Type(Rtt(heapType));
- } else {
- auto depth = atoi(s[1]->str().c_str());
- auto heapType = parseHeapType(*s[2]);
- return Type(Rtt(depth, heapType));
- }
- }
// It's a tuple.
std::vector<Type> types;
for (size_t i = 0; i < s.size(); ++i) {
@@ -2702,24 +2655,12 @@ Expression* SExpressionWasmBuilder::makeI31Get(Element& s, bool signed_) {
return ret;
}
-Expression* SExpressionWasmBuilder::makeRefTest(Element& s) {
- auto* ref = parseExpression(*s[1]);
- auto* rtt = parseExpression(*s[2]);
- return Builder(wasm).makeRefTest(ref, rtt);
-}
-
Expression* SExpressionWasmBuilder::makeRefTestStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
auto* ref = parseExpression(*s[2]);
return Builder(wasm).makeRefTest(ref, heapType);
}
-Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {
- auto* ref = parseExpression(*s[1]);
- auto* rtt = parseExpression(*s[2]);
- return Builder(wasm).makeRefCast(ref, rtt);
-}
-
Expression* SExpressionWasmBuilder::makeRefCastStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
auto* ref = parseExpression(*s[2]);
@@ -2735,12 +2676,8 @@ Expression* SExpressionWasmBuilder::makeRefCastNopStatic(Element& s) {
Expression* SExpressionWasmBuilder::makeBrOn(Element& s, BrOnOp op) {
auto name = getLabel(*s[1]);
auto* ref = parseExpression(*s[2]);
- Expression* rtt = nullptr;
- if (op == BrOnCast || op == BrOnCastFail) {
- rtt = parseExpression(*s[3]);
- }
return ValidatingBuilder(wasm, s.line, s.col)
- .validateAndMakeBrOn(op, name, ref, rtt);
+ .validateAndMakeBrOn(op, name, ref);
}
Expression* SExpressionWasmBuilder::makeBrOnStatic(Element& s, BrOnOp op) {
@@ -2750,39 +2687,6 @@ Expression* SExpressionWasmBuilder::makeBrOnStatic(Element& s, BrOnOp op) {
return Builder(wasm).makeBrOn(op, name, ref, heapType);
}
-Expression* SExpressionWasmBuilder::makeRttCanon(Element& s) {
- return Builder(wasm).makeRttCanon(parseHeapType(*s[1]));
-}
-
-Expression* SExpressionWasmBuilder::makeRttSub(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- auto parent = parseExpression(*s[2]);
- return Builder(wasm).makeRttSub(heapType, parent);
-}
-
-Expression* SExpressionWasmBuilder::makeRttFreshSub(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- auto parent = parseExpression(*s[2]);
- return Builder(wasm).makeRttFreshSub(heapType, parent);
-}
-
-Expression* SExpressionWasmBuilder::makeStructNew(Element& s, bool default_) {
- auto heapType = parseHeapType(*s[1]);
- auto numOperands = s.size() - 3;
- if (default_ && numOperands > 0) {
- throw ParseException(
- "arguments provided for struct.new_with_default", s.line, s.col);
- }
- std::vector<Expression*> operands;
- operands.resize(numOperands);
- for (Index i = 0; i < numOperands; i++) {
- operands[i] = parseExpression(*s[i + 2]);
- }
- auto* rtt = parseExpression(*s[s.size() - 1]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeStructNew(rtt, operands);
-}
-
Expression* SExpressionWasmBuilder::makeStructNewStatic(Element& s,
bool default_) {
auto heapType = parseHeapType(*s[1]);
@@ -2841,19 +2745,6 @@ Expression* SExpressionWasmBuilder::makeStructSet(Element& s) {
return Builder(wasm).makeStructSet(index, ref, value);
}
-Expression* SExpressionWasmBuilder::makeArrayNew(Element& s, bool default_) {
- auto heapType = parseHeapType(*s[1]);
- Expression* init = nullptr;
- size_t i = 2;
- if (!default_) {
- init = parseExpression(*s[i++]);
- }
- auto* size = parseExpression(*s[i++]);
- auto* rtt = parseExpression(*s[i++]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeArrayNew(rtt, size, init);
-}
-
Expression* SExpressionWasmBuilder::makeArrayNewStatic(Element& s,
bool default_) {
auto heapType = parseHeapType(*s[1]);
@@ -2866,18 +2757,6 @@ Expression* SExpressionWasmBuilder::makeArrayNewStatic(Element& s,
return Builder(wasm).makeArrayNew(heapType, size, init);
}
-Expression* SExpressionWasmBuilder::makeArrayInit(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- size_t i = 2;
- std::vector<Expression*> values;
- while (i < s.size() - 1) {
- values.push_back(parseExpression(*s[i++]));
- }
- auto* rtt = parseExpression(*s[i++]);
- validateHeapTypeUsingChild(rtt, heapType, s);
- return Builder(wasm).makeArrayInit(rtt, values);
-}
-
Expression* SExpressionWasmBuilder::makeArrayInitStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
size_t i = 2;
@@ -3853,7 +3732,7 @@ void SExpressionWasmBuilder::validateHeapTypeUsingChild(Expression* child,
if (child->type == Type::unreachable) {
return;
}
- if ((!child->type.isRef() && !child->type.isRtt()) ||
+ if (!child->type.isRef() ||
!HeapType::isSubType(child->type.getHeapType(), heapType)) {
throw ParseException("bad heap type: expected " + heapType.toString() +
" but found " + child->type.toString(),
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 2fc06b176..c29384dad 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2016,26 +2016,18 @@ void BinaryInstWriter::visitCallRef(CallRef* curr) {
void BinaryInstWriter::visitRefTest(RefTest* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::RefTest);
- } else {
- o << U32LEB(BinaryConsts::RefTestStatic);
- parent.writeIndexedHeapType(curr->intendedType);
- }
+ o << U32LEB(BinaryConsts::RefTestStatic);
+ parent.writeIndexedHeapType(curr->intendedType);
}
void BinaryInstWriter::visitRefCast(RefCast* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::RefCast);
+ if (curr->safety == RefCast::Unsafe) {
+ o << U32LEB(BinaryConsts::RefCastNopStatic);
} else {
- if (curr->safety == RefCast::Unsafe) {
- o << U32LEB(BinaryConsts::RefCastNopStatic);
- } else {
- o << U32LEB(BinaryConsts::RefCastStatic);
- }
- parent.writeIndexedHeapType(curr->intendedType);
+ o << U32LEB(BinaryConsts::RefCastStatic);
}
+ parent.writeIndexedHeapType(curr->intendedType);
}
void BinaryInstWriter::visitBrOn(BrOn* curr) {
@@ -2048,19 +2040,11 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
break;
case BrOnCast:
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::BrOnCast);
- } else {
- o << U32LEB(BinaryConsts::BrOnCastStatic);
- }
+ o << U32LEB(BinaryConsts::BrOnCastStatic);
break;
case BrOnCastFail:
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::BrOnCastFail);
- } else {
- o << U32LEB(BinaryConsts::BrOnCastStaticFail);
- }
+ o << U32LEB(BinaryConsts::BrOnCastStaticFail);
break;
case BrOnFunc:
o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::BrOnFunc);
@@ -2084,36 +2068,17 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) {
WASM_UNREACHABLE("invalid br_on_*");
}
o << U32LEB(getBreakIndex(curr->name));
- if ((curr->op == BrOnCast || curr->op == BrOnCastFail) && !curr->rtt) {
+ if (curr->op == BrOnCast || curr->op == BrOnCastFail) {
parent.writeIndexedHeapType(curr->intendedType);
}
}
-void BinaryInstWriter::visitRttCanon(RttCanon* curr) {
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RttCanon);
- parent.writeIndexedHeapType(curr->type.getRtt().heapType);
-}
-
-void BinaryInstWriter::visitRttSub(RttSub* curr) {
- o << int8_t(BinaryConsts::GCPrefix);
- o << U32LEB(curr->fresh ? BinaryConsts::RttFreshSub : BinaryConsts::RttSub);
- parent.writeIndexedHeapType(curr->type.getRtt().heapType);
-}
-
void BinaryInstWriter::visitStructNew(StructNew* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::StructNewDefaultWithRtt);
- } else {
- o << U32LEB(BinaryConsts::StructNewWithRtt);
- }
+ if (curr->isWithDefault()) {
+ o << U32LEB(BinaryConsts::StructNewDefault);
} else {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::StructNewDefault);
- } else {
- o << U32LEB(BinaryConsts::StructNew);
- }
+ o << U32LEB(BinaryConsts::StructNew);
}
parent.writeIndexedHeapType(curr->type.getHeapType());
}
@@ -2142,29 +2107,17 @@ void BinaryInstWriter::visitStructSet(StructSet* curr) {
void BinaryInstWriter::visitArrayNew(ArrayNew* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::ArrayNewDefaultWithRtt);
- } else {
- o << U32LEB(BinaryConsts::ArrayNewWithRtt);
- }
+ if (curr->isWithDefault()) {
+ o << U32LEB(BinaryConsts::ArrayNewDefault);
} else {
- if (curr->isWithDefault()) {
- o << U32LEB(BinaryConsts::ArrayNewDefault);
- } else {
- o << U32LEB(BinaryConsts::ArrayNew);
- }
+ o << U32LEB(BinaryConsts::ArrayNew);
}
parent.writeIndexedHeapType(curr->type.getHeapType());
}
void BinaryInstWriter::visitArrayInit(ArrayInit* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->rtt) {
- o << U32LEB(BinaryConsts::ArrayInit);
- } else {
- o << U32LEB(BinaryConsts::ArrayInitStatic);
- }
+ o << U32LEB(BinaryConsts::ArrayInitStatic);
parent.writeIndexedHeapType(curr->type.getHeapType());
o << U32LEB(curr->values.size());
}
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 84b11000f..23d2877f7 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -60,7 +60,6 @@ struct TypeInfo {
enum Kind {
TupleKind,
RefKind,
- RttKind,
} kind;
struct Ref {
HeapType heapType;
@@ -69,20 +68,17 @@ struct TypeInfo {
union {
Tuple tuple;
Ref ref;
- Rtt rtt;
};
TypeInfo(const Tuple& tuple) : kind(TupleKind), tuple(tuple) {}
TypeInfo(Tuple&& tuple) : kind(TupleKind), tuple(std::move(tuple)) {}
TypeInfo(HeapType heapType, Nullability nullable)
: kind(RefKind), ref{heapType, nullable} {}
- TypeInfo(Rtt rtt) : kind(RttKind), rtt(rtt) {}
TypeInfo(const TypeInfo& other);
~TypeInfo();
constexpr bool isTuple() const { return kind == TupleKind; }
constexpr bool isRef() const { return kind == RefKind; }
- constexpr bool isRtt() const { return kind == RttKind; }
bool isNullable() const { return kind == RefKind && ref.nullable; }
@@ -165,7 +161,6 @@ struct SubTyper {
bool isSubType(const Signature& a, const Signature& b);
bool isSubType(const Struct& a, const Struct& b);
bool isSubType(const Array& a, const Array& b);
- bool isSubType(const Rtt& a, const Rtt& b);
};
// Helper for finding the equirecursive least upper bound of two types.
@@ -192,7 +187,6 @@ private:
std::optional<Signature> lub(const Signature& a, const Signature& b);
Struct lub(const Struct& a, const Struct& b);
std::optional<Array> lub(const Array& a, const Array& b);
- std::optional<Rtt> lub(const Rtt& a, const Rtt& b);
};
// Helper for printing types.
@@ -231,7 +225,6 @@ struct TypePrinter {
std::optional<HeapType> super = std::nullopt);
std::ostream& print(const Array& array,
std::optional<HeapType> super = std::nullopt);
- std::ostream& print(const Rtt& rtt);
};
// Helper for hashing the shapes of TypeInfos and HeapTypeInfos. Keeps track of
@@ -255,7 +248,6 @@ struct FiniteShapeHasher {
size_t hash(const Signature& sig);
size_t hash(const Struct& struct_);
size_t hash(const Array& array);
- size_t hash(const Rtt& rtt);
};
// Helper for comparing the shapes of TypeInfos and HeapTypeInfos for equality.
@@ -281,7 +273,6 @@ struct FiniteShapeEquator {
bool eq(const Signature& a, const Signature& b);
bool eq(const Struct& a, const Struct& b);
bool eq(const Array& a, const Array& b);
- bool eq(const Rtt& a, const Rtt& b);
};
struct RecGroupHasher {
@@ -307,7 +298,6 @@ struct RecGroupHasher {
size_t hash(const Signature& sig) const;
size_t hash(const Struct& struct_) const;
size_t hash(const Array& array) const;
- size_t hash(const Rtt& rtt) const;
};
struct RecGroupEquator {
@@ -334,7 +324,6 @@ struct RecGroupEquator {
bool eq(const Signature& a, const Signature& b) const;
bool eq(const Struct& a, const Struct& b) const;
bool eq(const Array& a, const Array& b) const;
- bool eq(const Rtt& a, const Rtt& b) const;
};
// A wrapper around a RecGroup that provides equality and hashing based on the
@@ -626,9 +615,6 @@ TypeInfo::TypeInfo(const TypeInfo& other) {
case RefKind:
new (&ref) auto(other.ref);
return;
- case RttKind:
- new (&rtt) auto(other.rtt);
- return;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -641,9 +627,6 @@ TypeInfo::~TypeInfo() {
case RefKind:
ref.~Ref();
return;
- case RttKind:
- rtt.~Rtt();
- return;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -670,8 +653,6 @@ bool TypeInfo::operator==(const TypeInfo& other) const {
case RefKind:
return ref.nullable == other.ref.nullable &&
ref.heapType == other.ref.heapType;
- case RttKind:
- return rtt == other.rtt;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -947,11 +928,6 @@ Type::Type(HeapType heapType, Nullability nullable) {
new (this) Type(globalTypeStore.insert(TypeInfo(heapType, nullable)));
}
-Type::Type(Rtt rtt) {
- assert(!isTemp(rtt.heapType) && "Leaking temporary type!");
- new (this) Type(globalTypeStore.insert(rtt));
-}
-
bool Type::isTuple() const {
if (isBasic()) {
return false;
@@ -1002,14 +978,6 @@ bool Type::isNonNullable() const {
}
}
-bool Type::isRtt() const {
- if (isBasic()) {
- return false;
- } else {
- return getTypeInfo(*this)->isRtt();
- }
-}
-
bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); }
bool Type::isArray() const { return isRef() && getHeapType().isArray(); }
@@ -1026,19 +994,7 @@ bool Type::isDefaultable() const {
}
return true;
}
- return isConcrete() && !isNonNullable() && !isRtt();
-}
-
-bool Type::isDefaultableOrNonNullable() const {
- if (isTuple()) {
- for (auto t : *this) {
- if (!t.isDefaultableOrNonNullable()) {
- return false;
- }
- }
- return true;
- }
- return isConcrete() && !isRtt();
+ return isConcrete() && !isNonNullable();
}
Nullability Type::getNullability() const {
@@ -1132,8 +1088,6 @@ FeatureSet Type::getFeatures() const {
// load of the wasm we don't know the features yet, so we apply the more
// refined types), so we don't add that in any case here.
return FeatureSet::ReferenceTypes;
- } else if (t.isRtt()) {
- return FeatureSet::ReferenceTypes | FeatureSet::GC;
}
TODO_SINGLE_COMPOUND(t);
switch (t.getBasic()) {
@@ -1179,18 +1133,11 @@ HeapType Type::getHeapType() const {
break;
case TypeInfo::RefKind:
return info->ref.heapType;
- case TypeInfo::RttKind:
- return info->rtt.heapType;
}
WASM_UNREACHABLE("Unexpected type");
}
}
-Rtt Type::getRtt() const {
- assert(isRtt());
- return getTypeInfo(*this)->rtt;
-}
-
Type Type::get(unsigned byteSize, bool float_) {
if (byteSize < 4) {
return Type::i32;
@@ -1264,15 +1211,6 @@ Type Type::getLeastUpperBound(Type a, Type b) {
HeapType::getLeastUpperBound(a.getHeapType(), b.getHeapType());
return Type(heapType, nullability);
}
- if (a.isRtt() && b.isRtt()) {
- auto heapType = a.getHeapType();
- if (heapType != b.getHeapType()) {
- return Type::none;
- }
- auto rttA = a.getRtt(), rttB = b.getRtt();
- auto depth = rttA.depth == rttB.depth ? rttA.depth : Rtt::NoDepth;
- return Rtt(depth, heapType);
- }
return Type::none;
WASM_UNREACHABLE("unexpected type");
}
@@ -1593,7 +1531,6 @@ std::string Tuple::toString() const { return genericToString(*this); }
std::string Signature::toString() const { return genericToString(*this); }
std::string Struct::toString() const { return genericToString(*this); }
std::string Array::toString() const { return genericToString(*this); }
-std::string Rtt::toString() const { return genericToString(*this); }
std::ostream& operator<<(std::ostream& os, Type type) {
return TypePrinter(os).print(type);
@@ -1622,9 +1559,6 @@ std::ostream& operator<<(std::ostream& os, Struct struct_) {
std::ostream& operator<<(std::ostream& os, Array array) {
return TypePrinter(os).print(array);
}
-std::ostream& operator<<(std::ostream& os, Rtt rtt) {
- return TypePrinter(os).print(rtt);
-}
std::ostream& operator<<(std::ostream& os, TypeBuilder::ErrorReason reason) {
switch (reason) {
case TypeBuilder::ErrorReason::SelfSupertype:
@@ -1670,9 +1604,6 @@ bool SubTyper::isSubType(Type a, Type b) {
if (a.isTuple() && b.isTuple()) {
return isSubType(a.getTuple(), b.getTuple());
}
- if (a.isRtt() && b.isRtt()) {
- return isSubType(a.getRtt(), b.getRtt());
- }
return false;
}
@@ -1783,13 +1714,6 @@ bool SubTyper::isSubType(const Array& a, const Array& b) {
return isSubType(a.element, b.element);
}
-bool SubTyper::isSubType(const Rtt& a, const Rtt& b) {
- // (rtt n $x) is a subtype of (rtt $x), that is, if the only difference in
- // information is that the left side specifies a depth while the right side
- // allows any depth.
- return a.heapType == b.heapType && a.hasDepth() && !b.hasDepth();
-}
-
bool TypeBounder::hasLeastUpperBound(Type a, Type b) { return bool(lub(a, b)); }
Type TypeBounder::getLeastUpperBound(Type a, Type b) {
@@ -1847,12 +1771,6 @@ std::optional<Type> TypeBounder::lub(Type a, Type b) {
(a.isNullable() || b.isNullable()) ? Nullable : NonNullable;
HeapType heapType = lub(a.getHeapType(), b.getHeapType());
return builder.getTempRefType(heapType, nullability);
- } else if (a.isRtt() && b.isRtt()) {
- auto rtt = lub(a.getRtt(), b.getRtt());
- if (!rtt) {
- return {};
- }
- return builder.getTempRttType(*rtt);
}
return {};
}
@@ -1987,14 +1905,6 @@ std::optional<Array> TypeBounder::lub(const Array& a, const Array& b) {
}
}
-std::optional<Rtt> TypeBounder::lub(const Rtt& a, const Rtt& b) {
- if (a.heapType != b.heapType) {
- return {};
- }
- uint32_t depth = (a.depth == b.depth) ? a.depth : Rtt::NoDepth;
- return Rtt(depth, a.heapType);
-}
-
void TypePrinter::printHeapTypeName(HeapType type) {
if (type.isBasic()) {
print(type);
@@ -2080,8 +1990,6 @@ std::ostream& TypePrinter::print(Type type) {
}
printHeapTypeName(heapType);
os << ')';
- } else if (type.isRtt()) {
- print(type.getRtt());
} else {
WASM_UNREACHABLE("unexpected type");
}
@@ -2234,15 +2142,6 @@ std::ostream& TypePrinter::print(const Array& array,
return os << ')';
}
-std::ostream& TypePrinter::print(const Rtt& rtt) {
- os << "(rtt ";
- if (rtt.hasDepth()) {
- os << rtt.depth << ' ';
- }
- printHeapTypeName(rtt.heapType);
- return os << ')';
-}
-
size_t FiniteShapeHasher::hash(Type type) {
size_t digest = wasm::hash(type.isBasic());
if (type.isBasic()) {
@@ -2285,9 +2184,6 @@ size_t FiniteShapeHasher::hash(const TypeInfo& info) {
rehash(digest, info.ref.nullable);
hash_combine(digest, hash(info.ref.heapType));
return digest;
- case TypeInfo::RttKind:
- hash_combine(digest, hash(info.rtt));
- return digest;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2355,12 +2251,6 @@ size_t FiniteShapeHasher::hash(const Array& array) {
return hash(array.element);
}
-size_t FiniteShapeHasher::hash(const Rtt& rtt) {
- size_t digest = wasm::hash(rtt.depth);
- hash_combine(digest, hash(rtt.heapType));
- return digest;
-}
-
bool FiniteShapeEquator::eq(Type a, Type b) {
if (a.isBasic() != b.isBasic()) {
return false;
@@ -2404,8 +2294,6 @@ bool FiniteShapeEquator::eq(const TypeInfo& a, const TypeInfo& b) {
case TypeInfo::RefKind:
return a.ref.nullable == b.ref.nullable &&
eq(a.ref.heapType, b.ref.heapType);
- case TypeInfo::RttKind:
- return eq(a.rtt, b.rtt);
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2466,10 +2354,6 @@ bool FiniteShapeEquator::eq(const Array& a, const Array& b) {
return eq(a.element, b.element);
}
-bool FiniteShapeEquator::eq(const Rtt& a, const Rtt& b) {
- return a.depth == b.depth && eq(a.heapType, b.heapType);
-}
-
size_t RecGroupHasher::operator()() const {
size_t digest = wasm::hash(group.size());
for (auto type : group) {
@@ -2526,9 +2410,6 @@ size_t RecGroupHasher::hash(const TypeInfo& info) const {
rehash(digest, info.ref.nullable);
hash_combine(digest, hash(info.ref.heapType));
return digest;
- case TypeInfo::RttKind:
- hash_combine(digest, hash(info.rtt));
- return digest;
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2589,12 +2470,6 @@ size_t RecGroupHasher::hash(const Array& array) const {
return hash(array.element);
}
-size_t RecGroupHasher::hash(const Rtt& rtt) const {
- size_t digest = wasm::hash(rtt.depth);
- hash_combine(digest, hash(rtt.heapType));
- return digest;
-}
-
bool RecGroupEquator::operator()() const {
if (newGroup == otherGroup) {
return true;
@@ -2655,8 +2530,6 @@ bool RecGroupEquator::eq(const TypeInfo& a, const TypeInfo& b) const {
case TypeInfo::RefKind:
return a.ref.nullable == b.ref.nullable &&
eq(a.ref.heapType, b.ref.heapType);
- case TypeInfo::RttKind:
- return eq(a.rtt, b.rtt);
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -2717,10 +2590,6 @@ bool RecGroupEquator::eq(const Array& a, const Array& b) const {
return eq(a.element, b.element);
}
-bool RecGroupEquator::eq(const Rtt& a, const Rtt& b) const {
- return a.depth == b.depth && eq(a.heapType, b.heapType);
-}
-
template<typename Self> void TypeGraphWalkerBase<Self>::walkRoot(Type* type) {
assert(taskList.empty());
taskList.push_back(Task::scan(type));
@@ -2781,9 +2650,6 @@ template<typename Self> void TypeGraphWalkerBase<Self>::scanType(Type* type) {
taskList.push_back(Task::scan(&info->ref.heapType));
break;
}
- case TypeInfo::RttKind:
- taskList.push_back(Task::scan(&info->rtt.heapType));
- break;
}
}
@@ -2921,10 +2787,6 @@ Type TypeBuilder::getTempRefType(HeapType type, Nullability nullable) {
return markTemp(impl->typeStore.insert(TypeInfo(type, nullable)));
}
-Type TypeBuilder::getTempRttType(Rtt rtt) {
- return markTemp(impl->typeStore.insert(rtt));
-}
-
void TypeBuilder::setSubType(size_t i, size_t j) {
assert(i < size() && j < size() && "index out of bounds");
HeapTypeInfo* sub = impl->entries[i].info.get();
@@ -4031,12 +3893,6 @@ size_t hash<wasm::RecGroup>::operator()(const wasm::RecGroup& group) const {
return wasm::hash(group.getID());
}
-size_t hash<wasm::Rtt>::operator()(const wasm::Rtt& rtt) const {
- auto digest = wasm::hash(rtt.depth);
- wasm::rehash(digest, rtt.heapType);
- return digest;
-}
-
size_t hash<wasm::TypeInfo>::operator()(const wasm::TypeInfo& info) const {
auto digest = wasm::hash(info.kind);
switch (info.kind) {
@@ -4047,9 +3903,6 @@ size_t hash<wasm::TypeInfo>::operator()(const wasm::TypeInfo& info) const {
wasm::rehash(digest, info.ref.nullable);
wasm::rehash(digest, info.ref.heapType);
return digest;
- case wasm::TypeInfo::RttKind:
- wasm::rehash(digest, info.rtt);
- return digest;
}
WASM_UNREACHABLE("unexpected kind");
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 65a910747..bc51d8b63 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -383,8 +383,6 @@ public:
void visitRefTest(RefTest* curr);
void visitRefCast(RefCast* curr);
void visitBrOn(BrOn* curr);
- void visitRttCanon(RttCanon* curr);
- void visitRttSub(RttSub* curr);
void visitStructNew(StructNew* curr);
void visitStructGet(StructGet* curr);
void visitStructSet(StructSet* curr);
@@ -2338,23 +2336,12 @@ void FunctionValidator::visitRefTest(RefTest* curr) {
shouldBeTrue(
curr->ref->type.isRef(), curr, "ref.test ref must have ref type");
}
- if (curr->rtt) {
- if (curr->rtt->type != Type::unreachable) {
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "ref.test rtt must have rtt type");
- }
- shouldBeEqual(curr->intendedType,
+ shouldBeUnequal(curr->intendedType,
HeapType(),
curr,
- "dynamic ref.test must not use intendedType field");
- } else {
- shouldBeUnequal(curr->intendedType,
- HeapType(),
- curr,
- "static ref.test must set intendedType field");
- shouldBeTrue(
- !curr->intendedType.isBasic(), curr, "ref.test must test a non-basic");
- }
+ "static ref.test must set intendedType field");
+ shouldBeTrue(
+ !curr->intendedType.isBasic(), curr, "ref.test must test a non-basic");
}
void FunctionValidator::visitRefCast(RefCast* curr) {
@@ -2364,23 +2351,12 @@ void FunctionValidator::visitRefCast(RefCast* curr) {
shouldBeTrue(
curr->ref->type.isRef(), curr, "ref.cast ref must have ref type");
}
- if (curr->rtt) {
- if (curr->rtt->type != Type::unreachable) {
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "ref.cast rtt must have rtt type");
- }
- shouldBeEqual(curr->intendedType,
+ shouldBeUnequal(curr->intendedType,
HeapType(),
curr,
- "dynamic ref.cast must not use intendedType field");
- } else {
- shouldBeUnequal(curr->intendedType,
- HeapType(),
- curr,
- "static ref.cast must set intendedType field");
- shouldBeTrue(
- !curr->intendedType.isBasic(), curr, "ref.cast must cast to a non-basic");
- }
+ "static ref.cast must set intendedType field");
+ shouldBeTrue(
+ !curr->intendedType.isBasic(), curr, "ref.cast must cast to a non-basic");
}
void FunctionValidator::visitBrOn(BrOn* curr) {
@@ -2392,28 +2368,14 @@ void FunctionValidator::visitBrOn(BrOn* curr) {
curr->ref->type.isRef(), curr, "br_on_cast ref must have ref type");
}
if (curr->op == BrOnCast || curr->op == BrOnCastFail) {
- if (curr->rtt) {
- // Note that an unreachable rtt is not supported: the text and binary
- // formats do not provide the type, so if it's unreachable we should not
- // even create a br_on_cast in such a case, as we'd have no idea what it
- // casts to.
- shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "br_on_cast rtt must have rtt type");
- shouldBeEqual(curr->intendedType,
+ shouldBeUnequal(curr->intendedType,
HeapType(),
curr,
- "dynamic br_on_cast* must not use intendedType field");
- } else {
- shouldBeUnequal(curr->intendedType,
- HeapType(),
- curr,
- "static br_on_cast* must set intendedType field");
- shouldBeTrue(!curr->intendedType.isBasic(),
- curr,
- "br_on_cast* must cast to a non-basic");
- }
+ "static br_on_cast* must set intendedType field");
+ shouldBeTrue(!curr->intendedType.isBasic(),
+ curr,
+ "br_on_cast* must cast to a non-basic");
} else {
- shouldBeTrue(curr->rtt == nullptr, curr, "non-cast BrOn must not have rtt");
shouldBeEqual(curr->intendedType,
HeapType(),
curr,
@@ -2422,38 +2384,6 @@ void FunctionValidator::visitBrOn(BrOn* curr) {
noteBreak(curr->name, curr->getSentType(), curr);
}
-void FunctionValidator::visitRttCanon(RttCanon* curr) {
- shouldBeTrue(
- 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(curr->type.getHeapType().getDepth()),
- curr,
- "rtt.canon must have the depth of its heap type");
-}
-
-void FunctionValidator::visitRttSub(RttSub* curr) {
- shouldBeTrue(
- getModule()->features.hasGC(), curr, "rtt.sub requires gc to be enabled");
- shouldBeTrue(curr->type.isRtt(), curr, "rtt.sub must have RTT type");
- if (curr->parent->type != Type::unreachable) {
- shouldBeTrue(
- curr->parent->type.isRtt(), curr, "rtt.sub parent must have RTT type");
- auto parentRtt = curr->parent->type.getRtt();
- auto rtt = curr->type.getRtt();
- if (rtt.hasDepth() && parentRtt.hasDepth()) {
- shouldBeEqual(rtt.depth,
- parentRtt.depth + 1,
- curr,
- "rtt.canon has a depth of 1 over the parent");
- }
- shouldBeTrue(HeapType::isSubType(rtt.heapType, parentRtt.heapType),
- curr,
- "rtt.sub parent must be a supertype");
- }
-}
-
void FunctionValidator::visitStructNew(StructNew* curr) {
shouldBeTrue(getModule()->features.hasGC(),
curr,
@@ -2461,19 +2391,7 @@ void FunctionValidator::visitStructNew(StructNew* curr) {
if (curr->type == Type::unreachable) {
return;
}
- if (curr->rtt) {
- if (!shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "struct.new rtt must be rtt")) {
- return;
- }
- }
auto heapType = curr->type.getHeapType();
- if (curr->rtt) {
- shouldBeEqual(curr->rtt->type.getHeapType(),
- heapType,
- curr,
- "struct.new heap type must match rtt");
- }
if (!shouldBeTrue(
heapType.isStruct(), curr, "struct.new heap type must be struct")) {
return;
@@ -2565,19 +2483,7 @@ void FunctionValidator::visitArrayNew(ArrayNew* curr) {
if (curr->type == Type::unreachable) {
return;
}
- if (curr->rtt) {
- if (!shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "array.new rtt must be rtt")) {
- return;
- }
- }
auto heapType = curr->type.getHeapType();
- if (curr->rtt) {
- shouldBeEqual(curr->rtt->type.getHeapType(),
- heapType,
- curr,
- "array.new heap type must match rtt");
- }
if (!shouldBeTrue(
heapType.isArray(), curr, "array.new heap type must be array")) {
return;
@@ -2607,19 +2513,7 @@ void FunctionValidator::visitArrayInit(ArrayInit* curr) {
if (curr->type == Type::unreachable) {
return;
}
- if (curr->rtt) {
- if (!shouldBeTrue(
- curr->rtt->type.isRtt(), curr, "array.init rtt must be rtt")) {
- return;
- }
- }
auto heapType = curr->type.getHeapType();
- if (curr->rtt) {
- shouldBeEqual(curr->rtt->type.getHeapType(),
- heapType,
- curr,
- "array.init heap type must match rtt");
- }
if (!shouldBeTrue(
heapType.isArray(), curr, "array.init heap type must be array")) {
return;
@@ -2716,9 +2610,7 @@ void FunctionValidator::visitFunction(Function* curr) {
}
for (const auto& var : curr->vars) {
features |= var.getFeatures();
- bool valid = getModule()->features.hasGCNNLocals()
- ? var.isDefaultableOrNonNullable()
- : var.isDefaultable();
+ bool valid = getModule()->features.hasGCNNLocals() || var.isDefaultable();
shouldBeTrue(valid, var, "vars must be defaultable");
}
shouldBeTrue(features <= getModule()->features,
@@ -3167,10 +3059,9 @@ static void validateTables(Module& module, ValidationInfo& info) {
for (auto& segment : module.elementSegments) {
// Since element segment items need to be constant expressions, that leaves
- // us with ref.null, ref.func and global.get. The GC proposal adds rtt.canon
- // and rtt.sub to the list, but Binaryen doesn't consider RTTs as reference-
- // types yet. As a result, the only possible type for element segments will
- // be function references.
+ // us with ref.null, ref.func and global.get. As a result, the only possible
+ // type for element segments will be function references.
+ // TODO: This is not true! Allow GC data here (#4846).
info.shouldBeTrue(segment->type.isFunction(),
"elem",
"element segment type must be of function type.");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 1a6acf5bd..34b1e82b7 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -931,36 +931,25 @@ void CallRef::finalize(Type type_) {
}
void RefTest::finalize() {
- if (ref->type == Type::unreachable ||
- (rtt && rtt->type == Type::unreachable)) {
+ if (ref->type == Type::unreachable) {
type = Type::unreachable;
} else {
type = Type::i32;
}
}
-HeapType RefTest::getIntendedType() {
- return rtt ? rtt->type.getHeapType() : intendedType;
-}
-
void RefCast::finalize() {
- if (ref->type == Type::unreachable ||
- (rtt && rtt->type == Type::unreachable)) {
+ if (ref->type == Type::unreachable) {
type = Type::unreachable;
} else {
// The output of ref.cast may be null if the input is null (in that case the
// null is passed through).
- type = Type(getIntendedType(), ref->type.getNullability());
+ type = Type(intendedType, ref->type.getNullability());
}
}
-HeapType RefCast::getIntendedType() {
- return rtt ? rtt->type.getHeapType() : intendedType;
-}
-
void BrOn::finalize() {
- if (ref->type == Type::unreachable ||
- (rtt && rtt->type == Type::unreachable)) {
+ if (ref->type == Type::unreachable) {
type = Type::unreachable;
return;
}
@@ -984,7 +973,7 @@ void BrOn::finalize() {
case BrOnCastFail:
// If we do not branch, the cast worked, and we have something of the cast
// type.
- type = Type(getIntendedType(), NonNullable);
+ type = Type(intendedType, NonNullable);
break;
case BrOnNonFunc:
type = Type(HeapType::func, NonNullable);
@@ -1000,11 +989,6 @@ void BrOn::finalize() {
}
}
-HeapType BrOn::getIntendedType() {
- assert(op == BrOnCast || op == BrOnCastFail);
- return rtt ? rtt->type.getHeapType() : intendedType;
-}
-
Type BrOn::getSentType() {
switch (op) {
case BrOnNull:
@@ -1022,7 +1006,7 @@ Type BrOn::getSentType() {
if (ref->type == Type::unreachable) {
return Type::unreachable;
}
- return Type(getIntendedType(), NonNullable);
+ return Type(intendedType, NonNullable);
case BrOnFunc:
return Type(HeapType::func, NonNullable);
case BrOnData:
@@ -1039,31 +1023,10 @@ Type BrOn::getSentType() {
}
}
-void RttCanon::finalize() {
- // Nothing to do - the type must have been set already during construction.
-}
-
-void RttSub::finalize() {
- if (parent->type == Type::unreachable) {
- type = Type::unreachable;
- }
- // Else nothing to do - the type must have been set already during
- // construction.
-}
-
void StructNew::finalize() {
- if (rtt && rtt->type == Type::unreachable) {
- type = Type::unreachable;
- return;
- }
if (handleUnreachableOperands(this)) {
return;
}
- // A dynamic StructNew infers the type from the rtt. A static one has the type
- // already in the type field.
- if (rtt) {
- type = Type(rtt->type.getHeapType(), NonNullable);
- }
}
void StructGet::finalize() {
@@ -1083,35 +1046,20 @@ void StructSet::finalize() {
}
void ArrayNew::finalize() {
- if ((rtt && rtt->type == Type::unreachable) ||
- size->type == Type::unreachable ||
+ if (size->type == Type::unreachable ||
(init && init->type == Type::unreachable)) {
type = Type::unreachable;
return;
}
- // A dynamic ArrayNew infers the type from the rtt. A static one has the type
- // already in the type field.
- if (rtt) {
- type = Type(rtt->type.getHeapType(), NonNullable);
- }
}
void ArrayInit::finalize() {
- if (rtt && rtt->type == Type::unreachable) {
- type = Type::unreachable;
- return;
- }
for (auto* value : values) {
if (value->type == Type::unreachable) {
type = Type::unreachable;
return;
}
}
- // A dynamic ArrayInit infers the type from the rtt. A static one has the type
- // already in the type field.
- if (rtt) {
- type = Type(rtt->type.getHeapType(), NonNullable);
- }
}
void ArrayGet::finalize() {
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp
index 8b86017ff..89eab3297 100644
--- a/src/wasm/wat-parser.cpp
+++ b/src/wasm/wat-parser.cpp
@@ -967,14 +967,6 @@ Result<typename Ctx::InstrT> makeBrOn(Ctx&, ParseInput&, BrOnOp op);
template<typename Ctx>
Result<typename Ctx::InstrT> makeBrOnStatic(Ctx&, ParseInput&, BrOnOp op);
template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttCanon(Ctx&, ParseInput&);
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttSub(Ctx&, ParseInput&);
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttFreshSub(Ctx&, ParseInput&);
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeStructNew(Ctx&, ParseInput&, bool default_);
-template<typename Ctx>
Result<typename Ctx::InstrT>
makeStructNewStatic(Ctx&, ParseInput&, bool default_);
template<typename Ctx>
@@ -983,13 +975,9 @@ makeStructGet(Ctx&, ParseInput&, bool signed_ = false);
template<typename Ctx>
Result<typename Ctx::InstrT> makeStructSet(Ctx&, ParseInput&);
template<typename Ctx>
-Result<typename Ctx::InstrT> makeArrayNew(Ctx&, ParseInput&, bool default_);
-template<typename Ctx>
Result<typename Ctx::InstrT>
makeArrayNewStatic(Ctx&, ParseInput&, bool default_);
template<typename Ctx>
-Result<typename Ctx::InstrT> makeArrayInit(Ctx&, ParseInput&);
-template<typename Ctx>
Result<typename Ctx::InstrT> makeArrayInitStatic(Ctx&, ParseInput&);
template<typename Ctx>
Result<typename Ctx::InstrT>
@@ -1779,27 +1767,6 @@ makeBrOnStatic(Ctx& ctx, ParseInput& in, BrOnOp op) {
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttCanon(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttSub(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT> makeRttFreshSub(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeStructNew(Ctx& ctx, ParseInput& in, bool default_) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
Result<typename Ctx::InstrT>
makeStructNewStatic(Ctx& ctx, ParseInput& in, bool default_) {
return in.err("unimplemented instruction");
@@ -1818,22 +1785,11 @@ Result<typename Ctx::InstrT> makeStructSet(Ctx& ctx, ParseInput& in) {
template<typename Ctx>
Result<typename Ctx::InstrT>
-makeArrayNew(Ctx& ctx, ParseInput& in, bool default_) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT>
makeArrayNewStatic(Ctx& ctx, ParseInput& in, bool default_) {
return in.err("unimplemented instruction");
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeArrayInit(Ctx& ctx, ParseInput& in) {
- return in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
Result<typename Ctx::InstrT> makeArrayInitStatic(Ctx& ctx, ParseInput& in) {
return in.err("unimplemented instruction");
}