| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 final RuntimeTypes rti; | 149 final RuntimeTypes rti; |
| 150 | 150 |
| 151 /// Holds the method "disableTreeShaking" in js_mirrors when | 151 /// Holds the method "disableTreeShaking" in js_mirrors when |
| 152 /// dart:mirrors has been loaded. | 152 /// dart:mirrors has been loaded. |
| 153 FunctionElement disableTreeShakingMarker; | 153 FunctionElement disableTreeShakingMarker; |
| 154 | 154 |
| 155 /// Holds the method "preserveNames" in js_mirrors when | 155 /// Holds the method "preserveNames" in js_mirrors when |
| 156 /// dart:mirrors has been loaded. | 156 /// dart:mirrors has been loaded. |
| 157 FunctionElement preserveNamesMarker; | 157 FunctionElement preserveNamesMarker; |
| 158 | 158 |
| 159 /// Holds the method "preserveMetadata" in js_mirrors when |
| 160 /// dart:mirrors has been loaded. |
| 161 FunctionElement preserveMetadataMarker; |
| 162 |
| 163 /// True if a call to preserveMetadataMarker has been seen. This means that |
| 164 /// metadata must be retained for dart:mirrors to work correctly. |
| 165 bool mustRetainMetadata = false; |
| 166 |
| 167 /// True if any metadata has been retained. This is slightly different from |
| 168 /// [mustRetainMetadata] and tells us if any metadata was retained. For |
| 169 /// example, if [mustRetainMetadata] is true but there is no metadata in the |
| 170 /// program, this variable will stil be false. |
| 171 bool hasRetainedMetadata = false; |
| 172 |
| 173 /// True if a call to preserveNames has been seen. |
| 174 bool mustPreserveNames = false; |
| 175 |
| 176 /// True if a call to disableTreeShaking has been seen. |
| 177 bool isTreeShakingDisabled = false; |
| 178 |
| 179 /// List of instantiated classes from metadata. If metadata must be |
| 180 /// preserved, these classes must registered. |
| 181 final List<Dependency> metadataInstantiatedClasses = <Dependency>[]; |
| 182 |
| 183 /// List of elements used from metadata. If metadata must be preserved, |
| 184 /// these elements must be compiled. |
| 185 final List<Element> metadataStaticUse = <Element>[]; |
| 186 |
| 187 /// List of tear-off functions referenced from metadata. If metadata must be |
| 188 /// preserved, these elements must be compiled. |
| 189 final List<FunctionElement> metadataGetOfStaticFunction = <FunctionElement>[]; |
| 190 |
| 159 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) | 191 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) |
| 160 : namer = determineNamer(compiler), | 192 : namer = determineNamer(compiler), |
| 161 oneShotInterceptors = new Map<String, Selector>(), | 193 oneShotInterceptors = new Map<String, Selector>(), |
| 162 interceptedElements = new Map<SourceString, Set<Element>>(), | 194 interceptedElements = new Map<SourceString, Set<Element>>(), |
| 163 rti = new RuntimeTypes(compiler), | 195 rti = new RuntimeTypes(compiler), |
| 164 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), | 196 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), |
| 165 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { | 197 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { |
| 166 emitter = disableEval | 198 emitter = disableEval |
| 167 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) | 199 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) |
| 168 : new CodeEmitterTask(compiler, namer, generateSourceMap); | 200 : new CodeEmitterTask(compiler, namer, generateSourceMap); |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 } | 622 } |
| 591 | 623 |
| 592 void registerThrowExpression(TreeElements elements) { | 624 void registerThrowExpression(TreeElements elements) { |
| 593 enqueueInResolution(getThrowExpressionHelper(), elements); | 625 enqueueInResolution(getThrowExpressionHelper(), elements); |
| 594 } | 626 } |
| 595 | 627 |
| 596 void registerLazyField(TreeElements elements) { | 628 void registerLazyField(TreeElements elements) { |
| 597 enqueueInResolution(getCyclicThrowHelper(), elements); | 629 enqueueInResolution(getCyclicThrowHelper(), elements); |
| 598 } | 630 } |
| 599 | 631 |
| 600 void registerTypeLiteral(TreeElements elements) { | 632 void registerTypeLiteral(Element element, TreeElements elements) { |
| 601 enqueueInResolution(getCreateRuntimeType(), elements); | 633 enqueueInResolution(getCreateRuntimeType(), elements); |
| 634 // TODO(ahe): Might want to register [element] as an instantiated class |
| 635 // when reflection is used. However, as long as we disable tree-shaking |
| 636 // eagerly it doesn't matter. |
| 602 } | 637 } |
| 603 | 638 |
| 604 void registerStackTraceInCatch(TreeElements elements) { | 639 void registerStackTraceInCatch(TreeElements elements) { |
| 605 enqueueInResolution(getTraceFromException(), elements); | 640 enqueueInResolution(getTraceFromException(), elements); |
| 606 } | 641 } |
| 607 | 642 |
| 608 void registerSetRuntimeType(TreeElements elements) { | 643 void registerSetRuntimeType(TreeElements elements) { |
| 609 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 644 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
| 610 } | 645 } |
| 611 | 646 |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 ClassElement get listImplementation => jsArrayClass; | 1138 ClassElement get listImplementation => jsArrayClass; |
| 1104 ClassElement get constListImplementation => jsArrayClass; | 1139 ClassElement get constListImplementation => jsArrayClass; |
| 1105 ClassElement get fixedListImplementation => jsFixedArrayClass; | 1140 ClassElement get fixedListImplementation => jsFixedArrayClass; |
| 1106 ClassElement get growableListImplementation => jsExtendableArrayClass; | 1141 ClassElement get growableListImplementation => jsExtendableArrayClass; |
| 1107 ClassElement get mapImplementation => mapLiteralClass; | 1142 ClassElement get mapImplementation => mapLiteralClass; |
| 1108 ClassElement get constMapImplementation => constMapLiteralClass; | 1143 ClassElement get constMapImplementation => constMapLiteralClass; |
| 1109 ClassElement get typeImplementation => typeLiteralClass; | 1144 ClassElement get typeImplementation => typeLiteralClass; |
| 1110 ClassElement get boolImplementation => jsBoolClass; | 1145 ClassElement get boolImplementation => jsBoolClass; |
| 1111 ClassElement get nullImplementation => jsNullClass; | 1146 ClassElement get nullImplementation => jsNullClass; |
| 1112 | 1147 |
| 1113 void enableMirrors() { | |
| 1114 LibraryElement library = compiler.libraries['dart:_js_mirrors']; | |
| 1115 disableTreeShakingMarker = | |
| 1116 library.find(const SourceString('disableTreeShaking')); | |
| 1117 preserveNamesMarker = | |
| 1118 library.find(const SourceString('preserveNames')); | |
| 1119 } | |
| 1120 | |
| 1121 void registerStaticUse(Element element, Enqueuer enqueuer) { | 1148 void registerStaticUse(Element element, Enqueuer enqueuer) { |
| 1122 if (element == disableTreeShakingMarker) { | 1149 if (element == disableTreeShakingMarker) { |
| 1123 enqueuer.enqueueEverything(); | 1150 enqueuer.enqueueEverything(); |
| 1151 if (isTreeShakingDisabled) return; |
| 1124 compiler.disableTypeInferenceForMirrors = true; | 1152 compiler.disableTypeInferenceForMirrors = true; |
| 1153 isTreeShakingDisabled = true; |
| 1125 } else if (element == preserveNamesMarker) { | 1154 } else if (element == preserveNamesMarker) { |
| 1155 if (mustPreserveNames) return; |
| 1156 mustPreserveNames = true; |
| 1157 compiler.log('Preserving names.'); |
| 1158 } else if (element == preserveMetadataMarker) { |
| 1159 if (mustRetainMetadata) return; |
| 1160 compiler.log('Retaining metadata.'); |
| 1161 mustRetainMetadata = true; |
| 1162 for (LibraryElement library in compiler.libraries.values) { |
| 1163 if (retainMetadataOf(library)) { |
| 1164 for (Link link = library.metadata; !link.isEmpty; link = link.tail) { |
| 1165 link.head.ensureResolved(compiler); |
| 1166 } |
| 1167 } |
| 1168 } |
| 1169 for (Dependency dependency in metadataInstantiatedClasses) { |
| 1170 registerMetadataInstantiatedClass(dependency.element, dependency.user); |
| 1171 } |
| 1172 metadataInstantiatedClasses.clear(); |
| 1173 for (Element e in metadataStaticUse) { |
| 1174 registerMetadataStaticUse(e); |
| 1175 } |
| 1176 metadataStaticUse.clear(); |
| 1177 for (Element e in metadataGetOfStaticFunction) { |
| 1178 registerMetadataGetOfStaticFunction(e); |
| 1179 } |
| 1180 metadataGetOfStaticFunction.clear(); |
| 1181 } |
| 1182 } |
| 1183 |
| 1184 /// Called when [:const Symbol(name):] is seen. |
| 1185 void registerConstSymbol(String name, TreeElements elements) { |
| 1186 } |
| 1187 |
| 1188 /// Called when [:new Symbol(...):] is seen. |
| 1189 void registerNewSymbol(TreeElements elements) { |
| 1190 } |
| 1191 |
| 1192 bool retainGetter(Element element) => isTreeShakingDisabled; |
| 1193 |
| 1194 bool retainSetter(Element element) => isTreeShakingDisabled; |
| 1195 |
| 1196 bool retainName(SourceString name) => mustPreserveNames; |
| 1197 |
| 1198 bool retainMetadataOf(Element element) { |
| 1199 if (mustRetainMetadata) hasRetainedMetadata = true; |
| 1200 return mustRetainMetadata; |
| 1201 } |
| 1202 |
| 1203 void onLibraryScanned(LibraryElement library, Uri uri) { |
| 1204 if (uri == Uri.parse('dart:_js_mirrors')) { |
| 1205 disableTreeShakingMarker = |
| 1206 library.find(const SourceString('disableTreeShaking')); |
| 1207 preserveMetadataMarker = |
| 1208 library.find(const SourceString('preserveMetadata')); |
| 1209 } else if (uri == Uri.parse('dart:_js_names')) { |
| 1210 preserveNamesMarker = |
| 1211 library.find(const SourceString('preserveNames')); |
| 1212 } |
| 1213 } |
| 1214 |
| 1215 void registerMetadataInstantiatedClass(ClassElement element, |
| 1216 TreeElements elements) { |
| 1217 if (mustRetainMetadata) { |
| 1218 compiler.constantHandler.registerInstantiatedClass(element, elements); |
| 1219 } else { |
| 1220 metadataInstantiatedClasses.add(new Dependency(element, elements)); |
| 1221 } |
| 1222 } |
| 1223 |
| 1224 void registerMetadataStaticUse(Element element) { |
| 1225 if (mustRetainMetadata) { |
| 1226 compiler.constantHandler.registerStaticUse(element); |
| 1227 } else { |
| 1228 metadataStaticUse.add(element); |
| 1229 } |
| 1230 } |
| 1231 |
| 1232 void registerMetadataGetOfStaticFunction(FunctionElement element) { |
| 1233 if (mustRetainMetadata) { |
| 1234 compiler.constantHandler.registerGetOfStaticFunction(element); |
| 1235 } else { |
| 1236 metadataGetOfStaticFunction.add(element); |
| 1126 } | 1237 } |
| 1127 } | 1238 } |
| 1128 } | 1239 } |
| 1240 |
| 1241 /// Records that [element] is used by [user.element]. |
| 1242 class Dependency { |
| 1243 final Element element; |
| 1244 final TreeElements user; |
| 1245 |
| 1246 const Dependency(this.element, this.user); |
| 1247 } |
| OLD | NEW |