diff options
author | Thomas Lively <tlively@google.com> | 2023-09-08 20:08:33 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-09 01:08:33 +0000 |
commit | 4e58466b40b65cda399b4749105f0ce10f48f62b (patch) | |
tree | 9e34ae5ed464d87d75683603171e7b2645015568 /src/wasm | |
parent | 90571051b3d6f89eab184df3d4dd716472a6cd7c (diff) | |
download | binaryen-4e58466b40b65cda399b4749105f0ce10f48f62b.tar.gz binaryen-4e58466b40b65cda399b4749105f0ce10f48f62b.tar.bz2 binaryen-4e58466b40b65cda399b4749105f0ce10f48f62b.zip |
Make final types the default (#5918)
Match the spec and parse the shorthand binary and text formats as final and emit
final types without supertypes using the shorthands as well. This is a
potentially-breaking change, since the text and binary shorthands can no longer
be used to define types that have subtypes.
Also make TypeBuilder entries final by default to better match the spec and
update the internal APIs to use the "open" terminology rather than "final"
terminology. Future changes will update the text format to use the standard "sub
open" rather than the current "sub final" keywords. The exception is the new wat
parser, which supporst "sub open" as of this change, since it didn't support
final types at all previously.
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 7 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 21 | ||||
-rw-r--r-- | src/wasm/wat-parser.cpp | 6 |
4 files changed, 28 insertions, 21 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 51325e7dd..d43640e26 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -265,13 +265,11 @@ void WasmBinaryWriter::writeTypes() { // Emit the type definition. BYN_TRACE("write " << type << std::endl); auto super = type.getSuperType(); - // TODO: Use the binary shorthand for final types once we parse MVP - // signatures as final. - if (type.isFinal() || super || hasSubtypes[i]) { - if (type.isFinal()) { - o << S32LEB(BinaryConsts::EncodedType::SubFinal); - } else { + if (super || type.isOpen()) { + if (type.isOpen()) { o << S32LEB(BinaryConsts::EncodedType::Sub); + } else { + o << S32LEB(BinaryConsts::EncodedType::SubFinal); } if (super) { o << U32LEB(1); @@ -2268,9 +2266,8 @@ void WasmBinaryReader::readTypes() { std::optional<uint32_t> superIndex; if (form == BinaryConsts::EncodedType::Sub || form == BinaryConsts::EncodedType::SubFinal) { - if (form == BinaryConsts::EncodedType::SubFinal) { - // TODO: Interpret type definitions without any `sub` as final as well. - builder[i].setFinal(); + if (form == BinaryConsts::EncodedType::Sub) { + builder[i].setOpen(); } uint32_t supers = getU32LEB(); if (supers > 0) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index b6b9a40fb..e30901c5b 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -929,8 +929,9 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { if (kind == SUB) { Index i = 1; if (*def[i] == FINAL) { - builder[index].setFinal(); ++i; + } else { + builder[index].setOpen(); } if (def[i]->dollared()) { super = def[i]; @@ -959,6 +960,7 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { if (kind == FUNC) { builder[index] = parseSignatureDef(def, 0); } else if (kind == FUNC_SUBTYPE) { + builder[index].setOpen(); builder[index] = parseSignatureDef(def, 1); super = def[def.size() - 1]; if (!super->dollared() && super->str() == FUNC) { @@ -968,6 +970,7 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { } else if (kind == STRUCT) { builder[index] = parseStructDef(def, index, 0); } else if (kind == STRUCT_SUBTYPE) { + builder[index].setOpen(); builder[index] = parseStructDef(def, index, 1); super = def[def.size() - 1]; if (!super->dollared() && super->str() == DATA) { @@ -977,6 +980,7 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { } else if (kind == ARRAY) { builder[index] = parseArrayDef(def); } else if (kind == ARRAY_SUBTYPE) { + builder[index].setOpen(); builder[index] = parseArrayDef(def); super = def[def.size() - 1]; if (!super->dollared() && super->str() == DATA) { @@ -993,6 +997,7 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { } } else if (elementStartsWith(elem[elem.size() - 1], EXTENDS)) { // '(' 'extends' $supertype ')' + builder[index].setOpen(); Element& extends = *elem[elem.size() - 1]; super = extends[1]; } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 0c4e7b049..ba38231b6 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -85,7 +85,7 @@ struct HeapTypeInfo { // Used in assertions to ensure that temporary types don't leak into the // global store. bool isTemp = false; - bool isFinal = false; + bool isOpen = false; // The supertype of this HeapType, if it exists. HeapTypeInfo* supertype = nullptr; // The recursion group of this type or null if the recursion group is trivial @@ -1180,11 +1180,11 @@ bool HeapType::isBottom() const { return false; } -bool HeapType::isFinal() const { +bool HeapType::isOpen() const { if (isBasic()) { return false; } else { - return getHeapTypeInfo(*this)->isFinal; + return getHeapTypeInfo(*this)->isOpen; } } @@ -1771,13 +1771,12 @@ std::ostream& TypePrinter::print(HeapType type) { os << "(; temp ;) "; } - // TODO: Use shorthand for final types once we parse MVP signatures as final. bool useSub = false; auto super = type.getSuperType(); - if (super || type.isFinal()) { + if (super || type.isOpen()) { useSub = true; os << "(sub "; - if (type.isFinal()) { + if (!type.isOpen()) { os << "final "; } if (super) { @@ -1946,7 +1945,7 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const { if (info.supertype) { hash_combine(digest, hash(HeapType(uintptr_t(info.supertype)))); } - wasm::rehash(digest, info.isFinal); + wasm::rehash(digest, info.isOpen); wasm::rehash(digest, info.kind); switch (info.kind) { case HeapTypeInfo::SignatureKind: @@ -2069,7 +2068,7 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const { return false; } } - if (a.isFinal != b.isFinal) { + if (a.isOpen != b.isOpen) { return false; } if (a.kind != b.kind) { @@ -2325,15 +2324,15 @@ void TypeBuilder::createRecGroup(size_t index, size_t length) { {RecGroup(uintptr_t(groupInfo.get())), std::move(groupInfo)}); } -void TypeBuilder::setFinal(size_t i, bool final) { +void TypeBuilder::setOpen(size_t i, bool open) { assert(i < size() && "index out of bounds"); - impl->entries[i].info->isFinal = final; + impl->entries[i].info->isOpen = open; } namespace { bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) { - if (super.isFinal) { + if (!super.isOpen) { return false; } if (sub.kind != super.kind) { diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 3961cbb7f..bdd1af0d8 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -849,6 +849,7 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { void addFuncType(SignatureT) {} void addStructType(StructT) {} void addArrayType(ArrayT) {} + void setOpen() {} Result<> addSubtype(Index) { return Ok{}; } void finishSubtype(Name name, Index pos) { subtypeDefs.push_back({name, pos, Index(subtypeDefs.size())}); @@ -1078,6 +1079,8 @@ struct ParseTypeDefsCtx : TypeParserCtx<ParseTypeDefsCtx> { void addArrayType(ArrayT& type) { builder[index] = type; } + void setOpen() { builder[index].setOpen(); } + Result<> addSubtype(Index super) { if (super >= builder.size()) { return in.err("supertype index out of bounds"); @@ -3463,6 +3466,9 @@ template<typename Ctx> MaybeResult<> subtype(Ctx& ctx) { } if (ctx.in.takeSExprStart("sub"sv)) { + if (ctx.in.takeKeyword("open"sv)) { + ctx.setOpen(); + } if (auto super = maybeTypeidx(ctx)) { CHECK_ERR(super); CHECK_ERR(ctx.addSubtype(*super)); |