OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.backend_api; | 5 library dart2js.backend_api; |
6 | 6 |
7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
8 | 8 |
9 import '../common.dart'; | 9 import '../common.dart'; |
10 import '../common/codegen.dart' show | 10 import '../common/codegen.dart' show CodegenImpact; |
11 CodegenImpact; | 11 import '../common/resolution.dart' show ResolutionImpact; |
12 import '../common/resolution.dart' show | 12 import '../compiler.dart' show Compiler; |
13 ResolutionImpact; | 13 import '../compile_time_constants.dart' |
14 import '../compiler.dart' show | 14 show BackendConstantEnvironment, ConstantCompilerTask; |
15 Compiler; | 15 import '../constants/expressions.dart' show ConstantExpression; |
16 import '../compile_time_constants.dart' show | 16 import '../constants/constant_system.dart' show ConstantSystem; |
17 BackendConstantEnvironment, | 17 import '../constants/values.dart' show ConstantValue; |
18 ConstantCompilerTask; | 18 import '../dart_types.dart' show DartType, InterfaceType; |
19 import '../constants/expressions.dart' show | 19 import '../elements/elements.dart' |
20 ConstantExpression; | 20 show |
21 import '../constants/constant_system.dart' show | 21 ClassElement, |
22 ConstantSystem; | 22 ConstructorElement, |
23 import '../constants/values.dart' show | 23 Element, |
24 ConstantValue; | 24 FunctionElement, |
25 import '../dart_types.dart' show | 25 LibraryElement, |
26 DartType, | 26 MetadataAnnotation, |
27 InterfaceType; | 27 MethodElement; |
28 import '../elements/elements.dart' show | 28 import '../enqueue.dart' show Enqueuer, CodegenEnqueuer, ResolutionEnqueuer; |
29 ClassElement, | 29 import '../io/code_output.dart' show CodeBuffer; |
30 ConstructorElement, | 30 import '../io/source_information.dart' show SourceInformationStrategy; |
31 Element, | 31 import '../js_backend/backend_helpers.dart' as js_backend show BackendHelpers; |
32 FunctionElement, | 32 import '../js_backend/js_backend.dart' as js_backend show JavaScriptBackend; |
33 LibraryElement, | 33 import '../library_loader.dart' show LibraryLoader, LoadedLibraries; |
34 MetadataAnnotation, | 34 import '../native/native.dart' as native show NativeEnqueuer, maybeEnableNative; |
35 MethodElement; | 35 import '../patch_parser.dart' |
36 import '../enqueue.dart' show | 36 show checkNativeAnnotation, checkJsInteropAnnotation; |
37 Enqueuer, | 37 import '../resolution/tree_elements.dart' show TreeElements; |
38 CodegenEnqueuer, | 38 import '../serialization/serialization.dart' |
39 ResolutionEnqueuer; | 39 show DeserializerPlugin, ObjectDecoder, ObjectEncoder, SerializerPlugin; |
40 import '../io/code_output.dart' show | 40 import '../tree/tree.dart' show Node, Send; |
41 CodeBuffer; | 41 import '../universe/call_structure.dart' show CallStructure; |
42 import '../io/source_information.dart' show | 42 import '../universe/world_impact.dart' show ImpactStrategy, WorldImpact; |
43 SourceInformationStrategy; | |
44 import '../js_backend/backend_helpers.dart' as js_backend show | |
45 BackendHelpers; | |
46 import '../js_backend/js_backend.dart' as js_backend show | |
47 JavaScriptBackend; | |
48 import '../library_loader.dart' show | |
49 LibraryLoader, | |
50 LoadedLibraries; | |
51 import '../native/native.dart' as native show | |
52 NativeEnqueuer, | |
53 maybeEnableNative; | |
54 import '../patch_parser.dart' show | |
55 checkNativeAnnotation, checkJsInteropAnnotation; | |
56 import '../resolution/tree_elements.dart' show | |
57 TreeElements; | |
58 import '../serialization/serialization.dart' show | |
59 DeserializerPlugin, | |
60 ObjectDecoder, | |
61 ObjectEncoder, | |
62 SerializerPlugin; | |
63 import '../tree/tree.dart' show | |
64 Node, | |
65 Send; | |
66 import '../universe/call_structure.dart' show | |
67 CallStructure; | |
68 import '../universe/world_impact.dart' show | |
69 ImpactStrategy, | |
70 WorldImpact; | |
71 | 43 |
72 import 'codegen.dart' show | 44 import 'codegen.dart' show CodegenWorkItem; |
73 CodegenWorkItem; | 45 import 'registry.dart' show Registry; |
74 import 'registry.dart' show | 46 import 'tasks.dart' show CompilerTask; |
75 Registry; | 47 import 'work.dart' show ItemCompilationContext; |
76 import 'tasks.dart' show | |
77 CompilerTask; | |
78 import 'work.dart' show | |
79 ItemCompilationContext; | |
80 | |
81 | 48 |
82 abstract class Backend { | 49 abstract class Backend { |
83 final Compiler compiler; | 50 final Compiler compiler; |
84 | 51 |
85 Backend(this.compiler); | 52 Backend(this.compiler); |
86 | 53 |
87 /// Returns true if the backend supports reflection. | 54 /// Returns true if the backend supports reflection. |
88 bool get supportsReflection; | 55 bool get supportsReflection; |
89 | 56 |
90 /// The [ConstantSystem] used to interpret compile-time constants for this | 57 /// The [ConstantSystem] used to interpret compile-time constants for this |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 | 92 |
126 void enqueueHelpers(ResolutionEnqueuer world, Registry registry); | 93 void enqueueHelpers(ResolutionEnqueuer world, Registry registry); |
127 | 94 |
128 WorldImpact codegen(CodegenWorkItem work); | 95 WorldImpact codegen(CodegenWorkItem work); |
129 | 96 |
130 // The backend determines the native resolution enqueuer, with a no-op | 97 // The backend determines the native resolution enqueuer, with a no-op |
131 // default, so tools like dart2dart can ignore the native classes. | 98 // default, so tools like dart2dart can ignore the native classes. |
132 native.NativeEnqueuer nativeResolutionEnqueuer(world) { | 99 native.NativeEnqueuer nativeResolutionEnqueuer(world) { |
133 return new native.NativeEnqueuer(); | 100 return new native.NativeEnqueuer(); |
134 } | 101 } |
| 102 |
135 native.NativeEnqueuer nativeCodegenEnqueuer(world) { | 103 native.NativeEnqueuer nativeCodegenEnqueuer(world) { |
136 return new native.NativeEnqueuer(); | 104 return new native.NativeEnqueuer(); |
137 } | 105 } |
138 | 106 |
139 /// Generates the output and returns the total size of the generated code. | 107 /// Generates the output and returns the total size of the generated code. |
140 int assembleProgram(); | 108 int assembleProgram(); |
141 | 109 |
142 List<CompilerTask> get tasks; | 110 List<CompilerTask> get tasks; |
143 | 111 |
144 void onResolutionComplete() {} | 112 void onResolutionComplete() {} |
(...skipping 13 matching lines...) Expand all Loading... |
158 /// Enable deferred loading. Returns `true` if the backend supports deferred | 126 /// Enable deferred loading. Returns `true` if the backend supports deferred |
159 /// loading. | 127 /// loading. |
160 bool enableDeferredLoadingIfSupported(Spannable node, Registry registry); | 128 bool enableDeferredLoadingIfSupported(Spannable node, Registry registry); |
161 | 129 |
162 /// Called during codegen when [constant] has been used. | 130 /// Called during codegen when [constant] has been used. |
163 void registerCompileTimeConstant(ConstantValue constant, Registry registry) {} | 131 void registerCompileTimeConstant(ConstantValue constant, Registry registry) {} |
164 | 132 |
165 /// Called during resolution when a constant value for [metadata] on | 133 /// Called during resolution when a constant value for [metadata] on |
166 /// [annotatedElement] has been evaluated. | 134 /// [annotatedElement] has been evaluated. |
167 void registerMetadataConstant(MetadataAnnotation metadata, | 135 void registerMetadataConstant(MetadataAnnotation metadata, |
168 Element annotatedElement, | 136 Element annotatedElement, Registry registry) {} |
169 Registry registry) {} | |
170 | 137 |
171 /// Called to notify to the backend that a class is being instantiated. | 138 /// Called to notify to the backend that a class is being instantiated. |
172 // TODO(johnniwinther): Remove this. It's only called once for each [cls] and | 139 // TODO(johnniwinther): Remove this. It's only called once for each [cls] and |
173 // only with [Compiler.globalDependencies] as [registry]. | 140 // only with [Compiler.globalDependencies] as [registry]. |
174 void registerInstantiatedClass(ClassElement cls, | 141 void registerInstantiatedClass( |
175 Enqueuer enqueuer, | 142 ClassElement cls, Enqueuer enqueuer, Registry registry) {} |
176 Registry registry) {} | |
177 | 143 |
178 /// Called to notify to the backend that a class is implemented by an | 144 /// Called to notify to the backend that a class is implemented by an |
179 /// instantiated class. | 145 /// instantiated class. |
180 void registerImplementedClass(ClassElement cls, | 146 void registerImplementedClass( |
181 Enqueuer enqueuer, | 147 ClassElement cls, Enqueuer enqueuer, Registry registry) {} |
182 Registry registry) {} | |
183 | 148 |
184 /// Called to instruct to the backend register [type] as instantiated on | 149 /// Called to instruct to the backend register [type] as instantiated on |
185 /// [enqueuer]. | 150 /// [enqueuer]. |
186 void registerInstantiatedType(InterfaceType type, | 151 void registerInstantiatedType( |
187 Enqueuer enqueuer, | 152 InterfaceType type, Enqueuer enqueuer, Registry registry, |
188 Registry registry, | 153 {bool mirrorUsage: false}) { |
189 {bool mirrorUsage: false}) { | |
190 registry.registerDependency(type.element); | 154 registry.registerDependency(type.element); |
191 enqueuer.registerInstantiatedType(type, mirrorUsage: mirrorUsage); | 155 enqueuer.registerInstantiatedType(type, mirrorUsage: mirrorUsage); |
192 } | 156 } |
193 | 157 |
194 /// Register a runtime type variable bound tests between [typeArgument] and | 158 /// Register a runtime type variable bound tests between [typeArgument] and |
195 /// [bound]. | 159 /// [bound]. |
196 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, | 160 void registerTypeVariableBoundsSubtypeCheck( |
197 DartType bound) {} | 161 DartType typeArgument, DartType bound) {} |
198 | 162 |
199 /** | 163 /** |
200 * Call this to register that an instantiated generic class has a call | 164 * Call this to register that an instantiated generic class has a call |
201 * method. | 165 * method. |
202 */ | 166 */ |
203 void registerCallMethodWithFreeTypeVariables( | 167 void registerCallMethodWithFreeTypeVariables( |
204 Element callMethod, | 168 Element callMethod, Enqueuer enqueuer, Registry registry) {} |
205 Enqueuer enqueuer, | |
206 Registry registry) {} | |
207 | 169 |
208 /// Called to instruct the backend to register that a closure exists for a | 170 /// Called to instruct the backend to register that a closure exists for a |
209 /// function on an instantiated generic class. | 171 /// function on an instantiated generic class. |
210 void registerClosureWithFreeTypeVariables( | 172 void registerClosureWithFreeTypeVariables( |
211 Element closure, | 173 Element closure, Enqueuer enqueuer, Registry registry) { |
212 Enqueuer enqueuer, | |
213 Registry registry) { | |
214 enqueuer.universe.closuresWithFreeTypeVariables.add(closure); | 174 enqueuer.universe.closuresWithFreeTypeVariables.add(closure); |
215 } | 175 } |
216 | 176 |
217 /// Call this to register that a member has been closurized. | 177 /// Call this to register that a member has been closurized. |
218 void registerBoundClosure(Enqueuer enqueuer) {} | 178 void registerBoundClosure(Enqueuer enqueuer) {} |
219 | 179 |
220 /// Call this to register that a static function has been closurized. | 180 /// Call this to register that a static function has been closurized. |
221 void registerGetOfStaticFunction(Enqueuer enqueuer) {} | 181 void registerGetOfStaticFunction(Enqueuer enqueuer) {} |
222 | 182 |
223 /** | 183 /** |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 /// This method is called when all new libraries loaded through | 302 /// This method is called when all new libraries loaded through |
343 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports | 303 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
344 /// have been computed. | 304 /// have been computed. |
345 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 305 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
346 return new Future.value(); | 306 return new Future.value(); |
347 } | 307 } |
348 | 308 |
349 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed | 309 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed |
350 /// annotations. The arguments corresponds to the unions of the corresponding | 310 /// annotations. The arguments corresponds to the unions of the corresponding |
351 /// fields of the annotations. | 311 /// fields of the annotations. |
352 void registerMirrorUsage(Set<String> symbols, | 312 void registerMirrorUsage( |
353 Set<Element> targets, | 313 Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) {} |
354 Set<Element> metaTargets) {} | |
355 | 314 |
356 /// Returns true if this element needs reflection information at runtime. | 315 /// Returns true if this element needs reflection information at runtime. |
357 bool isAccessibleByReflection(Element element) => true; | 316 bool isAccessibleByReflection(Element element) => true; |
358 | 317 |
359 /// Returns true if this element is covered by a mirrorsUsed annotation. | 318 /// Returns true if this element is covered by a mirrorsUsed annotation. |
360 /// | 319 /// |
361 /// Note that it might still be ok to tree shake the element away if no | 320 /// Note that it might still be ok to tree shake the element away if no |
362 /// reflection is used in the program (and thus [isTreeShakingDisabled] is | 321 /// reflection is used in the program (and thus [isTreeShakingDisabled] is |
363 /// still false). Therefore _do not_ use this predicate to decide inclusion | 322 /// still false). Therefore _do not_ use this predicate to decide inclusion |
364 /// in the tree, use [requiredByMirrorSystem] instead. | 323 /// in the tree, use [requiredByMirrorSystem] instead. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 FunctionElement helperForBadMain() => null; | 371 FunctionElement helperForBadMain() => null; |
413 | 372 |
414 FunctionElement helperForMissingMain() => null; | 373 FunctionElement helperForMissingMain() => null; |
415 | 374 |
416 FunctionElement helperForMainArity() => null; | 375 FunctionElement helperForMainArity() => null; |
417 | 376 |
418 void forgetElement(Element element) {} | 377 void forgetElement(Element element) {} |
419 | 378 |
420 void registerMainHasArguments(Enqueuer enqueuer) {} | 379 void registerMainHasArguments(Enqueuer enqueuer) {} |
421 | 380 |
422 void registerAsyncMarker(FunctionElement element, | 381 void registerAsyncMarker( |
423 Enqueuer enqueuer, | 382 FunctionElement element, Enqueuer enqueuer, Registry registry) {} |
424 Registry registry) {} | |
425 | 383 |
426 /// Called when resolving a call to a foreign function. | 384 /// Called when resolving a call to a foreign function. |
427 void registerForeignCall(Send node, | 385 void registerForeignCall(Send node, Element element, |
428 Element element, | 386 CallStructure callStructure, ForeignResolver resolver) {} |
429 CallStructure callStructure, | |
430 ForeignResolver resolver) {} | |
431 | 387 |
432 /// Returns the location of the patch-file associated with [libraryName] | 388 /// Returns the location of the patch-file associated with [libraryName] |
433 /// resolved from [plaformConfigUri]. | 389 /// resolved from [plaformConfigUri]. |
434 /// | 390 /// |
435 /// Returns null if there is none. | 391 /// Returns null if there is none. |
436 Uri resolvePatchUri(String libraryName, Uri plaformConfigUri); | 392 Uri resolvePatchUri(String libraryName, Uri plaformConfigUri); |
437 | 393 |
438 /// Creates an impact strategy to use for compilation. | 394 /// Creates an impact strategy to use for compilation. |
439 ImpactStrategy createImpactStrategy( | 395 ImpactStrategy createImpactStrategy( |
440 {bool supportDeferredLoad: true, | 396 {bool supportDeferredLoad: true, |
441 bool supportDumpInfo: true, | 397 bool supportDumpInfo: true, |
442 bool supportSerialization: true}) { | 398 bool supportSerialization: true}) { |
443 return const ImpactStrategy(); | 399 return const ImpactStrategy(); |
444 } | 400 } |
445 } | 401 } |
446 | 402 |
447 /// Interface for resolving calls to foreign functions. | 403 /// Interface for resolving calls to foreign functions. |
448 abstract class ForeignResolver { | 404 abstract class ForeignResolver { |
449 /// Returns the constant expression of [node], or `null` if [node] is not | 405 /// Returns the constant expression of [node], or `null` if [node] is not |
450 /// a constant expression. | 406 /// a constant expression. |
451 ConstantExpression getConstant(Node node); | 407 ConstantExpression getConstant(Node node); |
452 | 408 |
(...skipping 13 matching lines...) Expand all Loading... |
466 } | 422 } |
467 | 423 |
468 /// Transform the [CodegenImpact] into a [WorldImpact] adding the | 424 /// Transform the [CodegenImpact] into a [WorldImpact] adding the |
469 /// backend dependencies for features used in [worldImpact]. | 425 /// backend dependencies for features used in [worldImpact]. |
470 WorldImpact transformCodegenImpact(CodegenImpact worldImpact) { | 426 WorldImpact transformCodegenImpact(CodegenImpact worldImpact) { |
471 return worldImpact; | 427 return worldImpact; |
472 } | 428 } |
473 } | 429 } |
474 | 430 |
475 /// Interface for serialization of backend specific data. | 431 /// Interface for serialization of backend specific data. |
476 class BackendSerialization { | 432 class BackendSerialization { |
477 const BackendSerialization(); | 433 const BackendSerialization(); |
478 | 434 |
479 SerializerPlugin get serializer => const SerializerPlugin(); | 435 SerializerPlugin get serializer => const SerializerPlugin(); |
480 DeserializerPlugin get deserializer => const DeserializerPlugin(); | 436 DeserializerPlugin get deserializer => const DeserializerPlugin(); |
481 } | 437 } |
OLD | NEW |