Version 2.17.0-134.0.dev
Merge commit '7831f051721c9a11b6ffd2dfbd100b37abed0562' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
index fbc3ab3..4f5ad4e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -42,6 +42,7 @@
ContinueTarget,
Deferred,
DocumentationComment,
+ EnumConstantInfo,
Expression,
ExtendsClause,
FieldInitializer,
diff --git a/pkg/dart2wasm/bin/dart2wasm.dart b/pkg/dart2wasm/bin/dart2wasm.dart
index 10f1750..19b9604 100644
--- a/pkg/dart2wasm/bin/dart2wasm.dart
+++ b/pkg/dart2wasm/bin/dart2wasm.dart
@@ -33,6 +33,9 @@
Never usage(String message) {
print("Usage: dart2wasm [<options>] <infile.dart> <outfile.wasm>");
print("");
+ print("*NOTE*: Wasm compilation is experimental.");
+ print("The support may change, or be removed, with no advance notice.");
+ print("");
print("Options:");
print(" --dart-sdk=<path>");
print("");
diff --git a/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart b/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart
index 79df036..7b52198 100644
--- a/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart
@@ -3,15 +3,41 @@
// BSD-style license that can be found in the LICENSE file.
class Benchmarker {
+ final List<PhaseTiming> _phaseTimings =
+ new List<PhaseTiming>.generate(BenchmarkPhases.values.length, (index) {
+ assert(BenchmarkPhases.values[index].index == index);
+ return new PhaseTiming(BenchmarkPhases.values[index]);
+ }, growable: false);
+
final Stopwatch _totalStopwatch = new Stopwatch()..start();
final Stopwatch _phaseStopwatch = new Stopwatch()..start();
+ final Stopwatch _subdivideStopwatch = new Stopwatch()..start();
+
BenchmarkPhases _currentPhase = BenchmarkPhases.implicitInitialization;
- List<PhaseTiming> _phaseTimings = [];
+ BenchmarkSubdivides? _subdivide;
+
+ void beginSubdivide(final BenchmarkSubdivides phase) {
+ BenchmarkSubdivides? subdivide = _subdivide;
+ if (subdivide != null) throw "Can't subdivide a subdivide";
+ _subdivideStopwatch.reset();
+ _subdivide = phase;
+ }
+
+ void endSubdivide() {
+ BenchmarkSubdivides? subdivide = _subdivide;
+ if (subdivide == null) throw "Can't end a nonexistent subdivide";
+ _phaseTimings[_currentPhase.index]
+ .subdivides[subdivide.index]
+ .addRuntime(_subdivideStopwatch.elapsedMicroseconds);
+ _subdivide = null;
+ }
void enterPhase(BenchmarkPhases phase) {
if (_currentPhase == phase) return;
- _phaseTimings.add(
- new PhaseTiming(_currentPhase, _phaseStopwatch.elapsedMicroseconds));
+ if (_subdivide != null) throw "Can't enter a phase while in a subdivide";
+
+ _phaseTimings[_currentPhase.index]
+ .addRuntime(_phaseStopwatch.elapsedMicroseconds);
_phaseStopwatch.reset();
_currentPhase = phase;
}
@@ -22,7 +48,6 @@
}
Map<String, Object?> toJson() {
- // TODO: Merge unknown?
return <String, Object?>{
"totalTime": _totalStopwatch.elapsedMicroseconds,
"phases": _phaseTimings,
@@ -32,14 +57,48 @@
class PhaseTiming {
final BenchmarkPhases phase;
- final int runtime;
+ int _runtime = 0;
- PhaseTiming(this.phase, this.runtime);
+ final List<SubdivideTiming> subdivides = new List<SubdivideTiming>.generate(
+ BenchmarkSubdivides.values.length, (index) {
+ assert(BenchmarkSubdivides.values[index].index == index);
+ return new SubdivideTiming(BenchmarkSubdivides.values[index]);
+ }, growable: false);
+
+ PhaseTiming(this.phase);
+
+ void addRuntime(int runtime) {
+ _runtime += runtime;
+ }
+
+ Map<String, Object?> toJson() {
+ List<SubdivideTiming> enteredSubdivides =
+ subdivides.where((element) => element._count > 0).toList();
+ return <String, Object?>{
+ "phase": phase.name,
+ "runtime": _runtime,
+ if (enteredSubdivides.isNotEmpty) "subdivides": enteredSubdivides,
+ };
+ }
+}
+
+class SubdivideTiming {
+ final BenchmarkSubdivides phase;
+ int _runtime = 0;
+ int _count = 0;
+
+ SubdivideTiming(this.phase);
+
+ void addRuntime(int runtime) {
+ _runtime += runtime;
+ _count++;
+ }
Map<String, Object?> toJson() {
return <String, Object?>{
"phase": phase.name,
- "runtime": runtime,
+ "runtime": _runtime,
+ "count": _count,
};
}
}
@@ -93,7 +152,6 @@
body_buildBodies,
body_finishSynthesizedParameters,
-
body_finishDeferredLoadTearoffs,
body_finishNoSuchMethodForwarders,
body_collectSourceClasses,
@@ -108,8 +166,30 @@
printComponentText,
omitPlatform,
writeComponent,
+ benchmarkAstVisit,
// add more here
//
end,
unknown,
}
+
+enum BenchmarkSubdivides {
+ tokenize,
+
+ body_buildBody_benchmark_specific_diet_parser,
+ body_buildBody_benchmark_specific_parser,
+
+ inferConstructorParameterTypes,
+ inferDeclarationType,
+ inferExpression,
+ inferFieldInitializer,
+ inferFunctionBody,
+ inferInitializer,
+ inferMetadata,
+ inferMetadataKeepingHelper,
+ inferParameterInitializer,
+ inferInvocation,
+
+ buildOutlineExpressions,
+ delayedActionPerformer,
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 35ed1fa..a8921af 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -33,6 +33,7 @@
import 'package:_fe_analyzer_shared/src/scanner/token_impl.dart'
show isBinaryOperator, isMinusOperator, isUserDefinableOperator;
import 'package:_fe_analyzer_shared/src/util/link.dart';
+import 'package:front_end/src/fasta/kernel/benchmarker.dart' show Benchmarker;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/clone.dart';
@@ -178,6 +179,8 @@
final TypeInferrer typeInferrer;
+ final Benchmarker? benchmarker;
+
/// Only used when [member] is a constructor. It tracks if an implicit super
/// initializer is needed.
///
@@ -361,6 +364,7 @@
needsImplicitSuperInitializer =
declarationBuilder is SourceClassBuilder &&
coreTypes.objectClass != declarationBuilder.cls,
+ benchmarker = libraryBuilder.loader.target.benchmarker,
super(enclosingScope) {
formalParameterScope?.forEach((String name, Builder builder) {
if (builder is VariableBuilder) {
@@ -1777,6 +1781,7 @@
(index) =>
typeInferrer.inferInitializer(this, initializers[index]),
growable: false);
+
if (!builder.isExternal) {
for (int i = 0; i < initializers.length; i++) {
builder.addInitializer(initializers[i], this,
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index c81a969..554ec8f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -8,12 +8,11 @@
as macro;
import 'package:_fe_analyzer_shared/src/macros/executor/remote_instance.dart'
as macro;
-import 'package:front_end/src/base/common.dart';
import 'package:kernel/ast.dart' show DartType;
-import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/src/types.dart';
import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+import '../../base/common.dart';
import '../builder/builder.dart';
import '../builder/class_builder.dart';
import '../builder/formal_parameter_builder.dart';
@@ -31,6 +30,8 @@
import '../source/source_field_builder.dart';
import '../source/source_library_builder.dart';
import '../source/source_procedure_builder.dart';
+import 'hierarchy/hierarchy_builder.dart';
+import 'hierarchy/hierarchy_node.dart';
bool enableMacros = false;
@@ -171,8 +172,8 @@
return new MacroApplications(macroExecutor, libraryData, dataForTesting);
}
- Map<SourceClassBuilder, macro.ClassDeclaration> _classDeclarations = {};
- Map<macro.ClassDeclaration, SourceClassBuilder> _classBuilders = {};
+ Map<ClassBuilder, macro.ClassDeclaration> _classDeclarations = {};
+ Map<macro.ClassDeclaration, ClassBuilder> _classBuilders = {};
Map<MemberBuilder, macro.Declaration?> _memberDeclarations = {};
// TODO(johnniwinther): Support all members.
@@ -181,11 +182,11 @@
_createMemberDeclaration(memberBuilder);
}
- macro.ClassDeclaration _getClassDeclaration(SourceClassBuilder builder) {
+ macro.ClassDeclaration _getClassDeclaration(ClassBuilder builder) {
return _classDeclarations[builder] ??= _createClassDeclaration(builder);
}
- SourceClassBuilder _getClassBuilder(macro.ClassDeclaration declaration) {
+ ClassBuilder _getClassBuilder(macro.ClassDeclaration declaration) {
return _classBuilders[declaration]!;
}
@@ -407,11 +408,11 @@
late macro.TypeResolver typeResolver;
late macro.ClassIntrospector classIntrospector;
- Future<void> applyDeclarationsMacros(ClassHierarchyBase classHierarchy,
+ Future<void> applyDeclarationsMacros(ClassHierarchyBuilder classHierarchy,
Future<void> Function(SourceLibraryBuilder) onAugmentationLibrary) async {
types = new Types(classHierarchy);
typeResolver = new _TypeResolver(this);
- classIntrospector = new _ClassIntrospector(this);
+ classIntrospector = new _ClassIntrospector(this, classHierarchy);
for (_ApplicationData macroApplication in _applicationData) {
await _applyDeclarationsMacros(macroApplication, onAugmentationLibrary);
}
@@ -463,7 +464,7 @@
_applicationDataCache?.clear();
}
- macro.ClassDeclaration _createClassDeclaration(SourceClassBuilder builder) {
+ macro.ClassDeclaration _createClassDeclaration(ClassBuilder builder) {
macro.ClassDeclaration declaration = new macro.ClassDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new _IdentifierImpl.forTypeDeclarationBuilder(
@@ -873,8 +874,9 @@
class _ClassIntrospector implements macro.ClassIntrospector {
final MacroApplications macroApplications;
+ final ClassHierarchyBuilder classHierarchy;
- _ClassIntrospector(this.macroApplications);
+ _ClassIntrospector(this.macroApplications, this.classHierarchy);
@override
Future<List<macro.ConstructorDeclaration>> constructorsOf(
@@ -939,8 +941,19 @@
@override
Future<macro.ClassDeclaration?> superclassOf(macro.ClassDeclaration clazz) {
- // TODO: implement superclassOf
- throw new UnimplementedError('_ClassIntrospector.superclassOf');
+ ClassBuilder classBuilder = macroApplications._getClassBuilder(clazz);
+ ClassHierarchyNode node =
+ classHierarchy.getNodeFromClassBuilder(classBuilder);
+ ClassHierarchyNode? superNode = node.supernode;
+ while (superNode != null &&
+ superNode.classBuilder.isAnonymousMixinApplication) {
+ superNode = superNode.supernode;
+ }
+ if (superNode != null) {
+ return new Future.value(
+ macroApplications._getClassDeclaration(superNode.classBuilder));
+ }
+ return new Future.value();
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index c51ff0c..97f94e2 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -2358,7 +2358,7 @@
..argumentsBeginToken = argumentsBeginToken);
} else {
assert(enumConstantInfo is ParserRecovery);
- push(enumConstantInfo);
+ push(NullValue.EnumConstantInfo);
}
}
@@ -2400,6 +2400,26 @@
int elementsCount = pop() as int;
List<EnumConstantInfo?>? enumConstantInfos =
const FixedNullableList<EnumConstantInfo>().pop(stack, elementsCount);
+
+ if (enumConstantInfos != null) {
+ List<EnumConstantInfo?>? parsedEnumConstantInfos;
+ for (int index = 0; index < enumConstantInfos.length; index++) {
+ EnumConstantInfo? info = enumConstantInfos[index];
+ if (info == null) {
+ parsedEnumConstantInfos = enumConstantInfos.take(index).toList();
+ } else if (parsedEnumConstantInfos != null) {
+ parsedEnumConstantInfos.add(info);
+ }
+ }
+ if (parsedEnumConstantInfos != null) {
+ if (parsedEnumConstantInfos.isEmpty) {
+ enumConstantInfos = null;
+ } else {
+ enumConstantInfos = parsedEnumConstantInfos;
+ }
+ }
+ }
+
int endCharOffset = popCharOffset();
int startCharOffset = popCharOffset();
List<TypeBuilder>? interfaces = pop() as List<TypeBuilder>?;
diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index 03bae33..0f94bdb 100644
--- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -401,10 +401,9 @@
List<DartType>? typeArguments = redirectingFactoryBody.typeArguments;
Member? target = redirectingFactoryBody.target;
if (typeArguments != null && typeArguments.any((t) => t is UnknownType)) {
- TypeInferrerImpl inferrer = library.loader.typeInferenceEngine
- .createLocalTypeInferrer(
- fileUri, classBuilder!.thisType, library, null)
- as TypeInferrerImpl;
+ TypeInferrer inferrer = library.loader.typeInferenceEngine
+ .createLocalTypeInferrer(
+ fileUri, classBuilder!.thisType, library, null);
inferrer.helper = library.loader.createBodyBuilderForOutlineExpression(
library, classBuilder, this, classBuilder!.scope, fileUri);
Builder? targetBuilder = redirectionTarget.target;
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 3df221f..10654aa 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -95,7 +95,7 @@
import '../operator.dart';
import '../problems.dart' show unexpected, unhandled;
import '../scope.dart';
-import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
+import '../type_inference/type_inferrer.dart' show TypeInferrer;
import '../util/helpers.dart';
import 'name_scheme.dart';
import 'source_class_builder.dart' show SourceClassBuilder;
@@ -4427,7 +4427,7 @@
DartType receiverType,
TypeEnvironment typeEnvironment,
ClassHierarchy hierarchy,
- TypeInferrerImpl typeInferrer,
+ TypeInferrer typeInferrer,
Name name,
Member? interfaceTarget,
Arguments arguments,
@@ -4504,7 +4504,7 @@
void checkBoundsInFunctionInvocation(
TypeEnvironment typeEnvironment,
ClassHierarchy hierarchy,
- TypeInferrerImpl typeInferrer,
+ TypeInferrer typeInferrer,
FunctionType functionType,
String? localName,
Arguments arguments,
@@ -4539,7 +4539,7 @@
void checkBoundsInInstantiation(
TypeEnvironment typeEnvironment,
ClassHierarchy hierarchy,
- TypeInferrerImpl typeInferrer,
+ TypeInferrer typeInferrer,
FunctionType functionType,
List<DartType> typeArguments,
Uri fileUri,
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index cd4c326..2dfbd15 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -8,6 +8,9 @@
import 'dart:convert' show utf8;
import 'dart:typed_data' show Uint8List;
+import 'package:_fe_analyzer_shared/src/parser/forwarding_listener.dart'
+ show ForwardingListener;
+
import 'package:_fe_analyzer_shared/src/macros/executor.dart'
show MacroExecutor;
import 'package:_fe_analyzer_shared/src/parser/class_member_parser.dart'
@@ -23,6 +26,8 @@
ScannerResult,
Token,
scan;
+import 'package:front_end/src/fasta/kernel/benchmarker.dart'
+ show BenchmarkSubdivides;
import 'package:front_end/src/fasta/source/source_type_alias_builder.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart'
@@ -805,6 +810,7 @@
Future<Token> tokenize(SourceLibraryBuilder library,
{bool suppressLexicalErrors: false}) async {
+ target.benchmarker?.beginSubdivide(BenchmarkSubdivides.tokenize);
Uri fileUri = library.fileUri;
// Lookup the file URI in the cache.
@@ -818,6 +824,7 @@
library.addProblemAtAccessors(message);
bytes = synthesizeSourceForMissingFile(library.importUri, null);
} else if (!fileUri.hasScheme) {
+ target.benchmarker?.endSubdivide();
return internalProblem(
templateInternalProblemUriMissingScheme.withArguments(fileUri),
-1,
@@ -912,6 +919,7 @@
}
token = token.next!;
}
+ target.benchmarker?.endSubdivide();
return token;
}
@@ -1114,7 +1122,30 @@
// time we suppress lexical errors.
Token tokens = await tokenize(library, suppressLexicalErrors: true);
// ignore: unnecessary_null_comparison
- if (tokens == null) return;
+ if (tokens == null) {
+ return;
+ }
+
+ if (target.benchmarker != null) {
+ // When benchmarking we do extra parsing on it's own to get a timing of
+ // how much time is spent on the actual parsing (as opposed to the
+ // building of what's parsed).
+ {
+ target.benchmarker?.beginSubdivide(
+ BenchmarkSubdivides.body_buildBody_benchmark_specific_diet_parser);
+ DietParser parser = new DietParser(new ForwardingListener());
+ parser.parseUnit(tokens);
+ target.benchmarker?.endSubdivide();
+ }
+ {
+ target.benchmarker?.beginSubdivide(
+ BenchmarkSubdivides.body_buildBody_benchmark_specific_parser);
+ Parser parser = new Parser(new ForwardingListener());
+ parser.parseUnit(tokens);
+ target.benchmarker?.endSubdivide();
+ }
+ }
+
DietListener listener = createDietListener(library);
DietParser parser = new DietParser(listener);
parser.parseUnit(tokens);
@@ -2155,10 +2186,14 @@
library.buildOutlineExpressions(
classHierarchy, synthesizedFunctionNodes, delayedActionPerformers);
}
+
+ target.benchmarker
+ ?.beginSubdivide(BenchmarkSubdivides.delayedActionPerformer);
for (DelayedActionPerformer delayedActionPerformer
in delayedActionPerformers) {
delayedActionPerformer.performDelayedActions();
}
+ target.benchmarker?.endSubdivide();
ticker.logMs("Build outline expressions");
}
@@ -2179,7 +2214,8 @@
}
void createTypeInferenceEngine() {
- _typeInferenceEngine = new TypeInferenceEngineImpl(instrumentation);
+ _typeInferenceEngine =
+ new TypeInferenceEngineImpl(instrumentation, target.benchmarker);
}
void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index fcc9c8e..d4ffcab 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -9,6 +9,7 @@
import 'package:kernel/type_environment.dart';
import '../../base/instrumentation.dart' show Instrumentation;
+import '../kernel/benchmarker.dart' show Benchmarker;
import '../kernel/forest.dart';
import '../kernel/hierarchy/hierarchy_builder.dart' show ClassHierarchyBuilder;
import '../kernel/hierarchy/members_builder.dart' show ClassMembersBuilder;
@@ -176,7 +177,9 @@
/// Concrete implementation of [TypeInferenceEngine] specialized to work with
/// kernel objects.
class TypeInferenceEngineImpl extends TypeInferenceEngine {
- TypeInferenceEngineImpl(Instrumentation? instrumentation)
+ final Benchmarker? benchmarker;
+
+ TypeInferenceEngineImpl(Instrumentation? instrumentation, this.benchmarker)
: super(instrumentation);
@override
@@ -190,8 +193,12 @@
assignedVariables =
new AssignedVariables<TreeNode, VariableDeclaration>();
}
- return new TypeInferrerImpl(
- this, uri, false, thisType, library, assignedVariables, dataForTesting);
+ if (benchmarker == null) {
+ return new TypeInferrerImpl(this, uri, false, thisType, library,
+ assignedVariables, dataForTesting);
+ }
+ return new TypeInferrerImplBenchmarked(this, uri, false, thisType, library,
+ assignedVariables, dataForTesting, benchmarker!);
}
@override
@@ -205,8 +212,12 @@
assignedVariables =
new AssignedVariables<TreeNode, VariableDeclaration>();
}
- return new TypeInferrerImpl(
- this, uri, true, thisType, library, assignedVariables, dataForTesting);
+ if (benchmarker == null) {
+ return new TypeInferrerImpl(this, uri, true, thisType, library,
+ assignedVariables, dataForTesting);
+ }
+ return new TypeInferrerImplBenchmarked(this, uri, true, thisType, library,
+ assignedVariables, dataForTesting, benchmarker!);
}
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 5f7680b..14e18d1 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -27,6 +27,7 @@
import '../builder/extension_builder.dart';
import '../builder/member_builder.dart';
import '../fasta_codes.dart';
+import '../kernel/benchmarker.dart' show BenchmarkSubdivides, Benchmarker;
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/hierarchy/class_member.dart' show ClassMember;
import '../kernel/inference_visitor.dart';
@@ -115,6 +116,8 @@
AssignedVariables<TreeNode, VariableDeclaration> get assignedVariables;
+ InferenceHelper? helper;
+
/// Performs full type inference on the given field initializer.
ExpressionInferenceResult inferFieldInitializer(
InferenceHelper helper, DartType declaredType, Expression initializer);
@@ -158,6 +161,19 @@
// TODO(johnniwinther): We are still parameters on synthesized mixin
// application constructors.
void inferConstructorParameterTypes(Constructor constructor);
+
+ InvocationInferenceResult inferInvocation(DartType typeContext, int offset,
+ FunctionType calleeType, ArgumentsImpl arguments,
+ {List<VariableDeclaration>? hoistedExpressions,
+ bool isSpecialCasedBinaryOperator: false,
+ bool isSpecialCasedTernaryOperator: false,
+ DartType? receiverType,
+ bool skipTypeArgumentInference: false,
+ bool isConst: false,
+ bool isImplicitExtensionMember: false,
+ bool isImplicitCall: false,
+ Member? staticTarget,
+ bool isExtensionMemberInvocation = false});
}
/// Concrete implementation of [TypeInferrer] specialized to work with kernel
@@ -207,6 +223,7 @@
@override
final SourceLibraryBuilder library;
+ @override
InferenceHelper? helper;
/// Context information for the current closure, or `null` if we are not
@@ -2033,16 +2050,16 @@
@override
ExpressionInferenceResult inferFieldInitializer(
InferenceHelper helper,
- DartType context,
+ DartType declaredType,
Expression initializer,
) {
assert(closureContext == null);
assert(!isTopLevel);
this.helper = helper;
ExpressionInferenceResult initializerResult =
- inferExpression(initializer, context, true, isVoidAllowed: true);
- initializer = ensureAssignableResult(context, initializerResult,
- isVoidAllowed: context is VoidType);
+ inferExpression(initializer, declaredType, true, isVoidAllowed: true);
+ initializer = ensureAssignableResult(declaredType, initializerResult,
+ isVoidAllowed: declaredType is VoidType);
this.helper = null;
return new ExpressionInferenceResult(
initializerResult.inferredType, initializer);
@@ -2079,6 +2096,7 @@
result.hasChanged ? result.statement : body, futureValueType);
}
+ @override
InvocationInferenceResult inferInvocation(DartType typeContext, int offset,
FunctionType calleeType, ArgumentsImpl arguments,
{List<VariableDeclaration>? hoistedExpressions,
@@ -4641,6 +4659,167 @@
}
}
+class TypeInferrerImplBenchmarked implements TypeInferrer {
+ final TypeInferrerImpl impl;
+ final Benchmarker benchmarker;
+
+ TypeInferrerImplBenchmarked(
+ TypeInferenceEngine engine,
+ Uri uriForInstrumentation,
+ bool topLevel,
+ InterfaceType? thisType,
+ SourceLibraryBuilder library,
+ AssignedVariables<TreeNode, VariableDeclaration> assignedVariables,
+ InferenceDataForTesting? dataForTesting,
+ this.benchmarker)
+ : impl = new TypeInferrerImpl(engine, uriForInstrumentation, topLevel,
+ thisType, library, assignedVariables, dataForTesting);
+
+ @override
+ AssignedVariables<TreeNode, VariableDeclaration> get assignedVariables =>
+ impl.assignedVariables;
+
+ @override
+ FlowAnalysis<TreeNode, Statement, Expression, VariableDeclaration, DartType>
+ get flowAnalysis => impl.flowAnalysis;
+
+ @override
+ SourceLibraryBuilder get library => impl.library;
+
+ @override
+ TypeSchemaEnvironment get typeSchemaEnvironment => impl.typeSchemaEnvironment;
+
+ @override
+ Uri get uriForInstrumentation => impl.uriForInstrumentation;
+
+ @override
+ void inferConstructorParameterTypes(Constructor constructor) {
+ benchmarker
+ .beginSubdivide(BenchmarkSubdivides.inferConstructorParameterTypes);
+ impl.inferConstructorParameterTypes(constructor);
+ benchmarker.endSubdivide();
+ }
+
+ @override
+ DartType inferDeclarationType(DartType initializerType) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferDeclarationType);
+ DartType result = impl.inferDeclarationType(initializerType);
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ ExpressionInferenceResult inferExpression(
+ Expression expression, DartType typeContext, bool typeNeeded,
+ {bool isVoidAllowed = false, bool forEffect = false}) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferExpression);
+ ExpressionInferenceResult result = impl.inferExpression(
+ expression, typeContext, typeNeeded,
+ isVoidAllowed: isVoidAllowed, forEffect: forEffect);
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ ExpressionInferenceResult inferFieldInitializer(
+ InferenceHelper helper, DartType declaredType, Expression initializer) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferFieldInitializer);
+ ExpressionInferenceResult result =
+ impl.inferFieldInitializer(helper, declaredType, initializer);
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ InferredFunctionBody inferFunctionBody(InferenceHelper helper, int fileOffset,
+ DartType returnType, AsyncMarker asyncMarker, Statement body) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferFunctionBody);
+ InferredFunctionBody result = impl.inferFunctionBody(
+ helper, fileOffset, returnType, asyncMarker, body);
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ InitializerInferenceResult inferInitializer(
+ InferenceHelper helper, Initializer initializer) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferInitializer);
+ InitializerInferenceResult result =
+ impl.inferInitializer(helper, initializer);
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ void inferMetadata(
+ InferenceHelper helper, TreeNode? parent, List<Expression>? annotations) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferMetadata);
+ impl.inferMetadata(helper, parent, annotations);
+ benchmarker.endSubdivide();
+ }
+
+ @override
+ void inferMetadataKeepingHelper(
+ TreeNode parent, List<Expression> annotations) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferMetadataKeepingHelper);
+ impl.inferMetadataKeepingHelper(parent, annotations);
+ benchmarker.endSubdivide();
+ }
+
+ @override
+ Expression inferParameterInitializer(
+ InferenceHelper helper,
+ Expression initializer,
+ DartType declaredType,
+ bool hasDeclaredInitializer) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferParameterInitializer);
+ Expression result = impl.inferParameterInitializer(
+ helper, initializer, declaredType, hasDeclaredInitializer);
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ InvocationInferenceResult inferInvocation(DartType typeContext, int offset,
+ FunctionType calleeType, ArgumentsImpl arguments,
+ {List<VariableDeclaration>? hoistedExpressions,
+ bool isSpecialCasedBinaryOperator = false,
+ bool isSpecialCasedTernaryOperator = false,
+ DartType? receiverType,
+ bool skipTypeArgumentInference = false,
+ bool isConst = false,
+ bool isImplicitExtensionMember = false,
+ bool isImplicitCall = false,
+ Member? staticTarget,
+ bool isExtensionMemberInvocation = false}) {
+ benchmarker.beginSubdivide(BenchmarkSubdivides.inferInvocation);
+ InvocationInferenceResult result = impl.inferInvocation(
+ typeContext,
+ offset,
+ calleeType,
+ arguments,
+ hoistedExpressions: hoistedExpressions,
+ isSpecialCasedBinaryOperator: isSpecialCasedBinaryOperator,
+ isSpecialCasedTernaryOperator: isSpecialCasedTernaryOperator,
+ receiverType: receiverType,
+ skipTypeArgumentInference: skipTypeArgumentInference,
+ isConst: isConst,
+ isImplicitExtensionMember: isImplicitExtensionMember,
+ isImplicitCall: isImplicitCall,
+ staticTarget: staticTarget,
+ isExtensionMemberInvocation: isExtensionMemberInvocation,
+ );
+ benchmarker.endSubdivide();
+ return result;
+ }
+
+ @override
+ InferenceHelper? get helper => impl.helper;
+
+ @override
+ void set helper(InferenceHelper? helper) => impl.helper = helper;
+}
+
abstract class MixinInferrer {
final CoreTypes coreTypes;
final TypeConstraintGatherer gatherer;
diff --git a/pkg/front_end/test/fasta/expression_suite.dart b/pkg/front_end/test/fasta/expression_suite.dart
index 8e867b7..47c08bb 100644
--- a/pkg/front_end/test/fasta/expression_suite.dart
+++ b/pkg/front_end/test/fasta/expression_suite.dart
@@ -37,6 +37,9 @@
import 'package:front_end/src/fasta/incremental_compiler.dart'
show IncrementalCompiler;
+import 'package:front_end/src/fasta/kernel/utils.dart'
+ show serializeComponent, serializeProcedure;
+
import "package:kernel/ast.dart"
show
Class,
@@ -63,9 +66,6 @@
import "package:yaml/yaml.dart" show YamlMap, YamlList, loadYamlNode;
-import '../../lib/src/fasta/kernel/utils.dart'
- show serializeComponent, serializeProcedure;
-
import '../utils/kernel_chain.dart' show runDiff, openWrite;
class Context extends ChainContext {
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 9db87a4..c35e622 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -119,7 +119,7 @@
new TypeParameter("T"), libraryBuilder);
VariableDeclaration variable = new VariableDeclaration(null);
- TypeInferenceEngineImpl engine = new TypeInferenceEngineImpl(null);
+ TypeInferenceEngineImpl engine = new TypeInferenceEngineImpl(null, null);
engine.prepareTopLevel(coreTypes, hierarchy);
BodyBuilder helper = new BodyBuilder(
diff --git a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
index d1a5810..ad78c6f 100644
--- a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
+++ b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
@@ -308,7 +308,8 @@
Iterable<FieldDeclaration> fields = await builder.fieldsOf(clazz);
List<Object> parts = ['''
toString() {
- return "${clazz.identifier.name}('''];
+ return "${clazz.identifier.name}('''
+ ];
String comma = '';
for (FieldDeclaration field in fields) {
parts.add(comma);
@@ -316,8 +317,8 @@
parts.add(field.identifier.name);
parts.add('}');
comma = ',';
- }
- parts.add(''')";
+ }
+ parts.add(''')";
}''');
builder.declareInClass(new DeclarationCode.fromParts(parts));
}
@@ -325,11 +326,12 @@
}
macro
+
class SequenceMacro implements ClassDeclarationsMacro {
const SequenceMacro();
- FutureOr<void> buildDeclarationsForClass(
- ClassDeclaration clazz, ClassMemberDeclarationBuilder builder) async {
+ FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
+ ClassMemberDeclarationBuilder builder) async {
Iterable<MethodDeclaration> methods = await builder.methodsOf(clazz);
int index = 0;
String suffix = '';
@@ -340,4 +342,22 @@
builder.declareInClass(new DeclarationCode.fromString('''
method$suffix() {}'''));
}
+}
+
+macro
+
+class SupertypesMacro implements ClassDefinitionMacro {
+ const SupertypesMacro();
+
+ FutureOr<void> buildDefinitionForClass(ClassDeclaration clazz,
+ ClassDefinitionBuilder builder) async {
+ ClassDeclaration? superClass = await builder.superclassOf(clazz);
+ FunctionDefinitionBuilder getSuperClassBuilder = await builder.buildMethod(
+ (await builder.methodsOf(clazz))
+ .firstWhere((m) => m.identifier.name == 'getSuperClass')
+ .identifier);
+ getSuperClassBuilder.augment(new FunctionBodyCode.fromString('''{
+ return "${superClass?.identifier.name}";
+ }'''));
+ }
}
\ No newline at end of file
diff --git a/pkg/front_end/test/macro_application/data/tests/supertypes.dart b/pkg/front_end/test/macro_application/data/tests/supertypes.dart
new file mode 100644
index 0000000..5690609
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/supertypes.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library:
+
+
+*/
+
+import 'package:macro/macro.dart';
+
+/*class: A:
+augment class A {
+augment String getSuperClass() {
+ return "Object";
+ }
+}*/
+@SupertypesMacro()
+class A {
+ external String getSuperClass();
+}
+
+/*class: B:
+augment class B {
+augment String getSuperClass() {
+ return "A";
+ }
+}*/
+@SupertypesMacro()
+class B extends A {
+ external String getSuperClass();
+}
+
+/*class: M:
+augment class M {
+augment String getSuperClass() {
+ return "Object";
+ }
+}*/
+@SupertypesMacro()
+mixin M {
+ external String getSuperClass();
+}
+
+/*class: C:
+augment class C {
+augment String getSuperClass() {
+ return "A";
+ }
+}*/
+@SupertypesMacro()
+class C extends A with M {
+ external String getSuperClass();
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/supertypes.dart.expect b/pkg/front_end/test/macro_application/data/tests/supertypes.dart.expect
new file mode 100644
index 0000000..3351c329
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/supertypes.dart.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "package:macro/macro.dart" as mac;
+import "dart:core" as core;
+
+import "package:macro/macro.dart";
+
+@#C1
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ external method getSuperClass() → core::String;
+}
+@#C1
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ external method getSuperClass() → core::String;
+}
+@#C1
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ external method getSuperClass() → core::String;
+}
+abstract class _C&A&M = self::A with self::M /*isAnonymousMixin*/ {
+ synthetic constructor •() → self::_C&A&M
+ : super self::A::•()
+ ;
+ mixin-super-stub method getSuperClass() → core::String
+ return super.{self::M::getSuperClass}();
+}
+@#C1
+class C extends self::_C&A&M {
+ synthetic constructor •() → self::C
+ : super self::_C&A&M::•()
+ ;
+ external method getSuperClass() → core::String;
+}
+
+constants {
+ #C1 = mac::SupertypesMacro {}
+}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 5669280..ce825bb 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -107,7 +107,9 @@
belonging
beloning
benchmark
+benchmarked
benchmarker
+benchmarking
benchmarks
bf
bi
@@ -799,6 +801,7 @@
nnbd
node's
nominality
+nonexistent
nonimplementation
norm
normalization
@@ -1184,6 +1187,7 @@
specifics
speeding
spend
+spent
spuriously
sq
sra
@@ -1224,6 +1228,9 @@
stubs
stx
sub
+subdivide
+subdivided
+subdivides
subexpression
subexpression's
subexpressions
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart
new file mode 100644
index 0000000..cfe7ef0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+enum E {
+ element, // The declaration of the element is correct.
+
+ final String foo = "foo"; // Error: attempt to parse the field as an element.
+}
+
+test() {
+ return E.element; // No error: the element is added to the enum.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.strong.expect
new file mode 100644
index 0000000..a8b2f34
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.strong.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected an identifier, but got 'final'.
+// Try inserting an identifier before 'final'.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected '}' before this.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E element = #C3;
+ const constructor •(core::int index, core::String name) → self::E
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ return #C3;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///recovery_in_elements.dart:
+- E. (from org-dartlang-testcase:///recovery_in_elements.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.strong.transformed.expect
new file mode 100644
index 0000000..a8b2f34
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected an identifier, but got 'final'.
+// Try inserting an identifier before 'final'.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected '}' before this.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E element = #C3;
+ const constructor •(core::int index, core::String name) → self::E
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ return #C3;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///recovery_in_elements.dart:
+- E. (from org-dartlang-testcase:///recovery_in_elements.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.textual_outline.expect
new file mode 100644
index 0000000..da5979b
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+enum E { element, final String foo = "foo"; }
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.expect
new file mode 100644
index 0000000..f5d37c6
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected an identifier, but got 'final'.
+// Try inserting an identifier before 'final'.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected '}' before this.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E element = #C3;
+ const constructor •(core::int index, core::String name) → self::E
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ return #C3;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E*>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///recovery_in_elements.dart:
+- E. (from org-dartlang-testcase:///recovery_in_elements.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.modular.expect
new file mode 100644
index 0000000..f5d37c6
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.modular.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected an identifier, but got 'final'.
+// Try inserting an identifier before 'final'.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected '}' before this.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E element = #C3;
+ const constructor •(core::int index, core::String name) → self::E
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ return #C3;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E*>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///recovery_in_elements.dart:
+- E. (from org-dartlang-testcase:///recovery_in_elements.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.outline.expect
new file mode 100644
index 0000000..55b1431
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.outline.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected an identifier, but got 'final'.
+// Try inserting an identifier before 'final'.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected '}' before this.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = const <self::E>[self::E::element];
+ static const field self::E element = const self::E::•(0, "element");
+ const constructor •(core::int index, core::String name) → self::E
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///recovery_in_elements.dart:5:6 -> ListConstant(const <E*>[const E{_Enum.index: 0, _Enum._name: "element"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///recovery_in_elements.dart:6:3 -> InstanceConstant(const E{_Enum.index: 0, _Enum._name: "element"})
+Extra constant evaluation: evaluated: 7, effectively constant: 2
diff --git a/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.transformed.expect
new file mode 100644
index 0000000..f5d37c6
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart.weak.transformed.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected an identifier, but got 'final'.
+// Try inserting an identifier before 'final'.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+// pkg/front_end/testcases/enhanced_enums/recovery_in_elements.dart:8:3: Error: Expected '}' before this.
+// final String foo = "foo"; // Error: attempt to parse the field as an element.
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E element = #C3;
+ const constructor •(core::int index, core::String name) → self::E
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ return #C3;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E*>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///recovery_in_elements.dart:
+- E. (from org-dartlang-testcase:///recovery_in_elements.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 5382eb0..248e387 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -44,6 +44,7 @@
enhanced_enums/named_arguments: FormatterCrash
enhanced_enums/named_arguments_anywhere/redirecting_constructor: FormatterCrash
enhanced_enums/qualified_names_with_no_type_arguments: FormatterCrash
+enhanced_enums/recovery_in_elements: FormatterCrash
enhanced_enums/redirecting_initializers: FormatterCrash
enhanced_enums/simple_fields: FormatterCrash
enhanced_enums/simple_interfaces: FormatterCrash
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index adc8826..05a3d5d 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -22,7 +22,13 @@
show BenchmarkPhases, Benchmarker;
import 'package:kernel/kernel.dart'
- show CanonicalName, Library, Component, Source, loadComponentFromBytes;
+ show
+ CanonicalName,
+ Component,
+ Library,
+ RecursiveVisitor,
+ Source,
+ loadComponentFromBytes;
import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
@@ -476,11 +482,21 @@
await writeComponentToFile(component, uri);
ticker.logMs("Wrote component to ${uri.toFilePath()}");
}
+ if (benchmarker != null) {
+ // When benchmarking also do a recursive visit of the produced component
+ // that does nothing other than visiting everything. Do this to produce
+ // a reference point for comparing inference time and serialization time.
+ benchmarker.enterPhase(BenchmarkPhases.benchmarkAstVisit);
+ Component component = buildResult.component!;
+ component.accept(new EmptyRecursiveVisitorForBenchmarking());
+ }
benchmarker?.enterPhase(BenchmarkPhases.unknown);
return uri;
}
}
+class EmptyRecursiveVisitorForBenchmarking extends RecursiveVisitor {}
+
/// Load the [Component] from the given [uri] and append its libraries
/// to the [dillTarget].
Component _appendDillForUri(DillTarget dillTarget, Uri uri) {
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index 9523ad8..df48df4 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -92,6 +92,25 @@
return Api::UnwrapHandle(result);
}
+InstructionsPtr BuildInstructions(
+ std::function<void(compiler::Assembler* assembler)> fun) {
+ auto thread = Thread::Current();
+ compiler::Assembler assembler(nullptr);
+
+ fun(&assembler);
+
+ auto& code = Code::Handle();
+ auto install_code_fun = [&] {
+ code = Code::FinalizeCode(nullptr, &assembler,
+ Code::PoolAttachment::kNotAttachPool,
+ /*optimized=*/false, /*stats=*/nullptr);
+ };
+ SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+ thread->isolate_group()->RunWithStoppedMutators(install_code_fun,
+ /*use_force_growth=*/true);
+ return code.instructions();
+}
+
FlowGraph* TestPipeline::RunPasses(
std::initializer_list<CompilerPass::Id> passes) {
auto thread = Thread::Current();
@@ -144,11 +163,29 @@
} else {
flow_graph_ = CompilerPass::RunPipeline(mode_, pass_state_);
}
+ pass_state_->call_specializer = nullptr;
}
return flow_graph_;
}
+void TestPipeline::RunAdditionalPasses(
+ std::initializer_list<CompilerPass::Id> passes) {
+ SpeculativeInliningPolicy speculative_policy(/*enable_suppression=*/false);
+
+ JitCallSpecializer jit_call_specializer(flow_graph_, &speculative_policy);
+ AotCallSpecializer aot_call_specializer(/*precompiler=*/nullptr, flow_graph_,
+ &speculative_policy);
+ if (mode_ == CompilerPass::kAOT) {
+ pass_state_->call_specializer = &aot_call_specializer;
+ } else {
+ pass_state_->call_specializer = &jit_call_specializer;
+ }
+
+ flow_graph_ = CompilerPass::RunPipelineWithPasses(pass_state_, passes);
+ pass_state_->call_specializer = nullptr;
+}
+
void TestPipeline::CompileGraphAndAttachFunction() {
Zone* zone = thread_->zone();
const bool optimized = true;
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 73f32bf..babe427 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -65,6 +65,9 @@
ObjectPtr Invoke(const Library& lib, const char* name);
+InstructionsPtr BuildInstructions(
+ std::function<void(compiler::Assembler* assembler)> fun);
+
class TestPipeline : public ValueObject {
public:
explicit TestPipeline(const Function& function,
@@ -86,6 +89,8 @@
// - [flow_graph_]
FlowGraph* RunPasses(std::initializer_list<CompilerPass::Id> passes);
+ void RunAdditionalPasses(std::initializer_list<CompilerPass::Id> passes);
+
void CompileGraphAndAttachFunction();
private:
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 6fd0db2..4ebaff1 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -791,6 +791,39 @@
return body;
}
+#define LOAD_NATIVE_FIELD(V) \
+ V(ByteDataViewLength, TypedDataBase_length) \
+ V(ByteDataViewOffsetInBytes, TypedDataView_offset_in_bytes) \
+ V(ByteDataViewTypedData, TypedDataView_typed_data) \
+ V(GrowableArrayLength, GrowableObjectArray_length) \
+ V(ImmutableArrayLength, Array_length) \
+ V(ImmutableLinkedHashBase_getData, ImmutableLinkedHashBase_data) \
+ V(ImmutableLinkedHashBase_getIndex, ImmutableLinkedHashBase_index) \
+ V(LinkedHashBase_getData, LinkedHashBase_data) \
+ V(LinkedHashBase_getDeletedKeys, LinkedHashBase_deleted_keys) \
+ V(LinkedHashBase_getHashMask, LinkedHashBase_hash_mask) \
+ V(LinkedHashBase_getIndex, LinkedHashBase_index) \
+ V(LinkedHashBase_getUsedData, LinkedHashBase_used_data) \
+ V(ObjectArrayLength, Array_length) \
+ V(TypedDataViewOffsetInBytes, TypedDataView_offset_in_bytes) \
+ V(TypedDataViewTypedData, TypedDataView_typed_data) \
+ V(TypedListBaseLength, TypedDataBase_length) \
+ V(WeakProperty_getKey, WeakProperty_key) \
+ V(WeakProperty_getValue, WeakProperty_value) \
+ V(WeakReference_getTarget, WeakReference_target)
+
+#define STORE_NATIVE_FIELD(V) \
+ V(LinkedHashBase_setData, LinkedHashBase_data) \
+ V(LinkedHashBase_setIndex, LinkedHashBase_index) \
+ V(WeakProperty_setKey, WeakProperty_key) \
+ V(WeakProperty_setValue, WeakProperty_value) \
+ V(WeakReference_setTarget, WeakReference_target)
+
+#define STORE_NATIVE_FIELD_NO_BARRIER(V) \
+ V(LinkedHashBase_setDeletedKeys, LinkedHashBase_deleted_keys) \
+ V(LinkedHashBase_setHashMask, LinkedHashBase_hash_mask) \
+ V(LinkedHashBase_setUsedData, LinkedHashBase_used_data)
+
bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph(
const Function& function) {
const MethodRecognizer::Kind kind = function.recognized_kind();
@@ -867,44 +900,22 @@
case MethodRecognizer::kObjectEquals:
case MethodRecognizer::kStringBaseLength:
case MethodRecognizer::kStringBaseIsEmpty:
- case MethodRecognizer::kGrowableArrayLength:
- case MethodRecognizer::kObjectArrayLength:
- case MethodRecognizer::kImmutableArrayLength:
- case MethodRecognizer::kTypedListBaseLength:
- case MethodRecognizer::kByteDataViewLength:
- case MethodRecognizer::kByteDataViewOffsetInBytes:
- case MethodRecognizer::kTypedDataViewOffsetInBytes:
- case MethodRecognizer::kByteDataViewTypedData:
- case MethodRecognizer::kTypedDataViewTypedData:
case MethodRecognizer::kClassIDgetID:
case MethodRecognizer::kGrowableArrayAllocateWithData:
case MethodRecognizer::kGrowableArrayCapacity:
case MethodRecognizer::kListFactory:
case MethodRecognizer::kObjectArrayAllocate:
case MethodRecognizer::kCopyRangeFromUint8ListToOneByteString:
- case MethodRecognizer::kLinkedHashBase_getIndex:
- case MethodRecognizer::kLinkedHashBase_setIndex:
- case MethodRecognizer::kLinkedHashBase_getData:
- case MethodRecognizer::kLinkedHashBase_setData:
- case MethodRecognizer::kLinkedHashBase_getHashMask:
- case MethodRecognizer::kLinkedHashBase_setHashMask:
- case MethodRecognizer::kLinkedHashBase_getUsedData:
- case MethodRecognizer::kLinkedHashBase_setUsedData:
- case MethodRecognizer::kLinkedHashBase_getDeletedKeys:
- case MethodRecognizer::kLinkedHashBase_setDeletedKeys:
- case MethodRecognizer::kImmutableLinkedHashBase_getData:
- case MethodRecognizer::kImmutableLinkedHashBase_getIndex:
case MethodRecognizer::kImmutableLinkedHashBase_setIndexStoreRelease:
- case MethodRecognizer::kWeakProperty_getKey:
- case MethodRecognizer::kWeakProperty_setKey:
- case MethodRecognizer::kWeakProperty_getValue:
- case MethodRecognizer::kWeakProperty_setValue:
- case MethodRecognizer::kWeakReference_getTarget:
- case MethodRecognizer::kWeakReference_setTarget:
case MethodRecognizer::kFfiAbi:
case MethodRecognizer::kReachabilityFence:
case MethodRecognizer::kUtf8DecoderScan:
case MethodRecognizer::kHas63BitSmis:
+#define CASE(method, slot) case MethodRecognizer::k##method:
+ LOAD_NATIVE_FIELD(CASE)
+ STORE_NATIVE_FIELD(CASE)
+ STORE_NATIVE_FIELD_NO_BARRIER(CASE)
+#undef CASE
return true;
case MethodRecognizer::kDoubleToInteger:
case MethodRecognizer::kDoubleMod:
@@ -1091,35 +1102,6 @@
body += StrictCompare(Token::kEQ_STRICT);
}
break;
- case MethodRecognizer::kGrowableArrayLength:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::GrowableObjectArray_length());
- break;
- case MethodRecognizer::kObjectArrayLength:
- case MethodRecognizer::kImmutableArrayLength:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::Array_length());
- break;
- case MethodRecognizer::kTypedListBaseLength:
- case MethodRecognizer::kByteDataViewLength:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::TypedDataBase_length());
- break;
- case MethodRecognizer::kByteDataViewOffsetInBytes:
- case MethodRecognizer::kTypedDataViewOffsetInBytes:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::TypedDataView_offset_in_bytes());
- break;
- case MethodRecognizer::kByteDataViewTypedData:
- case MethodRecognizer::kTypedDataViewTypedData:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::TypedDataView_typed_data());
- break;
case MethodRecognizer::kClassIDgetID:
ASSERT_EQUAL(function.NumParameters(), 1);
body += LoadLocal(parsed_function_->RawParameterVariable(0));
@@ -1230,23 +1212,6 @@
body += MemoryCopy(kTypedDataUint8ArrayCid, kOneByteStringCid);
body += NullConstant();
break;
- case MethodRecognizer::kLinkedHashBase_getIndex:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::LinkedHashBase_index());
- break;
- case MethodRecognizer::kImmutableLinkedHashBase_getIndex:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::ImmutableLinkedHashBase_index());
- break;
- case MethodRecognizer::kLinkedHashBase_setIndex:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::LinkedHashBase_index());
- body += NullConstant();
- break;
case MethodRecognizer::kImmutableLinkedHashBase_setIndexStoreRelease:
ASSERT_EQUAL(function.NumParameters(), 2);
body += LoadLocal(parsed_function_->RawParameterVariable(0));
@@ -1259,101 +1224,6 @@
kEmitStoreBarrier, compiler::Assembler::kRelease);
body += NullConstant();
break;
- case MethodRecognizer::kLinkedHashBase_getData:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::LinkedHashBase_data());
- break;
- case MethodRecognizer::kImmutableLinkedHashBase_getData:
- ASSERT(function.NumParameters() == 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::ImmutableLinkedHashBase_data());
- break;
- case MethodRecognizer::kLinkedHashBase_setData:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::LinkedHashBase_data());
- body += NullConstant();
- break;
- case MethodRecognizer::kLinkedHashBase_getHashMask:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::LinkedHashBase_hash_mask());
- break;
- case MethodRecognizer::kLinkedHashBase_setHashMask:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::LinkedHashBase_hash_mask(),
- StoreInstanceFieldInstr::Kind::kOther,
- kNoStoreBarrier);
- body += NullConstant();
- break;
- case MethodRecognizer::kLinkedHashBase_getUsedData:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::LinkedHashBase_used_data());
- break;
- case MethodRecognizer::kLinkedHashBase_setUsedData:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::LinkedHashBase_used_data(),
- StoreInstanceFieldInstr::Kind::kOther,
- kNoStoreBarrier);
- body += NullConstant();
- break;
- case MethodRecognizer::kLinkedHashBase_getDeletedKeys:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::LinkedHashBase_deleted_keys());
- break;
- case MethodRecognizer::kLinkedHashBase_setDeletedKeys:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::LinkedHashBase_deleted_keys(),
- StoreInstanceFieldInstr::Kind::kOther,
- kNoStoreBarrier);
- body += NullConstant();
- break;
- case MethodRecognizer::kWeakProperty_getKey:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::WeakProperty_key());
- break;
- case MethodRecognizer::kWeakProperty_setKey:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::WeakProperty_key());
- body += NullConstant();
- break;
- case MethodRecognizer::kWeakProperty_getValue:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::WeakProperty_value());
- break;
- case MethodRecognizer::kWeakProperty_setValue:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::WeakProperty_value());
- body += NullConstant();
- break;
- case MethodRecognizer::kWeakReference_getTarget:
- ASSERT_EQUAL(function.NumParameters(), 1);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadNativeField(Slot::WeakReference_target());
- break;
- case MethodRecognizer::kWeakReference_setTarget:
- ASSERT_EQUAL(function.NumParameters(), 2);
- body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += LoadLocal(parsed_function_->RawParameterVariable(1));
- body += StoreNativeField(Slot::WeakReference_target());
- body += NullConstant();
- break;
case MethodRecognizer::kUtf8DecoderScan:
ASSERT_EQUAL(function.NumParameters(), 5);
body += LoadLocal(parsed_function_->RawParameterVariable(0)); // decoder
@@ -1675,6 +1545,35 @@
body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += MathUnary(MathUnaryInstr::kSqrt);
} break;
+#define IL_BODY(method, slot) \
+ case MethodRecognizer::k##method: \
+ ASSERT_EQUAL(function.NumParameters(), 1); \
+ body += LoadLocal(parsed_function_->RawParameterVariable(0)); \
+ body += LoadNativeField(Slot::slot()); \
+ break;
+ LOAD_NATIVE_FIELD(IL_BODY)
+#undef IL_BODY
+#define IL_BODY(method, slot) \
+ case MethodRecognizer::k##method: \
+ ASSERT_EQUAL(function.NumParameters(), 2); \
+ body += LoadLocal(parsed_function_->RawParameterVariable(0)); \
+ body += LoadLocal(parsed_function_->RawParameterVariable(1)); \
+ body += StoreNativeField(Slot::slot()); \
+ body += NullConstant(); \
+ break;
+ STORE_NATIVE_FIELD(IL_BODY)
+#undef IL_BODY
+#define IL_BODY(method, slot) \
+ case MethodRecognizer::k##method: \
+ ASSERT_EQUAL(function.NumParameters(), 2); \
+ body += LoadLocal(parsed_function_->RawParameterVariable(0)); \
+ body += LoadLocal(parsed_function_->RawParameterVariable(1)); \
+ body += StoreNativeField( \
+ Slot::slot(), StoreInstanceFieldInstr::Kind::kOther, kNoStoreBarrier); \
+ body += NullConstant(); \
+ break;
+ STORE_NATIVE_FIELD_NO_BARRIER(IL_BODY)
+#undef IL_BODY
default: {
UNREACHABLE();
break;
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index d847251..e14994c 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -278,6 +278,8 @@
#undef SET_FUNCTION_BIT
if (!fingerprints_match) {
+ // Private names are mangled. Mangling depends on Library::private_key_.
+ // If registering a new bootstrap library, add at the end.
FATAL(
"FP mismatch while recognizing methods. If the behavior of "
"these functions has changed, then changes are also needed in "
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 5d42253..5debd94 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -189,11 +189,11 @@
V(_WeakProperty, set:value, WeakProperty_setValue, 0x8b2bafab) \
V(_WeakReferenceImpl, get:target, WeakReference_getTarget, 0x632d6ca8) \
V(_WeakReferenceImpl, set:_target, WeakReference_setTarget, 0x6edc7518) \
- V(::, _classRangeCheck, ClassRangeCheck, 0x00269620) \
+ V(::, _classRangeCheck, ClassRangeCheck, 0x09f5fc7a) \
V(::, _abi, FfiAbi, 0x7c4ab3b4) \
V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x92ae104f) \
V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x3ff5ae9c) \
- V(::, _nativeEffect, NativeEffect, 0x61e00b59) \
+ V(::, _nativeEffect, NativeEffect, 0x537dce91) \
V(::, _loadAbiSpecificInt, FfiLoadAbiSpecificInt, 0x7807e872) \
V(::, _loadAbiSpecificIntAtIndex, FfiLoadAbiSpecificIntAtIndex, 0x6aa4cab4) \
V(::, _loadInt8, FfiLoadInt8, 0x0f04e397) \
@@ -239,7 +239,7 @@
V(::, _getNativeField, GetNativeField, 0xa0139b85) \
V(::, reachabilityFence, ReachabilityFence, 0x730f2b7f) \
V(::, _asyncThenWrapperHelper, AsyncThenWrapperHelper, 0xd9974c34) \
- V(_Utf8Decoder, _scan, Utf8DecoderScan, 0x1dcaf73d) \
+ V(_Utf8Decoder, _scan, Utf8DecoderScan, 0x037e7601) \
V(_Future, timeout, FutureTimeout, 0x73041520) \
V(Future, wait, FutureWait, 0x495c83cd) \
V(_RootZone, runUnary, RootZoneRunUnary, 0xb607f8bf) \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c4a2ee5..a7966c7 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2341,6 +2341,18 @@
pending_classes.Add(cls);
RegisterClass(cls, Symbols::FfiDynamicLibrary(), lib);
+ // Pre-register the internal library so we can place the vm class
+ // FinalizerEntry there rather than the core library.
+ lib = Library::LookupLibrary(thread, Symbols::DartInternal());
+ if (lib.IsNull()) {
+ lib = Library::NewLibraryHelper(Symbols::DartInternal(), true);
+ lib.SetLoadRequested();
+ lib.Register(thread);
+ }
+ object_store->set_bootstrap_library(ObjectStore::kInternal, lib);
+ ASSERT(!lib.IsNull());
+ ASSERT(lib.ptr() == Library::InternalLibrary());
+
// Finish the initialization by compiling the bootstrap scripts containing
// the base interfaces and the implementation of the internal classes.
const Error& error = Error::Handle(
@@ -14388,6 +14400,8 @@
#undef CHECK_FACTORY_FINGERPRINTS
if (!fingerprints_match) {
+ // Private names are mangled. Mangling depends on Library::private_key_.
+ // If registering a new bootstrap library, add at the end.
FATAL(
"FP mismatch while recognizing methods. If the behavior of "
"these functions has changed, then changes are also needed in "
diff --git a/tools/VERSION b/tools/VERSION
index 6601fe5..43c10b9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 133
+PRERELEASE 134
PRERELEASE_PATCH 0
\ No newline at end of file