| 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 library js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/backend_api.dart' | 8 import '../common/backend_api.dart' |
| 9 show ForeignResolver, NativeRegistry, ImpactTransformer; | 9 show ForeignResolver, NativeRegistry, ImpactTransformer; |
| 10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 static const String JS = 'JS'; | 303 static const String JS = 'JS'; |
| 304 static const String JS_BUILTIN = 'JS_BUILTIN'; | 304 static const String JS_BUILTIN = 'JS_BUILTIN'; |
| 305 static const String JS_EMBEDDED_GLOBAL = 'JS_EMBEDDED_GLOBAL'; | 305 static const String JS_EMBEDDED_GLOBAL = 'JS_EMBEDDED_GLOBAL'; |
| 306 static const String JS_INTERCEPTOR_CONSTANT = 'JS_INTERCEPTOR_CONSTANT'; | 306 static const String JS_INTERCEPTOR_CONSTANT = 'JS_INTERCEPTOR_CONSTANT'; |
| 307 | 307 |
| 308 final Compiler compiler; | 308 final Compiler compiler; |
| 309 | 309 |
| 310 /// Returns true if the backend supports reflection. | 310 /// Returns true if the backend supports reflection. |
| 311 bool get supportsReflection => emitter.supportsReflection; | 311 bool get supportsReflection => emitter.supportsReflection; |
| 312 | 312 |
| 313 final OptimizerHintsForTests optimizerHints; | 313 final OptimizerHintsForTests annotations; |
| 314 | 314 |
| 315 /// Set of classes that need to be considered for reflection although not | 315 /// Set of classes that need to be considered for reflection although not |
| 316 /// otherwise visible during resolution. | 316 /// otherwise visible during resolution. |
| 317 Iterable<ClassEntity> get classesRequiredForReflection { | 317 Iterable<ClassEntity> get classesRequiredForReflection { |
| 318 // TODO(herhut): Clean this up when classes needed for rti are tracked. | 318 // TODO(herhut): Clean this up when classes needed for rti are tracked. |
| 319 return [commonElements.closureClass, commonElements.jsIndexableClass]; | 319 return [commonElements.closureClass, commonElements.jsIndexableClass]; |
| 320 } | 320 } |
| 321 | 321 |
| 322 FunctionCompiler functionCompiler; | 322 FunctionCompiler functionCompiler; |
| 323 | 323 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 } | 471 } |
| 472 } | 472 } |
| 473 | 473 |
| 474 JavaScriptBackend(this.compiler, | 474 JavaScriptBackend(this.compiler, |
| 475 {bool generateSourceMap: true, | 475 {bool generateSourceMap: true, |
| 476 bool useStartupEmitter: false, | 476 bool useStartupEmitter: false, |
| 477 bool useMultiSourceInfo: false, | 477 bool useMultiSourceInfo: false, |
| 478 bool useNewSourceInfo: false, | 478 bool useNewSourceInfo: false, |
| 479 bool useKernel: false}) | 479 bool useKernel: false}) |
| 480 : _rti = new _RuntimeTypes(compiler), | 480 : _rti = new _RuntimeTypes(compiler), |
| 481 optimizerHints = new OptimizerHintsForTests( | 481 annotations = new OptimizerHintsForTests(compiler), |
| 482 compiler.elementEnvironment, compiler.commonElements), | |
| 483 this.sourceInformationStrategy = createSourceInformationStrategy( | 482 this.sourceInformationStrategy = createSourceInformationStrategy( |
| 484 generateSourceMap: generateSourceMap, | 483 generateSourceMap: generateSourceMap, |
| 485 useMultiSourceInfo: useMultiSourceInfo, | 484 useMultiSourceInfo: useMultiSourceInfo, |
| 486 useNewSourceInfo: useNewSourceInfo), | 485 useNewSourceInfo: useNewSourceInfo), |
| 487 constantCompilerTask = new JavaScriptConstantTask(compiler), | 486 constantCompilerTask = new JavaScriptConstantTask(compiler), |
| 488 _nativeDataResolver = new NativeDataResolverImpl(compiler), | 487 _nativeDataResolver = new NativeDataResolverImpl(compiler), |
| 489 _rtiNeedBuilder = | 488 _rtiNeedBuilder = |
| 490 compiler.frontEndStrategy.createRuntimeTypesNeedBuilder() { | 489 compiler.frontEndStrategy.createRuntimeTypesNeedBuilder() { |
| 491 _target = new JavaScriptBackendTarget(this); | 490 _target = new JavaScriptBackendTarget(this); |
| 492 impacts = new BackendImpacts(compiler.options, commonElements); | 491 impacts = new BackendImpacts(compiler.options, commonElements); |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 bool isTargetSpecificLibrary(LibraryElement library) { | 1172 bool isTargetSpecificLibrary(LibraryElement library) { |
| 1174 Uri canonicalUri = library.canonicalUri; | 1173 Uri canonicalUri = library.canonicalUri; |
| 1175 if (canonicalUri == Uris.dart__js_helper || | 1174 if (canonicalUri == Uris.dart__js_helper || |
| 1176 canonicalUri == Uris.dart__interceptors) { | 1175 canonicalUri == Uris.dart__interceptors) { |
| 1177 return true; | 1176 return true; |
| 1178 } | 1177 } |
| 1179 return false; | 1178 return false; |
| 1180 } | 1179 } |
| 1181 | 1180 |
| 1182 /// Process backend specific annotations. | 1181 /// Process backend specific annotations. |
| 1183 // TODO(johnniwinther): Merge this with [AnnotationProcessor] and use | |
| 1184 // [ElementEnvironment.getMemberMetadata] in [AnnotationProcessor]. | |
| 1185 void processAnnotations( | 1182 void processAnnotations( |
| 1186 MemberEntity element, ClosedWorldRefiner closedWorldRefiner) { | 1183 MemberElement element, ClosedWorldRefiner closedWorldRefiner) { |
| 1187 if (element is MemberElement && element.isMalformed) { | 1184 if (element.isMalformed) { |
| 1188 // Elements that are marked as malformed during parsing or resolution | 1185 // Elements that are marked as malformed during parsing or resolution |
| 1189 // might be registered here. These should just be ignored. | 1186 // might be registered here. These should just be ignored. |
| 1190 return; | 1187 return; |
| 1191 } | 1188 } |
| 1192 | 1189 |
| 1193 if (element.isFunction || element.isConstructor) { | 1190 if (element.isFunction || element.isConstructor) { |
| 1194 if (optimizerHints.noInline(element)) { | 1191 MethodElement method = element.implementation; |
| 1195 inlineCache.markAsNonInlinable(element); | 1192 if (annotations.noInline(method)) { |
| 1193 inlineCache.markAsNonInlinable(method); |
| 1196 } | 1194 } |
| 1197 } | 1195 } |
| 1198 if (element.isField) return; | 1196 if (element.isField) return; |
| 1199 FunctionEntity method = element; | 1197 MethodElement method = element; |
| 1200 | 1198 |
| 1201 LibraryEntity library = method.library; | 1199 LibraryElement library = method.library; |
| 1202 if (library.canonicalUri.scheme != 'dart' && | 1200 if (!library.isPlatformLibrary && !canLibraryUseNative(library)) return; |
| 1203 !canLibraryUseNative(library)) { | |
| 1204 return; | |
| 1205 } | |
| 1206 bool hasNoInline = false; | 1201 bool hasNoInline = false; |
| 1207 bool hasForceInline = false; | 1202 bool hasForceInline = false; |
| 1208 bool hasNoThrows = false; | 1203 bool hasNoThrows = false; |
| 1209 bool hasNoSideEffects = false; | 1204 bool hasNoSideEffects = false; |
| 1210 for (ConstantValue constantValue | 1205 for (MetadataAnnotation metadata in method.implementation.metadata) { |
| 1211 in compiler.elementEnvironment.getMemberMetadata(method)) { | 1206 metadata.ensureResolved(resolution); |
| 1207 ConstantValue constantValue = |
| 1208 compiler.constants.getConstantValue(metadata.constant); |
| 1212 if (!constantValue.isConstructedObject) continue; | 1209 if (!constantValue.isConstructedObject) continue; |
| 1213 ObjectConstantValue value = constantValue; | 1210 ObjectConstantValue value = constantValue; |
| 1214 ClassEntity cls = value.type.element; | 1211 ClassElement cls = value.type.element; |
| 1215 if (cls == commonElements.forceInlineClass) { | 1212 if (cls == commonElements.forceInlineClass) { |
| 1216 hasForceInline = true; | 1213 hasForceInline = true; |
| 1217 if (VERBOSE_OPTIMIZER_HINTS) { | 1214 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1218 reporter.reportHintMessage( | 1215 reporter.reportHintMessage( |
| 1219 method, MessageKind.GENERIC, {'text': "Must inline"}); | 1216 method, MessageKind.GENERIC, {'text': "Must inline"}); |
| 1220 } | 1217 } |
| 1221 inlineCache.markAsMustInline(method); | 1218 inlineCache.markAsMustInline(method); |
| 1222 } else if (cls == commonElements.noInlineClass) { | 1219 } else if (cls == commonElements.noInlineClass) { |
| 1223 hasNoInline = true; | 1220 hasNoInline = true; |
| 1224 if (VERBOSE_OPTIMIZER_HINTS) { | 1221 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1225 reporter.reportHintMessage( | 1222 reporter.reportHintMessage( |
| 1226 method, MessageKind.GENERIC, {'text': "Cannot inline"}); | 1223 method, MessageKind.GENERIC, {'text': "Cannot inline"}); |
| 1227 } | 1224 } |
| 1228 inlineCache.markAsNonInlinable(method); | 1225 inlineCache.markAsNonInlinable(method); |
| 1229 } else if (cls == commonElements.noThrowsClass) { | 1226 } else if (cls == commonElements.noThrowsClass) { |
| 1230 hasNoThrows = true; | 1227 hasNoThrows = true; |
| 1231 bool isValid = true; | 1228 if (!Elements.isStaticOrTopLevelFunction(method) && |
| 1232 if (method.isTopLevel) { | 1229 !method.isFactoryConstructor) { |
| 1233 isValid = true; | |
| 1234 } else if (method.isStatic) { | |
| 1235 isValid = true; | |
| 1236 } else if (method is ConstructorEntity && method.isFactoryConstructor) { | |
| 1237 isValid = true; | |
| 1238 } | |
| 1239 if (!isValid) { | |
| 1240 reporter.internalError( | 1230 reporter.internalError( |
| 1241 method, | 1231 method, |
| 1242 "@NoThrows() is currently limited to top-level" | 1232 "@NoThrows() is currently limited to top-level" |
| 1243 " or static functions and factory constructors."); | 1233 " or static functions and factory constructors."); |
| 1244 } | 1234 } |
| 1245 if (VERBOSE_OPTIMIZER_HINTS) { | 1235 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1246 reporter.reportHintMessage( | 1236 reporter.reportHintMessage( |
| 1247 method, MessageKind.GENERIC, {'text': "Cannot throw"}); | 1237 method, MessageKind.GENERIC, {'text': "Cannot throw"}); |
| 1248 } | 1238 } |
| 1249 closedWorldRefiner.registerCannotThrow(method); | 1239 closedWorldRefiner.registerCannotThrow(method); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 | 1452 |
| 1463 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { | 1453 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { |
| 1464 return !selector.isGetter; | 1454 return !selector.isGetter; |
| 1465 } | 1455 } |
| 1466 | 1456 |
| 1467 /// Returns `true` if [member] is called from a subclass via `super`. | 1457 /// Returns `true` if [member] is called from a subclass via `super`. |
| 1468 bool isAliasedSuperMember(MemberEntity member) { | 1458 bool isAliasedSuperMember(MemberEntity member) { |
| 1469 return _aliasedSuperMembers.contains(member); | 1459 return _aliasedSuperMembers.contains(member); |
| 1470 } | 1460 } |
| 1471 } | 1461 } |
| OLD | NEW |