@@ -292,7 +292,16 @@ struct IRBuilder::ChildPopper
292292 size_t arity;
293293 };
294294
295- struct Constraint : std::variant<Subtype, AnyType, AnyReference, AnyTuple> {
295+ struct AnyI8ArrayReference {};
296+
297+ struct AnyI16ArrayReference {};
298+
299+ struct Constraint : std::variant<Subtype,
300+ AnyType,
301+ AnyReference,
302+ AnyTuple,
303+ AnyI8ArrayReference,
304+ AnyI16ArrayReference> {
296305 std::optional<Type> getSubtype () const {
297306 if (auto * subtype = std::get_if<Subtype>(this )) {
298307 return subtype->bound ;
@@ -301,6 +310,12 @@ struct IRBuilder::ChildPopper
301310 }
302311 bool isAnyType () const { return std::get_if<AnyType>(this ); }
303312 bool isAnyReference () const { return std::get_if<AnyReference>(this ); }
313+ bool isAnyI8ArrayReference () const {
314+ return std::get_if<AnyI8ArrayReference>(this );
315+ }
316+ bool isAnyI16ArrayReference () const {
317+ return std::get_if<AnyI16ArrayReference>(this );
318+ }
304319 std::optional<size_t > getAnyTuple () const {
305320 if (auto * tuple = std::get_if<AnyTuple>(this )) {
306321 return tuple->arity ;
@@ -356,6 +371,14 @@ struct IRBuilder::ChildPopper
356371 children.push_back ({childp, {AnyTuple{arity}}});
357372 }
358373
374+ void noteAnyI8ArrayReferenceType (Expression** childp) {
375+ children.push_back ({childp, {AnyI8ArrayReference{}}});
376+ }
377+
378+ void noteAnyI16ArrayReferenceType (Expression** childp) {
379+ children.push_back ({childp, {AnyI16ArrayReference{}}});
380+ }
381+
359382 Type getLabelType (Name label) {
360383 WASM_UNREACHABLE (" labels should be explicitly provided" );
361384 };
@@ -455,6 +478,26 @@ struct IRBuilder::ChildPopper
455478 needUnreachableFallback = true ;
456479 break ;
457480 }
481+ } else if (constraint.isAnyI8ArrayReference ()) {
482+ bool isI8Array =
483+ type.isRef () && type.getHeapType ().isArray () &&
484+ type.getHeapType ().getArray ().element .packedType == Field::i8 ;
485+ bool isNone =
486+ type.isRef () && type.getHeapType ().isMaybeShared (HeapType::none);
487+ if (!isI8Array && !isNone && type != Type::unreachable) {
488+ needUnreachableFallback = true ;
489+ break ;
490+ }
491+ } else if (constraint.isAnyI16ArrayReference ()) {
492+ bool isI16Array =
493+ type.isRef () && type.getHeapType ().isArray () &&
494+ type.getHeapType ().getArray ().element .packedType == Field::i16 ;
495+ bool isNone =
496+ type.isRef () && type.getHeapType ().isMaybeShared (HeapType::none);
497+ if (!isI16Array && !isNone && type != Type::unreachable) {
498+ needUnreachableFallback = true ;
499+ break ;
500+ }
458501 } else {
459502 WASM_UNREACHABLE (" unexpected constraint" );
460503 }
@@ -601,13 +644,6 @@ struct IRBuilder::ChildPopper
601644 return popConstrainedChildren (children);
602645 }
603646
604- Result<> visitStringNew (StringNew* curr,
605- std::optional<HeapType> ht = std::nullopt ) {
606- std::vector<Child> children;
607- ConstraintCollector{builder, children}.visitStringNew (curr, ht);
608- return popConstrainedChildren (children);
609- }
610-
611647 Result<> visitStringEncode (StringEncode* curr,
612648 std::optional<HeapType> ht = std::nullopt ) {
613649 std::vector<Child> children;
@@ -1951,11 +1987,7 @@ Result<> IRBuilder::makeStringNew(StringNewOp op) {
19511987 push (builder.makeStringNew (op, curr.ref ));
19521988 return Ok{};
19531989 }
1954- // There's no type annotation on these instructions due to a bug in the
1955- // stringref proposal, so we just fudge it and pass `array` instead of a
1956- // defined heap type. This will allow us to pop a child with an invalid
1957- // array type, but that's just too bad.
1958- CHECK_ERR (ChildPopper{*this }.visitStringNew (&curr, HeapType::array));
1990+ CHECK_ERR (visitStringNew (&curr));
19591991 push (builder.makeStringNew (op, curr.ref , curr.start , curr.end ));
19601992 return Ok{};
19611993}
0 commit comments