@@ -900,92 +900,7 @@ Type Type::reinterpret() const {
900900FeatureSet Type::getFeatures () const {
901901 auto getSingleFeatures = [](Type t) -> FeatureSet {
902902 if (t.isRef ()) {
903- // A reference type implies we need that feature. Some also require
904- // more, such as GC or exceptions, and may require us to look into child
905- // types.
906- struct ReferenceFeatureCollector
907- : HeapTypeChildWalker<ReferenceFeatureCollector> {
908- FeatureSet feats = FeatureSet::None;
909-
910- void noteChild (HeapType* heapType) {
911- if (heapType->isBasic ()) {
912- switch (heapType->getBasic (Unshared)) {
913- case HeapType::ext:
914- case HeapType::func:
915- feats |= FeatureSet::ReferenceTypes;
916- return ;
917- case HeapType::any:
918- case HeapType::eq:
919- case HeapType::i31:
920- case HeapType::struct_:
921- case HeapType::array:
922- feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
923- return ;
924- case HeapType::string:
925- feats |= FeatureSet::ReferenceTypes | FeatureSet::Strings;
926- return ;
927- case HeapType::none:
928- case HeapType::noext:
929- case HeapType::nofunc:
930- // Technically introduced in GC, but used internally as part of
931- // ref.null with just reference types.
932- feats |= FeatureSet::ReferenceTypes;
933- return ;
934- case HeapType::exn:
935- case HeapType::noexn:
936- feats |=
937- FeatureSet::ExceptionHandling | FeatureSet::ReferenceTypes;
938- return ;
939- case HeapType::cont:
940- case HeapType::nocont:
941- feats |= FeatureSet::TypedContinuations;
942- return ;
943- }
944- }
945-
946- if (heapType->getRecGroup ().size () > 1 ||
947- heapType->getDeclaredSuperType () || heapType->isOpen ()) {
948- feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
949- }
950-
951- if (heapType->isShared ()) {
952- feats |= FeatureSet::SharedEverything;
953- }
954-
955- if (heapType->isStruct () || heapType->isArray ()) {
956- feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
957- } else if (heapType->isSignature ()) {
958- // This is a function reference, which requires reference types and
959- // possibly also multivalue (if it has multiple returns). Note that
960- // technically typed function references also require GC, however,
961- // we use these types internally regardless of the presence of GC
962- // (in particular, since during load of the wasm we don't know the
963- // features yet, so we apply the more refined types), so we don't
964- // add that in any case here.
965- feats |= FeatureSet::ReferenceTypes;
966- auto sig = heapType->getSignature ();
967- if (sig.results .isTuple ()) {
968- feats |= FeatureSet::Multivalue;
969- }
970- } else if (heapType->isContinuation ()) {
971- feats |= FeatureSet::TypedContinuations;
972- }
973-
974- // In addition, scan their non-ref children, to add dependencies on
975- // things like SIMD.
976- for (auto child : heapType->getTypeChildren ()) {
977- if (!child.isRef ()) {
978- feats |= child.getFeatures ();
979- }
980- }
981- }
982- };
983-
984- ReferenceFeatureCollector collector;
985- auto heapType = t.getHeapType ();
986- collector.walkRoot (&heapType);
987- collector.noteChild (&heapType);
988- return collector.feats ;
903+ return t.getHeapType ().getFeatures ();
989904 }
990905
991906 switch (t.getBasic ()) {
@@ -1604,6 +1519,95 @@ size_t HeapType::getRecGroupIndex() const {
16041519 return getHeapTypeInfo (*this )->recGroupIndex ;
16051520}
16061521
1522+ FeatureSet HeapType::getFeatures () const {
1523+ // Collects features from a type + children.
1524+ struct ReferenceFeatureCollector
1525+ : HeapTypeChildWalker<ReferenceFeatureCollector> {
1526+ FeatureSet feats = FeatureSet::None;
1527+
1528+ void noteChild (HeapType* heapType) {
1529+ if (heapType->isBasic ()) {
1530+ switch (heapType->getBasic (Unshared)) {
1531+ case HeapType::ext:
1532+ case HeapType::func:
1533+ feats |= FeatureSet::ReferenceTypes;
1534+ return ;
1535+ case HeapType::any:
1536+ case HeapType::eq:
1537+ case HeapType::i31:
1538+ case HeapType::struct_:
1539+ case HeapType::array:
1540+ feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
1541+ return ;
1542+ case HeapType::string:
1543+ feats |= FeatureSet::ReferenceTypes | FeatureSet::Strings;
1544+ return ;
1545+ case HeapType::none:
1546+ case HeapType::noext:
1547+ case HeapType::nofunc:
1548+ // Technically introduced in GC, but used internally as part of
1549+ // ref.null with just reference types.
1550+ feats |= FeatureSet::ReferenceTypes;
1551+ return ;
1552+ case HeapType::exn:
1553+ case HeapType::noexn:
1554+ feats |= FeatureSet::ExceptionHandling | FeatureSet::ReferenceTypes;
1555+ return ;
1556+ case HeapType::cont:
1557+ case HeapType::nocont:
1558+ feats |= FeatureSet::TypedContinuations;
1559+ return ;
1560+ }
1561+ }
1562+
1563+ if (heapType->getRecGroup ().size () > 1 ||
1564+ heapType->getDeclaredSuperType () || heapType->isOpen ()) {
1565+ feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
1566+ }
1567+
1568+ if (heapType->isShared ()) {
1569+ feats |= FeatureSet::SharedEverything;
1570+ }
1571+
1572+ if (heapType->isStruct () || heapType->isArray ()) {
1573+ feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
1574+ } else if (heapType->isSignature ()) {
1575+ // This is a function reference, which requires reference types and
1576+ // possibly also multivalue (if it has multiple returns). Note that
1577+ // technically typed function references also require GC, however,
1578+ // we use these types internally regardless of the presence of GC
1579+ // (in particular, since during load of the wasm we don't know the
1580+ // features yet, so we apply the more refined types), so we don't
1581+ // add that in any case here.
1582+ feats |= FeatureSet::ReferenceTypes;
1583+ auto sig = heapType->getSignature ();
1584+ if (sig.results .isTuple ()) {
1585+ feats |= FeatureSet::Multivalue;
1586+ }
1587+ } else if (heapType->isContinuation ()) {
1588+ feats |= FeatureSet::TypedContinuations;
1589+ }
1590+
1591+ // In addition, scan their non-ref children, to add dependencies on
1592+ // things like SIMD.
1593+ for (auto child : heapType->getTypeChildren ()) {
1594+ if (!child.isRef ()) {
1595+ feats |= child.getFeatures ();
1596+ }
1597+ }
1598+ }
1599+ };
1600+
1601+ ReferenceFeatureCollector collector;
1602+ // For internal reasons, the walkRoot/noteChild APIs all require non-const
1603+ // pointers. We only use them to scan the type, so it is safe for us to
1604+ // send |this| there from a |const| method.
1605+ auto * unconst = const_cast <HeapType*>(this );
1606+ collector.walkRoot (unconst);
1607+ collector.noteChild (unconst);
1608+ return collector.feats ;
1609+ }
1610+
16071611HeapType RecGroup::Iterator::operator *() const {
16081612 if (parent->id & 1 ) {
16091613 // This is a trivial recursion group. Mask off the low bit to recover the
0 commit comments