diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/type-updating.cpp | 1 | ||||
-rw-r--r-- | src/parser/contexts.h | 3 | ||||
-rw-r--r-- | src/parser/parsers.h | 36 | ||||
-rw-r--r-- | src/passes/TypeMerging.cpp | 4 | ||||
-rw-r--r-- | src/wasm-type.h | 11 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 28 |
6 files changed, 70 insertions, 13 deletions
diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 520408d44..d9935ee32 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -90,6 +90,7 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( i = 0; for (auto [type, _] : typeIndices) { typeBuilder[i].setOpen(type.isOpen()); + typeBuilder[i].setShared(type.isShared()); if (type.isSignature()) { auto sig = type.getSignature(); TypeList newParams, newResults; diff --git a/src/parser/contexts.h b/src/parser/contexts.h index bce051a93..7c1a07b53 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -907,6 +907,7 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { void addStructType(StructT) {} void addArrayType(ArrayT) {} void setOpen() {} + void setShared() {} Result<> addSubtype(Index) { return Ok{}; } void finishSubtype(Name name, Index pos) { // TODO: type annotations @@ -1077,6 +1078,8 @@ struct ParseTypeDefsCtx : TypeParserCtx<ParseTypeDefsCtx> { void setOpen() { builder[index].setOpen(); } + void setShared() { builder[index].setShared(); } + Result<> addSubtype(Index super) { if (super >= builder.size()) { return in.err("supertype index out of bounds"); diff --git a/src/parser/parsers.h b/src/parser/parsers.h index c4eaf5fc6..a3fe5e5eb 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -331,7 +331,8 @@ template<typename Ctx> Result<typename Ctx::TypeUseT> typeuse(Ctx&, bool allowNames = true); MaybeResult<ImportNames> inlineImport(Lexer&); Result<std::vector<Name>> inlineExports(Lexer&); -template<typename Ctx> Result<> strtype(Ctx&); +template<typename Ctx> Result<> comptype(Ctx&); +template<typename Ctx> Result<> sharecomptype(Ctx&); template<typename Ctx> MaybeResult<typename Ctx::ModuleNameT> subtype(Ctx&); template<typename Ctx> MaybeResult<> deftype(Ctx&); template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx&); @@ -2709,11 +2710,11 @@ inline Result<std::vector<Name>> inlineExports(Lexer& in) { return exports; } -// strtype ::= ft:functype => ft -// | ct:conttype => ct -// | st:structtype => st -// | at:arraytype => at -template<typename Ctx> Result<> strtype(Ctx& ctx) { +// comptype ::= ft:functype => ft +// | ct:conttype => ct +// | st:structtype => st +// | at:arraytype => at +template<typename Ctx> Result<> comptype(Ctx& ctx) { if (auto type = functype(ctx)) { CHECK_ERR(type); ctx.addFuncType(*type); @@ -2737,8 +2738,23 @@ template<typename Ctx> Result<> strtype(Ctx& ctx) { return ctx.in.err("expected type description"); } -// subtype ::= '(' 'type' id? '(' 'sub' typeidx? strtype ')' ')' -// | '(' 'type' id? strtype ')' +// sharecomptype ::= '(' 'shared' t:comptype ')' => shared t +// | t:comptype => unshared t +template<typename Ctx> Result<> sharecomptype(Ctx& ctx) { + if (ctx.in.takeSExprStart("shared"sv)) { + ctx.setShared(); + CHECK_ERR(comptype(ctx)); + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of shared comptype"); + } + } else { + CHECK_ERR(comptype(ctx)); + } + return Ok{}; +} + +// subtype ::= '(' 'type' id? '(' 'sub' typeidx? sharecomptype ')' ')' +// | '(' 'type' id? sharecomptype ')' template<typename Ctx> MaybeResult<> subtype(Ctx& ctx) { auto pos = ctx.in.getPos(); @@ -2760,13 +2776,13 @@ template<typename Ctx> MaybeResult<> subtype(Ctx& ctx) { CHECK_ERR(ctx.addSubtype(*super)); } - CHECK_ERR(strtype(ctx)); + CHECK_ERR(sharecomptype(ctx)); if (!ctx.in.takeRParen()) { return ctx.in.err("expected end of subtype definition"); } } else { - CHECK_ERR(strtype(ctx)); + CHECK_ERR(sharecomptype(ctx)); } if (!ctx.in.takeRParen()) { diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index f827e097c..e5ac7888b 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -541,6 +541,9 @@ bool shapeEq(HeapType a, HeapType b) { if (a.isOpen() != b.isOpen()) { return false; } + if (a.isShared() != b.isShared()) { + return false; + } if (a.isStruct() && b.isStruct()) { return shapeEq(a.getStruct(), b.getStruct()); } @@ -555,6 +558,7 @@ bool shapeEq(HeapType a, HeapType b) { size_t shapeHash(HeapType a) { size_t digest = hash(a.isOpen()); + rehash(digest, a.isShared()); if (a.isStruct()) { rehash(digest, 0); hash_combine(digest, shapeHash(a.getStruct())); diff --git a/src/wasm-type.h b/src/wasm-type.h index b02484ae3..3e9fa4db3 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -377,6 +377,7 @@ public: bool isString() const; bool isBottom() const; bool isOpen() const; + bool isShared() const; Signature getSignature() const; Continuation getContinuation() const; @@ -614,9 +615,8 @@ struct TypeBuilder { Type getTempTupleType(const Tuple&); Type getTempRefType(HeapType heapType, Nullability nullable); - // In nominal mode, or for nominal types, declare the HeapType being built at - // index `i` to be an immediate subtype of the given HeapType. Does nothing - // for equirecursive types. + // Declare the HeapType being built at index `i` to be an immediate subtype of + // the given HeapType. void setSubType(size_t i, HeapType super); // Create a new recursion group covering slots [i, i + length). Groups must @@ -624,6 +624,7 @@ struct TypeBuilder { void createRecGroup(size_t i, size_t length); void setOpen(size_t i, bool open = true); + void setShared(size_t i, bool shared = true); enum class ErrorReason { // There is a cycle in the supertype relation. @@ -696,6 +697,10 @@ struct TypeBuilder { builder.setOpen(index, open); return *this; } + Entry& setShared(bool shared = true) { + builder.setShared(index, shared); + return *this; + } }; Entry operator[](size_t i) { return Entry{*this, i}; } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 3e215b23a..83bf47107 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -86,6 +86,7 @@ struct HeapTypeInfo { // global store. bool isTemp = false; bool isOpen = false; + bool isShared = 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 @@ -1251,6 +1252,15 @@ bool HeapType::isOpen() const { } } +bool HeapType::isShared() const { + if (isBasic()) { + // TODO: shared basic heap types + return false; + } else { + return getHeapTypeInfo(*this)->isShared; + } +} + Signature HeapType::getSignature() const { assert(isSignature()); return getHeapTypeInfo(*this)->signature; @@ -1953,6 +1963,9 @@ std::ostream& TypePrinter::print(HeapType type) { os << ' '; } } + if (type.isShared()) { + os << "(shared "; + } if (type.isSignature()) { print(type.getSignature()); } else if (type.isContinuation()) { @@ -1964,6 +1977,9 @@ std::ostream& TypePrinter::print(HeapType type) { } else { WASM_UNREACHABLE("unexpected type"); } + if (type.isShared()) { + os << ')'; + } if (useSub) { os << ')'; } @@ -2121,6 +2137,7 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const { hash_combine(digest, hash(HeapType(uintptr_t(info.supertype)))); } wasm::rehash(digest, info.isOpen); + wasm::rehash(digest, info.isShared); wasm::rehash(digest, info.kind); switch (info.kind) { case HeapTypeInfo::SignatureKind: @@ -2257,6 +2274,9 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const { if (a.isOpen != b.isOpen) { return false; } + if (a.isShared != b.isShared) { + return false; + } if (a.kind != b.kind) { return false; } @@ -2532,12 +2552,20 @@ void TypeBuilder::setOpen(size_t i, bool open) { impl->entries[i].info->isOpen = open; } +void TypeBuilder::setShared(size_t i, bool shared) { + assert(i < size() && "index out of bounds"); + impl->entries[i].info->isShared = shared; +} + namespace { bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) { if (!super.isOpen) { return false; } + if (sub.isShared != super.isShared) { + return false; + } if (sub.kind != super.kind) { return false; } |