mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
Add ElementCodegenWorldBuilder
Reusable parts are left in CodegenWorldBuilderImpl and a stub KernelCodegenWorldBuilder is added. R=sigmund@google.com Review-Url: https://codereview.chromium.org/2894893002 .
This commit is contained in:
parent
aa60a2ea90
commit
789fce309f
|
@ -4,8 +4,10 @@
|
|||
|
||||
library dart2js.backend_strategy;
|
||||
|
||||
import 'compiler.dart';
|
||||
import 'enqueue.dart';
|
||||
import 'js_backend/native_data.dart';
|
||||
import 'js_emitter/sorter.dart';
|
||||
import 'universe/world_builder.dart';
|
||||
import 'world.dart';
|
||||
|
||||
/// Strategy pattern that defines the element model used in type inference
|
||||
|
@ -19,21 +21,13 @@ abstract class BackendStrategy {
|
|||
|
||||
/// The [Sorter] used for sorting elements in the generated code.
|
||||
Sorter get sorter;
|
||||
}
|
||||
|
||||
/// Strategy for using the [Element] model from the resolver as the backend
|
||||
/// model.
|
||||
class ElementBackendStrategy implements BackendStrategy {
|
||||
final Compiler _compiler;
|
||||
|
||||
ElementBackendStrategy(this._compiler);
|
||||
|
||||
ClosedWorldRefiner createClosedWorldRefiner(ClosedWorldImpl closedWorld) =>
|
||||
closedWorld;
|
||||
|
||||
Sorter get sorter => const ElementSorter();
|
||||
|
||||
void convertClosures(ClosedWorldRefiner closedWorldRefiner) {
|
||||
_compiler.closureToClassMapper.createClosureClasses(closedWorldRefiner);
|
||||
}
|
||||
|
||||
/// Creates the [CodegenWorldBuilder] used by the codegen enqueuer.
|
||||
CodegenWorldBuilder createCodegenWorldBuilder(
|
||||
NativeBasicData nativeBasicData,
|
||||
ClosedWorld closedWorld,
|
||||
SelectorConstraintsStrategy selectorConstraintsStrategy);
|
||||
|
||||
/// Creates the [WorkItemBuilder] used by the codegen enqueuer.
|
||||
WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld);
|
||||
}
|
||||
|
|
|
@ -4,23 +4,15 @@
|
|||
|
||||
library dart2js.common.codegen;
|
||||
|
||||
import '../common.dart';
|
||||
import '../elements/elements.dart'
|
||||
show
|
||||
AsyncMarker,
|
||||
ClassElement,
|
||||
LocalFunctionElement,
|
||||
MemberElement,
|
||||
ResolvedAst;
|
||||
show AsyncMarker, ClassElement, LocalFunctionElement, MemberElement;
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/types.dart' show DartType, InterfaceType;
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||
import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
|
||||
import '../universe/world_impact.dart'
|
||||
show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;
|
||||
import '../util/enumset.dart';
|
||||
import '../util/util.dart' show Pair, Setlet;
|
||||
import '../world.dart' show ClosedWorld;
|
||||
import 'work.dart' show WorkItem;
|
||||
|
||||
class CodegenImpact extends WorldImpact {
|
||||
|
@ -181,32 +173,6 @@ class CodegenRegistry {
|
|||
}
|
||||
|
||||
/// [WorkItem] used exclusively by the [CodegenEnqueuer].
|
||||
class CodegenWorkItem extends WorkItem {
|
||||
CodegenRegistry registry;
|
||||
final ResolvedAst resolvedAst;
|
||||
final JavaScriptBackend _backend;
|
||||
final ClosedWorld _closedWorld;
|
||||
|
||||
factory CodegenWorkItem(JavaScriptBackend backend, ClosedWorld closedWorld,
|
||||
MemberElement element) {
|
||||
// If this assertion fails, the resolution callbacks of the backend may be
|
||||
// missing call of form registry.registerXXX. Alternatively, the code
|
||||
// generation could spuriously be adding dependencies on things we know we
|
||||
// don't need.
|
||||
assert(invariant(element, element.hasResolvedAst,
|
||||
message: "$element has no resolved ast."));
|
||||
ResolvedAst resolvedAst = element.resolvedAst;
|
||||
return new CodegenWorkItem.internal(resolvedAst, backend, closedWorld);
|
||||
}
|
||||
|
||||
CodegenWorkItem.internal(this.resolvedAst, this._backend, this._closedWorld);
|
||||
|
||||
MemberElement get element => resolvedAst.element;
|
||||
|
||||
WorldImpact run() {
|
||||
registry = new CodegenRegistry(element);
|
||||
return _backend.codegen(this, _closedWorld);
|
||||
}
|
||||
|
||||
String toString() => 'CodegenWorkItem(${resolvedAst.element})';
|
||||
abstract class CodegenWorkItem extends WorkItem {
|
||||
CodegenRegistry get registry;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import 'frontend_strategy.dart';
|
|||
import 'id_generator.dart';
|
||||
import 'io/source_information.dart' show SourceInformation;
|
||||
import 'js_backend/backend.dart' show JavaScriptBackend;
|
||||
import 'js_backend/element_strategy.dart' show ElementBackendStrategy;
|
||||
import 'kernel/kernel_strategy.dart';
|
||||
import 'library_loader.dart'
|
||||
show
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
library entities;
|
||||
|
||||
import '../common.dart';
|
||||
import '../universe/call_structure.dart' show CallStructure;
|
||||
|
||||
/// Abstract interface for entities.
|
||||
///
|
||||
|
@ -183,4 +184,11 @@ class ParameterStructure {
|
|||
/// The number of optional parameters (positional or named).
|
||||
int get optionalParameters =>
|
||||
positionalParameters - requiredParameters + namedParameters.length;
|
||||
|
||||
/// Returns the [CallStructure] corresponding to a call site passing all
|
||||
/// parameters both required and optional.
|
||||
CallStructure get callStructure {
|
||||
return new CallStructure(
|
||||
positionalParameters + namedParameters.length, namedParameters);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -893,9 +893,9 @@ class JavaScriptBackend {
|
|||
task,
|
||||
compiler.options,
|
||||
const TreeShakingEnqueuerStrategy(),
|
||||
new CodegenWorldBuilderImpl(
|
||||
nativeBasicData, closedWorld, constants, const TypeMaskStrategy()),
|
||||
new CodegenWorkItemBuilder(this, closedWorld, compiler.options),
|
||||
compiler.backendStrategy.createCodegenWorldBuilder(
|
||||
nativeBasicData, closedWorld, const TypeMaskStrategy()),
|
||||
compiler.backendStrategy.createCodegenWorkItemBuilder(closedWorld),
|
||||
new CodegenEnqueuerListener(
|
||||
compiler.elementEnvironment,
|
||||
commonElements,
|
||||
|
|
|
@ -105,13 +105,14 @@ class CodegenEnqueuerListener extends EnqueuerListener {
|
|||
}
|
||||
|
||||
/// Computes the [WorldImpact] of calling [mainMethod] as the entry point.
|
||||
WorldImpact _computeMainImpact(MethodElement mainMethod) {
|
||||
WorldImpact _computeMainImpact(FunctionEntity mainMethod) {
|
||||
WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
|
||||
if (mainMethod.parameters.isNotEmpty) {
|
||||
CallStructure callStructure = mainMethod.parameterStructure.callStructure;
|
||||
if (callStructure.argumentCount > 0) {
|
||||
_impacts.mainWithArguments
|
||||
.registerImpact(mainImpact, _elementEnvironment);
|
||||
mainImpact.registerStaticUse(
|
||||
new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS));
|
||||
new StaticUse.staticInvoke(mainMethod, callStructure));
|
||||
// If the main method takes arguments, this compilation could be the
|
||||
// target of Isolate.spawnUri. Strictly speaking, that can happen also if
|
||||
// main takes no arguments, but in this case the spawned isolate can't
|
||||
|
|
117
pkg/compiler/lib/src/js_backend/element_strategy.dart
Normal file
117
pkg/compiler/lib/src/js_backend/element_strategy.dart
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Copyright (c) 2017, 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 dart2js.js_backend.element_strategy;
|
||||
|
||||
import '../backend_strategy.dart';
|
||||
import '../common.dart';
|
||||
import '../common/codegen.dart';
|
||||
import '../common/work.dart';
|
||||
import '../compiler.dart';
|
||||
import '../elements/elements.dart';
|
||||
import '../enqueue.dart';
|
||||
import '../js_backend/backend.dart';
|
||||
import '../js_backend/native_data.dart';
|
||||
import '../js_emitter/sorter.dart';
|
||||
import '../options.dart';
|
||||
import '../universe/world_builder.dart';
|
||||
import '../universe/world_impact.dart';
|
||||
import '../world.dart';
|
||||
|
||||
/// Strategy for using the [Element] model from the resolver as the backend
|
||||
/// model.
|
||||
class ElementBackendStrategy implements BackendStrategy {
|
||||
final Compiler _compiler;
|
||||
|
||||
ElementBackendStrategy(this._compiler);
|
||||
|
||||
ClosedWorldRefiner createClosedWorldRefiner(ClosedWorldImpl closedWorld) =>
|
||||
closedWorld;
|
||||
|
||||
Sorter get sorter => const ElementSorter();
|
||||
|
||||
void convertClosures(ClosedWorldRefiner closedWorldRefiner) {
|
||||
_compiler.closureToClassMapper.createClosureClasses(closedWorldRefiner);
|
||||
}
|
||||
|
||||
@override
|
||||
CodegenWorldBuilder createCodegenWorldBuilder(
|
||||
NativeBasicData nativeBasicData,
|
||||
ClosedWorld closedWorld,
|
||||
SelectorConstraintsStrategy selectorConstraintsStrategy) {
|
||||
return new ElementCodegenWorldBuilderImpl(
|
||||
_compiler.elementEnvironment,
|
||||
nativeBasicData,
|
||||
closedWorld,
|
||||
_compiler.backend.constants,
|
||||
selectorConstraintsStrategy);
|
||||
}
|
||||
|
||||
@override
|
||||
WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
|
||||
return new ElementCodegenWorkItemBuilder(
|
||||
_compiler.backend, closedWorld, _compiler.options);
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder that creates the work item necessary for the code generation of a
|
||||
/// [MemberElement].
|
||||
class ElementCodegenWorkItemBuilder extends WorkItemBuilder {
|
||||
final JavaScriptBackend _backend;
|
||||
final ClosedWorld _closedWorld;
|
||||
final CompilerOptions _options;
|
||||
|
||||
ElementCodegenWorkItemBuilder(
|
||||
this._backend, this._closedWorld, this._options);
|
||||
|
||||
@override
|
||||
WorkItem createWorkItem(MemberElement element) {
|
||||
assert(invariant(element, element.isDeclaration));
|
||||
// Don't generate code for foreign elements.
|
||||
if (_backend.isForeign(element)) return null;
|
||||
if (element.isAbstract) return null;
|
||||
|
||||
// Codegen inlines field initializers. It only needs to generate
|
||||
// code for checked setters.
|
||||
if (element.isField && element.isInstanceMember) {
|
||||
if (!_options.enableTypeAssertions ||
|
||||
element.enclosingElement.isClosure) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new ElementCodegenWorkItem(_backend, _closedWorld, element);
|
||||
}
|
||||
}
|
||||
|
||||
class ElementCodegenWorkItem extends CodegenWorkItem {
|
||||
CodegenRegistry registry;
|
||||
final ResolvedAst resolvedAst;
|
||||
final JavaScriptBackend _backend;
|
||||
final ClosedWorld _closedWorld;
|
||||
|
||||
factory ElementCodegenWorkItem(JavaScriptBackend backend,
|
||||
ClosedWorld closedWorld, MemberElement element) {
|
||||
// If this assertion fails, the resolution callbacks of the backend may be
|
||||
// missing call of form registry.registerXXX. Alternatively, the code
|
||||
// generation could spuriously be adding dependencies on things we know we
|
||||
// don't need.
|
||||
assert(invariant(element, element.hasResolvedAst,
|
||||
message: "$element has no resolved ast."));
|
||||
ResolvedAst resolvedAst = element.resolvedAst;
|
||||
return new ElementCodegenWorkItem.internal(
|
||||
resolvedAst, backend, closedWorld);
|
||||
}
|
||||
|
||||
ElementCodegenWorkItem.internal(
|
||||
this.resolvedAst, this._backend, this._closedWorld);
|
||||
|
||||
MemberElement get element => resolvedAst.element;
|
||||
|
||||
WorldImpact run() {
|
||||
registry = new CodegenRegistry(element);
|
||||
return _backend.codegen(this, _closedWorld);
|
||||
}
|
||||
|
||||
String toString() => 'CodegenWorkItem(${resolvedAst.element})';
|
||||
}
|
|
@ -6,17 +6,14 @@ library dart2js.js.enqueue;
|
|||
|
||||
import 'dart:collection' show Queue;
|
||||
|
||||
import '../common/codegen.dart' show CodegenWorkItem;
|
||||
import '../common/tasks.dart' show CompilerTask;
|
||||
import '../common/work.dart' show WorkItem;
|
||||
import '../common.dart';
|
||||
import '../common_elements.dart' show ElementEnvironment;
|
||||
import '../elements/resolution_types.dart'
|
||||
show ResolutionDartType, ResolutionInterfaceType;
|
||||
import '../elements/elements.dart' show MemberElement;
|
||||
import '../elements/entities.dart';
|
||||
import '../enqueue.dart';
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||
import '../options.dart';
|
||||
import '../universe/world_builder.dart';
|
||||
import '../universe/use.dart'
|
||||
|
@ -31,7 +28,6 @@ import '../universe/world_impact.dart'
|
|||
show ImpactUseCase, WorldImpact, WorldImpactVisitor;
|
||||
import '../util/enumset.dart';
|
||||
import '../util/util.dart' show Setlet;
|
||||
import '../world.dart' show ClosedWorld;
|
||||
|
||||
/// [Enqueuer] which is specific to code generation.
|
||||
class CodegenEnqueuer extends EnqueuerImpl {
|
||||
|
@ -268,31 +264,3 @@ class CodegenEnqueuer extends EnqueuerImpl {
|
|||
@override
|
||||
Iterable<ClassEntity> get processedClasses => _worldBuilder.processedClasses;
|
||||
}
|
||||
|
||||
/// Builder that creates the work item necessary for the code generation of a
|
||||
/// [MemberElement].
|
||||
class CodegenWorkItemBuilder extends WorkItemBuilder {
|
||||
final JavaScriptBackend _backend;
|
||||
final ClosedWorld _closedWorld;
|
||||
final CompilerOptions _options;
|
||||
|
||||
CodegenWorkItemBuilder(this._backend, this._closedWorld, this._options);
|
||||
|
||||
@override
|
||||
WorkItem createWorkItem(MemberElement element) {
|
||||
assert(invariant(element, element.isDeclaration));
|
||||
// Don't generate code for foreign elements.
|
||||
if (_backend.isForeign(element)) return null;
|
||||
if (element.isAbstract) return null;
|
||||
|
||||
// Codegen inlines field initializers. It only needs to generate
|
||||
// code for checked setters.
|
||||
if (element.isField && element.isInstanceMember) {
|
||||
if (!_options.enableTypeAssertions ||
|
||||
element.enclosingElement.isClosure) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new CodegenWorkItem(_backend, _closedWorld, element);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,11 +153,7 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
/// Computes the [WorldImpact] of calling [mainMethod] as the entry point.
|
||||
WorldImpact _computeMainImpact(FunctionEntity mainMethod) {
|
||||
WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
|
||||
ParameterStructure parameterStructure = mainMethod.parameterStructure;
|
||||
CallStructure callStructure = new CallStructure(
|
||||
parameterStructure.positionalParameters +
|
||||
parameterStructure.namedParameters.length,
|
||||
parameterStructure.namedParameters);
|
||||
CallStructure callStructure = mainMethod.parameterStructure.callStructure;
|
||||
if (callStructure.argumentCount > 0) {
|
||||
_impacts.mainWithArguments
|
||||
.registerImpact(mainImpact, _elementEnvironment);
|
||||
|
|
|
@ -203,7 +203,7 @@ class Collector {
|
|||
.toList());
|
||||
|
||||
// Compute needed classes.
|
||||
Set<ClassElement> instantiatedClasses =
|
||||
Set<ClassEntity> instantiatedClasses =
|
||||
// TODO(johnniwinther): This should be accessed from a codegen closed
|
||||
// world.
|
||||
_worldBuilder.directlyInstantiatedClasses
|
||||
|
@ -219,7 +219,7 @@ class Collector {
|
|||
}
|
||||
}
|
||||
|
||||
void addClassesWithSuperclasses(Iterable<ClassElement> classes) {
|
||||
void addClassesWithSuperclasses(Iterable<ClassEntity> classes) {
|
||||
for (ClassElement cls in classes) {
|
||||
addClassWithSuperclasses(cls);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ library dart2js.js_emitter.type_test_registry;
|
|||
import '../common.dart';
|
||||
import '../common_elements.dart';
|
||||
import '../elements/elements.dart'
|
||||
show ClassElement, Element, ElementKind, MemberElement, MethodElement;
|
||||
show ClassElement, ElementKind, MemberElement, MethodElement;
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/resolution_types.dart'
|
||||
show
|
||||
|
@ -138,7 +138,7 @@ class TypeTestRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
bool canTearOff(Element function) {
|
||||
bool canTearOff(MemberElement function) {
|
||||
if (!function.isFunction ||
|
||||
function.isConstructor ||
|
||||
function.isAccessor) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import '../backend_strategy.dart';
|
|||
import '../common.dart';
|
||||
import '../common_elements.dart';
|
||||
import '../common/backend_api.dart';
|
||||
import '../common/codegen.dart' show CodegenWorkItem;
|
||||
import '../common/resolution.dart';
|
||||
import '../common/tasks.dart';
|
||||
import '../common/work.dart';
|
||||
|
@ -256,4 +257,25 @@ class KernelBackendStrategy implements BackendStrategy {
|
|||
// elements.
|
||||
throw new UnimplementedError('KernelBackendStrategy.createClosureClasses');
|
||||
}
|
||||
|
||||
@override
|
||||
WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
|
||||
return new KernelCodegenWorkItemBuilder();
|
||||
}
|
||||
|
||||
@override
|
||||
CodegenWorldBuilder createCodegenWorldBuilder(
|
||||
NativeBasicData nativeBasicData,
|
||||
ClosedWorld closedWorld,
|
||||
SelectorConstraintsStrategy selectorConstraintsStrategy) {
|
||||
return new KernelCodegenWorldBuilder(
|
||||
null, nativeBasicData, closedWorld, selectorConstraintsStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
|
||||
@override
|
||||
CodegenWorkItem createWorkItem(MemberEntity entity) {
|
||||
throw new UnimplementedError('KernelCodegenWorkItemBuilder.createWorkItem');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ class NativeCodegenEnqueuer extends NativeEnqueuerBase {
|
|||
this._nativeData)
|
||||
: super(options, elementEnvironment, commonElements, dartTypes);
|
||||
|
||||
WorldImpact processNativeClasses(Iterable<LibraryElement> libraries) {
|
||||
WorldImpact processNativeClasses(Iterable<LibraryEntity> libraries) {
|
||||
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
|
||||
_unusedClasses.addAll(_resolutionEnqueuer._nativeClasses);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import 'package:js_runtime/shared/embedded_names.dart';
|
|||
|
||||
import '../closure.dart';
|
||||
import '../common.dart';
|
||||
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
|
||||
import '../common/codegen.dart' show CodegenRegistry;
|
||||
import '../common/names.dart' show Identifiers, Selectors;
|
||||
import '../common/tasks.dart' show CompilerTask;
|
||||
import '../compiler.dart';
|
||||
|
@ -27,6 +27,7 @@ import '../elements/types.dart';
|
|||
import '../io/source_information.dart';
|
||||
import '../js/js.dart' as js;
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||
import '../js_backend/element_strategy.dart' show ElementCodegenWorkItem;
|
||||
import '../js_backend/runtime_types.dart';
|
||||
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
|
||||
import '../native/native.dart' as native;
|
||||
|
@ -65,7 +66,7 @@ class SsaBuilderTask extends CompilerTask {
|
|||
|
||||
DiagnosticReporter get reporter => backend.reporter;
|
||||
|
||||
HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
|
||||
HGraph build(ElementCodegenWorkItem work, ClosedWorld closedWorld) {
|
||||
return measure(() {
|
||||
MemberElement element = work.element.implementation;
|
||||
return reporter.withCurrentElement(element, () {
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:kernel/ast.dart' as ir;
|
|||
|
||||
import '../closure.dart';
|
||||
import '../common.dart';
|
||||
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
|
||||
import '../common/codegen.dart' show CodegenRegistry;
|
||||
import '../common/names.dart';
|
||||
import '../common/tasks.dart' show CompilerTask;
|
||||
import '../compiler.dart';
|
||||
|
@ -22,6 +22,7 @@ import '../elements/resolution_types.dart';
|
|||
import '../io/source_information.dart';
|
||||
import '../js/js.dart' as js;
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||
import '../js_backend/element_strategy.dart' show ElementCodegenWorkItem;
|
||||
import '../kernel/kernel.dart';
|
||||
import '../native/native.dart' as native;
|
||||
import '../resolution/tree_elements.dart';
|
||||
|
@ -53,7 +54,7 @@ class SsaKernelBuilderTask extends CompilerTask {
|
|||
: backend = backend,
|
||||
super(backend.compiler.measurer);
|
||||
|
||||
HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
|
||||
HGraph build(ElementCodegenWorkItem work, ClosedWorld closedWorld) {
|
||||
return measure(() {
|
||||
MemberElement element = work.element.implementation;
|
||||
Kernel kernel = backend.kernelTask.kernel;
|
||||
|
|
|
@ -19,6 +19,7 @@ import '../js/js.dart' as js;
|
|||
import '../js_backend/interceptor_data.dart';
|
||||
import '../js_backend/backend.dart';
|
||||
import '../js_backend/checked_mode_helpers.dart';
|
||||
import '../js_backend/element_strategy.dart' show ElementCodegenWorkItem;
|
||||
import '../js_backend/native_data.dart';
|
||||
import '../js_backend/namer.dart';
|
||||
import '../js_backend/runtime_types.dart';
|
||||
|
@ -63,7 +64,7 @@ class SsaCodeGeneratorTask extends CompilerTask {
|
|||
}
|
||||
|
||||
js.Expression generateCode(
|
||||
CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
|
||||
ElementCodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
|
||||
if (work.element.isField) {
|
||||
return generateLazyInitializer(work, graph, closedWorld);
|
||||
} else {
|
||||
|
@ -72,7 +73,7 @@ class SsaCodeGeneratorTask extends CompilerTask {
|
|||
}
|
||||
|
||||
js.Expression generateLazyInitializer(
|
||||
CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
|
||||
ElementCodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
|
||||
return measure(() {
|
||||
backend.tracer.traceGraph("codegen", graph);
|
||||
SourceInformation sourceInformation = sourceInformationFactory
|
||||
|
@ -97,7 +98,7 @@ class SsaCodeGeneratorTask extends CompilerTask {
|
|||
}
|
||||
|
||||
js.Expression generateMethod(
|
||||
CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
|
||||
ElementCodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
|
||||
return measure(() {
|
||||
MethodElement element = work.element;
|
||||
if (element.asyncMarker != AsyncMarker.SYNC) {
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
library ssa;
|
||||
|
||||
import '../common/codegen.dart' show CodegenWorkItem;
|
||||
import '../common/tasks.dart' show CompilerTask;
|
||||
import '../elements/elements.dart' show Element, FunctionElement;
|
||||
import '../io/source_information.dart';
|
||||
import '../js/js.dart' as js;
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend, FunctionCompiler;
|
||||
import '../js_backend/element_strategy.dart' show ElementCodegenWorkItem;
|
||||
import '../world.dart' show ClosedWorld;
|
||||
|
||||
import 'builder.dart';
|
||||
|
@ -37,7 +37,7 @@ class SsaFunctionCompiler implements FunctionCompiler {
|
|||
|
||||
/// Generates JavaScript code for `work.element`.
|
||||
/// Using the ssa builder, optimizer and codegenerator.
|
||||
js.Fun compile(CodegenWorkItem work, ClosedWorld closedWorld) {
|
||||
js.Fun compile(ElementCodegenWorkItem work, ClosedWorld closedWorld) {
|
||||
HGraph graph = useKernel
|
||||
? builderKernel.build(work, closedWorld)
|
||||
: builder.build(work, closedWorld);
|
||||
|
|
|
@ -28,9 +28,9 @@ abstract class CodegenWorldBuilder implements WorldBuilder {
|
|||
f(String name, Map<Selector, SelectorConstraints> selectors));
|
||||
|
||||
/// Returns `true` if [member] is invoked as a setter.
|
||||
bool hasInvokedSetter(Element member, ClosedWorld world);
|
||||
bool hasInvokedSetter(MemberEntity member, ClosedWorld world);
|
||||
|
||||
bool hasInvokedGetter(Element member, ClosedWorld world);
|
||||
bool hasInvokedGetter(MemberEntity member, ClosedWorld world);
|
||||
|
||||
Map<Selector, SelectorConstraints> invocationsByName(String name);
|
||||
|
||||
|
@ -50,10 +50,10 @@ abstract class CodegenWorldBuilder implements WorldBuilder {
|
|||
Iterable<FunctionEntity> get closurizedMembers;
|
||||
}
|
||||
|
||||
class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
||||
final NativeBasicData _nativeData;
|
||||
abstract class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
||||
final ElementEnvironment _elementEnvironment;
|
||||
final NativeBasicData _nativeBasicData;
|
||||
final ClosedWorld _world;
|
||||
final JavaScriptConstantCompiler _constants;
|
||||
|
||||
/// The set of all directly instantiated classes, that is, classes with a
|
||||
/// generative constructor that has been called directly and not only through
|
||||
|
@ -62,8 +62,7 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
/// Invariant: Elements are declaration elements.
|
||||
// TODO(johnniwinther): [_directlyInstantiatedClasses] and
|
||||
// [_instantiatedTypes] sets should be merged.
|
||||
final Set<ClassElement> _directlyInstantiatedClasses =
|
||||
new Set<ClassElement>();
|
||||
final Set<ClassEntity> _directlyInstantiatedClasses = new Set<ClassEntity>();
|
||||
|
||||
/// The set of all directly instantiated types, that is, the types of the
|
||||
/// directly instantiated classes.
|
||||
|
@ -72,12 +71,12 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
final Set<InterfaceType> _instantiatedTypes = new Set<InterfaceType>();
|
||||
|
||||
/// Classes implemented by directly instantiated classes.
|
||||
final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
|
||||
final Set<ClassEntity> _implementedClasses = new Set<ClassEntity>();
|
||||
|
||||
/// The set of all referenced static fields.
|
||||
///
|
||||
/// Invariant: Elements are declaration elements.
|
||||
final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
|
||||
final Set<FieldEntity> allReferencedStaticFields = new Set<FieldEntity>();
|
||||
|
||||
/**
|
||||
* Documentation wanted -- johnniwinther
|
||||
|
@ -95,8 +94,8 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
|
||||
<String, Map<Selector, SelectorConstraints>>{};
|
||||
|
||||
final Map<ClassElement, _ClassUsage> _processedClasses =
|
||||
<ClassElement, _ClassUsage>{};
|
||||
final Map<ClassEntity, _ClassUsage> _processedClasses =
|
||||
<ClassEntity, _ClassUsage>{};
|
||||
|
||||
/// Map of registered usage of static members of live classes.
|
||||
final Map<Entity, _StaticMemberUsage> _staticMemberUsage =
|
||||
|
@ -116,7 +115,7 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
final Map<String, Set<_MemberUsage>> _instanceFunctionsByName =
|
||||
<String, Set<_MemberUsage>>{};
|
||||
|
||||
final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>();
|
||||
final Set<DartType> isChecks = new Set<DartType>();
|
||||
|
||||
final SelectorConstraintsStrategy selectorConstraintsStrategy;
|
||||
|
||||
|
@ -125,34 +124,17 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
/// Set of methods in instantiated classes that are potentially closurized.
|
||||
final Set<FunctionEntity> closurizedMembers = new Set<FunctionEntity>();
|
||||
|
||||
CodegenWorldBuilderImpl(this._nativeData, this._world, this._constants,
|
||||
this.selectorConstraintsStrategy);
|
||||
CodegenWorldBuilderImpl(this._elementEnvironment, this._nativeBasicData,
|
||||
this._world, this.selectorConstraintsStrategy);
|
||||
|
||||
/// Calls [f] with every instance field, together with its declarer, in an
|
||||
/// instance of [cls].
|
||||
void forEachInstanceField(
|
||||
ClassElement cls, void f(ClassEntity declarer, FieldEntity field)) {
|
||||
cls.implementation
|
||||
.forEachInstanceField(f, includeSuperAndInjectedMembers: true);
|
||||
}
|
||||
|
||||
@override
|
||||
void forEachParameter(
|
||||
MethodElement function, void f(DartType type, String name)) {
|
||||
FunctionSignature parameters = function.functionSignature;
|
||||
parameters.forEachParameter((ParameterElement parameter) {
|
||||
f(parameter.type, parameter.name);
|
||||
});
|
||||
}
|
||||
|
||||
Iterable<ClassElement> get processedClasses => _processedClasses.keys
|
||||
Iterable<ClassEntity> get processedClasses => _processedClasses.keys
|
||||
.where((cls) => _processedClasses[cls].isInstantiated);
|
||||
|
||||
/// All directly instantiated classes, that is, classes with a generative
|
||||
/// constructor that has been called directly and not only through a
|
||||
/// super-call.
|
||||
// TODO(johnniwinther): Improve semantic precision.
|
||||
Iterable<ClassElement> get directlyInstantiatedClasses {
|
||||
Iterable<ClassEntity> get directlyInstantiatedClasses {
|
||||
return _directlyInstantiatedClasses;
|
||||
}
|
||||
|
||||
|
@ -170,10 +152,10 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
// subclass and through subtype instantiated types/classes.
|
||||
// TODO(johnniwinther): Support unknown type arguments for generic types.
|
||||
void registerTypeInstantiation(
|
||||
ResolutionInterfaceType type, ClassUsedCallback classUsed,
|
||||
InterfaceType type, ClassUsedCallback classUsed,
|
||||
{bool byMirrors: false}) {
|
||||
ClassElement cls = type.element;
|
||||
bool isNative = _nativeData.isNativeClass(cls);
|
||||
ClassEntity cls = type.element;
|
||||
bool isNative = _nativeBasicData.isNativeClass(cls);
|
||||
_instantiatedTypes.add(type);
|
||||
if (!cls.isAbstract
|
||||
// We can't use the closed-world assumption with native abstract
|
||||
|
@ -195,7 +177,7 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
// include the type arguments.
|
||||
if (_implementedClasses.add(cls)) {
|
||||
classUsed(cls, _getClassUsage(cls).implement());
|
||||
cls.allSupertypes.forEach((ResolutionInterfaceType supertype) {
|
||||
_elementEnvironment.forEachSupertype(cls, (InterfaceType supertype) {
|
||||
if (_implementedClasses.add(supertype.element)) {
|
||||
classUsed(
|
||||
supertype.element, _getClassUsage(supertype.element).implement());
|
||||
|
@ -205,7 +187,7 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
}
|
||||
|
||||
bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
|
||||
MemberElement member, ClosedWorld world) {
|
||||
MemberEntity member, ClosedWorld world) {
|
||||
if (selectors == null) return false;
|
||||
for (Selector selector in selectors.keys) {
|
||||
if (selector.appliesUnnamed(member)) {
|
||||
|
@ -218,16 +200,16 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool hasInvocation(Element member, ClosedWorld world) {
|
||||
bool hasInvocation(MemberEntity member, ClosedWorld world) {
|
||||
return _hasMatchingSelector(_invokedNames[member.name], member, world);
|
||||
}
|
||||
|
||||
bool hasInvokedGetter(Element member, ClosedWorld world) {
|
||||
bool hasInvokedGetter(MemberEntity member, ClosedWorld world) {
|
||||
return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
|
||||
member.isFunction && methodsNeedingSuperGetter.contains(member);
|
||||
}
|
||||
|
||||
bool hasInvokedSetter(Element member, ClosedWorld world) {
|
||||
bool hasInvokedSetter(MemberEntity member, ClosedWorld world) {
|
||||
return _hasMatchingSelector(_invokedSetters[member.name], member, world);
|
||||
}
|
||||
|
||||
|
@ -318,28 +300,23 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
_invokedSetters.forEach(f);
|
||||
}
|
||||
|
||||
void registerIsCheck(ResolutionDartType type) {
|
||||
type = type.unaliased;
|
||||
// Even in checked mode, type annotations for return type and argument
|
||||
// types do not imply type checks, so there should never be a check
|
||||
// against the type variable of a typedef.
|
||||
assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
|
||||
isChecks.add(type);
|
||||
void registerIsCheck(DartType type) {
|
||||
isChecks.add(type.unaliased);
|
||||
}
|
||||
|
||||
void _registerStaticUse(StaticUse staticUse) {
|
||||
Element element = staticUse.element;
|
||||
if (Elements.isStaticOrTopLevel(element) && element.isField) {
|
||||
allReferencedStaticFields.add(element);
|
||||
if (staticUse.element is FieldEntity) {
|
||||
FieldEntity field = staticUse.element;
|
||||
if (field.isTopLevel || field.isStatic) {
|
||||
allReferencedStaticFields.add(field);
|
||||
}
|
||||
}
|
||||
switch (staticUse.kind) {
|
||||
case StaticUseKind.STATIC_TEAR_OFF:
|
||||
MethodElement method = element;
|
||||
staticFunctionsNeedingGetter.add(method);
|
||||
staticFunctionsNeedingGetter.add(staticUse.element);
|
||||
break;
|
||||
case StaticUseKind.SUPER_TEAR_OFF:
|
||||
MethodElement method = element;
|
||||
methodsNeedingSuperGetter.add(method);
|
||||
methodsNeedingSuperGetter.add(staticUse.element);
|
||||
break;
|
||||
case StaticUseKind.SUPER_FIELD_SET:
|
||||
case StaticUseKind.FIELD_SET:
|
||||
|
@ -357,12 +334,12 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
}
|
||||
|
||||
void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
|
||||
Element element = staticUse.element;
|
||||
assert(invariant(element, element.isDeclaration,
|
||||
message: "Element ${element} is not the declaration."));
|
||||
Entity element = staticUse.element;
|
||||
_registerStaticUse(staticUse);
|
||||
_StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () {
|
||||
if ((element.isStatic || element.isTopLevel) && element.isFunction) {
|
||||
if (element is MemberEntity &&
|
||||
(element.isStatic || element.isTopLevel) &&
|
||||
element.isFunction) {
|
||||
return new _StaticFunctionUsage(element);
|
||||
} else {
|
||||
return new _GeneralStaticMemberUsage(element);
|
||||
|
@ -413,22 +390,25 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
closurizedMembers.add(element);
|
||||
}
|
||||
|
||||
void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) {
|
||||
cls.implementation.forEachMember((_, MemberElement member) {
|
||||
assert(invariant(member, member.isDeclaration));
|
||||
if (!member.isInstanceMember) return;
|
||||
if (member.isMalformed) return;
|
||||
_getMemberUsage(member, memberUsed);
|
||||
void processClassMembers(ClassEntity cls, MemberUsedCallback memberUsed) {
|
||||
_elementEnvironment.forEachClassMember(cls,
|
||||
(ClassEntity cls, MemberEntity member) {
|
||||
_processInstantiatedClassMember(cls, member, memberUsed);
|
||||
});
|
||||
}
|
||||
|
||||
void _processInstantiatedClassMember(
|
||||
ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed) {
|
||||
if (!member.isInstanceMember) return;
|
||||
_getMemberUsage(member, memberUsed);
|
||||
}
|
||||
|
||||
_MemberUsage _getMemberUsage(
|
||||
MemberElement member, MemberUsedCallback memberUsed) {
|
||||
assert(invariant(member, member.isDeclaration));
|
||||
MemberEntity member, MemberUsedCallback memberUsed) {
|
||||
return _instanceMemberUsage.putIfAbsent(member, () {
|
||||
String memberName = member.name;
|
||||
ClassElement cls = member.enclosingClass;
|
||||
bool isNative = _nativeData.isNativeClass(cls);
|
||||
ClassEntity cls = member.enclosingClass;
|
||||
bool isNative = _nativeBasicData.isNativeClass(cls);
|
||||
_MemberUsage usage = new _MemberUsage(member, isNative: isNative);
|
||||
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
|
||||
useSet.addAll(usage.appliedUse);
|
||||
|
@ -477,16 +457,15 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
}
|
||||
|
||||
/// Return the canonical [_ClassUsage] for [cls].
|
||||
_ClassUsage _getClassUsage(ClassElement cls) {
|
||||
_ClassUsage _getClassUsage(ClassEntity cls) {
|
||||
return _processedClasses.putIfAbsent(cls, () => new _ClassUsage(cls));
|
||||
}
|
||||
|
||||
void _processInstantiatedClass(
|
||||
ClassElement cls, ClassUsedCallback classUsed) {
|
||||
void _processInstantiatedClass(ClassEntity cls, ClassUsedCallback classUsed) {
|
||||
// Registers [superclass] as instantiated. Returns `true` if it wasn't
|
||||
// already instantiated and we therefore have to process its superclass as
|
||||
// well.
|
||||
bool processClass(ClassElement superclass) {
|
||||
bool processClass(ClassEntity superclass) {
|
||||
_ClassUsage usage = _getClassUsage(superclass);
|
||||
if (!usage.isInstantiated) {
|
||||
classUsed(usage.cls, usage.instantiate());
|
||||
|
@ -496,16 +475,108 @@ class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
|
|||
}
|
||||
|
||||
while (cls != null && processClass(cls)) {
|
||||
cls = cls.superclass;
|
||||
cls = _elementEnvironment.getSuperClass(cls);
|
||||
}
|
||||
}
|
||||
|
||||
bool registerConstantUse(ConstantUse use);
|
||||
}
|
||||
|
||||
class ElementCodegenWorldBuilderImpl extends CodegenWorldBuilderImpl {
|
||||
final JavaScriptConstantCompiler _constants;
|
||||
|
||||
ElementCodegenWorldBuilderImpl(
|
||||
ElementEnvironment elementEnvironment,
|
||||
NativeBasicData nativeBasicData,
|
||||
ClosedWorld world,
|
||||
this._constants,
|
||||
SelectorConstraintsStrategy selectorConstraintsStrategy)
|
||||
: super(elementEnvironment, nativeBasicData, world,
|
||||
selectorConstraintsStrategy);
|
||||
|
||||
/// Calls [f] with every instance field, together with its declarer, in an
|
||||
/// instance of [cls].
|
||||
void forEachInstanceField(
|
||||
ClassElement cls, void f(ClassEntity declarer, FieldEntity field)) {
|
||||
cls.implementation
|
||||
.forEachInstanceField(f, includeSuperAndInjectedMembers: true);
|
||||
}
|
||||
|
||||
@override
|
||||
void forEachParameter(
|
||||
MethodElement function, void f(DartType type, String name)) {
|
||||
FunctionSignature parameters = function.functionSignature;
|
||||
parameters.forEachParameter((ParameterElement parameter) {
|
||||
f(parameter.type, parameter.name);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void _processInstantiatedClassMember(
|
||||
ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) {
|
||||
assert(invariant(member, member.isDeclaration));
|
||||
if (member.isMalformed) return;
|
||||
super._processInstantiatedClassMember(cls, member, memberUsed);
|
||||
}
|
||||
|
||||
@override
|
||||
_MemberUsage _getMemberUsage(
|
||||
MemberElement member, MemberUsedCallback memberUsed) {
|
||||
assert(invariant(member, member.isDeclaration));
|
||||
return super._getMemberUsage(member, memberUsed);
|
||||
}
|
||||
|
||||
void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
|
||||
Element element = staticUse.element;
|
||||
assert(invariant(element, element.isDeclaration,
|
||||
message: "Element ${element} is not the declaration."));
|
||||
super.registerStaticUse(staticUse, memberUsed);
|
||||
}
|
||||
|
||||
/// Register the constant [use] with this world builder. Returns `true` if
|
||||
/// the constant use was new to the world.
|
||||
@override
|
||||
bool registerConstantUse(ConstantUse use) {
|
||||
if (use.kind == ConstantUseKind.DIRECT) {
|
||||
_constants.addCompileTimeConstantForEmission(use.value);
|
||||
}
|
||||
return _constantValues.add(use.value);
|
||||
}
|
||||
|
||||
void registerIsCheck(ResolutionDartType type) {
|
||||
// Even in checked mode, type annotations for return type and argument
|
||||
// types do not imply type checks, so there should never be a check
|
||||
// against the type variable of a typedef.
|
||||
assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
|
||||
super.registerIsCheck(type);
|
||||
}
|
||||
}
|
||||
|
||||
class KernelCodegenWorldBuilder extends CodegenWorldBuilderImpl {
|
||||
KernelCodegenWorldBuilder(
|
||||
ElementEnvironment elementEnvironment,
|
||||
NativeBasicData nativeBasicData,
|
||||
ClosedWorld world,
|
||||
SelectorConstraintsStrategy selectorConstraintsStrategy)
|
||||
: super(elementEnvironment, nativeBasicData, world,
|
||||
selectorConstraintsStrategy);
|
||||
|
||||
@override
|
||||
bool registerConstantUse(ConstantUse use) {
|
||||
throw new UnimplementedError(
|
||||
'KernelCodegenWorldBuilder.registerConstantUse');
|
||||
}
|
||||
|
||||
@override
|
||||
void forEachParameter(
|
||||
FunctionEntity function, void f(DartType type, String name)) {
|
||||
throw new UnimplementedError('KernelCodegenWorldBuilder.forEachParameter');
|
||||
}
|
||||
|
||||
@override
|
||||
void forEachInstanceField(
|
||||
ClassEntity cls, void f(ClassEntity declarer, FieldEntity field)) {
|
||||
throw new UnimplementedError(
|
||||
'KernelCodegenWorldBuilder.forEachInstanceField');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import 'package:compiler/src/elements/elements.dart';
|
|||
export 'package:compiler/src/elements/elements.dart';
|
||||
|
||||
import 'package:compiler/src/js_backend/js_backend.dart' as js;
|
||||
import 'package:compiler/src/js_backend/element_strategy.dart'
|
||||
show ElementCodegenWorkItem;
|
||||
|
||||
import 'package:compiler/src/commandline_options.dart';
|
||||
import 'package:compiler/src/common/codegen.dart';
|
||||
|
@ -83,7 +85,7 @@ Future<String> compile(String code,
|
|||
resolutionWork.run();
|
||||
ClosedWorld closedWorld = compiler.closeResolution().closedWorld;
|
||||
CodegenWorkItem work =
|
||||
new CodegenWorkItem(compiler.backend, closedWorld, element);
|
||||
new ElementCodegenWorkItem(compiler.backend, closedWorld, element);
|
||||
compiler.phase = Compiler.PHASE_COMPILING;
|
||||
work.run();
|
||||
js.JavaScriptBackend backend = compiler.backend;
|
||||
|
|
|
@ -49,7 +49,8 @@ void testTypeRepresentations() {
|
|||
env.compiler.enqueuer.createCodegenEnqueuer(closedWorld);
|
||||
env.compiler.backend.onCodegenStart(
|
||||
closedWorld,
|
||||
new CodegenWorldBuilderImpl(
|
||||
new ElementCodegenWorldBuilderImpl(
|
||||
env.compiler.elementEnvironment,
|
||||
env.compiler.backend.nativeBasicData,
|
||||
closedWorld,
|
||||
env.compiler.backend.constants,
|
||||
|
|
Loading…
Reference in a new issue