Skip to content

Commit 13e950e

Browse files
author
Dart CI
committed
Version 3.8.0-219.0.dev
Merge a48e5e5 into dev
2 parents f381305 + a48e5e5 commit 13e950e

19 files changed

+1391
-882
lines changed

pkg/dart2wasm/lib/class_info.dart

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:kernel/ast.dart';
88
import 'package:wasm_builder/wasm_builder.dart' as w;
99

1010
import 'dynamic_modules.dart';
11+
import 'serialization.dart';
1112
import 'translator.dart';
1213

1314
/// Wasm struct field indices for fields that are accessed explicitly from Wasm
@@ -375,8 +376,8 @@ class ClassInfoCollector {
375376
}
376377

377378
if (translator.isDynamicModule) {
378-
final brandIndex =
379-
translator.dynamicModuleInfo!.classMetadata[cls]?.brandIndex;
379+
final brandIndex = translator
380+
.dynamicModuleInfo!.metadata.classMetadata[cls]?.brandIndex;
380381
if (brandIndex != null) {
381382
translator.typesBuilder.addBrandTypeAssignment(struct, brandIndex);
382383
}
@@ -551,16 +552,20 @@ class ClassInfoCollector {
551552

552553
final mainModuleConcreteRange =
553554
classIdNumbering.getConcreteClassIdRangeForMainModule(cls);
554-
final dynamicModuleConcreteRange =
555-
classIdNumbering.getConcreteClassIdRangeForDynamicModule(cls);
556-
557555
// Only non-extendable classes can get here so they should only have
558556
// concrete implementations in either the main module or the dynamic
559557
// module, not both.
560-
assert(mainModuleConcreteRange.isEmpty ||
561-
dynamicModuleConcreteRange.isEmpty);
562-
addRanges(mainModuleConcreteRange);
563-
addRanges(dynamicModuleConcreteRange);
558+
if (translator.isDynamicModule && mainModuleConcreteRange.isEmpty) {
559+
final dynamicModuleConcreteRange =
560+
classIdNumbering.getConcreteClassIdRangeForDynamicModule(cls);
561+
assert(dynamicModuleConcreteRange.isNotEmpty);
562+
addRanges(dynamicModuleConcreteRange);
563+
} else {
564+
assert(classIdNumbering
565+
.getConcreteClassIdRangeForDynamicModule(cls)
566+
.isEmpty);
567+
addRanges(mainModuleConcreteRange);
568+
}
564569
}
565570
final info = translator.classInfo[cls]!;
566571
info._repr = representation ?? info;
@@ -709,9 +714,9 @@ class ClassIdNumbering {
709714
final classIds = <Class, ClassId>{};
710715

711716
if (translator.isDynamicModule) {
712-
final savedMapping = translator.dynamicModuleInfo!.classMetadata;
713-
savedMapping.forEach((cls, info) {
714-
final classId = info.classId;
717+
final savedMapping = translator.dynamicModuleInfo!.metadata.classMetadata;
718+
savedMapping.forEach((cls, metadata) {
719+
final classId = metadata.classId;
715720
classIds[cls] = AbsoluteClassId(classId);
716721
savedMaxClassId = max(savedMaxClassId ?? -2, classId);
717722
if (!cls.isAbstract && !cls.isAnonymousMixin) {
@@ -805,7 +810,9 @@ class ClassIdNumbering {
805810
}
806811

807812
// Make a list of the depth-first pre-order traversal.
808-
final dfsOrder = [...?translator.dynamicModuleInfo?.dfsOrderClassIds];
813+
final dfsOrder = [
814+
...?translator.dynamicModuleInfo?.metadata.dfsOrderClassIds
815+
];
809816
final inDfsOrder = {...dfsOrder};
810817

811818
// Maps any class to a dense range of concrete class ids that are subclasses
@@ -945,6 +952,17 @@ class Range {
945952
return Range._(start, end);
946953
}
947954

955+
void serialize(DataSerializer sink) {
956+
sink.writeInt(start);
957+
sink.writeInt(end);
958+
}
959+
960+
factory Range.deserialize(DataDeserializer source) {
961+
final start = source.readInt();
962+
final end = source.readInt();
963+
return Range(start, end);
964+
}
965+
948966
int get length => 1 + (end - start);
949967
bool get isEmpty => length == 0;
950968

pkg/dart2wasm/lib/code_generator.dart

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,8 +1828,14 @@ abstract class AstCodeGenerator
18281828
w.ValueType? intrinsicResult = intrinsifier.generateEqualsIntrinsic(node);
18291829
if (intrinsicResult != null) return intrinsicResult;
18301830

1831+
final leftType = translator.translateType(dartTypeOf(node.left));
18311832
Member? singleTarget = translator.singleTarget(node);
1832-
if (singleTarget == translator.coreTypes.objectEquals) {
1833+
if (singleTarget == translator.coreTypes.objectEquals ||
1834+
// If leftType is not a Dart type (or builtin value type) then use
1835+
// reference equality (e.g. the vtable type is not a subtype of
1836+
// topType).
1837+
(leftType is w.RefType &&
1838+
!leftType.isSubtypeOf(translator.topInfo.nullableType))) {
18331839
// Plain reference comparison
18341840
translateExpression(node.left, w.RefType.eq(nullable: true));
18351841
translateExpression(node.right, w.RefType.eq(nullable: true));
@@ -1924,64 +1930,51 @@ abstract class AstCodeGenerator
19241930
void Function(w.FunctionType signature, ParameterInfo) pushArguments,
19251931
{required bool useUncheckedEntry}) {
19261932
assert(kind != _VirtualCallKind.Get || !useUncheckedEntry);
1927-
SelectorInfo selector = translator.dispatchTable.selectorForTarget(
1928-
interfaceTarget.referenceAs(
1929-
getter: kind.isGetter, setter: kind.isSetter));
1933+
final reference = interfaceTarget.referenceAs(
1934+
getter: kind.isGetter, setter: kind.isSetter);
1935+
final dispatchTable = translator.dispatchTableForTarget(reference);
1936+
SelectorInfo selector = dispatchTable.selectorForTarget(reference);
1937+
final signature = selector.signature;
19301938
final name = selector.entryPointName(useUncheckedEntry);
19311939
assert(selector.name == interfaceTarget.name.text);
19321940

1933-
pushReceiver(selector.signature);
1934-
1935-
SelectorTargets targets;
1936-
1937-
if (!translator.dynamicModuleSupportEnabled ||
1938-
b.module == translator.mainModule) {
1939-
targets =
1940-
selector.targets(unchecked: useUncheckedEntry, dynamicModule: false);
1941-
} else {
1942-
targets =
1943-
selector.targets(unchecked: useUncheckedEntry, dynamicModule: true);
1944-
}
1945-
1946-
final isDynamicModuleOverrideable = selector.isDynamicModuleOverrideable;
1947-
if (!isDynamicModuleOverrideable) {
1948-
w.ValueType? checkRanges(List<({Range range, Reference target})> ranges) {
1949-
if (ranges.length == 1) {
1950-
final target = translator.getFunctionEntry(ranges[0].target,
1951-
uncheckedEntry: useUncheckedEntry);
1952-
final signature = translator.signatureForDirectCall(target);
1953-
final paramInfo = translator.paramInfoForDirectCall(target);
1954-
pushArguments(signature, paramInfo);
1955-
return translator.outputOrVoid(call(target));
1956-
}
1957-
if (ranges.isEmpty) {
1958-
// Unreachable call
1959-
b.comment("Virtual call of $name with no targets"
1960-
" at ${node.location}");
1961-
pushArguments(selector.signature, selector.paramInfo);
1962-
for (int i = 0; i < selector.signature.inputs.length; ++i) {
1963-
b.drop();
1964-
}
1965-
b.block(const [], selector.signature.outputs);
1966-
b.unreachable();
1967-
b.end();
1968-
return translator.outputOrVoid(selector.signature.outputs);
1941+
pushReceiver(signature);
1942+
1943+
final targets = selector.targets(unchecked: useUncheckedEntry);
1944+
List<({Range range, Reference target})> targetRanges = targets.targetRanges;
1945+
List<({Range range, Reference target})> staticDispatchRanges =
1946+
targets.staticDispatchRanges;
1947+
if (!selector.isDynamicModuleOverrideable) {
1948+
if (targetRanges.length == 1) {
1949+
final target = translator.getFunctionEntry(targetRanges[0].target,
1950+
uncheckedEntry: useUncheckedEntry);
1951+
final directCallSignature = translator.signatureForDirectCall(target);
1952+
final paramInfo = translator.paramInfoForDirectCall(target);
1953+
pushArguments(directCallSignature, paramInfo);
1954+
return translator.outputOrVoid(call(target));
1955+
}
1956+
if (targetRanges.isEmpty) {
1957+
// Unreachable call
1958+
b.comment("Virtual call of $name with no targets"
1959+
" at ${node.location}");
1960+
pushArguments(signature, selector.paramInfo);
1961+
for (int i = 0; i < signature.inputs.length; ++i) {
1962+
b.drop();
19691963
}
1970-
return null;
1964+
b.block(const [], signature.outputs);
1965+
b.unreachable();
1966+
b.end();
1967+
return translator.outputOrVoid(signature.outputs);
19711968
}
1972-
1973-
final result = checkRanges(targets.targetRanges);
1974-
if (result != null) return result;
19751969
}
19761970

19771971
// Receiver is already on stack.
1978-
w.Local receiverVar = addLocal(selector.signature.inputs.first);
1972+
w.Local receiverVar = addLocal(signature.inputs.first);
19791973
assert(!receiverVar.type.nullable);
19801974
b.local_tee(receiverVar);
1981-
pushArguments(selector.signature, selector.paramInfo);
1975+
pushArguments(signature, selector.paramInfo);
19821976

1983-
if (targets.staticDispatchRanges.isNotEmpty) {
1984-
assert(!translator.dynamicModuleSupportEnabled);
1977+
if (staticDispatchRanges.isNotEmpty) {
19851978
b.invoke(translator
19861979
.getPolymorphicDispatchersForModule(b.module)
19871980
.getPolymorphicDispatcher(selector,
@@ -1990,11 +1983,12 @@ abstract class AstCodeGenerator
19901983
b.comment("Instance $kind of '$name'");
19911984
b.local_get(receiverVar);
19921985
translator.callDispatchTable(b, selector,
1993-
interfaceTarget: interfaceTarget,
1994-
useUncheckedEntry: useUncheckedEntry);
1986+
interfaceTarget: reference,
1987+
useUncheckedEntry: useUncheckedEntry,
1988+
table: dispatchTable);
19951989
}
19961990

1997-
return translator.outputOrVoid(selector.signature.outputs);
1991+
return translator.outputOrVoid(signature.outputs);
19981992
}
19991993

20001994
@override
@@ -2102,7 +2096,7 @@ abstract class AstCodeGenerator
21022096
() => visitThis(w.RefType.struct(nullable: false)));
21032097
return w.RefType.def(closureStruct, nullable: false);
21042098
}
2105-
return _directGet(target, ThisExpression(), () => null);
2099+
return _directGet(target, ThisExpression());
21062100
}
21072101

21082102
@override
@@ -2143,10 +2137,13 @@ abstract class AstCodeGenerator
21432137
b.end(); // doneLabel
21442138
return resultType;
21452139
}
2140+
21462141
Member? singleTarget = translator.singleTarget(node);
21472142
if (singleTarget != null) {
2148-
return _directGet(singleTarget, node.receiver,
2149-
() => intrinsifier.generateInstanceGetterIntrinsic(node));
2143+
final intrinsic = intrinsifier.generateInstanceGetterIntrinsic(node);
2144+
if (intrinsic != null) return intrinsic;
2145+
2146+
return _directGet(singleTarget, node.receiver);
21502147
} else {
21512148
return _virtualCall(
21522149
node,
@@ -2229,11 +2226,7 @@ abstract class AstCodeGenerator
22292226
return translator.topInfo.nullableType;
22302227
}
22312228

2232-
w.ValueType _directGet(
2233-
Member target, Expression receiver, w.ValueType? Function() intrinsify) {
2234-
w.ValueType? intrinsicResult = intrinsify();
2235-
if (intrinsicResult != null) return intrinsicResult;
2236-
2229+
w.ValueType _directGet(Member target, Expression receiver) {
22372230
if (target is Field) {
22382231
ClassInfo info = translator.classInfo[target.enclosingClass]!;
22392232
int fieldIndex = translator.fieldIndex[target]!;

pkg/dart2wasm/lib/compile.dart

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ Future<CompilationResult> compileToModule(
183183

184184
Component component = compilerResult!.component!;
185185
CoreTypes coreTypes = compilerResult.coreTypes!;
186-
ClassHierarchy classHierarchy = compilerResult.classHierarchy!;
186+
final classHierarchy =
187+
ClassHierarchy(component, coreTypes) as ClosedWorldClassHierarchy;
187188
LibraryIndex libraryIndex = LibraryIndex(component, [
188189
"dart:_boxed_bool",
189190
"dart:_boxed_double",
@@ -222,12 +223,11 @@ Future<CompilationResult> compileToModule(
222223
moduleStrategy = DynamicMainModuleStrategy(
223224
component,
224225
coreTypes,
225-
classHierarchy,
226226
File.fromUri(dynamicInterfaceUri).readAsStringSync(),
227227
options.dynamicInterfaceUri!);
228228
} else if (isDynamicModule) {
229-
moduleStrategy = DynamicModuleStrategy(component, options, target,
230-
coreTypes, classHierarchy, dynamicModuleMainUri);
229+
moduleStrategy = DynamicModuleStrategy(
230+
component, options, target, coreTypes, dynamicModuleMainUri);
231231
} else {
232232
moduleStrategy = DefaultModuleStrategy(component);
233233
}
@@ -244,8 +244,8 @@ Future<CompilationResult> compileToModule(
244244
? null
245245
: js.createRuntimeFinalizer(component, coreTypes, classHierarchy);
246246

247-
final Map<RecordShape, Class> recordClasses =
248-
generateRecordClasses(component, coreTypes);
247+
final Map<RecordShape, Class> recordClasses = generateRecordClasses(
248+
component, coreTypes, isDynamicMainModule || isDynamicModule);
249249
target.recordClasses = recordClasses;
250250

251251
if (options.dumpKernelBeforeTfa != null) {
@@ -268,19 +268,25 @@ Future<CompilationResult> compileToModule(
268268
final source = DataDeserializer(dynamicModuleMetadataBytes, component);
269269
mainModuleMetadata = MainModuleMetadata.deserialize(source);
270270
mainModuleMetadata.verifyDynamicModuleOptions(options);
271+
mainModuleMetadata.initializeDynamicModuleKernel(
272+
component,
273+
coreTypes,
274+
// Create a new hierarchy with generated record classes.
275+
ClassHierarchy(component, coreTypes) as ClosedWorldClassHierarchy);
271276
} else if (isDynamicMainModule) {
272277
MainModuleMetadata.verifyMainModuleOptions(options);
273278
writeComponentToBinary(component, dynamicModuleMainUri.path,
274279
includeSource: false);
275280
}
276281

277-
_patchMainTearOffs(coreTypes, component);
282+
if (!isDynamicModule) {
283+
_patchMainTearOffs(coreTypes, component);
278284

279-
// Keep the flags in-sync with
280-
// pkg/vm/test/transformations/type_flow/transformer_test.dart
281-
// TODO(natebiggs): Only run TFA on main module when dynamic modules enabled.
282-
globalTypeFlow.transformComponent(target, coreTypes, component,
283-
useRapidTypeAnalysis: false);
285+
// Keep the flags in-sync with
286+
// pkg/vm/test/transformations/type_flow/transformer_test.dart
287+
globalTypeFlow.transformComponent(target, coreTypes, component,
288+
useRapidTypeAnalysis: false);
289+
}
284290

285291
if (options.dumpKernelAfterTfa != null) {
286292
writeComponentToText(component,
@@ -295,10 +301,6 @@ Future<CompilationResult> compileToModule(
295301

296302
final moduleOutputData = moduleStrategy.buildModuleOutputData();
297303

298-
if (isDynamicMainModule) {
299-
mainModuleMetadata.initialize(component, coreTypes);
300-
}
301-
302304
var translator = Translator(component, coreTypes, libraryIndex, recordClasses,
303305
moduleOutputData, options.translatorOptions,
304306
mainModuleMetadata: mainModuleMetadata,
@@ -340,7 +342,7 @@ Future<CompilationResult> compileToModule(
340342
Uri.parse(
341343
path.setExtension(dynamicMainModuleUri!.toFilePath(), '.dyndata'));
342344
final serializer = DataSerializer(translator.component);
343-
translator.dynamicModuleInfo!.metadata.serialize(translator, serializer);
345+
translator.dynamicModuleInfo!.metadata.serialize(serializer, translator);
344346
await File.fromUri(filename).writeAsBytes(serializer.takeBytes());
345347
}
346348

pkg/dart2wasm/lib/constants.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,8 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?>
595595

596596
if (cls == Constants._relativeInterfaceTypeIndicator) {
597597
cls = translator.interfaceTypeClass;
598+
constant = InstanceConstant(
599+
cls.reference, constant.typeArguments, constant.fieldValues);
598600
isRelativeInterfaceType = true;
599601
}
600602

0 commit comments

Comments
 (0)