| 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(FunctionElement functionElement) => null; |
| 86 |
| 88 void initializeHelperClasses() {} | 87 void initializeHelperClasses() {} |
| 89 | 88 |
| 90 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { | 89 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { |
| 91 lib.forEachExport((Element e) { | 90 lib.forEachExport((Element e) { |
| 92 if (e.isFunction()) world.addToWorkList(e); | 91 if (e.isFunction()) world.addToWorkList(e); |
| 93 }); | 92 }); |
| 94 } | 93 } |
| 95 | 94 |
| 96 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements); | 95 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements); |
| 97 void codegen(CodegenWorkItem work); | 96 void codegen(CodegenWorkItem work); |
| 98 | 97 |
| 99 // The backend determines the native resolution enqueuer, with a no-op | 98 // The backend determines the native resolution enqueuer, with a no-op |
| 100 // default, so tools like dart2dart can ignore the native classes. | 99 // default, so tools like dart2dart can ignore the native classes. |
| 101 native.NativeEnqueuer nativeResolutionEnqueuer(world) { | 100 native.NativeEnqueuer nativeResolutionEnqueuer(world) { |
| 102 return new native.NativeEnqueuer(); | 101 return new native.NativeEnqueuer(); |
| 103 } | 102 } |
| 104 native.NativeEnqueuer nativeCodegenEnqueuer(world) { | 103 native.NativeEnqueuer nativeCodegenEnqueuer(world) { |
| 105 return new native.NativeEnqueuer(); | 104 return new native.NativeEnqueuer(); |
| 106 } | 105 } |
| 107 | 106 |
| 108 void assembleProgram(); | 107 void assembleProgram(); |
| 109 List<CompilerTask> get tasks; | 108 List<CompilerTask> get tasks; |
| 110 | 109 |
| 111 void onResolutionComplete() {} | 110 void onResolutionComplete() {} |
| 112 | 111 |
| 113 // TODO(ahe,karlklose): rename this? | |
| 114 void dumpInferredTypes() {} | |
| 115 | |
| 116 ItemCompilationContext createItemCompilationContext() { | 112 ItemCompilationContext createItemCompilationContext() { |
| 117 return new ItemCompilationContext(); | 113 return new ItemCompilationContext(); |
| 118 } | 114 } |
| 119 | 115 |
| 120 bool classNeedsRti(ClassElement cls); | 116 bool classNeedsRti(ClassElement cls); |
| 121 bool methodNeedsRti(FunctionElement function); | 117 bool methodNeedsRti(FunctionElement function); |
| 122 | 118 |
| 123 | 119 |
| 124 /// Called during codegen when [constant] has been used. | 120 /// Called during codegen when [constant] has been used. |
| 125 void registerCompileTimeConstant(Constant constant, TreeElements elements) {} | 121 void registerCompileTimeConstant(Constant constant, TreeElements elements) {} |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 * associated with a particular element. | 357 * associated with a particular element. |
| 362 */ | 358 */ |
| 363 final TreeElements globalDependencies = new TreeElementMapping(null); | 359 final TreeElements globalDependencies = new TreeElementMapping(null); |
| 364 | 360 |
| 365 final bool enableMinification; | 361 final bool enableMinification; |
| 366 final bool enableTypeAssertions; | 362 final bool enableTypeAssertions; |
| 367 final bool enableUserAssertions; | 363 final bool enableUserAssertions; |
| 368 final bool trustTypeAnnotations; | 364 final bool trustTypeAnnotations; |
| 369 final bool enableConcreteTypeInference; | 365 final bool enableConcreteTypeInference; |
| 370 final bool disableTypeInferenceFlag; | 366 final bool disableTypeInferenceFlag; |
| 367 final bool dumpInfo; |
| 371 | 368 |
| 372 /** | 369 /** |
| 373 * The maximum size of a concrete type before it widens to dynamic during | 370 * The maximum size of a concrete type before it widens to dynamic during |
| 374 * concrete type inference. | 371 * concrete type inference. |
| 375 */ | 372 */ |
| 376 final int maxConcreteTypeSize; | 373 final int maxConcreteTypeSize; |
| 377 final bool analyzeAllFlag; | 374 final bool analyzeAllFlag; |
| 378 final bool analyzeOnly; | 375 final bool analyzeOnly; |
| 379 /** | 376 /** |
| 380 * If true, skip analysis of method bodies and field initializers. Implies | 377 * If true, skip analysis of method bodies and field initializers. Implies |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 ResolverTask resolver; | 539 ResolverTask resolver; |
| 543 closureMapping.ClosureTask closureToClassMapper; | 540 closureMapping.ClosureTask closureToClassMapper; |
| 544 TypeCheckerTask checker; | 541 TypeCheckerTask checker; |
| 545 IrBuilderTask irBuilder; | 542 IrBuilderTask irBuilder; |
| 546 ti.TypesTask typesTask; | 543 ti.TypesTask typesTask; |
| 547 Backend backend; | 544 Backend backend; |
| 548 ConstantHandler constantHandler; | 545 ConstantHandler constantHandler; |
| 549 EnqueueTask enqueuer; | 546 EnqueueTask enqueuer; |
| 550 DeferredLoadTask deferredLoadTask; | 547 DeferredLoadTask deferredLoadTask; |
| 551 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; | 548 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
| 549 DumpInfoTask dumpInfoTask; |
| 552 String buildId; | 550 String buildId; |
| 553 | 551 |
| 554 static const String MAIN = 'main'; | 552 static const String MAIN = 'main'; |
| 555 static const String CALL_OPERATOR_NAME = 'call'; | 553 static const String CALL_OPERATOR_NAME = 'call'; |
| 556 static const String NO_SUCH_METHOD = 'noSuchMethod'; | 554 static const String NO_SUCH_METHOD = 'noSuchMethod'; |
| 557 static const int NO_SUCH_METHOD_ARG_COUNT = 1; | 555 static const int NO_SUCH_METHOD_ARG_COUNT = 1; |
| 558 static const String CREATE_INVOCATION_MIRROR = | 556 static const String CREATE_INVOCATION_MIRROR = |
| 559 'createInvocationMirror'; | 557 'createInvocationMirror'; |
| 560 | 558 |
| 561 // TODO(ahe): Rename this field and move this logic to backend, similar to how | 559 // 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... |
| 615 bool emitJavaScript: true, | 613 bool emitJavaScript: true, |
| 616 bool generateSourceMap: true, | 614 bool generateSourceMap: true, |
| 617 this.analyzeAllFlag: false, | 615 this.analyzeAllFlag: false, |
| 618 bool analyzeOnly: false, | 616 bool analyzeOnly: false, |
| 619 bool analyzeSignaturesOnly: false, | 617 bool analyzeSignaturesOnly: false, |
| 620 this.preserveComments: false, | 618 this.preserveComments: false, |
| 621 this.verbose: false, | 619 this.verbose: false, |
| 622 this.sourceMapUri: null, | 620 this.sourceMapUri: null, |
| 623 this.buildId: UNDETERMINED_BUILD_ID, | 621 this.buildId: UNDETERMINED_BUILD_ID, |
| 624 this.terseDiagnostics: false, | 622 this.terseDiagnostics: false, |
| 623 this.dumpInfo: false, |
| 625 outputProvider, | 624 outputProvider, |
| 626 List<String> strips: const []}) | 625 List<String> strips: const []}) |
| 627 : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly, | 626 : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly, |
| 628 this.analyzeSignaturesOnly = analyzeSignaturesOnly, | 627 this.analyzeSignaturesOnly = analyzeSignaturesOnly, |
| 629 this.outputProvider = (outputProvider == null) | 628 this.outputProvider = (outputProvider == null) |
| 630 ? NullSink.outputProvider | 629 ? NullSink.outputProvider |
| 631 : outputProvider { | 630 : outputProvider { |
| 632 world = new World(this); | 631 world = new World(this); |
| 633 | 632 |
| 634 closureMapping.ClosureNamer closureNamer; | 633 closureMapping.ClosureNamer closureNamer; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 652 parser = new ParserTask(this), | 651 parser = new ParserTask(this), |
| 653 patchParser = new PatchParserTask(this), | 652 patchParser = new PatchParserTask(this), |
| 654 resolver = new ResolverTask(this), | 653 resolver = new ResolverTask(this), |
| 655 closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer), | 654 closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer), |
| 656 checker = new TypeCheckerTask(this), | 655 checker = new TypeCheckerTask(this), |
| 657 irBuilder = new IrBuilderTask(this), | 656 irBuilder = new IrBuilderTask(this), |
| 658 typesTask = new ti.TypesTask(this), | 657 typesTask = new ti.TypesTask(this), |
| 659 constantHandler = new ConstantHandler(this, backend.constantSystem), | 658 constantHandler = new ConstantHandler(this, backend.constantSystem), |
| 660 deferredLoadTask = new DeferredLoadTask(this), | 659 deferredLoadTask = new DeferredLoadTask(this), |
| 661 mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this), | 660 mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this), |
| 662 enqueuer = new EnqueueTask(this)]; | 661 enqueuer = new EnqueueTask(this), |
| 663 | 662 dumpInfoTask = new DumpInfoTask(this)]; |
| 664 tasks.addAll(backend.tasks); | 663 tasks.addAll(backend.tasks); |
| 665 } | 664 } |
| 666 | 665 |
| 667 Universe get resolverWorld => enqueuer.resolution.universe; | 666 Universe get resolverWorld => enqueuer.resolution.universe; |
| 668 Universe get codegenWorld => enqueuer.codegen.universe; | 667 Universe get codegenWorld => enqueuer.codegen.universe; |
| 669 | 668 |
| 670 bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID; | 669 bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID; |
| 671 | 670 |
| 672 bool get analyzeAll => analyzeAllFlag || compileAll; | 671 bool get analyzeAll => analyzeAllFlag || compileAll; |
| 673 | 672 |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, | 1121 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, |
| 1123 enqueuer.codegen)); | 1122 enqueuer.codegen)); |
| 1124 } | 1123 } |
| 1125 processQueue(enqueuer.codegen, main); | 1124 processQueue(enqueuer.codegen, main); |
| 1126 enqueuer.codegen.logSummary(log); | 1125 enqueuer.codegen.logSummary(log); |
| 1127 | 1126 |
| 1128 if (compilationFailed) return; | 1127 if (compilationFailed) return; |
| 1129 | 1128 |
| 1130 backend.assembleProgram(); | 1129 backend.assembleProgram(); |
| 1131 | 1130 |
| 1131 if (dumpInfo) { |
| 1132 dumpInfoTask.dumpInfo(); |
| 1133 } |
| 1134 |
| 1132 checkQueues(); | 1135 checkQueues(); |
| 1133 | 1136 |
| 1134 if (compilationFailed) { | 1137 if (compilationFailed) { |
| 1135 assembledCode = null; // Signals failure. | 1138 assembledCode = null; // Signals failure. |
| 1136 } | 1139 } |
| 1137 } | 1140 } |
| 1138 | 1141 |
| 1139 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { | 1142 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { |
| 1140 void enqueueAll(Element element) { | 1143 void enqueueAll(Element element) { |
| 1141 fullyEnqueueTopLevelElement(element, world); | 1144 fullyEnqueueTopLevelElement(element, world); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 } | 1184 } |
| 1182 world.addToWorkList(main); | 1185 world.addToWorkList(main); |
| 1183 } | 1186 } |
| 1184 progress.reset(); | 1187 progress.reset(); |
| 1185 world.forEach((WorkItem work) { | 1188 world.forEach((WorkItem work) { |
| 1186 withCurrentElement(work.element, () => work.run(this, world)); | 1189 withCurrentElement(work.element, () => work.run(this, world)); |
| 1187 }); | 1190 }); |
| 1188 world.queueIsClosed = true; | 1191 world.queueIsClosed = true; |
| 1189 if (compilationFailed) return; | 1192 if (compilationFailed) return; |
| 1190 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 1193 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 1191 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { | |
| 1192 backend.dumpInferredTypes(); | |
| 1193 } | |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 /** | 1196 /** |
| 1197 * Perform various checks of the queues. This includes checking that | 1197 * Perform various checks of the queues. This includes checking that |
| 1198 * the queues are empty (nothing was added after we stopped | 1198 * the queues are empty (nothing was added after we stopped |
| 1199 * processing the queues). Also compute the number of methods that | 1199 * processing the queues). Also compute the number of methods that |
| 1200 * were resolved, but not compiled (aka excess resolution). | 1200 * were resolved, but not compiled (aka excess resolution). |
| 1201 */ | 1201 */ |
| 1202 checkQueues() { | 1202 checkQueues() { |
| 1203 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 1203 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 | 1649 |
| 1650 void close() {} | 1650 void close() {} |
| 1651 | 1651 |
| 1652 toString() => name; | 1652 toString() => name; |
| 1653 | 1653 |
| 1654 /// Convenience method for getting an [api.CompilerOutputProvider]. | 1654 /// Convenience method for getting an [api.CompilerOutputProvider]. |
| 1655 static NullSink outputProvider(String name, String extension) { | 1655 static NullSink outputProvider(String name, String extension) { |
| 1656 return new NullSink('$name.$extension'); | 1656 return new NullSink('$name.$extension'); |
| 1657 } | 1657 } |
| 1658 } | 1658 } |
| OLD | NEW |