Skip to content

Commit 2a40965

Browse files
authored
Remove open "ignorable public" array types (#6940)
There are a few heap types that are hard-coded to be considered public and therefore allowed on module boundaries even in --closed-world mode, specifically to support js-string-builtins. We previously considered both open and closed (i.e. final) mutable i8 arrays to be public in this manner, but js-string-builtins only uses the closed versions, so remove the open versions. This fixes a particular bug in which Unsubtyping optimized a private array type to be equivalent to an ignorable public array type, incorrectly changing the behavior of a cast, but it does not address the larger problem of optimizations producing types that are equivalent to public types. Add a TODO about that problem for now. Fixes #6935.
1 parent 4913080 commit 2a40965

3 files changed

Lines changed: 37 additions & 9 deletions

File tree

src/ir/type-updating.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes(
175175
#endif
176176
auto& newTypes = *buildResults;
177177

178+
// TODO: It is possible that the newly built rec group matches some public rec
179+
// group. If that is the case, we need to try a different permutation of the
180+
// types or add a brand type to distinguish the private types.
181+
178182
// Map the old types to the new ones.
179183
TypeMap oldToNewTypes;
180184
for (auto [type, index] : typeIndices) {

src/wasm/wasm-type.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,17 +2887,9 @@ void TypeBuilder::dump() {
28872887
std::unordered_set<HeapType> getIgnorablePublicTypes() {
28882888
auto array8 = Array(Field(Field::i8, Mutable));
28892889
auto array16 = Array(Field(Field::i16, Mutable));
2890-
TypeBuilder builder(4);
2891-
// We handle final and non-final here, but should remove one of them
2892-
// eventually TODO
2890+
TypeBuilder builder(2);
28932891
builder[0] = array8;
2894-
builder[0].setOpen(false);
28952892
builder[1] = array16;
2896-
builder[1].setOpen(false);
2897-
builder[2] = array8;
2898-
builder[2].setOpen(true);
2899-
builder[3] = array16;
2900-
builder[3].setOpen(true);
29012893
auto result = builder.build();
29022894
assert(result);
29032895
std::unordered_set<HeapType> ret;

test/lit/passes/unsubtyping.wast

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,3 +1747,35 @@
17471747
;; CHECK: (global $g (ref $super) (struct.new_default $sub))
17481748
(global $g (ref $super) (struct.new_default $sub))
17491749
)
1750+
1751+
;; Regression test for a bug where we considered $super to be a public type
1752+
;; (because it was once in contention to appear in js-string-builtin
1753+
;; signatures), so we only updated $sub, but that caused $sub and $super to be
1754+
;; the same type, changing the behavior of the cast.
1755+
(module
1756+
;; CHECK: (type $super (sub (array (mut i8))))
1757+
(type $super (sub (array (mut i8))))
1758+
(type $sub (sub $super (array (mut i8))))
1759+
;; CHECK: (type $1 (func))
1760+
1761+
;; CHECK: (export "test" (func $0))
1762+
1763+
;; CHECK: (func $0 (type $1)
1764+
;; CHECK-NEXT: (drop
1765+
;; CHECK-NEXT: (ref.cast (ref none)
1766+
;; CHECK-NEXT: (array.new_default $super
1767+
;; CHECK-NEXT: (i32.const 0)
1768+
;; CHECK-NEXT: )
1769+
;; CHECK-NEXT: )
1770+
;; CHECK-NEXT: )
1771+
;; CHECK-NEXT: )
1772+
(func $0 (export "test")
1773+
(drop
1774+
(ref.cast (ref $sub)
1775+
(array.new_default $super
1776+
(i32.const 0)
1777+
)
1778+
)
1779+
)
1780+
)
1781+
)

0 commit comments

Comments
 (0)