Skip to content

Commit 62e7377

Browse files
natebiggsCommit Queue
authored andcommitted
[dart2wasm] Update closure types to be not final when dynamic modules are enabled.
Dynamic modules can introduce new closure shapes that result in new subtypes of certain closure helper structs (#Vtable, #Closure, etc.). Because we need the struct definitions to match across modules, we need to assume that there may always be subtypes of these structs and not mark any of them as final. Change-Id: If578dc463d0f80352319d0bd44e1e4cecba28bee Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422340 Reviewed-by: Ömer Ağacan <[email protected]>
1 parent 8505c55 commit 62e7377

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

pkg/dart2wasm/lib/closures.dart

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)