Chromium Code Reviews| 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 |
|
ahe
2012/11/14 13:51:30
All my comments in this file are nitpicking.
| |
| 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; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 : this.constantSystem = constantSystem; | 67 : this.constantSystem = constantSystem; |
| 68 | 68 |
| 69 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { | 69 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { |
| 70 lib.forEachExport((Element e) { | 70 lib.forEachExport((Element e) { |
| 71 if (e.isFunction()) world.addToWorkList(e); | 71 if (e.isFunction()) world.addToWorkList(e); |
| 72 }); | 72 }); |
| 73 } | 73 } |
| 74 | 74 |
| 75 void enqueueHelpers(Enqueuer world); | 75 void enqueueHelpers(Enqueuer world); |
| 76 void codegen(WorkItem work); | 76 void codegen(WorkItem work); |
| 77 void processNativeClasses(Enqueuer world, | 77 |
| 78 Collection<LibraryElement> libraries); | 78 // The backend determines the native resolution enqueuer so tools like |
| 79 // dart2dart can ignore the native classes. | |
| 80 native.NativeEnqueuer nativeResolutionEnqueuer(world, bool liveTypeAnalysis) = > | |
|
ahe
2012/11/14 13:51:30
Long line. As a matter of style, I prefer to avoi
ahe
2012/11/14 13:51:30
I don't think the option liveTypeAnalysis is neces
ahe
2012/11/14 13:51:30
An undocumented property of the library native_han
ngeoffray
2012/11/14 21:17:39
Line too long, and the style we used is not to use
sra1
2012/11/15 00:09:10
Almost all the functionality in here will be neede
sra1
2012/11/15 00:09:10
Done.
sra1
2012/11/15 00:09:10
Done.
sra1
2012/11/15 00:09:10
I see plenty of examples.
| |
| 81 new native.NativeEnqueuer(); | |
| 82 native.NativeEnqueuer nativeCodegenEnqueuer(world, bool liveTypeAnalysis) => | |
| 83 new native.NativeEnqueuer(); | |
| 84 | |
| 79 void assembleProgram(); | 85 void assembleProgram(); |
| 80 List<CompilerTask> get tasks; | 86 List<CompilerTask> get tasks; |
| 81 | 87 |
| 82 // TODO(ahe,karlklose): rename this? | 88 // TODO(ahe,karlklose): rename this? |
| 83 void dumpInferredTypes() {} | 89 void dumpInferredTypes() {} |
| 84 | 90 |
| 85 ItemCompilationContext createItemCompilationContext() { | 91 ItemCompilationContext createItemCompilationContext() { |
| 86 return new ItemCompilationContext(); | 92 return new ItemCompilationContext(); |
| 87 } | 93 } |
| 88 | 94 |
| 89 SourceString getCheckedModeHelper(DartType type) => null; | 95 SourceString getCheckedModeHelper(DartType type) => null; |
| 90 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {} | 96 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {} |
| 91 | 97 |
| 92 Element getInterceptor(Selector selector); | 98 Element getInterceptor(Selector selector); |
| 93 } | 99 } |
| 94 | 100 |
| 95 abstract class Compiler implements DiagnosticListener { | 101 abstract class Compiler implements DiagnosticListener { |
| 96 final Map<String, LibraryElement> libraries; | 102 final Map<String, LibraryElement> libraries; |
| 97 int nextFreeClassId = 0; | 103 int nextFreeClassId = 0; |
| 98 World world; | 104 World world; |
| 99 String assembledCode; | 105 String assembledCode; |
| 100 Types types; | 106 Types types; |
| 101 | 107 |
| 102 final bool enableMinification; | 108 final bool enableMinification; |
| 103 final bool enableTypeAssertions; | 109 final bool enableTypeAssertions; |
| 104 final bool enableUserAssertions; | 110 final bool enableUserAssertions; |
| 105 final bool enableConcreteTypeInference; | 111 final bool enableConcreteTypeInference; |
| 112 final bool enableNativeLiveTypeAnalysis; | |
| 106 | 113 |
| 107 bool disableInlining = false; | 114 bool disableInlining = false; |
| 108 | 115 |
| 109 final Tracer tracer; | 116 final Tracer tracer; |
| 110 | 117 |
| 111 CompilerTask measuredTask; | 118 CompilerTask measuredTask; |
| 112 Element _currentElement; | 119 Element _currentElement; |
| 113 LibraryElement coreLibrary; | 120 LibraryElement coreLibrary; |
| 114 LibraryElement isolateLibrary; | 121 LibraryElement isolateLibrary; |
| 115 LibraryElement jsHelperLibrary; | 122 LibraryElement jsHelperLibrary; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 | 210 |
| 204 bool compilationFailed = false; | 211 bool compilationFailed = false; |
| 205 | 212 |
| 206 bool hasCrashed = false; | 213 bool hasCrashed = false; |
| 207 | 214 |
| 208 Compiler({this.tracer: const Tracer(), | 215 Compiler({this.tracer: const Tracer(), |
| 209 this.enableTypeAssertions: false, | 216 this.enableTypeAssertions: false, |
| 210 this.enableUserAssertions: false, | 217 this.enableUserAssertions: false, |
| 211 this.enableConcreteTypeInference: false, | 218 this.enableConcreteTypeInference: false, |
| 212 this.enableMinification: false, | 219 this.enableMinification: false, |
| 220 this.enableNativeLiveTypeAnalysis: false, | |
| 213 bool emitJavaScript: true, | 221 bool emitJavaScript: true, |
| 214 bool generateSourceMap: true, | 222 bool generateSourceMap: true, |
| 215 bool disallowUnsafeEval: false, | 223 bool disallowUnsafeEval: false, |
| 216 List<String> strips: const []}) | 224 List<String> strips: const []}) |
| 217 : libraries = new Map<String, LibraryElement>(), | 225 : libraries = new Map<String, LibraryElement>(), |
| 218 progress = new Stopwatch() { | 226 progress = new Stopwatch() { |
| 219 progress.start(); | 227 progress.start(); |
| 220 world = new World(this); | 228 world = new World(this); |
| 221 scanner = new ScannerTask(this); | 229 scanner = new ScannerTask(this); |
| 222 dietParser = new DietParserTask(this); | 230 dietParser = new DietParserTask(this); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 reportFatalError('Could not find $MAIN', mainApp); | 516 reportFatalError('Could not find $MAIN', mainApp); |
| 509 } else { | 517 } else { |
| 510 if (!main.isFunction()) reportFatalError('main is not a function', main); | 518 if (!main.isFunction()) reportFatalError('main is not a function', main); |
| 511 FunctionElement mainMethod = main; | 519 FunctionElement mainMethod = main; |
| 512 FunctionSignature parameters = mainMethod.computeSignature(this); | 520 FunctionSignature parameters = mainMethod.computeSignature(this); |
| 513 parameters.forEachParameter((Element parameter) { | 521 parameters.forEachParameter((Element parameter) { |
| 514 reportFatalError('main cannot have parameters', parameter); | 522 reportFatalError('main cannot have parameters', parameter); |
| 515 }); | 523 }); |
| 516 } | 524 } |
| 517 | 525 |
| 526 enqueuer.resolution.nativeEnqueuer = | |
| 527 backend.nativeResolutionEnqueuer(enqueuer.resolution, | |
| 528 enableNativeLiveTypeAnalysis); | |
| 529 enqueuer.codegen.nativeEnqueuer = | |
| 530 backend.nativeCodegenEnqueuer(enqueuer.codegen, | |
| 531 enableNativeLiveTypeAnalysis); | |
| 532 | |
| 518 log('Resolving...'); | 533 log('Resolving...'); |
| 519 phase = PHASE_RESOLVING; | 534 phase = PHASE_RESOLVING; |
| 520 backend.enqueueHelpers(enqueuer.resolution); | 535 backend.enqueueHelpers(enqueuer.resolution); |
| 521 processQueue(enqueuer.resolution, main); | 536 processQueue(enqueuer.resolution, main); |
| 522 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); | 537 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); |
| 538 enqueuer.resolution.nativeEnqueuer.logSummary(log); | |
|
ahe
2012/11/14 13:51:30
I like this approach. How about merging these two
sra1
2012/11/15 00:09:10
Done.
| |
| 523 | 539 |
| 524 if (compilationFailed) return; | 540 if (compilationFailed) return; |
| 525 | 541 |
| 526 log('Inferring types...'); | 542 log('Inferring types...'); |
| 527 typesTask.onResolutionComplete(main); | 543 typesTask.onResolutionComplete(main); |
| 528 | 544 |
| 529 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 545 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
| 530 // should know this. | 546 // should know this. |
| 531 world.populate(); | 547 world.populate(); |
| 532 | 548 |
| 533 log('Compiling...'); | 549 log('Compiling...'); |
| 534 phase = PHASE_COMPILING; | 550 phase = PHASE_COMPILING; |
| 535 processQueue(enqueuer.codegen, main); | 551 processQueue(enqueuer.codegen, main); |
| 536 log('Compiled ${codegenWorld.generatedCode.length} methods.'); | 552 log('Compiled ${codegenWorld.generatedCode.length} methods.'); |
| 553 enqueuer.codegen.nativeEnqueuer.logSummary(log); | |
|
ahe
2012/11/14 13:51:30
Ditto.
sra1
2012/11/15 00:09:10
Done.
| |
| 537 | 554 |
| 538 if (compilationFailed) return; | 555 if (compilationFailed) return; |
| 539 | 556 |
| 540 backend.assembleProgram(); | 557 backend.assembleProgram(); |
| 541 | 558 |
| 542 checkQueues(); | 559 checkQueues(); |
| 543 } | 560 } |
| 544 | 561 |
| 545 void processQueue(Enqueuer world, Element main) { | 562 void processQueue(Enqueuer world, Element main) { |
| 546 backend.processNativeClasses(world, libraries.values); | 563 world.nativeEnqueuer.processNativeClasses(libraries.values); |
| 547 world.addToWorkList(main); | 564 world.addToWorkList(main); |
| 548 progress.reset(); | 565 progress.reset(); |
| 549 world.forEach((WorkItem work) { | 566 world.forEach((WorkItem work) { |
| 550 withCurrentElement(work.element, () => work.run(this, world)); | 567 withCurrentElement(work.element, () => work.run(this, world)); |
| 551 }); | 568 }); |
| 552 world.queueIsClosed = true; | 569 world.queueIsClosed = true; |
| 553 if (compilationFailed) return; | 570 if (compilationFailed) return; |
| 554 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 571 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 555 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { | 572 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { |
| 556 backend.dumpInferredTypes(); | 573 backend.dumpInferredTypes(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 if (phase == PHASE_RESOLVING) { | 656 if (phase == PHASE_RESOLVING) { |
| 640 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' | 657 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' |
| 641 'elements.'); | 658 'elements.'); |
| 642 progress.reset(); | 659 progress.reset(); |
| 643 } | 660 } |
| 644 } | 661 } |
| 645 Element element = work.element; | 662 Element element = work.element; |
| 646 TreeElements result = world.getCachedElements(element); | 663 TreeElements result = world.getCachedElements(element); |
| 647 if (result != null) return result; | 664 if (result != null) return result; |
| 648 if (!identical(world, enqueuer.resolution)) { | 665 if (!identical(world, enqueuer.resolution)) { |
| 666 throw 'Internal error: unresolved element: $element.'; | |
|
ahe
2012/11/14 13:51:30
Remove this. FYI: you can often use --throw-on-er
ngeoffray
2012/11/14 21:17:39
Remove debugging code.
sra1
2012/11/15 00:09:10
Done.
| |
| 649 internalErrorOnElement(element, | 667 internalErrorOnElement(element, |
| 650 'Internal error: unresolved element: $element.'); | 668 'Internal error: unresolved element: $element.'); |
| 651 } | 669 } |
| 652 result = analyzeElement(element); | 670 result = analyzeElement(element); |
| 653 assert(invariant(element, element.isDeclaration)); | 671 assert(invariant(element, element.isDeclaration)); |
| 654 enqueuer.resolution.resolvedElements[element] = result; | 672 enqueuer.resolution.resolvedElements[element] = result; |
| 655 return result; | 673 return result; |
| 656 } | 674 } |
| 657 | 675 |
| 658 void codegen(WorkItem work, Enqueuer world) { | 676 void codegen(WorkItem work, Enqueuer world) { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 903 // TODO(johnniwinther): Use [spannable] and [message] to provide better | 921 // TODO(johnniwinther): Use [spannable] and [message] to provide better |
| 904 // information on assertion errors. | 922 // information on assertion errors. |
| 905 if (condition is Function){ | 923 if (condition is Function){ |
| 906 condition = condition(); | 924 condition = condition(); |
| 907 } | 925 } |
| 908 if (spannable == null || !condition) { | 926 if (spannable == null || !condition) { |
| 909 throw new SpannableAssertionFailure(spannable, message); | 927 throw new SpannableAssertionFailure(spannable, message); |
| 910 } | 928 } |
| 911 return true; | 929 return true; |
| 912 } | 930 } |
| OLD | NEW |