@@ -48,59 +48,73 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes(
48
48
std::unordered_set<HeapType> additionalSet (additionalPrivateTypes.begin (),
49
49
additionalPrivateTypes.end ());
50
50
51
- std::vector<std::pair<HeapType, SmallVector<HeapType, 1 >>> privateSupertypes;
52
- privateSupertypes.reserve (typeInfo.size ());
51
+ // Check if a type is private, given the info for it.
52
+ auto isPublicGivenInfo = [&](HeapType type, auto & info) {
53
+ return info.visibility != ModuleUtils::Visibility::Private &&
54
+ !additionalSet.count (type);
55
+ };
56
+
57
+ // Check if a type is private, looking for its info (if there is none, it is
58
+ // not private).
59
+ auto isPublic = [&](HeapType type) {
60
+ auto it = typeInfo.find (type);
61
+ if (it == typeInfo.end ()) {
62
+ return false ;
63
+ }
64
+ return isPublicGivenInfo (type, it->second );
65
+ };
66
+
67
+ // For each type, note all the predecessors it must have, i.e., that must
68
+ // appear before it. That includes supertypes and described types.
69
+ std::vector<std::pair<HeapType, SmallVector<HeapType, 1 >>> privatePreds;
70
+ privatePreds.reserve (typeInfo.size ());
53
71
for (auto & [type, info] : typeInfo) {
54
- if (info.visibility != ModuleUtils::Visibility::Private &&
55
- !additionalSet.count (type)) {
72
+ if (isPublicGivenInfo (type, info)) {
56
73
continue ;
57
74
}
58
- privateSupertypes .push_back ({type, {}});
75
+ privatePreds .push_back ({type, {}});
59
76
60
- if (auto super = getDeclaredSuperType (type)) {
61
- auto it = typeInfo.find (*super);
62
- // Record the supertype only if it is among the private types.
63
- if ((it != typeInfo.end () &&
64
- it->second .visibility == ModuleUtils::Visibility::Private) ||
65
- additionalSet.count (*super)) {
66
- privateSupertypes.back ().second .push_back (*super);
67
- }
77
+ // Check for a (private) supertype.
78
+ if (auto super = getDeclaredSuperType (type); super && !isPublic (*super)) {
79
+ privatePreds.back ().second .push_back (*super);
80
+ }
81
+
82
+ // Check for a (private) described type.
83
+ if (auto desc = type.getDescribedType ()) {
84
+ // It is not possible for a a described type to be public while its
85
+ // descriptor is private, or vice versa.
86
+ assert (!isPublic (*desc));
87
+ privatePreds.back ().second .push_back (*desc);
68
88
}
69
89
}
70
90
71
- // Topological sort to have subtypes first. This is the opposite of the
72
- // order we need, so the comparison is the opposite of what we ultimately
73
- // want.
74
91
std::vector<HeapType> sorted;
75
92
if (wasm.typeIndices .empty ()) {
76
- sorted = TopologicalSort::sortOf (privateSupertypes.begin (),
77
- privateSupertypes.end ());
93
+ sorted = TopologicalSort::sortOf (privatePreds.begin (), privatePreds.end ());
78
94
} else {
79
- sorted =
80
- TopologicalSort::minSortOf (privateSupertypes.begin (),
81
- privateSupertypes.end (),
82
- [&](Index a, Index b) {
83
- auto typeA = privateSupertypes[a].first ;
84
- auto typeB = privateSupertypes[b].first ;
85
- // Preserve type order.
86
- auto itA = wasm.typeIndices .find (typeA);
87
- auto itB = wasm.typeIndices .find (typeB);
88
- bool hasA = itA != wasm.typeIndices .end ();
89
- bool hasB = itB != wasm.typeIndices .end ();
90
- if (hasA != hasB) {
91
- // Types with preserved indices must be
92
- // sorted before (after in this reversed
93
- // comparison) types without indices to
94
- // maintain transitivity.
95
- return !hasA;
96
- }
97
- if (hasA && *itA != *itB) {
98
- return !(itA->second < itB->second );
99
- }
100
- // Break ties by the arbitrary order we
101
- // have collected the types in.
102
- return a > b;
103
- });
95
+ sorted = TopologicalSort::minSortOf (
96
+ privatePreds.begin (), privatePreds.end (), [&](Index a, Index b) {
97
+ auto typeA = privatePreds[a].first ;
98
+ auto typeB = privatePreds[b].first ;
99
+ // Preserve type order.
100
+ auto itA = wasm.typeIndices .find (typeA);
101
+ auto itB = wasm.typeIndices .find (typeB);
102
+ bool hasA = itA != wasm.typeIndices .end ();
103
+ bool hasB = itB != wasm.typeIndices .end ();
104
+ if (hasA != hasB) {
105
+ // Types with preserved indices must be
106
+ // sorted before (after in this reversed
107
+ // comparison) types without indices to
108
+ // maintain transitivity.
109
+ return !hasA;
110
+ }
111
+ if (hasA && *itA != *itB) {
112
+ return !(itA->second < itB->second );
113
+ }
114
+ // Break ties by the arbitrary order we
115
+ // have collected the types in.
116
+ return a > b;
117
+ });
104
118
}
105
119
std::reverse (sorted.begin (), sorted.end ());
106
120
Index i = 0 ;
0 commit comments