Skip to content

Commit ac98ba6

Browse files
authored
Update exact reference semantics (#7499)
Disallow exact references to abstract heap types and update subtyping to match the current proposed semantics.
1 parent ed04c5c commit ac98ba6

12 files changed

+364
-413
lines changed

src/wasm-builder.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -673,12 +673,6 @@ class Builder {
673673
ret->finalize(Type(type.getBottom(), Nullable));
674674
return ret;
675675
}
676-
RefNull* makeRefNull(Type type) {
677-
assert(type.isNullable() && type.isNull() && type.isExact());
678-
auto* ret = wasm.allocator.alloc<RefNull>();
679-
ret->finalize(type);
680-
return ret;
681-
}
682676
RefIsNull* makeRefIsNull(Expression* value) {
683677
auto* ret = wasm.allocator.alloc<RefIsNull>();
684678
ret->value = value;

src/wasm-type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ class Type {
323323
: Type(heapType.getID() | (nullable == Nullable ? NullMask : 0) |
324324
(exact == Exact ? ExactMask : 0)) {
325325
assert(!(heapType.getID() & (TupleMask | NullMask | ExactMask)));
326+
assert(!heapType.isBasic() || exact == Inexact);
326327
}
327328

328329
// Predicates

src/wasm/wasm-type.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -795,13 +795,14 @@ Type Type::getLeastUpperBound(Type a, Type b) {
795795
if (auto heapType = HeapType::getLeastUpperBound(heapTypeA, heapTypeB)) {
796796
auto nullability =
797797
(a.isNullable() || b.isNullable()) ? Nullable : NonNullable;
798-
auto exactness = (a.isInexact() || b.isInexact()) ? Inexact : Exact;
799-
// The LUB can only be exact if the heap types are the same or one of them
800-
// is bottom.
801-
if (heapTypeA != heapTypeB && !heapTypeA.isBottom() &&
802-
!heapTypeB.isBottom()) {
803-
exactness = Inexact;
804-
}
798+
// If one heap type is bottom, then the exactness comes from the other
799+
// heap type. Otherwise, the LUB can only be exact if both of the inputs
800+
// are the same exact heap type.
801+
auto exactness = heapTypeA.isBottom() ? b.getExactness()
802+
: heapTypeB.isBottom() ? a.getExactness()
803+
: (a.isInexact() || b.isInexact()) ? Inexact
804+
: (heapTypeA != heapTypeB) ? Inexact
805+
: Exact;
805806
return Type(*heapType, nullability, exactness);
806807
}
807808
}
@@ -850,6 +851,7 @@ Type Type::getGreatestLowerBound(Type a, Type b) {
850851
if ((a.isExact() && heapType != heapA) ||
851852
(b.isExact() && heapType != heapB)) {
852853
heapType = heapA.getBottom();
854+
exactness = Inexact;
853855
}
854856
return Type(heapType, nullability, exactness);
855857
}
@@ -1515,13 +1517,15 @@ bool SubTyper::isSubType(Type a, Type b) {
15151517
if (a.isNullable() && !b.isNullable()) {
15161518
return false;
15171519
}
1518-
if (a.isInexact() && !b.isInexact()) {
1519-
return false;
1520-
}
15211520
auto heapTypeA = a.getHeapType();
15221521
auto heapTypeB = b.getHeapType();
1523-
if (b.isExact() && !heapTypeA.isBottom()) {
1524-
return heapTypeA == heapTypeB;
1522+
if (b.isExact()) {
1523+
if (a.isExact()) {
1524+
return heapTypeA == heapTypeB;
1525+
}
1526+
if (!heapTypeA.isBottom()) {
1527+
return false;
1528+
}
15251529
}
15261530
return isSubType(heapTypeA, heapTypeB);
15271531
}

src/wasm/wasm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ void MemoryGrow::finalize() {
800800

801801
void RefNull::finalize(HeapType heapType) {
802802
assert(heapType.isBottom());
803-
type = Type(heapType, Nullable, Exact);
803+
type = Type(heapType, Nullable);
804804
}
805805

806806
void RefNull::finalize(Type type_) { type = type_; }

test/gtest/type-builder.cpp

Lines changed: 128 additions & 142 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)