| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 | 7 |
| 8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 }); | 513 }); |
| 514 } | 514 } |
| 515 } | 515 } |
| 516 | 516 |
| 517 void emitLazilyInitializedStaticFields(CodeOutput output) { | 517 void emitLazilyInitializedStaticFields(CodeOutput output) { |
| 518 JavaScriptConstantCompiler handler = backend.constants; | 518 JavaScriptConstantCompiler handler = backend.constants; |
| 519 List<VariableElement> lazyFields = | 519 List<VariableElement> lazyFields = |
| 520 handler.getLazilyInitializedFieldsForEmission(); | 520 handler.getLazilyInitializedFieldsForEmission(); |
| 521 if (!lazyFields.isEmpty) { | 521 if (!lazyFields.isEmpty) { |
| 522 needsLazyInitializer = true; | 522 needsLazyInitializer = true; |
| 523 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { | 523 List<jsAst.Expression> laziesInfo = buildLaziesInfo(lazyFields); |
| 524 jsAst.Expression init = | 524 jsAst.Statement code = js.statement(''' |
| 525 buildLazilyInitializedStaticField(element); | 525 (function(lazies) { |
| 526 if (init == null) continue; | 526 if (#notInMinifiedMode) { |
| 527 output.addBuffer( | 527 var descriptorLength = 4; |
| 528 jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask)); | 528 } else { |
| 529 output.add("$N"); | 529 var descriptorLength = 3; |
| 530 } | 530 } |
| 531 |
| 532 for (var i = 0; i < lazies.length; i += descriptorLength) { |
| 533 var fieldName = lazies [i]; |
| 534 var getterName = lazies[i + 1]; |
| 535 var lazyValue = lazies[i + 2]; |
| 536 if (#notInMinifiedMode) { |
| 537 var staticName = lazies[i + 3]; |
| 538 } |
| 539 |
| 540 // We build the lazy-check here: |
| 541 // lazyInitializer(fieldName, getterName, lazyValue, staticName); |
| 542 // 'staticName' is used for error reporting in non-minified mode. |
| 543 // 'lazyValue' must be a closure that constructs the initial value. |
| 544 if (#notInMinifiedMode) { |
| 545 #lazy(fieldName, getterName, lazyValue, staticName); |
| 546 } else { |
| 547 #lazy(fieldName, getterName, lazyValue); |
| 548 } |
| 549 } |
| 550 })(#laziesInfo) |
| 551 ''', {'notInMinifiedMode': !compiler.enableMinification, |
| 552 'laziesInfo': new jsAst.ArrayInitializer(laziesInfo), |
| 553 'lazy': js(lazyInitializerName)}); |
| 554 |
| 555 output.addBuffer( |
| 556 jsAst.prettyPrint(code, compiler, monitor: compiler.dumpInfoTask)); |
| 557 output.add("$N"); |
| 531 } | 558 } |
| 532 } | 559 } |
| 533 | 560 |
| 561 List<jsAst.Expression> buildLaziesInfo(List<VariableElement> lazies) { |
| 562 List<jsAst.Expression> laziesInfo = <jsAst.Expression>[]; |
| 563 for (VariableElement element in Elements.sortedByPosition(lazies)) { |
| 564 jsAst.Expression code = backend.generatedCode[element]; |
| 565 // The code is null if we ended up not needing the lazily |
| 566 // initialized field after all because of constant folding |
| 567 // before code generation. |
| 568 if (code == null) continue; |
| 569 if (compiler.enableMinification) { |
| 570 laziesInfo.addAll([js.string(namer.globalPropertyName(element)), |
| 571 js.string(namer.lazyInitializerName(element)), |
| 572 code]); |
| 573 } else { |
| 574 laziesInfo.addAll([js.string(namer.globalPropertyName(element)), |
| 575 js.string(namer.lazyInitializerName(element)), |
| 576 code, |
| 577 js.string(element.name)]); |
| 578 } |
| 579 } |
| 580 return laziesInfo; |
| 581 } |
| 582 |
| 534 jsAst.Expression buildLazilyInitializedStaticField( | 583 jsAst.Expression buildLazilyInitializedStaticField( |
| 535 VariableElement element, {String isolateProperties}) { | 584 VariableElement element, {String isolateProperties}) { |
| 536 jsAst.Expression code = backend.generatedCode[element]; | 585 jsAst.Expression code = backend.generatedCode[element]; |
| 537 // The code is null if we ended up not needing the lazily | 586 // The code is null if we ended up not needing the lazily |
| 538 // initialized field after all because of constant folding | 587 // initialized field after all because of constant folding |
| 539 // before code generation. | 588 // before code generation. |
| 540 if (code == null) return null; | 589 if (code == null) return null; |
| 541 // The code only computes the initial value. We build the lazy-check | 590 // The code only computes the initial value. We build the lazy-check |
| 542 // here: | 591 // here: |
| 543 // lazyInitializer(fieldName, getterName, initial, name, prototype); | 592 // lazyInitializer(fieldName, getterName, initial, name, prototype); |
| 544 // The name is used for error reporting. The 'initial' must be a | 593 // The name is used for error reporting. The 'initial' must be a |
| 545 // closure that constructs the initial value. | 594 // closure that constructs the initial value. |
| 546 if (isolateProperties != null) { | 595 if (isolateProperties != null) { |
| 547 // This is currently only used in incremental compilation to patch | 596 // This is currently only used in incremental compilation to patch |
| 548 // in new lazy values. | 597 // in new lazy values. |
| 549 return js('#(#,#,#,#,#)', | 598 return js('#(#,#,#,#,#)', |
| 550 [js(lazyInitializerName), | 599 [js(lazyInitializerName), |
| 551 js.string(namer.globalPropertyName(element)), | 600 js.string(namer.globalPropertyName(element)), |
| 552 js.string(namer.lazyInitializerName(element)), | 601 js.string(namer.lazyInitializerName(element)), |
| 553 code, | 602 code, |
| 554 js.string(element.name), | 603 js.string(element.name), |
| 555 isolateProperties]); | 604 isolateProperties]); |
| 556 } | 605 } |
| 557 | 606 |
| 558 if (compiler.enableMinification) { | 607 if (compiler.enableMinification) { |
| 559 return js('#(#,#,#)', | 608 return js('#(#,#,#)', |
| 560 [js(lazyInitializerName), | 609 [js(lazyInitializerName), |
| 561 js.string(namer.globalPropertyName(element)), | 610 js.string(namer.globalPropertyName(element)), |
| 562 js.string(namer.lazyInitializerName(element)), | 611 js.string(namer.lazyInitializerName(element)), |
| 563 code]); | 612 code]); |
| 564 } else { | 613 } else { |
| 565 return js('#(#,#,#,#)', | 614 return js('#(#,#,#,#)', |
| 566 [js(lazyInitializerName), | 615 [js(lazyInitializerName), |
| 567 js.string(namer.globalPropertyName(element)), | 616 js.string(namer.globalPropertyName(element)), |
| 568 js.string(namer.lazyInitializerName(element)), | 617 js.string(namer.lazyInitializerName(element)), |
| 569 code, | 618 code, |
| 570 js.string(element.name)]); | 619 js.string(element.name)]); |
| 571 } | 620 } |
| 572 } | 621 } |
| 573 | 622 |
| 574 void emitMetadata(Program program, CodeOutput output) { | 623 void emitMetadata(Program program, CodeOutput output) { |
| 575 | 624 |
| 576 addMetadataGlobal(List<String> list, String global) { | 625 addMetadataGlobal(List<String> list, String global) { |
| 577 String globalAccess = generateEmbeddedGlobalAccessString(global); | 626 String globalAccess = generateEmbeddedGlobalAccessString(global); |
| 578 output.add('$globalAccess$_=$_['); | 627 output.add('$globalAccess$_=$_['); |
| 579 for (String data in list) { | 628 for (String data in list) { |
| 580 if (data is String) { | 629 if (data is String) { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 try { | 784 try { |
| 736 result = this[fieldName] = lazyValue(); | 785 result = this[fieldName] = lazyValue(); |
| 737 } finally { | 786 } finally { |
| 738 // Use try-finally, not try-catch/throw as it destroys the | 787 // Use try-finally, not try-catch/throw as it destroys the |
| 739 // stack trace. | 788 // stack trace. |
| 740 if (result === sentinelUndefined) | 789 if (result === sentinelUndefined) |
| 741 this[fieldName] = null; | 790 this[fieldName] = null; |
| 742 } | 791 } |
| 743 } else { | 792 } else { |
| 744 if (result === sentinelInProgress) | 793 if (result === sentinelInProgress) |
| 745 // In minified mode, static name might not have been | 794 // In minified mode, static name is not provided, so fall |
| 746 // provided, so fall back to the minified fieldName. | 795 // back to the minified fieldName. |
| 747 #cyclicThrow(staticName || fieldName); | 796 #cyclicThrow(staticName || fieldName); |
| 748 } | 797 } |
| 749 | 798 |
| 750 return result; | 799 return result; |
| 751 } finally { | 800 } finally { |
| 752 this[getterName] = function() { return this[fieldName]; }; | 801 this[getterName] = function() { return this[fieldName]; }; |
| 753 } | 802 } |
| 754 } | 803 } |
| 755 } | 804 } |
| 756 } | 805 } |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 emitDeferredBoilerPlate(mainOutput, deferredLoadHashes); | 1327 emitDeferredBoilerPlate(mainOutput, deferredLoadHashes); |
| 1279 | 1328 |
| 1280 if (compiler.deferredMapUri != null) { | 1329 if (compiler.deferredMapUri != null) { |
| 1281 outputDeferredMap(); | 1330 outputDeferredMap(); |
| 1282 } | 1331 } |
| 1283 | 1332 |
| 1284 // Static field initializations require the classes and compile-time | 1333 // Static field initializations require the classes and compile-time |
| 1285 // constants to be set up. | 1334 // constants to be set up. |
| 1286 emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit); | 1335 emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit); |
| 1287 interceptorEmitter.emitTypeToInterceptorMap(program, mainOutput); | 1336 interceptorEmitter.emitTypeToInterceptorMap(program, mainOutput); |
| 1337 if (compiler.enableMinification) { |
| 1338 mainOutput.add(';'); |
| 1339 } |
| 1288 emitLazilyInitializedStaticFields(mainOutput); | 1340 emitLazilyInitializedStaticFields(mainOutput); |
| 1289 | 1341 |
| 1290 mainOutput.add('\n'); | 1342 mainOutput.add('\n'); |
| 1291 | 1343 |
| 1292 emitMetadata(program, mainOutput); | 1344 emitMetadata(program, mainOutput); |
| 1293 | 1345 |
| 1294 isolateProperties = isolatePropertiesName; | 1346 isolateProperties = isolatePropertiesName; |
| 1295 // The following code should not use the short-hand for the | 1347 // The following code should not use the short-hand for the |
| 1296 // initialStatics. | 1348 // initialStatics. |
| 1297 mainOutput.add('${namer.currentIsolate}$_=${_}null$N'); | 1349 mainOutput.add('${namer.currentIsolate}$_=${_}null$N'); |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 1875 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 1824 if (element.isInstanceMember) { | 1876 if (element.isInstanceMember) { |
| 1825 cachedClassBuilders.remove(element.enclosingClass); | 1877 cachedClassBuilders.remove(element.enclosingClass); |
| 1826 | 1878 |
| 1827 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 1879 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 1828 | 1880 |
| 1829 } | 1881 } |
| 1830 } | 1882 } |
| 1831 } | 1883 } |
| 1832 } | 1884 } |
| OLD | NEW |