@@ -604,6 +604,10 @@ struct Struct2Local : PostWalker<Struct2Local> {
604604 Builder builder;
605605 const FieldList& fields;
606606
607+ // The descriptor can arrive as nullable, but we trap if it is null, so there
608+ // is only something to store if it is non-nullable, and we store it that way.
609+ Type descType;
610+
607611 Struct2Local (StructNew* allocation,
608612 EscapeAnalyzer& analyzer,
609613 Function* func,
@@ -616,7 +620,8 @@ struct Struct2Local : PostWalker<Struct2Local> {
616620 localIndexes.push_back (builder.addVar (func, field.type ));
617621 }
618622 if (allocation->desc ) {
619- localIndexes.push_back (builder.addVar (func, allocation->desc ->type ));
623+ descType = allocation->desc ->type .with (NonNullable);
624+ localIndexes.push_back (builder.addVar (func, descType));
620625 }
621626
622627 // Replace the things we need to using the visit* methods.
@@ -744,7 +749,7 @@ struct Struct2Local : PostWalker<Struct2Local> {
744749 }
745750 }
746751 if (curr->desc ) {
747- tempIndexes.push_back (builder.addVar (func, curr-> desc -> type ));
752+ tempIndexes.push_back (builder.addVar (func, descType ));
748753 }
749754
750755 // Store the initial values into the temp locals.
@@ -773,8 +778,7 @@ struct Struct2Local : PostWalker<Struct2Local> {
773778 contents.push_back (builder.makeLocalSet (localIndexes[i], val));
774779 }
775780 if (curr->desc ) {
776- auto * val =
777- builder.makeLocalGet (tempIndexes[numTemps - 1 ], curr->desc ->type );
781+ auto * val = builder.makeLocalGet (tempIndexes[numTemps - 1 ], descType);
778782 contents.push_back (
779783 builder.makeLocalSet (localIndexes[fields.size ()], val));
780784 }
@@ -902,13 +906,12 @@ struct Struct2Local : PostWalker<Struct2Local> {
902906 } else {
903907 // The cast succeeds iff the optimized allocation's descriptor is the
904908 // same as the given descriptor and traps otherwise.
905- auto type = allocation->desc ->type ;
906909 replaceCurrent (builder.blockify (
907910 builder.makeDrop (curr->ref ),
908911 builder.makeIf (
909912 builder.makeRefEq (
910913 curr->desc ,
911- builder.makeLocalGet (localIndexes[fields.size ()], type )),
914+ builder.makeLocalGet (localIndexes[fields.size ()], descType )),
912915 builder.makeRefNull (allocation->type .getHeapType ()),
913916 builder.makeUnreachable ())));
914917 }
@@ -939,19 +942,13 @@ struct Struct2Local : PostWalker<Struct2Local> {
939942 return ;
940943 }
941944
942- auto type = allocation->desc ->type ;
943- Expression* value = builder.makeLocalGet (localIndexes[fields.size ()], type);
944- if (type != curr->type ) {
945- // We know exactly the allocation that flows into this expression, so we
946- // know the exact type of the descriptor. This type may be more precise
947- // than the static type of this expression.
948- refinalize = true ;
949- if (type.isNull ()) {
950- // This traps.
951- value = builder.makeUnreachable ();
952- }
953- }
945+ auto descIndex = localIndexes[fields.size ()];
946+ Expression* value = builder.makeLocalGet (descIndex, descType);
954947 replaceCurrent (builder.blockify (builder.makeDrop (curr->ref ), value));
948+
949+ // After removing the ref.get_desc, a null may be falling through,
950+ // requiring refinalization to update parents.
951+ refinalize = true ;
955952 }
956953
957954 void visitStructSet (StructSet* curr) {
0 commit comments