| 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 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
| 9 * compiled. | 9 * compiled. |
| 10 */ | 10 */ |
| 11 const bool REPORT_EXCESS_RESOLUTION = false; | 11 const bool REPORT_EXCESS_RESOLUTION = false; |
| 12 | 12 |
| 13 /** | 13 /** |
| 14 * If true, dump the inferred types after compilation. | |
| 15 */ | |
| 16 const bool DUMP_INFERRED_TYPES = false; | |
| 17 | |
| 18 /** | |
| 19 * Contains backend-specific data that is used throughout the compilation of | 14 * Contains backend-specific data that is used throughout the compilation of |
| 20 * one work item. | 15 * one work item. |
| 21 */ | 16 */ |
| 22 class ItemCompilationContext { | 17 class ItemCompilationContext { |
| 23 } | 18 } |
| 24 | 19 |
| 25 abstract class WorkItem { | 20 abstract class WorkItem { |
| 26 final ItemCompilationContext compilationContext; | 21 final ItemCompilationContext compilationContext; |
| 27 /** | 22 /** |
| 28 * Documentation wanted -- johnniwinther | 23 * Documentation wanted -- johnniwinther |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } | 73 } |
| 79 | 74 |
| 80 abstract class Backend { | 75 abstract class Backend { |
| 81 final Compiler compiler; | 76 final Compiler compiler; |
| 82 final ConstantSystem constantSystem; | 77 final ConstantSystem constantSystem; |
| 83 | 78 |
| 84 Backend(this.compiler, | 79 Backend(this.compiler, |
| 85 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) | 80 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) |
| 86 : this.constantSystem = constantSystem; | 81 : this.constantSystem = constantSystem; |
| 87 | 82 |
| 83 // Given a [FunctionElement], return a buffer with the code generated for it |
| 84 // or null if no code was generated. |
| 85 CodeBuffer codeOf(Element element) => null; |
| 86 |
| 88 void initializeHelperClasses() {} | 87 void initializeHelperClasses() {} |
| 89 | 88 |
| 90 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements); | 89 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements); |
| 91 void codegen(CodegenWorkItem work); | 90 void codegen(CodegenWorkItem work); |
| 92 | 91 |
| 93 // The backend determines the native resolution enqueuer, with a no-op | 92 // The backend determines the native resolution enqueuer, with a no-op |
| 94 // default, so tools like dart2dart can ignore the native classes. | 93 // default, so tools like dart2dart can ignore the native classes. |
| 95 native.NativeEnqueuer nativeResolutionEnqueuer(world) { | 94 native.NativeEnqueuer nativeResolutionEnqueuer(world) { |
| 96 return new native.NativeEnqueuer(); | 95 return new native.NativeEnqueuer(); |
| 97 } | 96 } |
| 98 native.NativeEnqueuer nativeCodegenEnqueuer(world) { | 97 native.NativeEnqueuer nativeCodegenEnqueuer(world) { |
| 99 return new native.NativeEnqueuer(); | 98 return new native.NativeEnqueuer(); |
| 100 } | 99 } |
| 101 | 100 |
| 102 void assembleProgram(); | 101 void assembleProgram(); |
| 103 List<CompilerTask> get tasks; | 102 List<CompilerTask> get tasks; |
| 104 | 103 |
| 105 void onResolutionComplete() {} | 104 void onResolutionComplete() {} |
| 106 | 105 |
| 107 // TODO(ahe,karlklose): rename this? | |
| 108 void dumpInferredTypes() {} | |
| 109 | |
| 110 ItemCompilationContext createItemCompilationContext() { | 106 ItemCompilationContext createItemCompilationContext() { |
| 111 return new ItemCompilationContext(); | 107 return new ItemCompilationContext(); |
| 112 } | 108 } |
| 113 | 109 |
| 114 bool classNeedsRti(ClassElement cls); | 110 bool classNeedsRti(ClassElement cls); |
| 115 bool methodNeedsRti(FunctionElement function); | 111 bool methodNeedsRti(FunctionElement function); |
| 116 | 112 |
| 117 | 113 |
| 118 /// Called during codegen when [constant] has been used. | 114 /// Called during codegen when [constant] has been used. |
| 119 void registerCompileTimeConstant(Constant constant, TreeElements elements) {} | 115 void registerCompileTimeConstant(Constant constant, TreeElements elements) {} |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 * associated with a particular element. | 351 * associated with a particular element. |
| 356 */ | 352 */ |
| 357 final TreeElements globalDependencies = new TreeElementMapping(null); | 353 final TreeElements globalDependencies = new TreeElementMapping(null); |
| 358 | 354 |
| 359 final bool enableMinification; | 355 final bool enableMinification; |
| 360 final bool enableTypeAssertions; | 356 final bool enableTypeAssertions; |
| 361 final bool enableUserAssertions; | 357 final bool enableUserAssertions; |
| 362 final bool trustTypeAnnotations; | 358 final bool trustTypeAnnotations; |
| 363 final bool enableConcreteTypeInference; | 359 final bool enableConcreteTypeInference; |
| 364 final bool disableTypeInferenceFlag; | 360 final bool disableTypeInferenceFlag; |
| 361 final bool dumpInfo; |
| 365 | 362 |
| 366 /** | 363 /** |
| 367 * The maximum size of a concrete type before it widens to dynamic during | 364 * The maximum size of a concrete type before it widens to dynamic during |
| 368 * concrete type inference. | 365 * concrete type inference. |
| 369 */ | 366 */ |
| 370 final int maxConcreteTypeSize; | 367 final int maxConcreteTypeSize; |
| 371 final bool analyzeAllFlag; | 368 final bool analyzeAllFlag; |
| 372 final bool analyzeOnly; | 369 final bool analyzeOnly; |
| 373 /** | 370 /** |
| 374 * If true, skip analysis of method bodies and field initializers. Implies | 371 * If true, skip analysis of method bodies and field initializers. Implies |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 ResolverTask resolver; | 533 ResolverTask resolver; |
| 537 closureMapping.ClosureTask closureToClassMapper; | 534 closureMapping.ClosureTask closureToClassMapper; |
| 538 TypeCheckerTask checker; | 535 TypeCheckerTask checker; |
| 539 IrBuilderTask irBuilder; | 536 IrBuilderTask irBuilder; |
| 540 ti.TypesTask typesTask; | 537 ti.TypesTask typesTask; |
| 541 Backend backend; | 538 Backend backend; |
| 542 ConstantHandler constantHandler; | 539 ConstantHandler constantHandler; |
| 543 EnqueueTask enqueuer; | 540 EnqueueTask enqueuer; |
| 544 DeferredLoadTask deferredLoadTask; | 541 DeferredLoadTask deferredLoadTask; |
| 545 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; | 542 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
| 543 DumpInfoTask dumpInfoTask; |
| 546 String buildId; | 544 String buildId; |
| 547 | 545 |
| 548 static const String MAIN = 'main'; | 546 static const String MAIN = 'main'; |
| 549 static const String CALL_OPERATOR_NAME = 'call'; | 547 static const String CALL_OPERATOR_NAME = 'call'; |
| 550 static const String NO_SUCH_METHOD = 'noSuchMethod'; | 548 static const String NO_SUCH_METHOD = 'noSuchMethod'; |
| 551 static const int NO_SUCH_METHOD_ARG_COUNT = 1; | 549 static const int NO_SUCH_METHOD_ARG_COUNT = 1; |
| 552 static const String CREATE_INVOCATION_MIRROR = | 550 static const String CREATE_INVOCATION_MIRROR = |
| 553 'createInvocationMirror'; | 551 'createInvocationMirror'; |
| 554 | 552 |
| 555 // TODO(ahe): Rename this field and move this logic to backend, similar to how | 553 // TODO(ahe): Rename this field and move this logic to backend, similar to how |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 bool emitJavaScript: true, | 607 bool emitJavaScript: true, |
| 610 bool generateSourceMap: true, | 608 bool generateSourceMap: true, |
| 611 this.analyzeAllFlag: false, | 609 this.analyzeAllFlag: false, |
| 612 bool analyzeOnly: false, | 610 bool analyzeOnly: false, |
| 613 bool analyzeSignaturesOnly: false, | 611 bool analyzeSignaturesOnly: false, |
| 614 this.preserveComments: false, | 612 this.preserveComments: false, |
| 615 this.verbose: false, | 613 this.verbose: false, |
| 616 this.sourceMapUri: null, | 614 this.sourceMapUri: null, |
| 617 this.buildId: UNDETERMINED_BUILD_ID, | 615 this.buildId: UNDETERMINED_BUILD_ID, |
| 618 this.terseDiagnostics: false, | 616 this.terseDiagnostics: false, |
| 617 this.dumpInfo: false, |
| 619 outputProvider, | 618 outputProvider, |
| 620 List<String> strips: const []}) | 619 List<String> strips: const []}) |
| 621 : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly, | 620 : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly, |
| 622 this.analyzeSignaturesOnly = analyzeSignaturesOnly, | 621 this.analyzeSignaturesOnly = analyzeSignaturesOnly, |
| 623 this.outputProvider = (outputProvider == null) | 622 this.outputProvider = (outputProvider == null) |
| 624 ? NullSink.outputProvider | 623 ? NullSink.outputProvider |
| 625 : outputProvider { | 624 : outputProvider { |
| 626 world = new World(this); | 625 world = new World(this); |
| 627 | 626 |
| 628 closureMapping.ClosureNamer closureNamer; | 627 closureMapping.ClosureNamer closureNamer; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 646 parser = new ParserTask(this), | 645 parser = new ParserTask(this), |
| 647 patchParser = new PatchParserTask(this), | 646 patchParser = new PatchParserTask(this), |
| 648 resolver = new ResolverTask(this), | 647 resolver = new ResolverTask(this), |
| 649 closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer), | 648 closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer), |
| 650 checker = new TypeCheckerTask(this), | 649 checker = new TypeCheckerTask(this), |
| 651 irBuilder = new IrBuilderTask(this), | 650 irBuilder = new IrBuilderTask(this), |
| 652 typesTask = new ti.TypesTask(this), | 651 typesTask = new ti.TypesTask(this), |
| 653 constantHandler = new ConstantHandler(this, backend.constantSystem), | 652 constantHandler = new ConstantHandler(this, backend.constantSystem), |
| 654 deferredLoadTask = new DeferredLoadTask(this), | 653 deferredLoadTask = new DeferredLoadTask(this), |
| 655 mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this), | 654 mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this), |
| 656 enqueuer = new EnqueueTask(this)]; | 655 enqueuer = new EnqueueTask(this), |
| 656 dumpInfoTask = new DumpInfoTask(this)]; |
| 657 | 657 |
| 658 tasks.addAll(backend.tasks); | 658 tasks.addAll(backend.tasks); |
| 659 } | 659 } |
| 660 | 660 |
| 661 Universe get resolverWorld => enqueuer.resolution.universe; | 661 Universe get resolverWorld => enqueuer.resolution.universe; |
| 662 Universe get codegenWorld => enqueuer.codegen.universe; | 662 Universe get codegenWorld => enqueuer.codegen.universe; |
| 663 | 663 |
| 664 bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID; | 664 bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID; |
| 665 | 665 |
| 666 bool get analyzeAll => analyzeAllFlag || compileAll; | 666 bool get analyzeAll => analyzeAllFlag || compileAll; |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, | 1123 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, |
| 1124 enqueuer.codegen)); | 1124 enqueuer.codegen)); |
| 1125 } | 1125 } |
| 1126 processQueue(enqueuer.codegen, main); | 1126 processQueue(enqueuer.codegen, main); |
| 1127 enqueuer.codegen.logSummary(log); | 1127 enqueuer.codegen.logSummary(log); |
| 1128 | 1128 |
| 1129 if (compilationFailed) return; | 1129 if (compilationFailed) return; |
| 1130 | 1130 |
| 1131 backend.assembleProgram(); | 1131 backend.assembleProgram(); |
| 1132 | 1132 |
| 1133 if (dumpInfo) { |
| 1134 dumpInfoTask.dumpInfo(); |
| 1135 } |
| 1136 |
| 1133 checkQueues(); | 1137 checkQueues(); |
| 1134 | 1138 |
| 1135 if (compilationFailed) { | 1139 if (compilationFailed) { |
| 1136 assembledCode = null; // Signals failure. | 1140 assembledCode = null; // Signals failure. |
| 1137 } | 1141 } |
| 1138 } | 1142 } |
| 1139 | 1143 |
| 1140 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { | 1144 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { |
| 1141 void enqueueAll(Element element) { | 1145 void enqueueAll(Element element) { |
| 1142 fullyEnqueueTopLevelElement(element, world); | 1146 fullyEnqueueTopLevelElement(element, world); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 } | 1186 } |
| 1183 world.addToWorkList(main); | 1187 world.addToWorkList(main); |
| 1184 } | 1188 } |
| 1185 progress.reset(); | 1189 progress.reset(); |
| 1186 world.forEach((WorkItem work) { | 1190 world.forEach((WorkItem work) { |
| 1187 withCurrentElement(work.element, () => work.run(this, world)); | 1191 withCurrentElement(work.element, () => work.run(this, world)); |
| 1188 }); | 1192 }); |
| 1189 world.queueIsClosed = true; | 1193 world.queueIsClosed = true; |
| 1190 if (compilationFailed) return; | 1194 if (compilationFailed) return; |
| 1191 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 1195 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 1192 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { | |
| 1193 backend.dumpInferredTypes(); | |
| 1194 } | |
| 1195 } | 1196 } |
| 1196 | 1197 |
| 1197 /** | 1198 /** |
| 1198 * Perform various checks of the queues. This includes checking that | 1199 * Perform various checks of the queues. This includes checking that |
| 1199 * the queues are empty (nothing was added after we stopped | 1200 * the queues are empty (nothing was added after we stopped |
| 1200 * processing the queues). Also compute the number of methods that | 1201 * processing the queues). Also compute the number of methods that |
| 1201 * were resolved, but not compiled (aka excess resolution). | 1202 * were resolved, but not compiled (aka excess resolution). |
| 1202 */ | 1203 */ |
| 1203 checkQueues() { | 1204 checkQueues() { |
| 1204 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 1205 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1672 | 1673 |
| 1673 void close() {} | 1674 void close() {} |
| 1674 | 1675 |
| 1675 toString() => name; | 1676 toString() => name; |
| 1676 | 1677 |
| 1677 /// Convenience method for getting an [api.CompilerOutputProvider]. | 1678 /// Convenience method for getting an [api.CompilerOutputProvider]. |
| 1678 static NullSink outputProvider(String name, String extension) { | 1679 static NullSink outputProvider(String name, String extension) { |
| 1679 return new NullSink('$name.$extension'); | 1680 return new NullSink('$name.$extension'); |
| 1680 } | 1681 } |
| 1681 } | 1682 } |
| OLD | NEW |