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 |
| 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 /** | 5 /** |
| 6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
| 7 * from the given element. | 7 * from the given element. |
| 8 */ | 8 */ |
| 9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
| 10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
| (...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 649 buffer.add("$finishClassesName($classesCollector);\n"); | 649 buffer.add("$finishClassesName($classesCollector);\n"); |
| 650 // Reset the map. | 650 // Reset the map. |
| 651 buffer.add("$classesCollector = {};\n"); | 651 buffer.add("$classesCollector = {};\n"); |
| 652 } | 652 } |
| 653 } | 653 } |
| 654 | 654 |
| 655 void emitStaticFunctionsWithNamer(CodeBuffer buffer, | 655 void emitStaticFunctionsWithNamer(CodeBuffer buffer, |
| 656 Map<Element, CodeBuffer> generatedCode, | 656 Map<Element, CodeBuffer> generatedCode, |
| 657 String functionNamer(Element element)) { | 657 String functionNamer(Element element)) { |
| 658 generatedCode.forEach((Element element, CodeBuffer functionBuffer) { | 658 generatedCode.forEach((Element element, CodeBuffer functionBuffer) { |
| 659 if (!element.isInstanceMember()) { | 659 if (!element.isInstanceMember() && element.kind != ElementKind.FIELD) { |
|
kasperl
2012/08/16 14:41:37
Don't we have an element.isField() tester?
floitsch
2012/08/16 22:52:33
Done.
| |
| 660 String functionName = functionNamer(element); | 660 String functionName = functionNamer(element); |
| 661 buffer.add('$isolateProperties.$functionName = '); | 661 buffer.add('$isolateProperties.$functionName = '); |
| 662 addMappings(functionBuffer, buffer.length); | 662 addMappings(functionBuffer, buffer.length); |
| 663 buffer.add(functionBuffer); | 663 buffer.add(functionBuffer); |
| 664 buffer.add(';\n\n'); | 664 buffer.add(';\n\n'); |
| 665 } | 665 } |
| 666 }); | 666 }); |
| 667 } | 667 } |
| 668 | 668 |
| 669 void emitStaticFunctions(CodeBuffer buffer) { | 669 void emitStaticFunctions(CodeBuffer buffer) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 827 handler.getStaticNonFinalFieldsForEmission(); | 827 handler.getStaticNonFinalFieldsForEmission(); |
| 828 for (Element element in staticNonFinalFields) { | 828 for (Element element in staticNonFinalFields) { |
| 829 buffer.add('$isolateProperties.${namer.getName(element)} = '); | 829 buffer.add('$isolateProperties.${namer.getName(element)} = '); |
| 830 compiler.withCurrentElement(element, () { | 830 compiler.withCurrentElement(element, () { |
| 831 handler.writeJsCodeForVariable(buffer, element); | 831 handler.writeJsCodeForVariable(buffer, element); |
| 832 }); | 832 }); |
| 833 buffer.add(';\n'); | 833 buffer.add(';\n'); |
| 834 } | 834 } |
| 835 } | 835 } |
| 836 | 836 |
| 837 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { | |
| 838 String nonBailoutElementNamer(Element element) { | |
| 839 if (element.kind == ElementKind.FIELD) { | |
|
kasperl
2012/08/16 14:41:37
isField
floitsch
2012/08/16 22:52:33
Done.
| |
| 840 return namer.getLazyInitializerName(element); | |
| 841 } else { | |
| 842 return namer.getName(element); | |
| 843 } | |
| 844 } | |
| 845 | |
| 846 String bailoutElementNamer(Element element) { | |
| 847 if (element.kind == ElementKind.FIELD) { | |
|
kasperl
2012/08/16 14:41:37
isField
floitsch
2012/08/16 22:52:33
Done.
| |
| 848 return namer.getLazyInitializerBailoutName(element); | |
| 849 } else { | |
| 850 return namer.getBailoutName(element); | |
| 851 } | |
| 852 } | |
| 853 | |
| 854 ConstantHandler handler = compiler.constantHandler; | |
| 855 List<VariableElement> lazyFields = | |
| 856 handler.getLazilyInitializedFieldsForEmission(); | |
| 857 if (!lazyFields.isEmpty()) { | |
| 858 JavaScriptBackend backend = compiler.backend; | |
| 859 String isolatePropertiesSentinelAccess = | |
| 860 '$isolateProperties.${namer.LAZY_INITIALIZATION_SENTINEL}'; | |
| 861 buffer.add('$isolatePropertiesSentinelAccess = {};\n'); | |
| 862 for (VariableElement element in lazyFields) { | |
| 863 StringBuffer code = compiler.codegenWorld.generatedCode[element]; | |
| 864 assert(code != null); | |
| 865 // The code only computes the initial value. We build the lazy-check | |
| 866 // here. | |
| 867 String fieldName = namer.getName(element); | |
| 868 String lazyGetterName = | |
| 869 '$isolateProperties.${namer.getLazyInitializerName(element)}'; | |
| 870 // We store the function that computes the initial value as field of | |
| 871 // the lazy getter. | |
| 872 // The lazy getter itself will be replaced at first access. | |
| 873 String directFieldAccess = namer.isolateAccess(element); | |
| 874 String sentinelAccess = | |
| 875 '${namer.CURRENT_ISOLATE}.${namer.LAZY_INITIALIZATION_SENTINEL}'; | |
| 876 buffer.add(''' | |
| 877 $lazyGetterName = function() { | |
|
kasperl
2012/08/16 14:41:37
As we discussed, I think this needs to do the try-
floitsch
2012/08/16 22:52:33
Done.
| |
| 878 var value = $directFieldAccess; | |
| 879 if (value === $sentinelAccess) { | |
| 880 value = ${namer.isolateLazyInitializerAccess(element)}.lazy(); | |
| 881 $directFieldAccess = value; | |
| 882 } | |
| 883 ${namer.isolateLazyInitializerAccess(element)} = function() { return $directFi eldAccess; }; | |
| 884 return value; | |
| 885 }; | |
| 886 '''); | |
| 887 buffer.add('$lazyGetterName.lazy = '); | |
| 888 buffer.add(code); | |
| 889 buffer.add('\n$isolateProperties.${namer.getName(element)} = '); | |
| 890 buffer.add(isolatePropertiesSentinelAccess); | |
| 891 buffer.add(';\n'); | |
| 892 } | |
| 893 } | |
| 894 } | |
| 895 | |
| 837 void emitCompileTimeConstants(CodeBuffer buffer) { | 896 void emitCompileTimeConstants(CodeBuffer buffer) { |
| 838 ConstantHandler handler = compiler.constantHandler; | 897 ConstantHandler handler = compiler.constantHandler; |
| 839 List<Constant> constants = handler.getConstantsForEmission(); | 898 List<Constant> constants = handler.getConstantsForEmission(); |
| 840 bool addedMakeConstantList = false; | 899 bool addedMakeConstantList = false; |
| 841 for (Constant constant in constants) { | 900 for (Constant constant in constants) { |
| 842 String name = handler.getNameForConstant(constant); | 901 String name = handler.getNameForConstant(constant); |
| 843 // The name is null when the constant is already a JS constant. | 902 // The name is null when the constant is already a JS constant. |
| 844 // TODO(floitsch): every constant should be registered, so that we can | 903 // TODO(floitsch): every constant should be registered, so that we can |
| 845 // share the ones that take up too much space (like some strings). | 904 // share the ones that take up too much space (like some strings). |
| 846 if (name === null) continue; | 905 if (name === null) continue; |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1121 boundClosureBuffer.clear(); | 1180 boundClosureBuffer.clear(); |
| 1122 emitStaticFunctions(mainBuffer); | 1181 emitStaticFunctions(mainBuffer); |
| 1123 emitStaticFunctionGetters(mainBuffer); | 1182 emitStaticFunctionGetters(mainBuffer); |
| 1124 // We need to finish the classes before we construct compile time | 1183 // We need to finish the classes before we construct compile time |
| 1125 // constants. | 1184 // constants. |
| 1126 emitFinishClassesInvocationIfNecessary(mainBuffer); | 1185 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 1127 emitCompileTimeConstants(mainBuffer); | 1186 emitCompileTimeConstants(mainBuffer); |
| 1128 // Static field initializations require the classes and compile-time | 1187 // Static field initializations require the classes and compile-time |
| 1129 // constants to be set up. | 1188 // constants to be set up. |
| 1130 emitStaticNonFinalFieldInitializations(mainBuffer); | 1189 emitStaticNonFinalFieldInitializations(mainBuffer); |
| 1190 emitLazilyInitializedStaticFields(mainBuffer); | |
| 1131 | 1191 |
| 1132 isolateProperties = isolatePropertiesName; | 1192 isolateProperties = isolatePropertiesName; |
| 1133 // The following code should not use the short-hand for the | 1193 // The following code should not use the short-hand for the |
| 1134 // initialStatics. | 1194 // initialStatics. |
| 1135 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); | 1195 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); |
| 1136 mainBuffer.add(boundClosureBuffer); | 1196 mainBuffer.add(boundClosureBuffer); |
| 1137 emitFinishClassesInvocationIfNecessary(mainBuffer); | 1197 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 1138 // After this assignment we will produce invalid JavaScript code if we use | 1198 // After this assignment we will produce invalid JavaScript code if we use |
| 1139 // the classesCollector variable. | 1199 // the classesCollector variable. |
| 1140 classesCollector = 'classesCollector should not be used from now on'; | 1200 classesCollector = 'classesCollector should not be used from now on'; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1173 sourceName = token.slowToString(); | 1233 sourceName = token.slowToString(); |
| 1174 } | 1234 } |
| 1175 int totalOffset = bufferOffset + offset; | 1235 int totalOffset = bufferOffset + offset; |
| 1176 sourceMapBuilder.addMapping( | 1236 sourceMapBuilder.addMapping( |
| 1177 sourceFile, token.charOffset, sourceName, totalOffset); | 1237 sourceFile, token.charOffset, sourceName, totalOffset); |
| 1178 }); | 1238 }); |
| 1179 } | 1239 } |
| 1180 } | 1240 } |
| 1181 | 1241 |
| 1182 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); | 1242 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); |
| OLD | NEW |