[dart2js] initial steps to prepare codegen and ssa/codegen.dart for migration

This removes most unmigrated dependencies, only 4 remain. 3 in the same ssa
folder, and one to js_backend/type_reference.dart

Change-Id: I15596d6f5a915c5043f87861ac1a9fa4327f8c4a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265680
Reviewed-by: Mayank Patke <fishythefish@google.com>
This commit is contained in:
Sigmund Cherem 2022-10-27 17:51:18 +00:00 committed by Commit Queue
parent 8d9fbbd208
commit d5a46dabca
20 changed files with 277 additions and 109 deletions

View file

@ -18,7 +18,7 @@ import '../inferrer/abstract_value_domain.dart';
import '../inferrer/types.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/backend.dart';
import '../js_backend/codegen_inputs.dart';
import '../js_backend/namer.dart';
import '../js_backend/deferred_holder_expression.dart'
show DeferredHolderExpression;
@ -38,6 +38,8 @@ import '../util/enumset.dart';
import '../util/util.dart';
import '../world.dart';
import 'codegen_interfaces.dart' as interfaces;
class CodegenImpact extends WorldImpact {
const CodegenImpact();
@ -322,7 +324,7 @@ class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact {
// TODO(johnniwinther): Split this class into interface and implementation.
// TODO(johnniwinther): Move this implementation to the JS backend.
class CodegenRegistry {
class CodegenRegistry implements interfaces.CodegenRegistry {
final ElementEnvironment _elementEnvironment;
final MemberEntity _currentElement;
final _CodegenImpact _worldImpact;
@ -336,81 +338,100 @@ class CodegenRegistry {
String toString() => 'CodegenRegistry for $_currentElement';
@deprecated
@override
void registerInstantiatedClass(ClassEntity element) {
registerInstantiation(_elementEnvironment.getRawType(element));
}
@override
void registerStaticUse(StaticUse staticUse) {
_worldImpact.registerStaticUse(staticUse);
}
@override
void registerDynamicUse(DynamicUse dynamicUse) {
_worldImpact.registerDynamicUse(dynamicUse);
}
@override
void registerTypeUse(TypeUse typeUse) {
_worldImpact.registerTypeUse(typeUse);
}
@override
void registerConstantUse(ConstantUse constantUse) {
_worldImpact.registerConstantUse(constantUse);
}
@override
void registerTypeVariableBoundsSubtypeCheck(
DartType subtype, DartType supertype) {
_worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
}
@override
void registerInstantiatedClosure(FunctionEntity element) {
_worldImpact.registerStaticUse(StaticUse.callMethod(element));
}
@override
void registerConstSymbol(String name) {
_worldImpact.registerConstSymbol(name);
}
@override
void registerSpecializedGetInterceptor(Set<ClassEntity> classes) {
_worldImpact.registerSpecializedGetInterceptor(classes);
}
@override
void registerOneShotInterceptor(Selector selector) {
_worldImpact.registerOneShotInterceptor(selector);
}
@override
void registerUseInterceptor() {
_worldImpact.registerUseInterceptor();
}
@override
void registerInstantiation(InterfaceType type) {
registerTypeUse(TypeUse.instantiation(type));
}
@override
void registerAsyncMarker(AsyncMarker asyncMarker) {
_worldImpact.registerAsyncMarker(asyncMarker);
}
@override
void registerGenericInstantiation(GenericInstantiation instantiation) {
_worldImpact.registerGenericInstantiation(instantiation);
}
@override
void registerNativeBehavior(NativeBehavior nativeBehavior) {
_worldImpact.registerNativeBehavior(nativeBehavior);
}
@override
void registerNativeMethod(FunctionEntity function) {
_worldImpact.registerNativeMethod(function);
}
void registerModularName(ModularName name) {
@override
void registerModularName(covariant ModularName name) {
_names ??= [];
_names.add(name);
}
void registerModularExpression(ModularExpression expression) {
@override
void registerModularExpression(covariant ModularExpression expression) {
_expressions ??= [];
_expressions.add(expression);
}
@override
CodegenResult close(js.Fun code) {
return CodegenResult(
code, _worldImpact, _names ?? const [], _expressions ?? const []);
@ -469,7 +490,7 @@ class DeserializedCodegenResults extends CodegenResults {
}
/// The code generation result for a single [MemberEntity].
class CodegenResult {
class CodegenResult implements interfaces.CodegenResult {
static const String tag = 'codegen-result';
final js.Fun code;
@ -614,7 +635,8 @@ enum ModularNameKind {
asName,
}
class ModularName extends js.Name implements js.AstContainer {
class ModularName extends js.Name
implements js.AstContainer, interfaces.ModularName {
static const String tag = 'modular-name';
final ModularNameKind kind;
@ -864,7 +886,7 @@ enum ModularExpressionKind {
}
class ModularExpression extends js.DeferredExpression
implements js.AstContainer {
implements js.AstContainer, interfaces.ModularExpression {
static const String tag = 'modular-expression';
final ModularExpressionKind kind;

View file

@ -0,0 +1,59 @@
// 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.
import '../js/js.dart' as js;
import '../elements/entities.dart';
import '../elements/types.dart' show DartType, InterfaceType;
import '../native/behavior.dart';
import '../universe/feature.dart';
import '../universe/selector.dart';
import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
abstract class CodegenRegistry {
@deprecated
void registerInstantiatedClass(ClassEntity element);
void registerStaticUse(StaticUse staticUse);
void registerDynamicUse(DynamicUse dynamicUse);
void registerTypeUse(TypeUse typeUse);
void registerConstantUse(ConstantUse constantUse);
void registerTypeVariableBoundsSubtypeCheck(
DartType subtype, DartType supertype);
void registerInstantiatedClosure(FunctionEntity element);
void registerConstSymbol(String name);
void registerSpecializedGetInterceptor(Set<ClassEntity> classes);
void registerOneShotInterceptor(Selector selector);
void registerUseInterceptor();
void registerInstantiation(InterfaceType type);
void registerAsyncMarker(AsyncMarker asyncMarker);
void registerGenericInstantiation(GenericInstantiation instantiation);
void registerNativeBehavior(NativeBehavior nativeBehavior);
void registerNativeMethod(FunctionEntity function);
void registerModularName(ModularName name);
void registerModularExpression(ModularExpression expression);
CodegenResult close(js.Fun code);
}
abstract class ModularExpression {}
abstract class ModularName {}
abstract class CodegenResult {}

View file

@ -52,7 +52,7 @@ import 'inferrer_experimental/typemasks/masks.dart' as experimentalInferrer
show TypeMaskStrategy;
import 'inferrer/wrapped.dart' show WrappedAbstractValueStrategy;
import 'ir/modular.dart';
import 'js_backend/backend.dart' show CodegenInputs;
import 'js_backend/codegen_inputs.dart' show CodegenInputs;
import 'js_backend/enqueuer.dart';
import 'js_backend/inferred_data.dart';
import 'js_model/js_strategy.dart';

View file

@ -11,12 +11,8 @@ import '../common/codegen.dart';
import '../elements/entities.dart';
import '../inferrer/types.dart';
import '../js_model/elements.dart';
import '../tracer.dart';
import 'annotations.dart';
import 'checked_mode_helpers.dart';
import 'namer.dart';
import 'runtime_types_codegen.dart';
import 'runtime_types_new.dart';
import 'codegen_inputs.dart';
abstract class FunctionCompiler {
void initialize(
@ -239,15 +235,3 @@ class FunctionInlineCache {
return _annotationsData.hasTryInline(element);
}
}
/// Holds resources only used during code generation.
class CodegenInputs {
final CheckedModeHelpers checkedModeHelpers = CheckedModeHelpers();
final RuntimeTypesSubstitutions rtiSubstitutions;
final RecipeEncoder rtiRecipeEncoder;
final Tracer tracer;
final FixedNames fixedNames;
CodegenInputs(this.rtiSubstitutions, this.rtiRecipeEncoder, this.tracer,
this.fixedNames);
}

View file

@ -0,0 +1,21 @@
// Copyright (c) 2012, 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.
import '../tracer_interfaces.dart';
import 'checked_mode_helpers.dart';
import 'namer_migrated.dart';
import 'runtime_types_codegen.dart';
import 'runtime_types_new_interfaces.dart';
/// Holds resources only used during code generation.
class CodegenInputs {
final CheckedModeHelpers checkedModeHelpers = CheckedModeHelpers();
final RuntimeTypesSubstitutions rtiSubstitutions;
final RecipeEncoder rtiRecipeEncoder;
final Tracer tracer;
final FixedNames fixedNames;
CodegenInputs(this.rtiSubstitutions, this.rtiRecipeEncoder, this.tracer,
this.fixedNames);
}

View file

@ -2071,23 +2071,6 @@ class NamingScope {
}
}
/// Fixed names usage by the namer.
class FixedNames {
const FixedNames();
String get getterPrefix => r'get$';
String get setterPrefix => r'set$';
String get callPrefix => 'call';
String get callCatchAllName => r'call*';
String get callNameField => r'$callName';
String get defaultValuesField => r'$defaultValues';
String get deferredAction => r'$deferredAction';
String get operatorIsPrefix => r'$is';
String get operatorSignature => r'$signature';
String get requiredParameterField => r'$requiredArgCount';
String get rtiName => r'$ti';
}
/// Minified version of the fixed names usage by the namer.
// TODO(johnniwinther): This should implement [FixedNames] and minify all fixed
// names.
@ -2130,6 +2113,7 @@ abstract class ModularNamer implements interfaces.ModularNamer {
/// Returns a variable use for accessing interceptors.
///
/// This is one of the [reservedGlobalObjectNames]
@override
jsAst.Expression readGlobalObjectForInterceptors() {
return DeferredHolderExpression.forInterceptors();
}
@ -2172,6 +2156,7 @@ abstract class ModularNamer implements interfaces.ModularNamer {
/// Returns the name for the instance field that holds runtime type arguments
/// on generic classes.
@override
jsAst.Name get rtiFieldJsName;
/// Property name on which [member] can be accessed directly,
@ -2194,12 +2179,15 @@ abstract class ModularNamer implements interfaces.ModularNamer {
/// this.super$A$foo(); // super.foo()
/// }
///
@override
jsAst.Name aliasedSuperMemberPropertyName(MemberEntity member);
/// Returns the JavaScript property name used to store an instance field.
@override
jsAst.Name instanceFieldPropertyName(FieldEntity element);
/// Annotated name for [method] encoding arity and named parameters.
@override
jsAst.Name instanceMethodName(FunctionEntity method);
/// Translates a [String] into the corresponding [Name] data structure as
@ -2207,9 +2195,11 @@ abstract class ModularNamer implements interfaces.ModularNamer {
///
/// If [name] is a setter or getter name, the corresponding [GetterName] or
/// [SetterName] data structure is used.
@override
jsAst.Name asName(String name);
/// Annotated name for the member being invoked by [selector].
@override
jsAst.Name invocationName(Selector selector);
/// Property name used for a specialization of `getInterceptor`.
@ -2217,6 +2207,7 @@ abstract class ModularNamer implements interfaces.ModularNamer {
/// js_runtime contains a top-level `getInterceptor` method. The
/// specializations have the same name, but with a suffix to avoid name
/// collisions.
@override
jsAst.Name nameForGetInterceptor(Set<ClassEntity> classes);
/// Property name used for the one-shot interceptor method for the given
@ -2275,12 +2266,14 @@ abstract class ModularNamer implements interfaces.ModularNamer {
}
/// Returns the label name for [label] used as a break target.
@override
String breakLabelName(LabelDefinition label) {
return '\$${label.labelName}\$${label.target.nestingLevel}';
}
/// Returns the label name for the implicit break label needed for the jump
/// [target].
@override
String implicitBreakLabelName(JumpTarget target) {
return '\$${target.nestingLevel}';
}
@ -2289,12 +2282,14 @@ abstract class ModularNamer implements interfaces.ModularNamer {
///
/// We sometimes handle continue targets differently from break targets,
/// so we have special continue-only labels.
@override
String continueLabelName(LabelDefinition label) {
return 'c\$${label.labelName}\$${label.target.nestingLevel}';
}
/// Returns the label name for the implicit continue label needed for the jump
/// [target].
@override
String implicitContinueLabelName(JumpTarget target) {
return 'c\$${target.nestingLevel}';
}

View file

@ -4,12 +4,25 @@
import '../common.dart';
import '../elements/entities.dart';
import '../elements/jumps.dart';
import '../js/js.dart' as jsAst;
import '../universe/selector.dart' show Selector;
import 'package:js_shared/synced/embedded_names.dart' show JsGetName;
abstract class ModularNamer {
jsAst.Name get rtiFieldJsName;
jsAst.Name aliasedSuperMemberPropertyName(MemberEntity member);
jsAst.Name asName(String name);
String breakLabelName(LabelDefinition label);
String continueLabelName(LabelDefinition label);
String implicitBreakLabelName(JumpTarget target);
String implicitContinueLabelName(JumpTarget target);
jsAst.Name invocationName(Selector selector);
jsAst.Name instanceFieldPropertyName(FieldEntity element);
jsAst.Name instanceMethodName(FunctionEntity method);
jsAst.Name nameForGetInterceptor(Set<ClassEntity> classes);
jsAst.Name nameForOneShotInterceptor(
Selector selector, Set<ClassEntity> classes);
jsAst.Name getNameForJsGetName(Spannable spannable, JsGetName name);
jsAst.Expression readGlobalObjectForInterceptors();
}

View file

@ -37,3 +37,20 @@ String suffixForGetInterceptor(CommonElements commonElements,
names.sort();
return names.join();
}
/// Fixed names usage by the namer.
class FixedNames {
const FixedNames();
String get getterPrefix => r'get$';
String get setterPrefix => r'set$';
String get callPrefix => 'call';
String get callCatchAllName => r'call*';
String get callNameField => r'$callName';
String get defaultValuesField => r'$defaultValues';
String get deferredAction => r'$deferredAction';
String get operatorIsPrefix => r'$is';
String get operatorSignature => r'$signature';
String get requiredParameterField => r'$requiredArgCount';
String get rtiName => r'$ti';
}

View file

@ -15,24 +15,20 @@ import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
import '../js_model/type_recipe.dart';
import '../js_emitter/js_emitter.dart' show ModularEmitter;
import '../universe/class_hierarchy.dart';
import '../world.dart';
import 'namer.dart';
import 'native_data.dart';
import 'runtime_types_codegen.dart' show RuntimeTypesSubstitutions;
import 'runtime_types_new_interfaces.dart' as interfaces;
import 'runtime_types_new_migrated.dart';
class RecipeEncoding {
final jsAst.Literal recipe;
final Set<TypeVariableType> typeVariables;
const RecipeEncoding(this.recipe, this.typeVariables);
}
export 'runtime_types_new_migrated.dart';
abstract class RecipeEncoder implements interfaces.RecipeEncoder {
/// Returns a [RecipeEncoding] representing the given [recipe] to be
/// evaluated against a type environment with shape [structure].
RecipeEncoding encodeRecipe(ModularEmitter emitter,
@override
RecipeEncoding encodeRecipe(covariant ModularEmitter emitter,
TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
@override
@ -416,52 +412,6 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
}
}
bool mustCheckAllSubtypes(JClosedWorld world, ClassEntity cls) =>
world.isUsedAsMixin(cls) ||
world.extractTypeArgumentsInterfacesNewRti.contains(cls);
int indexTypeVariable(
JClosedWorld world,
RuntimeTypesSubstitutions rtiSubstitutions,
FullTypeEnvironmentStructure environment,
TypeVariableType type,
{bool metadata = false}) {
int i = environment.bindings.indexOf(type);
if (i >= 0) {
// Indices are 1-based since '0' encodes using the entire type for the
// singleton structure.
return i + 1;
}
TypeVariableEntity element = type.element;
ClassEntity cls = element.typeDeclaration;
if (metadata) {
if (identical(environment.classType.element, cls)) {
// Indexed class type variables come after the bound function type
// variables.
return 1 + environment.bindings.length + element.index;
}
}
// TODO(sra): We might be in a context where the class type variable has an
// index, even though in the general case it is not at a specific index.
ClassHierarchy classHierarchy = world.classHierarchy;
var test = mustCheckAllSubtypes(world, cls)
? classHierarchy.anyStrictSubtypeOf
: classHierarchy.anyStrictSubclassOf;
if (test(cls, (ClassEntity subclass) {
return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
})) {
return null;
}
// Indexed class type variables come after the bound function type
// variables.
return 1 + environment.bindings.length + element.index;
}
class _RulesetEntry {
final Set<InterfaceType> _supertypes = {};
final Map<TypeVariableType, DartType> _typeVariables = {};

View file

@ -1,7 +1,10 @@
import '../js_emitter/code_emitter_task_interfaces.dart';
import '../js_model/type_recipe.dart';
import '../js/js.dart' as jsAst;
import 'runtime_types_new_migrated.dart';
abstract class RecipeEncoder {
jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe);
RecipeEncoding encodeRecipe(ModularEmitter emitter,
TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
}

View file

@ -0,0 +1,68 @@
// Copyright (c) 2019, 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 js_backend.runtime_types_new_migrated;
import '../elements/entities.dart';
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js_model/type_recipe.dart';
import '../universe/class_hierarchy.dart';
import '../world.dart';
import 'runtime_types_codegen.dart' show RuntimeTypesSubstitutions;
class RecipeEncoding {
final jsAst.Literal recipe;
final Set<TypeVariableType> typeVariables;
const RecipeEncoding(this.recipe, this.typeVariables);
}
int? indexTypeVariable(
JClosedWorld world,
RuntimeTypesSubstitutions rtiSubstitutions,
FullTypeEnvironmentStructure environment,
TypeVariableType type,
{bool metadata = false}) {
int i = environment.bindings.indexOf(type);
if (i >= 0) {
// Indices are 1-based since '0' encodes using the entire type for the
// singleton structure.
return i + 1;
}
TypeVariableEntity element = type.element;
// TODO(48820): remove `!`. Added to increase coverage of null assertions
// while the compiler runs in unsound null safety.
ClassEntity cls = element.typeDeclaration! as ClassEntity;
if (metadata) {
if (identical(environment.classType!.element, cls)) {
// Indexed class type variables come after the bound function type
// variables.
return 1 + environment.bindings.length + element.index;
}
}
// TODO(sra): We might be in a context where the class type variable has an
// index, even though in the general case it is not at a specific index.
ClassHierarchy classHierarchy = world.classHierarchy;
var test = mustCheckAllSubtypes(world, cls)
? classHierarchy.anyStrictSubtypeOf
: classHierarchy.anyStrictSubclassOf;
if (test(cls, (ClassEntity subclass) {
return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
})) {
return null;
}
// Indexed class type variables come after the bound function type
// variables.
return 1 + environment.bindings.length + element.index;
}
bool mustCheckAllSubtypes(JClosedWorld world, ClassEntity cls) =>
world.isUsedAsMixin(cls) ||
world.extractTypeArgumentsInterfacesNewRti.contains(cls);

View file

@ -14,7 +14,7 @@ import '../constants/values.dart';
import '../deferred_load/output_unit.dart' show OutputUnit;
import '../elements/entities.dart';
import '../js/js.dart' as jsAst;
import '../js_backend/backend.dart' show CodegenInputs;
import '../js_backend/codegen_inputs.dart' show CodegenInputs;
import '../js_backend/inferred_data.dart';
import '../js_backend/namer.dart' show Namer;
import '../js_backend/runtime_types.dart' show RuntimeTypesChecks;
@ -161,25 +161,31 @@ class CodeEmitterTask extends CompilerTask
/// the closed world computed by the codegen enqueuer.
abstract class ModularEmitter implements interfaces.ModularEmitter {
/// Returns the JS prototype of the given class [e].
@override
jsAst.Expression prototypeAccess(ClassEntity e);
/// Returns the JS function representing the given function.
///
/// The function must be invoked and can not be used as closure.
@override
jsAst.Expression staticFunctionAccess(FunctionEntity element);
@override
jsAst.Expression staticFieldAccess(FieldEntity element);
/// Returns the JS function that must be invoked to get the value of the
/// lazily initialized static.
@override
jsAst.Expression isolateLazyInitializerAccess(covariant FieldEntity element);
/// Returns the closure expression of a static function.
@override
jsAst.Expression staticClosureAccess(covariant FunctionEntity element);
/// Returns the JS constructor of the given element.
///
/// The returned expression must only be used in a JS `new` expression.
@override
jsAst.Expression constructorAccess(ClassEntity e);
/// Returns the JS name representing the type [e].
@ -192,6 +198,7 @@ abstract class ModularEmitter implements interfaces.ModularEmitter {
jsAst.Expression generateEmbeddedGlobalAccess(String global);
/// Returns the JS code for accessing the given [constant].
@override
jsAst.Expression constantReference(ConstantValue constant);
/// Returns the JS code for accessing the global property [global].

View file

@ -2,4 +2,16 @@
// 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.
abstract class ModularEmitter {}
import '../constants/values.dart';
import '../elements/entities.dart';
import '../js/js.dart' as jsAst;
abstract class ModularEmitter {
jsAst.Expression constructorAccess(ClassEntity e);
jsAst.Expression constantReference(ConstantValue constant);
jsAst.Expression isolateLazyInitializerAccess(covariant FieldEntity element);
jsAst.Expression prototypeAccess(ClassEntity e);
jsAst.Expression staticClosureAccess(covariant FunctionEntity element);
jsAst.Expression staticFieldAccess(FieldEntity element);
jsAst.Expression staticFunctionAccess(FunctionEntity element);
}

View file

@ -31,6 +31,7 @@ import '../inferrer_experimental/type_graph_inferrer.dart'
import '../js/js_source_mapping.dart';
import '../js_backend/backend.dart';
import '../js_backend/backend_impact.dart';
import '../js_backend/codegen_inputs.dart';
import '../js_backend/codegen_listener.dart';
import '../js_backend/custom_elements_analysis.dart';
import '../js_backend/enqueuer.dart';
@ -38,6 +39,7 @@ import '../js_backend/impact_transformer.dart';
import '../js_backend/inferred_data.dart';
import '../js_backend/interceptor_data.dart';
import '../js_backend/namer.dart';
import '../js_backend/namer_migrated.dart';
import '../js_backend/runtime_types.dart';
import '../js_backend/runtime_types_codegen.dart';
import '../js_backend/runtime_types_new.dart'

View file

@ -19,7 +19,7 @@ import '../environment.dart';
import '../inferrer/abstract_value_strategy.dart';
import '../inferrer/types.dart';
import '../ir/modular.dart';
import '../js_backend/backend.dart';
import '../js_backend/codegen_inputs.dart';
import '../js_backend/inferred_data.dart';
import '../js_model/js_world.dart';
import '../js_model/element_map_impl.dart';

View file

@ -13,7 +13,7 @@ import '../common.dart';
import '../common/elements.dart' show JCommonElements;
import '../common/metrics.dart';
import '../common/names.dart';
import '../common/codegen.dart' show CodegenRegistry;
import '../common/codegen_interfaces.dart' show CodegenRegistry;
import '../common/tasks.dart' show Measurer, CompilerTask;
import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart';
@ -24,21 +24,22 @@ import '../inferrer/abstract_value_domain.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/interceptor_data.dart';
import '../js_backend/backend.dart' show CodegenInputs;
import '../js_backend/codegen_inputs.dart' show CodegenInputs;
import '../js_backend/checked_mode_helpers.dart';
import '../js_backend/native_data.dart';
import '../js_backend/namer.dart' show ModularNamer;
import '../js_backend/namer_interfaces.dart' show ModularNamer;
import '../js_backend/runtime_types_codegen.dart';
import '../js_backend/runtime_types_new.dart'
show RecipeEncoder, RecipeEncoding, indexTypeVariable;
import '../js_backend/runtime_types_new_interfaces.dart' show RecipeEncoder;
import '../js_backend/runtime_types_new_migrated.dart'
show RecipeEncoding, indexTypeVariable;
import '../js_backend/specialized_checks.dart' show IsTestSpecialization;
import '../js_backend/type_reference.dart' show TypeReference;
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
import '../js_emitter/code_emitter_task_interfaces.dart' show ModularEmitter;
import '../js_model/elements.dart' show JGeneratorBody;
import '../js_model/type_recipe.dart';
import '../native/behavior.dart';
import '../options.dart';
import '../tracer.dart';
import '../tracer_interfaces.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;

View file

@ -19,7 +19,7 @@ import '../inferrer/types.dart';
import '../ir/util.dart';
import '../js_backend/field_analysis.dart'
show FieldAnalysisData, JFieldAnalysis;
import '../js_backend/backend.dart' show CodegenInputs;
import '../js_backend/codegen_inputs.dart' show CodegenInputs;
import '../js_backend/native_data.dart' show NativeData;
import '../js_model/type_recipe.dart'
show

View file

@ -19,7 +19,8 @@ import '../inferrer/types.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js/rewrite_async.dart';
import '../js_backend/backend.dart' show CodegenInputs, FunctionCompiler;
import '../js_backend/backend.dart' show FunctionCompiler;
import '../js_backend/codegen_inputs.dart' show CodegenInputs;
import '../js_backend/namer.dart' show ModularNamer, ModularNamerImpl;
import '../js_backend/type_reference.dart' show TypeReference;
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;

View file

@ -13,12 +13,13 @@ import 'options.dart' show CompilerOptions;
import 'ssa/nodes.dart' as ssa show HGraph;
import 'ssa/tracer.dart' show HTracer;
import 'world.dart' show JClosedWorld;
import 'tracer_interfaces.dart' as interfaces;
String TRACE_FILTER_PATTERN_FOR_TEST;
/// Dumps the intermediate representation after each phase in a format
/// readable by IR Hydra.
class Tracer extends TracerUtil {
class Tracer extends TracerUtil implements interfaces.Tracer {
final JClosedWorld closedWorld;
bool traceActive = false;
@override
@ -50,6 +51,7 @@ class Tracer extends TracerUtil {
});
}
@override
void traceGraph(String name, var irObject) {
if (!traceActive) return;
if (irObject is ssa.HGraph) {
@ -57,11 +59,13 @@ class Tracer extends TracerUtil {
}
}
@override
void traceJavaScriptText(String name, String Function() getText) {
if (!traceActive) return;
HTracer(output, closedWorld).traceJavaScriptText(name, getText());
}
@override
void close() {
if (output != null) {
output.close();

View file

@ -0,0 +1,9 @@
// 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.
abstract class Tracer {
void traceGraph(String name, var irObject);
void traceJavaScriptText(String name, String Function() getText);
void close();
}