@@ -223,39 +223,37 @@ class ClosureLayouter extends RecursiveVisitor {
223223 // Base struct for vtables without the dynamic call entry added. Referenced
224224 // by [closureBaseStruct] instead of the fully initialized version
225225 // ([vtableBaseStruct]) to break the type cycle.
226- late final w.StructType _vtableBaseStructBare =
227- translator.typesBuilder.defineStruct ("#VtableBase" );
226+ late final w.StructType _vtableBaseStructBase = _defineStruct ("#VtableBase" );
228227
229228 /// Base struct for instantiation closure contexts. Type tests against this
230229 /// type is used in `_Closure._equals` to check if a closure is an
231230 /// instantiation.
232- late final w.StructType instantiationContextBaseStruct = translator
233- .typesBuilder
234- .defineStruct ("#InstantiationClosureContextBase" , fields: [
231+ late final w.StructType instantiationContextBaseStruct =
232+ _defineStruct ("#InstantiationClosureContextBase" , fields: [
235233 w.FieldType (w.RefType .def (closureBaseStruct, nullable: false ),
236234 mutable: false ),
237235 ]);
238236
239237 /// Base struct for non-generic closure vtables.
240- late final w.StructType vtableBaseStruct = _vtableBaseStructBare
238+ late final w.StructType vtableBaseStruct = _vtableBaseStructBase
241239 ..fields.add (w.FieldType (
242240 w.RefType .def (translator.dynamicCallVtableEntryFunctionType,
243241 nullable: false ),
244242 mutable: false ));
245243
246244 /// Base struct for generic closure vtables.
247- late final w.StructType genericVtableBaseStruct = translator.typesBuilder
248- . defineStruct ( "#GenericVtableBase" ,
249- fields: vtableBaseStruct.fields.toList ()
250- ..add (w.FieldType (
251- w.RefType .def (instantiationClosureTypeComparisonFunctionType,
252- nullable: false ),
253- mutable: false ))
254- ..add (w.FieldType (
255- w.RefType .def (instantiationClosureTypeHashFunctionType,
256- nullable: false ),
257- mutable: false )),
258- superType: vtableBaseStruct);
245+ late final w.StructType genericVtableBaseStruct = _defineStruct (
246+ "#GenericVtableBase" ,
247+ fields: vtableBaseStruct.fields.toList ()
248+ ..add (w.FieldType (
249+ w.RefType .def (instantiationClosureTypeComparisonFunctionType,
250+ nullable: false ),
251+ mutable: false ))
252+ ..add (w.FieldType (
253+ w.RefType .def (instantiationClosureTypeHashFunctionType,
254+ nullable: false ),
255+ mutable: false )),
256+ superType: vtableBaseStruct);
259257
260258 /// Type of [ClosureRepresentation._instantiationTypeComparisonFunction] .
261259 late final w.FunctionType instantiationClosureTypeComparisonFunctionType =
@@ -275,7 +273,7 @@ class ClosureLayouter extends RecursiveVisitor {
275273
276274 // Base struct for closures.
277275 late final w.StructType closureBaseStruct = _makeClosureStruct (
278- "#ClosureBase" , _vtableBaseStructBare , translator.closureInfo.struct);
276+ "#ClosureBase" , _vtableBaseStructBase , translator.closureInfo.struct);
279277
280278 w.RefType get typeType => translator.types.nonNullableTypeType;
281279
@@ -287,8 +285,7 @@ class ClosureLayouter extends RecursiveVisitor {
287285 w.StructType _getInstantiationContextBaseStruct (int numTypes) =>
288286 _instantiationContextBaseStructs.putIfAbsent (
289287 numTypes,
290- () => translator.typesBuilder.defineStruct (
291- "#InstantiationClosureContextBase-$numTypes " ,
288+ () => _defineStruct ("#InstantiationClosureContextBase-$numTypes " ,
292289 fields: [
293290 w.FieldType (w.RefType .def (closureBaseStruct, nullable: false ),
294291 mutable: false ),
@@ -318,6 +315,18 @@ class ClosureLayouter extends RecursiveVisitor {
318315 .putIfAbsent (module,
319316 () => _createInstantiationTypeHashFunction (module, numTypes));
320317
318+ w.StructType _defineStruct (String name,
319+ {Iterable <w.FieldType >? fields, w.StructType ? superType}) {
320+ final type = translator.typesBuilder
321+ .defineStruct (name, fields: fields, superType: superType);
322+ if (translator.dynamicModuleSupportEnabled) {
323+ // Pessimistically assume there will be subtypes in a dynamic module. This
324+ // ensures the struct is not final in all modules so the types are equal.
325+ type.hasAnySubtypes = true ;
326+ }
327+ return type;
328+ }
329+
321330 w.StructType _makeClosureStruct (
322331 String name, w.StructType vtableStruct, w.StructType superType) {
323332 // A closure contains:
@@ -326,7 +335,7 @@ class ClosureLayouter extends RecursiveVisitor {
326335 // - A context reference (used for `this` in tear-offs)
327336 // - A vtable reference
328337 // - A `_FunctionType`
329- return translator.typesBuilder. defineStruct (name,
338+ return _defineStruct (name,
330339 fields: [
331340 w.FieldType (w.NumType .i32, mutable: false ),
332341 w.FieldType (w.NumType .i32),
@@ -421,7 +430,7 @@ class ClosureLayouter extends RecursiveVisitor {
421430 String closureName = ["#Closure" , ...nameTags].join ("-" );
422431 w.StructType parentVtableStruct = parent? .vtableStruct ??
423432 (typeCount == 0 ? vtableBaseStruct : genericVtableBaseStruct);
424- w.StructType vtableStruct = translator.typesBuilder. defineStruct (vtableName,
433+ w.StructType vtableStruct = _defineStruct (vtableName,
425434 fields: parentVtableStruct.fields, superType: parentVtableStruct);
426435 w.StructType closureStruct = _makeClosureStruct (
427436 closureName, vtableStruct, parent? .closureStruct ?? closureBaseStruct);
0 commit comments