| 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.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Generates the code for all used classes in the program. Static fields (even | 8 * Generates the code for all used classes in the program. Static fields (even |
| 9 * in classes) are ignored, since they can be treated as non-class elements. | 9 * in classes) are ignored, since they can be treated as non-class elements. |
| 10 * | 10 * |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 NativeEmitter nativeEmitter; | 26 NativeEmitter nativeEmitter; |
| 27 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>(); | 27 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>(); |
| 28 final CodeBuffer deferredConstants = new CodeBuffer(); | 28 final CodeBuffer deferredConstants = new CodeBuffer(); |
| 29 /** Shorter access to [isolatePropertiesName]. Both here in the code, as | 29 /** Shorter access to [isolatePropertiesName]. Both here in the code, as |
| 30 well as in the generated code. */ | 30 well as in the generated code. */ |
| 31 String isolateProperties; | 31 String isolateProperties; |
| 32 String classesCollector; | 32 String classesCollector; |
| 33 final Set<ClassElement> neededClasses = new Set<ClassElement>(); | 33 final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
| 34 final Map<OutputUnit, List<ClassElement>> outputClassLists = | 34 final Map<OutputUnit, List<ClassElement>> outputClassLists = |
| 35 new Map<OutputUnit, List<ClassElement>>(); | 35 new Map<OutputUnit, List<ClassElement>>(); |
| 36 final Map<OutputUnit, List<Constant>> outputConstantLists = |
| 37 new Map<OutputUnit, List<Constant>>(); |
| 36 final List<ClassElement> nativeClasses = <ClassElement>[]; | 38 final List<ClassElement> nativeClasses = <ClassElement>[]; |
| 37 final Map<String, String> mangledFieldNames = <String, String>{}; | 39 final Map<String, String> mangledFieldNames = <String, String>{}; |
| 38 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; | 40 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; |
| 39 final Set<String> recordedMangledNames = new Set<String>(); | 41 final Set<String> recordedMangledNames = new Set<String>(); |
| 40 | 42 |
| 41 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = | 43 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = |
| 42 new Map<ClassElement, Map<String, jsAst.Expression>>(); | 44 new Map<ClassElement, Map<String, jsAst.Expression>>(); |
| 43 | 45 |
| 44 /// Records if a type variable is read dynamically for type tests. | 46 /// Records if a type variable is read dynamically for type tests. |
| 45 final Set<TypeVariableElement> readTypeVariables = | 47 final Set<TypeVariableElement> readTypeVariables = |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 } | 885 } |
| 884 } | 886 } |
| 885 } | 887 } |
| 886 | 888 |
| 887 jsAst.Expression buildLazyInitializedGetter(VariableElement element) { | 889 jsAst.Expression buildLazyInitializedGetter(VariableElement element) { |
| 888 // Nothing to do, the 'lazy' function will create the getter. | 890 // Nothing to do, the 'lazy' function will create the getter. |
| 889 return null; | 891 return null; |
| 890 } | 892 } |
| 891 | 893 |
| 892 void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) { | 894 void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) { |
| 893 JavaScriptConstantCompiler handler = backend.constants; | 895 List<Constant> constants = outputConstantLists[outputUnit]; |
| 894 List<Constant> constants = handler.getConstantsForEmission( | 896 if (constants == null) return; |
| 895 compareConstants); | |
| 896 Set<Constant> outputUnitConstants = null; | |
| 897 // TODO(sigurdm): We shouldn't run through all constants for every | |
| 898 // outputUnit. | |
| 899 for (Constant constant in constants) { | 897 for (Constant constant in constants) { |
| 900 if (isConstantInlinedOrAlreadyEmitted(constant)) continue; | |
| 901 OutputUnit constantUnit = | |
| 902 compiler.deferredLoadTask.outputUnitForConstant(constant); | |
| 903 if (constantUnit != outputUnit && constantUnit != null) continue; | |
| 904 if (outputUnit != compiler.deferredLoadTask.mainOutputUnit | |
| 905 && constantUnit == null) { | |
| 906 // The back-end introduces some constants, like "InterceptorConstant" or | |
| 907 // some list constants. They are emitted in the main output-unit, and | |
| 908 // ignored otherwise. | |
| 909 // TODO(sigurdm): We should track those constants. | |
| 910 continue; | |
| 911 } | |
| 912 | |
| 913 String name = namer.constantName(constant); | 898 String name = namer.constantName(constant); |
| 914 if (constant.isList) emitMakeConstantListIfNotEmitted(buffer); | 899 if (constant.isList) emitMakeConstantListIfNotEmitted(buffer); |
| 915 jsAst.Expression init = js('#.# = #', | 900 jsAst.Expression init = js('#.# = #', |
| 916 [namer.globalObjectForConstant(constant), name, | 901 [namer.globalObjectForConstant(constant), name, |
| 917 constantInitializerExpression(constant)]); | 902 constantInitializerExpression(constant)]); |
| 918 buffer.write(jsAst.prettyPrint(init, compiler)); | 903 buffer.write(jsAst.prettyPrint(init, compiler)); |
| 919 buffer.write('$N'); | 904 buffer.write('$N'); |
| 920 } | 905 } |
| 921 } | 906 } |
| 922 | 907 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 } | 1072 } |
| 1088 })$N''', [mainCallClosure, mainCallClosure]); | 1073 })$N''', [mainCallClosure, mainCallClosure]); |
| 1089 | 1074 |
| 1090 buffer.write(';'); | 1075 buffer.write(';'); |
| 1091 buffer.write(jsAst.prettyPrint(invokeMain, compiler)); | 1076 buffer.write(jsAst.prettyPrint(invokeMain, compiler)); |
| 1092 buffer.write(N); | 1077 buffer.write(N); |
| 1093 addComment('END invoke [main].', buffer); | 1078 addComment('END invoke [main].', buffer); |
| 1094 } | 1079 } |
| 1095 | 1080 |
| 1096 /** | 1081 /** |
| 1082 * Compute all the constants that must be emitted. |
| 1083 */ |
| 1084 void computeNeededConstants() { |
| 1085 JavaScriptConstantCompiler handler = backend.constants; |
| 1086 List<Constant> constants = handler.getConstantsForEmission( |
| 1087 compareConstants); |
| 1088 for (Constant constant in constants) { |
| 1089 if (isConstantInlinedOrAlreadyEmitted(constant)) continue; |
| 1090 OutputUnit constantUnit = |
| 1091 compiler.deferredLoadTask.outputUnitForConstant(constant); |
| 1092 if (constantUnit == null) { |
| 1093 // The back-end introduces some constants, like "InterceptorConstant" or |
| 1094 // some list constants. They are emitted in the main output-unit. |
| 1095 // TODO(sigurdm): We should track those constants. |
| 1096 constantUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 1097 } |
| 1098 outputConstantLists.putIfAbsent(constantUnit, () => new List<Constant>()) |
| 1099 .add(constant); |
| 1100 } |
| 1101 } |
| 1102 |
| 1103 /** |
| 1097 * Compute all the classes that must be emitted. | 1104 * Compute all the classes that must be emitted. |
| 1098 */ | 1105 */ |
| 1099 void computeNeededClasses() { | 1106 void computeNeededClasses() { |
| 1100 instantiatedClasses = | 1107 instantiatedClasses = |
| 1101 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()) | 1108 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()) |
| 1102 .toSet(); | 1109 .toSet(); |
| 1103 | 1110 |
| 1104 void addClassWithSuperclasses(ClassElement cls) { | 1111 void addClassWithSuperclasses(ClassElement cls) { |
| 1105 neededClasses.add(cls); | 1112 neededClasses.add(cls); |
| 1106 for (ClassElement superclass = cls.superclass; | 1113 for (ClassElement superclass = cls.superclass; |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 classesCollector = oldClassesCollector; | 1464 classesCollector = oldClassesCollector; |
| 1458 } | 1465 } |
| 1459 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit; | 1466 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 1460 typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit); | 1467 typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit); |
| 1461 interceptorEmitter.emitGetInterceptorMethods(mainBuffer); | 1468 interceptorEmitter.emitGetInterceptorMethods(mainBuffer); |
| 1462 interceptorEmitter.emitOneShotInterceptors(mainBuffer); | 1469 interceptorEmitter.emitOneShotInterceptors(mainBuffer); |
| 1463 // Constants in checked mode call into RTI code to set type information | 1470 // Constants in checked mode call into RTI code to set type information |
| 1464 // which may need getInterceptor (and one-shot interceptor) methods, so | 1471 // which may need getInterceptor (and one-shot interceptor) methods, so |
| 1465 // we have to make sure that [emitGetInterceptorMethods] and | 1472 // we have to make sure that [emitGetInterceptorMethods] and |
| 1466 // [emitOneShotInterceptors] have been called. | 1473 // [emitOneShotInterceptors] have been called. |
| 1474 computeNeededConstants(); |
| 1467 emitCompileTimeConstants(mainBuffer, mainOutputUnit); | 1475 emitCompileTimeConstants(mainBuffer, mainOutputUnit); |
| 1468 | 1476 |
| 1469 // Write a javascript mapping from Deferred import load ids (derrived from | 1477 // Write a javascript mapping from Deferred import load ids (derrived from |
| 1470 // the import prefix.) to a list of lists of js hunks to load. | 1478 // the import prefix.) to a list of lists of js hunks to load. |
| 1471 // TODO(sigurdm): Create a syntax tree for this. | 1479 // TODO(sigurdm): Create a syntax tree for this. |
| 1472 // TODO(sigurdm): Also find out where to place it. | 1480 // TODO(sigurdm): Also find out where to place it. |
| 1473 mainBuffer.write("\$.libraries_to_load = {"); | 1481 mainBuffer.write("\$.libraries_to_load = {"); |
| 1474 for (String loadId in compiler.deferredLoadTask.hunksToLoad.keys) { | 1482 for (String loadId in compiler.deferredLoadTask.hunksToLoad.keys) { |
| 1475 // TODO(sigurdm): Escape these strings. | 1483 // TODO(sigurdm): Escape these strings. |
| 1476 mainBuffer.write('"$loadId":['); | 1484 mainBuffer.write('"$loadId":['); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1735 String sourceMap = sourceMapBuilder.build(); | 1743 String sourceMap = sourceMapBuilder.build(); |
| 1736 compiler.outputProvider(name, 'js.map') | 1744 compiler.outputProvider(name, 'js.map') |
| 1737 ..add(sourceMap) | 1745 ..add(sourceMap) |
| 1738 ..close(); | 1746 ..close(); |
| 1739 } | 1747 } |
| 1740 | 1748 |
| 1741 void registerReadTypeVariable(TypeVariableElement element) { | 1749 void registerReadTypeVariable(TypeVariableElement element) { |
| 1742 readTypeVariables.add(element); | 1750 readTypeVariables.add(element); |
| 1743 } | 1751 } |
| 1744 } | 1752 } |
| OLD | NEW |