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; |
11 | 11 |
12 final ContainerBuilder containerBuilder = new ContainerBuilder(); | 12 final ContainerBuilder containerBuilder = new ContainerBuilder(); |
13 final ClassEmitter classEmitter = new ClassEmitter(); | 13 final ClassEmitter classEmitter = new ClassEmitter(); |
14 final NsmEmitter nsmEmitter = new NsmEmitter(); | 14 final NsmEmitter nsmEmitter = new NsmEmitter(); |
15 TypeTestEmitter get typeTestEmitter => task.typeTestEmitter; | 15 TypeTestEmitter get typeTestEmitter => task.typeTestEmitter; |
16 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); | 16 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); |
17 final MetadataEmitter metadataEmitter = new MetadataEmitter(); | 17 final MetadataEmitter metadataEmitter = new MetadataEmitter(); |
18 | 18 |
19 final Set<Constant> cachedEmittedConstants; | 19 final Set<ConstantValue> cachedEmittedConstants; |
20 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer(); | 20 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer(); |
21 final Map<Element, ClassBuilder> cachedClassBuilders; | 21 final Map<Element, ClassBuilder> cachedClassBuilders; |
22 final Set<Element> cachedElements; | 22 final Set<Element> cachedElements; |
23 | 23 |
24 bool needsDefineClass = false; | 24 bool needsDefineClass = false; |
25 bool needsMixinSupport = false; | 25 bool needsMixinSupport = false; |
26 bool needsLazyInitializer = false; | 26 bool needsLazyInitializer = false; |
27 final Namer namer; | 27 final Namer namer; |
28 ConstantEmitter constantEmitter; | 28 ConstantEmitter constantEmitter; |
29 NativeEmitter get nativeEmitter => task.nativeEmitter; | 29 NativeEmitter get nativeEmitter => task.nativeEmitter; |
30 | 30 |
31 // The full code that is written to each hunk part-file. | 31 // The full code that is written to each hunk part-file. |
32 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>(); | 32 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>(); |
33 final CodeBuffer deferredConstants = new CodeBuffer(); | 33 final CodeBuffer deferredConstants = new CodeBuffer(); |
34 | 34 |
35 /** Shorter access to [isolatePropertiesName]. Both here in the code, as | 35 /** Shorter access to [isolatePropertiesName]. Both here in the code, as |
36 well as in the generated code. */ | 36 well as in the generated code. */ |
37 String isolateProperties; | 37 String isolateProperties; |
38 String classesCollector; | 38 String classesCollector; |
39 Set<ClassElement> get neededClasses => task.neededClasses; | 39 Set<ClassElement> get neededClasses => task.neededClasses; |
40 Map<OutputUnit, List<ClassElement>> get outputClassLists | 40 Map<OutputUnit, List<ClassElement>> get outputClassLists |
41 => task.outputClassLists; | 41 => task.outputClassLists; |
42 Map<OutputUnit, List<Constant>> get outputConstantLists | 42 Map<OutputUnit, List<ConstantValue>> get outputConstantLists |
43 => task.outputConstantLists; | 43 => task.outputConstantLists; |
44 List<ClassElement> get nativeClasses => task.nativeClasses; | 44 List<ClassElement> get nativeClasses => task.nativeClasses; |
45 final Map<String, String> mangledFieldNames = <String, String>{}; | 45 final Map<String, String> mangledFieldNames = <String, String>{}; |
46 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; | 46 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; |
47 final Set<String> recordedMangledNames = new Set<String>(); | 47 final Set<String> recordedMangledNames = new Set<String>(); |
48 | 48 |
49 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = | 49 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = |
50 new Map<ClassElement, Map<String, jsAst.Expression>>(); | 50 new Map<ClassElement, Map<String, jsAst.Expression>>(); |
51 | 51 |
52 Set<ClassElement> get instantiatedClasses => task.instantiatedClasses; | 52 Set<ClassElement> get instantiatedClasses => task.instantiatedClasses; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 /// Used by the incremental compiler. | 135 /// Used by the incremental compiler. |
136 void clearCspPrecompiledNodes() { | 136 void clearCspPrecompiledNodes() { |
137 _cspPrecompiledFunctions.clear(); | 137 _cspPrecompiledFunctions.clear(); |
138 _cspPrecompiledConstructorNames.clear(); | 138 _cspPrecompiledConstructorNames.clear(); |
139 } | 139 } |
140 | 140 |
141 void addComment(String comment, CodeBuffer buffer) { | 141 void addComment(String comment, CodeBuffer buffer) { |
142 buffer.write(jsAst.prettyPrint(js.comment(comment), compiler)); | 142 buffer.write(jsAst.prettyPrint(js.comment(comment), compiler)); |
143 } | 143 } |
144 | 144 |
145 jsAst.Expression constantReference(Constant value) { | 145 jsAst.Expression constantReference(ConstantValue value) { |
146 return constantEmitter.reference(value); | 146 return constantEmitter.reference(value); |
147 } | 147 } |
148 | 148 |
149 jsAst.Expression constantInitializerExpression(Constant value) { | 149 jsAst.Expression constantInitializerExpression(ConstantValue value) { |
150 return constantEmitter.initializationExpression(value); | 150 return constantEmitter.initializationExpression(value); |
151 } | 151 } |
152 | 152 |
153 String get name => 'CodeEmitter'; | 153 String get name => 'CodeEmitter'; |
154 | 154 |
155 String get currentGenerateAccessorName | 155 String get currentGenerateAccessorName |
156 => '${namer.currentIsolate}.\$generateAccessor'; | 156 => '${namer.currentIsolate}.\$generateAccessor'; |
157 String get generateAccessorHolder | 157 String get generateAccessorHolder |
158 => '$isolatePropertiesName.\$generateAccessor'; | 158 => '$isolatePropertiesName.\$generateAccessor'; |
159 String get finishClassesProperty | 159 String get finishClassesProperty |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 896 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
897 JavaScriptConstantCompiler handler = backend.constants; | 897 JavaScriptConstantCompiler handler = backend.constants; |
898 Iterable<VariableElement> staticNonFinalFields = | 898 Iterable<VariableElement> staticNonFinalFields = |
899 handler.getStaticNonFinalFieldsForEmission(); | 899 handler.getStaticNonFinalFieldsForEmission(); |
900 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 900 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { |
901 // [:interceptedNames:] is handled in [emitInterceptedNames]. | 901 // [:interceptedNames:] is handled in [emitInterceptedNames]. |
902 if (element == backend.interceptedNames) continue; | 902 if (element == backend.interceptedNames) continue; |
903 // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor]. | 903 // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor]. |
904 if (element == backend.mapTypeToInterceptor) continue; | 904 if (element == backend.mapTypeToInterceptor) continue; |
905 compiler.withCurrentElement(element, () { | 905 compiler.withCurrentElement(element, () { |
906 Constant initialValue = handler.getInitialValueFor(element).value; | 906 ConstantValue initialValue = handler.getInitialValueFor(element).value; |
907 jsAst.Expression init = | 907 jsAst.Expression init = |
908 js('$isolateProperties.# = #', | 908 js('$isolateProperties.# = #', |
909 [namer.getNameOfGlobalField(element), | 909 [namer.getNameOfGlobalField(element), |
910 constantEmitter.referenceInInitializationContext(initialValue)]); | 910 constantEmitter.referenceInInitializationContext(initialValue)]); |
911 buffer.write(jsAst.prettyPrint(init, compiler, | 911 buffer.write(jsAst.prettyPrint(init, compiler, |
912 monitor: compiler.dumpInfoTask)); | 912 monitor: compiler.dumpInfoTask)); |
913 buffer.write('$N'); | 913 buffer.write('$N'); |
914 }); | 914 }); |
915 } | 915 } |
916 } | 916 } |
(...skipping 29 matching lines...) Expand all Loading... |
946 buffer.write("$N"); | 946 buffer.write("$N"); |
947 } | 947 } |
948 } | 948 } |
949 } | 949 } |
950 | 950 |
951 jsAst.Expression buildLazyInitializedGetter(VariableElement element) { | 951 jsAst.Expression buildLazyInitializedGetter(VariableElement element) { |
952 // Nothing to do, the 'lazy' function will create the getter. | 952 // Nothing to do, the 'lazy' function will create the getter. |
953 return null; | 953 return null; |
954 } | 954 } |
955 | 955 |
956 bool isConstantInlinedOrAlreadyEmitted(Constant constant) { | 956 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { |
957 if (constant.isFunction) return true; // Already emitted. | 957 if (constant.isFunction) return true; // Already emitted. |
958 if (constant.isPrimitive) return true; // Inlined. | 958 if (constant.isPrimitive) return true; // Inlined. |
959 if (constant.isDummy) return true; // Inlined. | 959 if (constant.isDummy) return true; // Inlined. |
960 // The name is null when the constant is already a JS constant. | 960 // The name is null when the constant is already a JS constant. |
961 // TODO(floitsch): every constant should be registered, so that we can | 961 // TODO(floitsch): every constant should be registered, so that we can |
962 // share the ones that take up too much space (like some strings). | 962 // share the ones that take up too much space (like some strings). |
963 if (namer.constantName(constant) == null) return true; | 963 if (namer.constantName(constant) == null) return true; |
964 return false; | 964 return false; |
965 } | 965 } |
966 | 966 |
967 int compareConstants(Constant a, Constant b) { | 967 int compareConstants(ConstantValue a, ConstantValue b) { |
968 // Inlined constants don't affect the order and sometimes don't even have | 968 // Inlined constants don't affect the order and sometimes don't even have |
969 // names. | 969 // names. |
970 int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1; | 970 int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1; |
971 int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1; | 971 int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1; |
972 if (cmp1 + cmp2 < 2) return cmp1 - cmp2; | 972 if (cmp1 + cmp2 < 2) return cmp1 - cmp2; |
973 | 973 |
974 // Emit constant interceptors first. Constant interceptors for primitives | 974 // Emit constant interceptors first. Constant interceptors for primitives |
975 // might be used by code that builds other constants. See Issue 18173. | 975 // might be used by code that builds other constants. See Issue 18173. |
976 if (a.isInterceptor != b.isInterceptor) { | 976 if (a.isInterceptor != b.isInterceptor) { |
977 return a.isInterceptor ? -1 : 1; | 977 return a.isInterceptor ? -1 : 1; |
978 } | 978 } |
979 | 979 |
980 // Sorting by the long name clusters constants with the same constructor | 980 // Sorting by the long name clusters constants with the same constructor |
981 // which compresses a tiny bit better. | 981 // which compresses a tiny bit better. |
982 int r = namer.constantLongName(a).compareTo(namer.constantLongName(b)); | 982 int r = namer.constantLongName(a).compareTo(namer.constantLongName(b)); |
983 if (r != 0) return r; | 983 if (r != 0) return r; |
984 // Resolve collisions in the long name by using the constant name (i.e. JS | 984 // Resolve collisions in the long name by using the constant name (i.e. JS |
985 // name) which is unique. | 985 // name) which is unique. |
986 return namer.constantName(a).compareTo(namer.constantName(b)); | 986 return namer.constantName(a).compareTo(namer.constantName(b)); |
987 } | 987 } |
988 | 988 |
989 void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) { | 989 void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) { |
990 List<Constant> constants = outputConstantLists[outputUnit]; | 990 List<ConstantValue> constants = outputConstantLists[outputUnit]; |
991 if (constants == null) return; | 991 if (constants == null) return; |
992 bool isMainBuffer = buffer == mainBuffer; | 992 bool isMainBuffer = buffer == mainBuffer; |
993 if (compiler.hasIncrementalSupport && isMainBuffer) { | 993 if (compiler.hasIncrementalSupport && isMainBuffer) { |
994 buffer = cachedEmittedConstantsBuffer; | 994 buffer = cachedEmittedConstantsBuffer; |
995 } | 995 } |
996 for (Constant constant in constants) { | 996 for (ConstantValue constant in constants) { |
997 if (compiler.hasIncrementalSupport && isMainBuffer) { | 997 if (compiler.hasIncrementalSupport && isMainBuffer) { |
998 if (cachedEmittedConstants.contains(constant)) continue; | 998 if (cachedEmittedConstants.contains(constant)) continue; |
999 cachedEmittedConstants.add(constant); | 999 cachedEmittedConstants.add(constant); |
1000 } | 1000 } |
1001 String name = namer.constantName(constant); | 1001 String name = namer.constantName(constant); |
1002 if (constant.isList) emitMakeConstantListIfNotEmitted(buffer); | 1002 if (constant.isList) emitMakeConstantListIfNotEmitted(buffer); |
1003 jsAst.Expression init = js('#.# = #', | 1003 jsAst.Expression init = js('#.# = #', |
1004 [namer.globalObjectForConstant(constant), name, | 1004 [namer.globalObjectForConstant(constant), name, |
1005 constantInitializerExpression(constant)]); | 1005 constantInitializerExpression(constant)]); |
1006 buffer.write(jsAst.prettyPrint(init, compiler, | 1006 buffer.write(jsAst.prettyPrint(init, compiler, |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1919 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 1919 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
1920 if (element.isInstanceMember) { | 1920 if (element.isInstanceMember) { |
1921 cachedClassBuilders.remove(element.enclosingClass); | 1921 cachedClassBuilders.remove(element.enclosingClass); |
1922 | 1922 |
1923 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 1923 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
1924 | 1924 |
1925 } | 1925 } |
1926 } | 1926 } |
1927 } | 1927 } |
1928 } | 1928 } |
OLD | NEW |