| 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 library dart2js.js_emitter.full_emitter; | 5 library dart2js.js_emitter.full_emitter; |
| 6 | 6 |
| 7 import 'dart:collection' show HashMap; | 7 import 'dart:collection' show HashMap; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 | 9 |
| 10 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 10 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 return ':$names'; | 570 return ':$names'; |
| 571 } | 571 } |
| 572 | 572 |
| 573 jsAst.Statement buildCspPrecompiledFunctionFor(OutputUnit outputUnit) { | 573 jsAst.Statement buildCspPrecompiledFunctionFor(OutputUnit outputUnit) { |
| 574 if (compiler.options.useContentSecurityPolicy) { | 574 if (compiler.options.useContentSecurityPolicy) { |
| 575 // TODO(ahe): Compute a hash code. | 575 // TODO(ahe): Compute a hash code. |
| 576 // TODO(sigurdm): Avoid this precompiled function. Generated | 576 // TODO(sigurdm): Avoid this precompiled function. Generated |
| 577 // constructor-functions and getter/setter functions can be stored in the | 577 // constructor-functions and getter/setter functions can be stored in the |
| 578 // library-description table. Setting properties on these can be moved to | 578 // library-description table. Setting properties on these can be moved to |
| 579 // finishClasses. | 579 // finishClasses. |
| 580 return js.statement( | 580 return js.statement(r""" |
| 581 r""" | |
| 582 #precompiled = function ($collectedClasses$) { | 581 #precompiled = function ($collectedClasses$) { |
| 583 #norename; | 582 #norename; |
| 584 var $desc; | 583 var $desc; |
| 585 #functions; | 584 #functions; |
| 586 return #result; | 585 return #result; |
| 587 };""", | 586 };""", { |
| 588 { | 587 'norename': new jsAst.Comment("// ::norenaming:: "), |
| 589 'norename': new jsAst.Comment("// ::norenaming:: "), | 588 'precompiled': generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), |
| 590 'precompiled': | 589 'functions': cspPrecompiledFunctionFor(outputUnit), |
| 591 generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), | 590 'result': new jsAst.ArrayInitializer( |
| 592 'functions': cspPrecompiledFunctionFor(outputUnit), | 591 cspPrecompiledConstructorNamesFor(outputUnit)) |
| 593 'result': new jsAst.ArrayInitializer( | 592 }); |
| 594 cspPrecompiledConstructorNamesFor(outputUnit)) | |
| 595 }); | |
| 596 } else { | 593 } else { |
| 597 return js.comment("Constructors are generated at runtime."); | 594 return js.comment("Constructors are generated at runtime."); |
| 598 } | 595 } |
| 599 } | 596 } |
| 600 | 597 |
| 601 void assembleClass( | 598 void assembleClass( |
| 602 Class cls, ClassBuilder enclosingBuilder, Fragment fragment) { | 599 Class cls, ClassBuilder enclosingBuilder, Fragment fragment) { |
| 603 ClassEntity classElement = cls.element; | 600 ClassEntity classElement = cls.element; |
| 604 reporter.withCurrentElement(classElement, () { | 601 reporter.withCurrentElement(classElement, () { |
| 605 classEmitter.emitClass(cls, enclosingBuilder, fragment); | 602 classEmitter.emitClass(cls, enclosingBuilder, fragment); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 return new jsAst.Block(parts); | 661 return new jsAst.Block(parts); |
| 665 } | 662 } |
| 666 | 663 |
| 667 jsAst.Statement buildLazilyInitializedStaticFields( | 664 jsAst.Statement buildLazilyInitializedStaticFields( |
| 668 Iterable<StaticField> lazyFields, | 665 Iterable<StaticField> lazyFields, |
| 669 {bool isMainFragment: true}) { | 666 {bool isMainFragment: true}) { |
| 670 if (lazyFields.isNotEmpty) { | 667 if (lazyFields.isNotEmpty) { |
| 671 needsLazyInitializer = true; | 668 needsLazyInitializer = true; |
| 672 List<jsAst.Expression> laziesInfo = | 669 List<jsAst.Expression> laziesInfo = |
| 673 buildLaziesInfo(lazyFields, isMainFragment); | 670 buildLaziesInfo(lazyFields, isMainFragment); |
| 674 return js.statement( | 671 return js.statement(''' |
| 675 ''' | |
| 676 (function(lazies) { | 672 (function(lazies) { |
| 677 for (var i = 0; i < lazies.length; ) { | 673 for (var i = 0; i < lazies.length; ) { |
| 678 var fieldName = lazies[i++]; | 674 var fieldName = lazies[i++]; |
| 679 var getterName = lazies[i++]; | 675 var getterName = lazies[i++]; |
| 680 var lazyValue = lazies[i++]; | 676 var lazyValue = lazies[i++]; |
| 681 if (#notMinified) { | 677 if (#notMinified) { |
| 682 var staticName = lazies[i++]; | 678 var staticName = lazies[i++]; |
| 683 } | 679 } |
| 684 if (#isDeferredFragment) { | 680 if (#isDeferredFragment) { |
| 685 var fieldHolder = lazies[i++]; | 681 var fieldHolder = lazies[i++]; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 696 } | 692 } |
| 697 } else { | 693 } else { |
| 698 if (#notMinified) { | 694 if (#notMinified) { |
| 699 #lazy(fieldName, getterName, lazyValue, staticName, fieldHolder); | 695 #lazy(fieldName, getterName, lazyValue, staticName, fieldHolder); |
| 700 } else { | 696 } else { |
| 701 #lazy(fieldName, getterName, lazyValue, null, fieldHolder); | 697 #lazy(fieldName, getterName, lazyValue, null, fieldHolder); |
| 702 } | 698 } |
| 703 } | 699 } |
| 704 } | 700 } |
| 705 })(#laziesInfo) | 701 })(#laziesInfo) |
| 706 ''', | 702 ''', { |
| 707 { | 703 'notMinified': !compiler.options.enableMinification, |
| 708 'notMinified': !compiler.options.enableMinification, | 704 'laziesInfo': new jsAst.ArrayInitializer(laziesInfo), |
| 709 'laziesInfo': new jsAst.ArrayInitializer(laziesInfo), | 705 'lazy': js(lazyInitializerName), |
| 710 'lazy': js(lazyInitializerName), | 706 'isMainFragment': isMainFragment, |
| 711 'isMainFragment': isMainFragment, | 707 'isDeferredFragment': !isMainFragment |
| 712 'isDeferredFragment': !isMainFragment | 708 }); |
| 713 }); | |
| 714 } else { | 709 } else { |
| 715 return js.comment("No lazy statics."); | 710 return js.comment("No lazy statics."); |
| 716 } | 711 } |
| 717 } | 712 } |
| 718 | 713 |
| 719 List<jsAst.Expression> buildLaziesInfo( | 714 List<jsAst.Expression> buildLaziesInfo( |
| 720 Iterable<StaticField> lazies, bool isMainFragment) { | 715 Iterable<StaticField> lazies, bool isMainFragment) { |
| 721 List<jsAst.Expression> laziesInfo = <jsAst.Expression>[]; | 716 List<jsAst.Expression> laziesInfo = <jsAst.Expression>[]; |
| 722 for (StaticField field in lazies) { | 717 for (StaticField field in lazies) { |
| 723 laziesInfo.add(js.quoteName(field.name)); | 718 laziesInfo.add(js.quoteName(field.name)); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 return initializer; | 773 return initializer; |
| 779 } | 774 } |
| 780 | 775 |
| 781 jsAst.Expression constantListGenerator(jsAst.Expression array) { | 776 jsAst.Expression constantListGenerator(jsAst.Expression array) { |
| 782 // TODO(floitsch): there is no harm in caching the template. | 777 // TODO(floitsch): there is no harm in caching the template. |
| 783 return js('${namer.isolateName}.#(#)', [makeConstListProperty, array]); | 778 return js('${namer.isolateName}.#(#)', [makeConstListProperty, array]); |
| 784 } | 779 } |
| 785 | 780 |
| 786 jsAst.Statement buildMakeConstantList(bool outputContainsConstantList) { | 781 jsAst.Statement buildMakeConstantList(bool outputContainsConstantList) { |
| 787 if (outputContainsConstantList) { | 782 if (outputContainsConstantList) { |
| 788 return js.statement( | 783 return js.statement(r''' |
| 789 r''' | |
| 790 // Functions are stored in the hidden class and not as properties in | 784 // Functions are stored in the hidden class and not as properties in |
| 791 // the object. We never actually look at the value, but only want | 785 // the object. We never actually look at the value, but only want |
| 792 // to know if the property exists. | 786 // to know if the property exists. |
| 793 #.# = function (list) { | 787 #.# = function (list) { |
| 794 list.immutable$list = Array; | 788 list.immutable$list = Array; |
| 795 list.fixed$length = Array; | 789 list.fixed$length = Array; |
| 796 return list; | 790 return list; |
| 797 }''', | 791 }''', [namer.isolateName, makeConstListProperty]); |
| 798 [namer.isolateName, makeConstListProperty]); | |
| 799 } else { | 792 } else { |
| 800 return js.comment("Output contains no constant list."); | 793 return js.comment("Output contains no constant list."); |
| 801 } | 794 } |
| 802 } | 795 } |
| 803 | 796 |
| 804 jsAst.Statement buildFunctionThatReturnsNull() { | 797 jsAst.Statement buildFunctionThatReturnsNull() { |
| 805 return js.statement('#.# = function() {}', | 798 return js.statement('#.# = function() {}', |
| 806 [namer.isolateName, backend.rtiEncoder.getFunctionThatReturnsNullName]); | 799 [namer.isolateName, backend.rtiEncoder.getFunctionThatReturnsNullName]); |
| 807 } | 800 } |
| 808 | 801 |
| 809 jsAst.Expression generateFunctionThatReturnsNull() { | 802 jsAst.Expression generateFunctionThatReturnsNull() { |
| 810 return js("#.#", | 803 return js("#.#", |
| 811 [namer.isolateName, backend.rtiEncoder.getFunctionThatReturnsNullName]); | 804 [namer.isolateName, backend.rtiEncoder.getFunctionThatReturnsNullName]); |
| 812 } | 805 } |
| 813 | 806 |
| 814 buildMain(jsAst.Statement invokeMain) { | 807 buildMain(jsAst.Statement invokeMain) { |
| 815 if (compiler.isMockCompilation) return js.comment("Mock compilation"); | 808 if (compiler.isMockCompilation) return js.comment("Mock compilation"); |
| 816 | 809 |
| 817 List<jsAst.Statement> parts = <jsAst.Statement>[]; | 810 List<jsAst.Statement> parts = <jsAst.Statement>[]; |
| 818 | 811 |
| 819 if (NativeGenerator | 812 if (NativeGenerator |
| 820 .needsIsolateAffinityTagInitialization(_closedWorld.backendUsage)) { | 813 .needsIsolateAffinityTagInitialization(_closedWorld.backendUsage)) { |
| 821 parts.add(NativeGenerator.generateIsolateAffinityTagInitialization( | 814 parts.add(NativeGenerator.generateIsolateAffinityTagInitialization( |
| 822 _closedWorld.backendUsage, | 815 _closedWorld.backendUsage, generateEmbeddedGlobalAccess, js(""" |
| 823 generateEmbeddedGlobalAccess, | |
| 824 js( | |
| 825 """ | |
| 826 // On V8, the 'intern' function converts a string to a symbol, which | 816 // On V8, the 'intern' function converts a string to a symbol, which |
| 827 // makes property access much faster. | 817 // makes property access much faster. |
| 828 function (s) { | 818 function (s) { |
| 829 var o = {}; | 819 var o = {}; |
| 830 o[s] = 1; | 820 o[s] = 1; |
| 831 return Object.keys(convertToFastObject(o))[0]; | 821 return Object.keys(convertToFastObject(o))[0]; |
| 832 }""", | 822 }""", []))); |
| 833 []))); | |
| 834 } | 823 } |
| 835 | 824 |
| 836 parts | 825 parts |
| 837 ..add(js.comment('BEGIN invoke [main].')) | 826 ..add(js.comment('BEGIN invoke [main].')) |
| 838 ..add(invokeMain) | 827 ..add(invokeMain) |
| 839 ..add(js.comment('END invoke [main].')); | 828 ..add(js.comment('END invoke [main].')); |
| 840 | 829 |
| 841 return new jsAst.Block(parts); | 830 return new jsAst.Block(parts); |
| 842 } | 831 } |
| 843 | 832 |
| 844 jsAst.Statement buildInitFunction(bool outputContainsConstantList) { | 833 jsAst.Statement buildInitFunction(bool outputContainsConstantList) { |
| 845 jsAst.Expression allClassesAccess = | 834 jsAst.Expression allClassesAccess = |
| 846 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); | 835 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); |
| 847 jsAst.Expression getTypeFromNameAccess = | 836 jsAst.Expression getTypeFromNameAccess = |
| 848 generateEmbeddedGlobalAccess(embeddedNames.GET_TYPE_FROM_NAME); | 837 generateEmbeddedGlobalAccess(embeddedNames.GET_TYPE_FROM_NAME); |
| 849 jsAst.Expression interceptorsByTagAccess = | 838 jsAst.Expression interceptorsByTagAccess = |
| 850 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 839 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| 851 jsAst.Expression leafTagsAccess = | 840 jsAst.Expression leafTagsAccess = |
| 852 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 841 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 853 jsAst.Expression finishedClassesAccess = | 842 jsAst.Expression finishedClassesAccess = |
| 854 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); | 843 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 855 jsAst.Expression cyclicThrow = | 844 jsAst.Expression cyclicThrow = |
| 856 staticFunctionAccess(commonElements.cyclicThrowHelper); | 845 staticFunctionAccess(commonElements.cyclicThrowHelper); |
| 857 jsAst.Expression laziesAccess = | 846 jsAst.Expression laziesAccess = |
| 858 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); | 847 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); |
| 859 | 848 |
| 860 return js.statement( | 849 return js.statement(''' |
| 861 ''' | |
| 862 function init() { | 850 function init() { |
| 863 $isolatePropertiesName = Object.create(null); | 851 $isolatePropertiesName = Object.create(null); |
| 864 #allClasses = map(); | 852 #allClasses = map(); |
| 865 #getTypeFromName = function(name) {return #allClasses[name];}; | 853 #getTypeFromName = function(name) {return #allClasses[name];}; |
| 866 #interceptorsByTag = map(); | 854 #interceptorsByTag = map(); |
| 867 #leafTags = map(); | 855 #leafTags = map(); |
| 868 #finishedClasses = map(); | 856 #finishedClasses = map(); |
| 869 | 857 |
| 870 if (#needsLazyInitializer) { | 858 if (#needsLazyInitializer) { |
| 871 // [staticName] is only provided in non-minified mode. If missing, we | 859 // [staticName] is only provided in non-minified mode. If missing, we |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 Isolate.prototype.constructor = Isolate; | 943 Isolate.prototype.constructor = Isolate; |
| 956 Isolate.#isolatePropertiesName = isolateProperties; | 944 Isolate.#isolatePropertiesName = isolateProperties; |
| 957 if (#outputContainsConstantList) { | 945 if (#outputContainsConstantList) { |
| 958 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty; | 946 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty; |
| 959 } | 947 } |
| 960 Isolate.#functionThatReturnsNullProperty = | 948 Isolate.#functionThatReturnsNullProperty = |
| 961 oldIsolate.#functionThatReturnsNullProperty; | 949 oldIsolate.#functionThatReturnsNullProperty; |
| 962 return Isolate; | 950 return Isolate; |
| 963 } | 951 } |
| 964 | 952 |
| 965 }''', | 953 }''', { |
| 966 { | 954 'allClasses': allClassesAccess, |
| 967 'allClasses': allClassesAccess, | 955 'getTypeFromName': getTypeFromNameAccess, |
| 968 'getTypeFromName': getTypeFromNameAccess, | 956 'interceptorsByTag': interceptorsByTagAccess, |
| 969 'interceptorsByTag': interceptorsByTagAccess, | 957 'leafTags': leafTagsAccess, |
| 970 'leafTags': leafTagsAccess, | 958 'finishedClasses': finishedClassesAccess, |
| 971 'finishedClasses': finishedClassesAccess, | 959 'needsLazyInitializer': needsLazyInitializer, |
| 972 'needsLazyInitializer': needsLazyInitializer, | 960 'lazies': laziesAccess, |
| 973 'lazies': laziesAccess, | 961 'cyclicThrow': cyclicThrow, |
| 974 'cyclicThrow': cyclicThrow, | 962 'isolatePropertiesName': namer.isolatePropertiesName, |
| 975 'isolatePropertiesName': namer.isolatePropertiesName, | 963 'outputContainsConstantList': outputContainsConstantList, |
| 976 'outputContainsConstantList': outputContainsConstantList, | 964 'makeConstListProperty': makeConstListProperty, |
| 977 'makeConstListProperty': makeConstListProperty, | 965 'functionThatReturnsNullProperty': |
| 978 'functionThatReturnsNullProperty': | 966 backend.rtiEncoder.getFunctionThatReturnsNullName, |
| 979 backend.rtiEncoder.getFunctionThatReturnsNullName, | 967 }); |
| 980 }); | |
| 981 } | 968 } |
| 982 | 969 |
| 983 jsAst.Statement buildConvertToFastObjectFunction() { | 970 jsAst.Statement buildConvertToFastObjectFunction() { |
| 984 List<jsAst.Statement> debugCode = <jsAst.Statement>[]; | 971 List<jsAst.Statement> debugCode = <jsAst.Statement>[]; |
| 985 if (DEBUG_FAST_OBJECTS) { | 972 if (DEBUG_FAST_OBJECTS) { |
| 986 debugCode.add(js.statement(r''' | 973 debugCode.add(js.statement(r''' |
| 987 // The following only works on V8 when run with option | 974 // The following only works on V8 when run with option |
| 988 // "--allow-natives-syntax". We use'new Function' because the | 975 // "--allow-natives-syntax". We use'new Function' because the |
| 989 // miniparser does not understand V8 native syntax. | 976 // miniparser does not understand V8 native syntax. |
| 990 if (typeof print === "function") { | 977 if (typeof print === "function") { |
| 991 var HasFastProperties = | 978 var HasFastProperties = |
| 992 new Function("a", "return %HasFastProperties(a)"); | 979 new Function("a", "return %HasFastProperties(a)"); |
| 993 print("Size of global object: " | 980 print("Size of global object: " |
| 994 + String(Object.getOwnPropertyNames(properties).length) | 981 + String(Object.getOwnPropertyNames(properties).length) |
| 995 + ", fast properties " + HasFastProperties(properties)); | 982 + ", fast properties " + HasFastProperties(properties)); |
| 996 }''')); | 983 }''')); |
| 997 } | 984 } |
| 998 | 985 |
| 999 return js.statement( | 986 return js.statement(r''' |
| 1000 r''' | |
| 1001 function convertToFastObject(properties) { | 987 function convertToFastObject(properties) { |
| 1002 // Create an instance that uses 'properties' as prototype. This should | 988 // Create an instance that uses 'properties' as prototype. This should |
| 1003 // make 'properties' a fast object. | 989 // make 'properties' a fast object. |
| 1004 function MyClass() {}; | 990 function MyClass() {}; |
| 1005 MyClass.prototype = properties; | 991 MyClass.prototype = properties; |
| 1006 new MyClass(); | 992 new MyClass(); |
| 1007 #; | 993 #; |
| 1008 return properties; | 994 return properties; |
| 1009 }''', | 995 }''', [debugCode]); |
| 1010 [debugCode]); | |
| 1011 } | 996 } |
| 1012 | 997 |
| 1013 jsAst.Statement buildConvertToSlowObjectFunction() { | 998 jsAst.Statement buildConvertToSlowObjectFunction() { |
| 1014 return js.statement(r''' | 999 return js.statement(r''' |
| 1015 function convertToSlowObject(properties) { | 1000 function convertToSlowObject(properties) { |
| 1016 // Add and remove a property to make the object transition into hashmap | 1001 // Add and remove a property to make the object transition into hashmap |
| 1017 // mode. | 1002 // mode. |
| 1018 properties.__MAGIC_SLOW_PROPERTY = 1; | 1003 properties.__MAGIC_SLOW_PROPERTY = 1; |
| 1019 delete properties.__MAGIC_SLOW_PROPERTY; | 1004 delete properties.__MAGIC_SLOW_PROPERTY; |
| 1020 return properties; | 1005 return properties; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 + String(Object.getOwnPropertyNames(C).length) | 1240 + String(Object.getOwnPropertyNames(C).length) |
| 1256 + ", fast properties " + HasFastProperties(C)); | 1241 + ", fast properties " + HasFastProperties(C)); |
| 1257 var names = Object.getOwnPropertyNames($); | 1242 var names = Object.getOwnPropertyNames($); |
| 1258 for (var i = 0; i < names.length; i++) { | 1243 for (var i = 0; i < names.length; i++) { |
| 1259 print("$." + names[i]); | 1244 print("$." + names[i]); |
| 1260 } | 1245 } |
| 1261 } | 1246 } |
| 1262 ''')); | 1247 ''')); |
| 1263 | 1248 |
| 1264 for (String object in Namer.userGlobalObjects) { | 1249 for (String object in Namer.userGlobalObjects) { |
| 1265 parts.add(js.statement( | 1250 parts.add(js.statement(''' |
| 1266 ''' | |
| 1267 if (typeof print === "function") { | 1251 if (typeof print === "function") { |
| 1268 print("Size of " + #objectString + ": " | 1252 print("Size of " + #objectString + ": " |
| 1269 + String(Object.getOwnPropertyNames(#object).length) | 1253 + String(Object.getOwnPropertyNames(#object).length) |
| 1270 + ", fast properties " + HasFastProperties(#object)); | 1254 + ", fast properties " + HasFastProperties(#object)); |
| 1271 } | 1255 } |
| 1272 ''', | 1256 ''', {"object": object, "objectString": js.string(object)})); |
| 1273 {"object": object, "objectString": js.string(object)})); | |
| 1274 } | 1257 } |
| 1275 } | 1258 } |
| 1276 | 1259 |
| 1277 return new jsAst.Block(parts); | 1260 return new jsAst.Block(parts); |
| 1278 } | 1261 } |
| 1279 | 1262 |
| 1280 jsAst.Statement buildMangledNames() { | 1263 jsAst.Statement buildMangledNames() { |
| 1281 List<jsAst.Statement> parts = <jsAst.Statement>[]; | 1264 List<jsAst.Statement> parts = <jsAst.Statement>[]; |
| 1282 | 1265 |
| 1283 if (!mangledFieldNames.isEmpty) { | 1266 if (!mangledFieldNames.isEmpty) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 // contain typedefs that are used for reflection. | 1379 // contain typedefs that are used for reflection. |
| 1397 for (LibraryEntity element in remainingLibraries) { | 1380 for (LibraryEntity element in remainingLibraries) { |
| 1398 parts.add(generateLibraryDescriptor(element, mainFragment)); | 1381 parts.add(generateLibraryDescriptor(element, mainFragment)); |
| 1399 descriptors.remove(element); | 1382 descriptors.remove(element); |
| 1400 } | 1383 } |
| 1401 } | 1384 } |
| 1402 jsAst.ArrayInitializer descriptorsAst = new jsAst.ArrayInitializer(parts); | 1385 jsAst.ArrayInitializer descriptorsAst = new jsAst.ArrayInitializer(parts); |
| 1403 | 1386 |
| 1404 // Using a named function here produces easier to read stack traces in | 1387 // Using a named function here produces easier to read stack traces in |
| 1405 // Chrome/V8. | 1388 // Chrome/V8. |
| 1406 statements.add(js.statement( | 1389 statements.add(js.statement(""" |
| 1407 """ | |
| 1408 (function() { | 1390 (function() { |
| 1409 // No renaming in the top-level function to save the locals for the | 1391 // No renaming in the top-level function to save the locals for the |
| 1410 // nested context where they will be used more. We have to put the | 1392 // nested context where they will be used more. We have to put the |
| 1411 // comment into a hole as the parser strips out comments right away. | 1393 // comment into a hole as the parser strips out comments right away. |
| 1412 #disableVariableRenaming; | 1394 #disableVariableRenaming; |
| 1413 #supportsDirectProtoAccess; | 1395 #supportsDirectProtoAccess; |
| 1414 | 1396 |
| 1415 if (#isProgramSplit) { | 1397 if (#isProgramSplit) { |
| 1416 /// We collect all the global state, so it can be passed to the | 1398 /// We collect all the global state, so it can be passed to the |
| 1417 /// initializer of deferred files. | 1399 /// initializer of deferred files. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 #convertToFastObject; | 1476 #convertToFastObject; |
| 1495 #convertToSlowObject; | 1477 #convertToSlowObject; |
| 1496 | 1478 |
| 1497 #convertGlobalObjectsToFastObjects; | 1479 #convertGlobalObjectsToFastObjects; |
| 1498 #debugFastObjects; | 1480 #debugFastObjects; |
| 1499 | 1481 |
| 1500 #init; | 1482 #init; |
| 1501 | 1483 |
| 1502 #main; | 1484 #main; |
| 1503 })(); | 1485 })(); |
| 1504 """, | 1486 """, { |
| 1505 { | 1487 "disableVariableRenaming": js.comment("/* ::norenaming:: */"), |
| 1506 "disableVariableRenaming": js.comment("/* ::norenaming:: */"), | 1488 "isProgramSplit": isProgramSplit, |
| 1507 "isProgramSplit": isProgramSplit, | 1489 "supportsDirectProtoAccess": buildSupportsDirectProtoAccess(), |
| 1508 "supportsDirectProtoAccess": buildSupportsDirectProtoAccess(), | 1490 "globalsHolder": globalsHolder, |
| 1509 "globalsHolder": globalsHolder, | 1491 "globalObjectSetup": buildGlobalObjectSetup(isProgramSplit), |
| 1510 "globalObjectSetup": buildGlobalObjectSetup(isProgramSplit), | 1492 "isolateName": namer.isolateName, |
| 1511 "isolateName": namer.isolateName, | 1493 "isolatePropertiesName": js(isolatePropertiesName), |
| 1512 "isolatePropertiesName": js(isolatePropertiesName), | 1494 "initName": initName, |
| 1513 "initName": initName, | 1495 "functionThatReturnsNull": buildFunctionThatReturnsNull(), |
| 1514 "functionThatReturnsNull": buildFunctionThatReturnsNull(), | 1496 "mangledNames": buildMangledNames(), |
| 1515 "mangledNames": buildMangledNames(), | 1497 "setupProgram": buildSetupProgram( |
| 1516 "setupProgram": buildSetupProgram( | 1498 program, compiler, backend, namer, this, _closedWorld), |
| 1517 program, compiler, backend, namer, this, _closedWorld), | 1499 "setupProgramName": setupProgramName, |
| 1518 "setupProgramName": setupProgramName, | 1500 "descriptors": descriptorsAst, |
| 1519 "descriptors": descriptorsAst, | 1501 "cspPrecompiledFunctions": buildCspPrecompiledFunctionFor(mainOutputUnit), |
| 1520 "cspPrecompiledFunctions": | 1502 "getInterceptorMethods": interceptorEmitter.buildGetInterceptorMethods(), |
| 1521 buildCspPrecompiledFunctionFor(mainOutputUnit), | 1503 "oneShotInterceptors": interceptorEmitter.buildOneShotInterceptors(), |
| 1522 "getInterceptorMethods": | 1504 "makeConstantList": |
| 1523 interceptorEmitter.buildGetInterceptorMethods(), | 1505 buildMakeConstantList(program.outputContainsConstantList), |
| 1524 "oneShotInterceptors": interceptorEmitter.buildOneShotInterceptors(), | 1506 "compileTimeConstants": buildCompileTimeConstants(mainFragment.constants, |
| 1525 "makeConstantList": | 1507 isMainFragment: true), |
| 1526 buildMakeConstantList(program.outputContainsConstantList), | 1508 "deferredBoilerPlate": buildDeferredBoilerPlate(deferredLoadHashes), |
| 1527 "compileTimeConstants": buildCompileTimeConstants( | 1509 "staticNonFinalInitializers": |
| 1528 mainFragment.constants, | 1510 buildStaticNonFinalFieldInitializations(mainOutputUnit), |
| 1529 isMainFragment: true), | 1511 "typeToInterceptorMap": |
| 1530 "deferredBoilerPlate": buildDeferredBoilerPlate(deferredLoadHashes), | 1512 interceptorEmitter.buildTypeToInterceptorMap(program), |
| 1531 "staticNonFinalInitializers": | 1513 "lazyStaticFields": buildLazilyInitializedStaticFields( |
| 1532 buildStaticNonFinalFieldInitializations(mainOutputUnit), | 1514 mainFragment.staticLazilyInitializedFields), |
| 1533 "typeToInterceptorMap": | 1515 "metadata": buildMetadata(program, mainOutputUnit), |
| 1534 interceptorEmitter.buildTypeToInterceptorMap(program), | 1516 "convertToFastObject": buildConvertToFastObjectFunction(), |
| 1535 "lazyStaticFields": buildLazilyInitializedStaticFields( | 1517 "convertToSlowObject": buildConvertToSlowObjectFunction(), |
| 1536 mainFragment.staticLazilyInitializedFields), | 1518 "convertGlobalObjectsToFastObjects": |
| 1537 "metadata": buildMetadata(program, mainOutputUnit), | 1519 buildConvertGlobalObjectToFastObjects(), |
| 1538 "convertToFastObject": buildConvertToFastObjectFunction(), | 1520 "debugFastObjects": buildDebugFastObjectCode(), |
| 1539 "convertToSlowObject": buildConvertToSlowObjectFunction(), | 1521 "init": buildInitFunction(program.outputContainsConstantList), |
| 1540 "convertGlobalObjectsToFastObjects": | 1522 "main": buildMain(mainFragment.invokeMain) |
| 1541 buildConvertGlobalObjectToFastObjects(), | 1523 })); |
| 1542 "debugFastObjects": buildDebugFastObjectCode(), | |
| 1543 "init": buildInitFunction(program.outputContainsConstantList), | |
| 1544 "main": buildMain(mainFragment.invokeMain) | |
| 1545 })); | |
| 1546 | 1524 |
| 1547 return new jsAst.Program(statements); | 1525 return new jsAst.Program(statements); |
| 1548 } | 1526 } |
| 1549 | 1527 |
| 1550 void emitMainOutputUnit(OutputUnit mainOutputUnit, jsAst.Program program) { | 1528 void emitMainOutputUnit(OutputUnit mainOutputUnit, jsAst.Program program) { |
| 1551 LocationCollector locationCollector; | 1529 LocationCollector locationCollector; |
| 1552 List<CodeOutputListener> codeOutputListeners; | 1530 List<CodeOutputListener> codeOutputListeners; |
| 1553 if (generateSourceMap) { | 1531 if (generateSourceMap) { |
| 1554 locationCollector = new LocationCollector(); | 1532 locationCollector = new LocationCollector(); |
| 1555 codeOutputListeners = <CodeOutputListener>[locationCollector]; | 1533 codeOutputListeners = <CodeOutputListener>[locationCollector]; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 .putIfAbsent(owner, () { | 1688 .putIfAbsent(owner, () { |
| 1711 return new ClassBuilder.forLibrary(owner, namer); | 1689 return new ClassBuilder.forLibrary(owner, namer); |
| 1712 }); | 1690 }); |
| 1713 } | 1691 } |
| 1714 | 1692 |
| 1715 /// Emits support-code for deferred loading into [output]. | 1693 /// Emits support-code for deferred loading into [output]. |
| 1716 jsAst.Statement buildDeferredBoilerPlate( | 1694 jsAst.Statement buildDeferredBoilerPlate( |
| 1717 Map<OutputUnit, _DeferredOutputUnitHash> deferredLoadHashes) { | 1695 Map<OutputUnit, _DeferredOutputUnitHash> deferredLoadHashes) { |
| 1718 List<jsAst.Statement> parts = <jsAst.Statement>[]; | 1696 List<jsAst.Statement> parts = <jsAst.Statement>[]; |
| 1719 | 1697 |
| 1720 parts.add(js.statement( | 1698 parts.add(js.statement(''' |
| 1721 ''' | |
| 1722 { | 1699 { |
| 1723 // Function for checking if a hunk is loaded given its hash. | 1700 // Function for checking if a hunk is loaded given its hash. |
| 1724 #isHunkLoaded = function(hunkHash) { | 1701 #isHunkLoaded = function(hunkHash) { |
| 1725 return !!$deferredInitializers[hunkHash]; | 1702 return !!$deferredInitializers[hunkHash]; |
| 1726 }; | 1703 }; |
| 1727 #deferredInitialized = new Object(null); | 1704 #deferredInitialized = new Object(null); |
| 1728 // Function for checking if a hunk is initialized given its hash. | 1705 // Function for checking if a hunk is initialized given its hash. |
| 1729 #isHunkInitialized = function(hunkHash) { | 1706 #isHunkInitialized = function(hunkHash) { |
| 1730 return #deferredInitialized[hunkHash]; | 1707 return #deferredInitialized[hunkHash]; |
| 1731 }; | 1708 }; |
| 1732 // Function for initializing a loaded hunk, given its hash. | 1709 // Function for initializing a loaded hunk, given its hash. |
| 1733 #initializeLoadedHunk = function(hunkHash) { | 1710 #initializeLoadedHunk = function(hunkHash) { |
| 1734 $deferredInitializers[hunkHash]( | 1711 $deferredInitializers[hunkHash]( |
| 1735 #globalsHolder, ${namer.staticStateHolder}); | 1712 #globalsHolder, ${namer.staticStateHolder}); |
| 1736 #deferredInitialized[hunkHash] = true; | 1713 #deferredInitialized[hunkHash] = true; |
| 1737 }; | 1714 }; |
| 1738 } | 1715 } |
| 1739 ''', | 1716 ''', { |
| 1740 { | 1717 "globalsHolder": globalsHolder, |
| 1741 "globalsHolder": globalsHolder, | 1718 "isHunkLoaded": |
| 1742 "isHunkLoaded": | 1719 generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED), |
| 1743 generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED), | 1720 "isHunkInitialized": |
| 1744 "isHunkInitialized": | 1721 generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_INITIALIZED), |
| 1745 generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_INITIALIZED), | 1722 "initializeLoadedHunk": |
| 1746 "initializeLoadedHunk": generateEmbeddedGlobalAccess( | 1723 generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_LOADED_HUNK), |
| 1747 embeddedNames.INITIALIZE_LOADED_HUNK), | 1724 "deferredInitialized": |
| 1748 "deferredInitialized": | 1725 generateEmbeddedGlobalAccess(embeddedNames.DEFERRED_INITIALIZED) |
| 1749 generateEmbeddedGlobalAccess(embeddedNames.DEFERRED_INITIALIZED) | 1726 })); |
| 1750 })); | |
| 1751 | 1727 |
| 1752 // Write a javascript mapping from Deferred import load ids (derrived | 1728 // Write a javascript mapping from Deferred import load ids (derrived |
| 1753 // from the import prefix.) to a list of lists of uris of hunks to load, | 1729 // from the import prefix.) to a list of lists of uris of hunks to load, |
| 1754 // and a corresponding mapping to a list of hashes used by | 1730 // and a corresponding mapping to a list of hashes used by |
| 1755 // INITIALIZE_LOADED_HUNK and IS_HUNK_LOADED. | 1731 // INITIALIZE_LOADED_HUNK and IS_HUNK_LOADED. |
| 1756 Map<String, List<jsAst.LiteralString>> deferredLibraryUris = | 1732 Map<String, List<jsAst.LiteralString>> deferredLibraryUris = |
| 1757 new Map<String, List<jsAst.LiteralString>>(); | 1733 new Map<String, List<jsAst.LiteralString>>(); |
| 1758 Map<String, List<_DeferredOutputUnitHash>> deferredLibraryHashes = | 1734 Map<String, List<_DeferredOutputUnitHash>> deferredLibraryHashes = |
| 1759 new Map<String, List<_DeferredOutputUnitHash>>(); | 1735 new Map<String, List<_DeferredOutputUnitHash>>(); |
| 1760 compiler.deferredLoadTask.hunksToLoad | 1736 compiler.deferredLoadTask.hunksToLoad |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1962 // data. | 1938 // data. |
| 1963 mapping["_comment"] = "This mapping shows which compiled `.js` files are " | 1939 mapping["_comment"] = "This mapping shows which compiled `.js` files are " |
| 1964 "needed for a given deferred library import."; | 1940 "needed for a given deferred library import."; |
| 1965 mapping.addAll(compiler.deferredLoadTask.computeDeferredMap()); | 1941 mapping.addAll(compiler.deferredLoadTask.computeDeferredMap()); |
| 1966 compiler.outputProvider( | 1942 compiler.outputProvider( |
| 1967 compiler.options.deferredMapUri.path, '', OutputType.info) | 1943 compiler.options.deferredMapUri.path, '', OutputType.info) |
| 1968 ..add(const JsonEncoder.withIndent(" ").convert(mapping)) | 1944 ..add(const JsonEncoder.withIndent(" ").convert(mapping)) |
| 1969 ..close(); | 1945 ..close(); |
| 1970 } | 1946 } |
| 1971 } | 1947 } |
| OLD | NEW |