| 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 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 10 | 10 |
| (...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 dependency, impactBuilder, isForResolution); | 1064 dependency, impactBuilder, isForResolution); |
| 1065 } | 1065 } |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 void addCompileTimeConstantForEmission(ConstantValue constant) { | 1068 void addCompileTimeConstantForEmission(ConstantValue constant) { |
| 1069 constants.addCompileTimeConstantForEmission(constant); | 1069 constants.addCompileTimeConstantForEmission(constant); |
| 1070 } | 1070 } |
| 1071 | 1071 |
| 1072 void computeImpactForCompileTimeConstantInternal(ConstantValue constant, | 1072 void computeImpactForCompileTimeConstantInternal(ConstantValue constant, |
| 1073 WorldImpactBuilder impactBuilder, bool isForResolution) { | 1073 WorldImpactBuilder impactBuilder, bool isForResolution) { |
| 1074 DartType type = constant.getType(compiler.commonElements); | 1074 ResolutionDartType type = constant.getType(compiler.commonElements); |
| 1075 computeImpactForInstantiatedConstantType(type, impactBuilder); | 1075 computeImpactForInstantiatedConstantType(type, impactBuilder); |
| 1076 | 1076 |
| 1077 if (constant.isFunction) { | 1077 if (constant.isFunction) { |
| 1078 FunctionConstantValue function = constant; | 1078 FunctionConstantValue function = constant; |
| 1079 impactBuilder | 1079 impactBuilder |
| 1080 .registerStaticUse(new StaticUse.staticTearOff(function.element)); | 1080 .registerStaticUse(new StaticUse.staticTearOff(function.element)); |
| 1081 } else if (constant.isInterceptor) { | 1081 } else if (constant.isInterceptor) { |
| 1082 // An interceptor constant references the class's prototype chain. | 1082 // An interceptor constant references the class's prototype chain. |
| 1083 InterceptorConstantValue interceptor = constant; | 1083 InterceptorConstantValue interceptor = constant; |
| 1084 computeImpactForInstantiatedConstantType( | 1084 computeImpactForInstantiatedConstantType( |
| 1085 interceptor.dispatchedType, impactBuilder); | 1085 interceptor.dispatchedType, impactBuilder); |
| 1086 } else if (constant.isType) { | 1086 } else if (constant.isType) { |
| 1087 if (isForResolution) { | 1087 if (isForResolution) { |
| 1088 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 1088 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 1089 // TODO(johnniwinther): Find the right [CallStructure]. | 1089 // TODO(johnniwinther): Find the right [CallStructure]. |
| 1090 helpers.createRuntimeType, | 1090 helpers.createRuntimeType, |
| 1091 null)); | 1091 null)); |
| 1092 registerBackendUse(helpers.createRuntimeType); | 1092 registerBackendUse(helpers.createRuntimeType); |
| 1093 } | 1093 } |
| 1094 impactBuilder.registerTypeUse( | 1094 impactBuilder.registerTypeUse( |
| 1095 new TypeUse.instantiation(backendClasses.typeImplementation.rawType)); | 1095 new TypeUse.instantiation(backendClasses.typeImplementation.rawType)); |
| 1096 } | 1096 } |
| 1097 lookupMapAnalysis.registerConstantKey(constant); | 1097 lookupMapAnalysis.registerConstantKey(constant); |
| 1098 } | 1098 } |
| 1099 | 1099 |
| 1100 void computeImpactForInstantiatedConstantType( | 1100 void computeImpactForInstantiatedConstantType( |
| 1101 DartType type, WorldImpactBuilder impactBuilder) { | 1101 ResolutionDartType type, WorldImpactBuilder impactBuilder) { |
| 1102 DartType instantiatedType = | 1102 ResolutionDartType instantiatedType = |
| 1103 type.isFunctionType ? commonElements.functionType : type; | 1103 type.isFunctionType ? commonElements.functionType : type; |
| 1104 if (type is InterfaceType) { | 1104 if (type is ResolutionInterfaceType) { |
| 1105 impactBuilder | 1105 impactBuilder |
| 1106 .registerTypeUse(new TypeUse.instantiation(instantiatedType)); | 1106 .registerTypeUse(new TypeUse.instantiation(instantiatedType)); |
| 1107 if (classNeedsRtiField(type.element)) { | 1107 if (classNeedsRtiField(type.element)) { |
| 1108 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 1108 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 1109 // TODO(johnniwinther): Find the right [CallStructure]. | 1109 // TODO(johnniwinther): Find the right [CallStructure]. |
| 1110 helpers.setRuntimeTypeInfo, | 1110 helpers.setRuntimeTypeInfo, |
| 1111 null)); | 1111 null)); |
| 1112 } | 1112 } |
| 1113 if (type.element == backendClasses.typeImplementation) { | 1113 if (type.element == backendClasses.typeImplementation) { |
| 1114 // If we use a type literal in a constant, the compile time | 1114 // If we use a type literal in a constant, the compile time |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 | 1252 |
| 1253 customElementsAnalysis.registerInstantiatedClass(cls, | 1253 customElementsAnalysis.registerInstantiatedClass(cls, |
| 1254 forResolution: forResolution); | 1254 forResolution: forResolution); |
| 1255 if (!forResolution) { | 1255 if (!forResolution) { |
| 1256 lookupMapAnalysis.registerInstantiatedClass(cls); | 1256 lookupMapAnalysis.registerInstantiatedClass(cls); |
| 1257 } | 1257 } |
| 1258 | 1258 |
| 1259 return impactBuilder; | 1259 return impactBuilder; |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 void registerInstantiatedType(InterfaceType type) { | 1262 void registerInstantiatedType(ResolutionInterfaceType type) { |
| 1263 lookupMapAnalysis.registerInstantiatedType(type); | 1263 lookupMapAnalysis.registerInstantiatedType(type); |
| 1264 } | 1264 } |
| 1265 | 1265 |
| 1266 @override | 1266 @override |
| 1267 WorldImpact computeHelpersImpact() { | 1267 WorldImpact computeHelpersImpact() { |
| 1268 assert(helpers.interceptorsLibrary != null); | 1268 assert(helpers.interceptorsLibrary != null); |
| 1269 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 1269 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 1270 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1270 // TODO(ngeoffray): Not enqueuing those two classes currently make |
| 1271 // the compiler potentially crash. However, any reasonable program | 1271 // the compiler potentially crash. However, any reasonable program |
| 1272 // will instantiate those two classes. | 1272 // will instantiate those two classes. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 return impactTransformer.createImpactFor(impacts.computeSignature); | 1336 return impactTransformer.createImpactFor(impacts.computeSignature); |
| 1337 } | 1337 } |
| 1338 | 1338 |
| 1339 /// Called to register that the `runtimeType` property has been accessed. Any | 1339 /// Called to register that the `runtimeType` property has been accessed. Any |
| 1340 /// backend specific [WorldImpact] of this is returned. | 1340 /// backend specific [WorldImpact] of this is returned. |
| 1341 WorldImpact registerRuntimeType() { | 1341 WorldImpact registerRuntimeType() { |
| 1342 return impactTransformer.createImpactFor(impacts.runtimeTypeSupport); | 1342 return impactTransformer.createImpactFor(impacts.runtimeTypeSupport); |
| 1343 } | 1343 } |
| 1344 | 1344 |
| 1345 void registerTypeVariableBoundsSubtypeCheck( | 1345 void registerTypeVariableBoundsSubtypeCheck( |
| 1346 DartType typeArgument, DartType bound) { | 1346 ResolutionDartType typeArgument, ResolutionDartType bound) { |
| 1347 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 1347 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 WorldImpact computeDeferredLoadingImpact() { | 1350 WorldImpact computeDeferredLoadingImpact() { |
| 1351 return impactTransformer.createImpactFor(impacts.deferredLoading); | 1351 return impactTransformer.createImpactFor(impacts.deferredLoading); |
| 1352 } | 1352 } |
| 1353 | 1353 |
| 1354 /// Called to register a `noSuchMethod` implementation. | 1354 /// Called to register a `noSuchMethod` implementation. |
| 1355 void registerNoSuchMethod(MethodElement noSuchMethod) { | 1355 void registerNoSuchMethod(MethodElement noSuchMethod) { |
| 1356 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); | 1356 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1369 return nativeEnqueuer.resolveJsBuiltinCall(node, resolver); | 1369 return nativeEnqueuer.resolveJsBuiltinCall(node, resolver); |
| 1370 } else if (element.name == BackendHelpers.JS_INTERCEPTOR_CONSTANT) { | 1370 } else if (element.name == BackendHelpers.JS_INTERCEPTOR_CONSTANT) { |
| 1371 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names | 1371 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names |
| 1372 // a class that will be instantiated outside the program by attaching a | 1372 // a class that will be instantiated outside the program by attaching a |
| 1373 // native class dispatch record referencing the interceptor. | 1373 // native class dispatch record referencing the interceptor. |
| 1374 if (!node.argumentsNode.isEmpty) { | 1374 if (!node.argumentsNode.isEmpty) { |
| 1375 Node argument = node.argumentsNode.nodes.head; | 1375 Node argument = node.argumentsNode.nodes.head; |
| 1376 ConstantExpression constant = resolver.getConstant(argument); | 1376 ConstantExpression constant = resolver.getConstant(argument); |
| 1377 if (constant != null && constant.kind == ConstantExpressionKind.TYPE) { | 1377 if (constant != null && constant.kind == ConstantExpressionKind.TYPE) { |
| 1378 TypeConstantExpression typeConstant = constant; | 1378 TypeConstantExpression typeConstant = constant; |
| 1379 if (typeConstant.type is InterfaceType) { | 1379 if (typeConstant.type is ResolutionInterfaceType) { |
| 1380 resolver.registerInstantiatedType(typeConstant.type); | 1380 resolver.registerInstantiatedType(typeConstant.type); |
| 1381 // No native behavior for this call. | 1381 // No native behavior for this call. |
| 1382 return null; | 1382 return null; |
| 1383 } | 1383 } |
| 1384 } | 1384 } |
| 1385 } | 1385 } |
| 1386 reporter.reportErrorMessage( | 1386 reporter.reportErrorMessage( |
| 1387 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 1387 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 1388 } | 1388 } |
| 1389 // No native behavior for this call. | 1389 // No native behavior for this call. |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 } | 1585 } |
| 1586 return element; | 1586 return element; |
| 1587 } | 1587 } |
| 1588 | 1588 |
| 1589 /** | 1589 /** |
| 1590 * Returns the checked mode helper that will be needed to do a type check/type | 1590 * Returns the checked mode helper that will be needed to do a type check/type |
| 1591 * cast on [type] at runtime. Note that this method is being called both by | 1591 * cast on [type] at runtime. Note that this method is being called both by |
| 1592 * the resolver with interface types (int, String, ...), and by the SSA | 1592 * the resolver with interface types (int, String, ...), and by the SSA |
| 1593 * backend with implementation types (JSInt, JSString, ...). | 1593 * backend with implementation types (JSInt, JSString, ...). |
| 1594 */ | 1594 */ |
| 1595 CheckedModeHelper getCheckedModeHelper(DartType type, {bool typeCast}) { | 1595 CheckedModeHelper getCheckedModeHelper(ResolutionDartType type, |
| 1596 {bool typeCast}) { |
| 1596 return getCheckedModeHelperInternal(type, | 1597 return getCheckedModeHelperInternal(type, |
| 1597 typeCast: typeCast, nativeCheckOnly: false); | 1598 typeCast: typeCast, nativeCheckOnly: false); |
| 1598 } | 1599 } |
| 1599 | 1600 |
| 1600 /** | 1601 /** |
| 1601 * Returns the native checked mode helper that will be needed to do a type | 1602 * Returns the native checked mode helper that will be needed to do a type |
| 1602 * check/type cast on [type] at runtime. If no native helper exists for | 1603 * check/type cast on [type] at runtime. If no native helper exists for |
| 1603 * [type], [:null:] is returned. | 1604 * [type], [:null:] is returned. |
| 1604 */ | 1605 */ |
| 1605 CheckedModeHelper getNativeCheckedModeHelper(DartType type, {bool typeCast}) { | 1606 CheckedModeHelper getNativeCheckedModeHelper(ResolutionDartType type, |
| 1607 {bool typeCast}) { |
| 1606 return getCheckedModeHelperInternal(type, | 1608 return getCheckedModeHelperInternal(type, |
| 1607 typeCast: typeCast, nativeCheckOnly: true); | 1609 typeCast: typeCast, nativeCheckOnly: true); |
| 1608 } | 1610 } |
| 1609 | 1611 |
| 1610 /** | 1612 /** |
| 1611 * Returns the checked mode helper for the type check/type cast for [type]. If | 1613 * Returns the checked mode helper for the type check/type cast for [type]. If |
| 1612 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. | 1614 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. |
| 1613 */ | 1615 */ |
| 1614 CheckedModeHelper getCheckedModeHelperInternal(DartType type, | 1616 CheckedModeHelper getCheckedModeHelperInternal(ResolutionDartType type, |
| 1615 {bool typeCast, bool nativeCheckOnly}) { | 1617 {bool typeCast, bool nativeCheckOnly}) { |
| 1616 String name = getCheckedModeHelperNameInternal(type, | 1618 String name = getCheckedModeHelperNameInternal(type, |
| 1617 typeCast: typeCast, nativeCheckOnly: nativeCheckOnly); | 1619 typeCast: typeCast, nativeCheckOnly: nativeCheckOnly); |
| 1618 if (name == null) return null; | 1620 if (name == null) return null; |
| 1619 CheckedModeHelper helper = checkedModeHelperByName[name]; | 1621 CheckedModeHelper helper = checkedModeHelperByName[name]; |
| 1620 assert(helper != null); | 1622 assert(helper != null); |
| 1621 return helper; | 1623 return helper; |
| 1622 } | 1624 } |
| 1623 | 1625 |
| 1624 String getCheckedModeHelperNameInternal(DartType type, | 1626 String getCheckedModeHelperNameInternal(ResolutionDartType type, |
| 1625 {bool typeCast, bool nativeCheckOnly}) { | 1627 {bool typeCast, bool nativeCheckOnly}) { |
| 1626 assert(type.kind != TypeKind.TYPEDEF); | 1628 assert(type.kind != ResolutionTypeKind.TYPEDEF); |
| 1627 if (type.isMalformed) { | 1629 if (type.isMalformed) { |
| 1628 // The same error is thrown for type test and type cast of a malformed | 1630 // The same error is thrown for type test and type cast of a malformed |
| 1629 // type so we only need one check method. | 1631 // type so we only need one check method. |
| 1630 return 'checkMalformedType'; | 1632 return 'checkMalformedType'; |
| 1631 } | 1633 } |
| 1632 Element element = type.element; | 1634 Element element = type.element; |
| 1633 bool nativeCheck = | 1635 bool nativeCheck = |
| 1634 nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); | 1636 nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); |
| 1635 | 1637 |
| 1636 // TODO(13955), TODO(9731). The test for non-primitive types should use an | 1638 // TODO(13955), TODO(9731). The test for non-primitive types should use an |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 staticUses.add(helper.getStaticUse(compiler).element); | 1729 staticUses.add(helper.getStaticUse(compiler).element); |
| 1728 } | 1730 } |
| 1729 impactTransformer.registerBackendImpact( | 1731 impactTransformer.registerBackendImpact( |
| 1730 impactBuilder, new BackendImpact(globalUses: staticUses)); | 1732 impactBuilder, new BackendImpact(globalUses: staticUses)); |
| 1731 } | 1733 } |
| 1732 | 1734 |
| 1733 /** | 1735 /** |
| 1734 * Returns [:true:] if the checking of [type] is performed directly on the | 1736 * Returns [:true:] if the checking of [type] is performed directly on the |
| 1735 * object and not on an interceptor. | 1737 * object and not on an interceptor. |
| 1736 */ | 1738 */ |
| 1737 bool hasDirectCheckFor(DartType type) { | 1739 bool hasDirectCheckFor(ResolutionDartType type) { |
| 1738 Element element = type.element; | 1740 Element element = type.element; |
| 1739 return element == commonElements.stringClass || | 1741 return element == commonElements.stringClass || |
| 1740 element == commonElements.boolClass || | 1742 element == commonElements.boolClass || |
| 1741 element == commonElements.numClass || | 1743 element == commonElements.numClass || |
| 1742 element == commonElements.intClass || | 1744 element == commonElements.intClass || |
| 1743 element == commonElements.doubleClass || | 1745 element == commonElements.doubleClass || |
| 1744 element == helpers.jsArrayClass || | 1746 element == helpers.jsArrayClass || |
| 1745 element == helpers.jsMutableArrayClass || | 1747 element == helpers.jsMutableArrayClass || |
| 1746 element == helpers.jsExtendableArrayClass || | 1748 element == helpers.jsExtendableArrayClass || |
| 1747 element == helpers.jsFixedArrayClass || | 1749 element == helpers.jsFixedArrayClass || |
| 1748 element == helpers.jsUnmodifiableArrayClass; | 1750 element == helpers.jsUnmodifiableArrayClass; |
| 1749 } | 1751 } |
| 1750 | 1752 |
| 1751 bool mayGenerateInstanceofCheck(DartType type) { | 1753 bool mayGenerateInstanceofCheck(ResolutionDartType type) { |
| 1752 // We can use an instanceof check for raw types that have no subclass that | 1754 // We can use an instanceof check for raw types that have no subclass that |
| 1753 // is mixed-in or in an implements clause. | 1755 // is mixed-in or in an implements clause. |
| 1754 | 1756 |
| 1755 if (!type.isRaw) return false; | 1757 if (!type.isRaw) return false; |
| 1756 ClassElement classElement = type.element; | 1758 ClassElement classElement = type.element; |
| 1757 if (isInterceptorClass(classElement)) return false; | 1759 if (isInterceptorClass(classElement)) return false; |
| 1758 return _closedWorld.hasOnlySubclasses(classElement); | 1760 return _closedWorld.hasOnlySubclasses(classElement); |
| 1759 } | 1761 } |
| 1760 | 1762 |
| 1761 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { | 1763 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2014 bool matchesMirrorsMetaTarget(Element element) { | 2016 bool matchesMirrorsMetaTarget(Element element) { |
| 2015 if (metaTargetsUsed.isEmpty) return false; | 2017 if (metaTargetsUsed.isEmpty) return false; |
| 2016 for (MetadataAnnotation metadata in element.metadata) { | 2018 for (MetadataAnnotation metadata in element.metadata) { |
| 2017 // TODO(kasperl): It would be nice if we didn't have to resolve | 2019 // TODO(kasperl): It would be nice if we didn't have to resolve |
| 2018 // all metadata but only stuff that potentially would match one | 2020 // all metadata but only stuff that potentially would match one |
| 2019 // of the used meta targets. | 2021 // of the used meta targets. |
| 2020 metadata.ensureResolved(resolution); | 2022 metadata.ensureResolved(resolution); |
| 2021 ConstantValue value = | 2023 ConstantValue value = |
| 2022 compiler.constants.getConstantValue(metadata.constant); | 2024 compiler.constants.getConstantValue(metadata.constant); |
| 2023 if (value == null) continue; | 2025 if (value == null) continue; |
| 2024 DartType type = value.getType(compiler.commonElements); | 2026 ResolutionDartType type = value.getType(compiler.commonElements); |
| 2025 if (metaTargetsUsed.contains(type.element)) return true; | 2027 if (metaTargetsUsed.contains(type.element)) return true; |
| 2026 } | 2028 } |
| 2027 return false; | 2029 return false; |
| 2028 } | 2030 } |
| 2029 | 2031 |
| 2030 /** | 2032 /** |
| 2031 * Visits all classes and computes whether its members are needed for | 2033 * Visits all classes and computes whether its members are needed for |
| 2032 * reflection. | 2034 * reflection. |
| 2033 * | 2035 * |
| 2034 * We have to precompute this set as we cannot easily answer the need for | 2036 * We have to precompute this set as we cannot easily answer the need for |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2801 break; | 2803 break; |
| 2802 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: | 2804 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: |
| 2803 registerBackendImpact(transformed, impacts.typeVariableBoundCheck); | 2805 registerBackendImpact(transformed, impacts.typeVariableBoundCheck); |
| 2804 break; | 2806 break; |
| 2805 } | 2807 } |
| 2806 } | 2808 } |
| 2807 | 2809 |
| 2808 bool hasAsCast = false; | 2810 bool hasAsCast = false; |
| 2809 bool hasTypeLiteral = false; | 2811 bool hasTypeLiteral = false; |
| 2810 for (TypeUse typeUse in worldImpact.typeUses) { | 2812 for (TypeUse typeUse in worldImpact.typeUses) { |
| 2811 DartType type = typeUse.type; | 2813 ResolutionDartType type = typeUse.type; |
| 2812 switch (typeUse.kind) { | 2814 switch (typeUse.kind) { |
| 2813 case TypeUseKind.INSTANTIATION: | 2815 case TypeUseKind.INSTANTIATION: |
| 2814 case TypeUseKind.MIRROR_INSTANTIATION: | 2816 case TypeUseKind.MIRROR_INSTANTIATION: |
| 2815 case TypeUseKind.NATIVE_INSTANTIATION: | 2817 case TypeUseKind.NATIVE_INSTANTIATION: |
| 2816 registerRequiredType(type); | 2818 registerRequiredType(type); |
| 2817 break; | 2819 break; |
| 2818 case TypeUseKind.IS_CHECK: | 2820 case TypeUseKind.IS_CHECK: |
| 2819 onIsCheck(type, transformed); | 2821 onIsCheck(type, transformed); |
| 2820 break; | 2822 break; |
| 2821 case TypeUseKind.AS_CAST: | 2823 case TypeUseKind.AS_CAST: |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2968 registerBackendStaticUse(worldImpact, staticUse); | 2970 registerBackendStaticUse(worldImpact, staticUse); |
| 2969 } | 2971 } |
| 2970 for (Element staticUse in backendImpact.globalUses) { | 2972 for (Element staticUse in backendImpact.globalUses) { |
| 2971 assert(staticUse != null); | 2973 assert(staticUse != null); |
| 2972 registerBackendStaticUse(worldImpact, staticUse, isGlobal: true); | 2974 registerBackendStaticUse(worldImpact, staticUse, isGlobal: true); |
| 2973 } | 2975 } |
| 2974 for (Selector selector in backendImpact.dynamicUses) { | 2976 for (Selector selector in backendImpact.dynamicUses) { |
| 2975 assert(selector != null); | 2977 assert(selector != null); |
| 2976 worldImpact.registerDynamicUse(new DynamicUse(selector, null)); | 2978 worldImpact.registerDynamicUse(new DynamicUse(selector, null)); |
| 2977 } | 2979 } |
| 2978 for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) { | 2980 for (ResolutionInterfaceType instantiatedType |
| 2981 in backendImpact.instantiatedTypes) { |
| 2979 backend.registerBackendUse(instantiatedType.element); | 2982 backend.registerBackendUse(instantiatedType.element); |
| 2980 worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType)); | 2983 worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType)); |
| 2981 } | 2984 } |
| 2982 for (ClassElement cls in backendImpact.instantiatedClasses) { | 2985 for (ClassElement cls in backendImpact.instantiatedClasses) { |
| 2983 registerBackendInstantiation(worldImpact, cls); | 2986 registerBackendInstantiation(worldImpact, cls); |
| 2984 } | 2987 } |
| 2985 for (ClassElement cls in backendImpact.globalClasses) { | 2988 for (ClassElement cls in backendImpact.globalClasses) { |
| 2986 registerBackendInstantiation(worldImpact, cls, isGlobal: true); | 2989 registerBackendInstantiation(worldImpact, cls, isGlobal: true); |
| 2987 } | 2990 } |
| 2988 for (BackendImpact otherImpact in backendImpact.otherImpacts) { | 2991 for (BackendImpact otherImpact in backendImpact.otherImpacts) { |
| 2989 registerBackendImpact(worldImpact, otherImpact); | 2992 registerBackendImpact(worldImpact, otherImpact); |
| 2990 } | 2993 } |
| 2991 for (BackendFeature feature in backendImpact.features) { | 2994 for (BackendFeature feature in backendImpact.features) { |
| 2992 switch (feature) { | 2995 switch (feature) { |
| 2993 case BackendFeature.needToInitializeDispatchProperty: | 2996 case BackendFeature.needToInitializeDispatchProperty: |
| 2994 backend.needToInitializeDispatchProperty = true; | 2997 backend.needToInitializeDispatchProperty = true; |
| 2995 break; | 2998 break; |
| 2996 case BackendFeature.needToInitializeIsolateAffinityTag: | 2999 case BackendFeature.needToInitializeIsolateAffinityTag: |
| 2997 backend.needToInitializeIsolateAffinityTag = true; | 3000 backend.needToInitializeIsolateAffinityTag = true; |
| 2998 break; | 3001 break; |
| 2999 } | 3002 } |
| 3000 } | 3003 } |
| 3001 } | 3004 } |
| 3002 | 3005 |
| 3003 /// Register [type] as required for the runtime type information system. | 3006 /// Register [type] as required for the runtime type information system. |
| 3004 void registerRequiredType(DartType type) { | 3007 void registerRequiredType(ResolutionDartType type) { |
| 3005 // If [argument] has type variables or is a type variable, this method | 3008 // If [argument] has type variables or is a type variable, this method |
| 3006 // registers a RTI dependency between the class where the type variable is | 3009 // registers a RTI dependency between the class where the type variable is |
| 3007 // defined (that is the enclosing class of the current element being | 3010 // defined (that is the enclosing class of the current element being |
| 3008 // resolved) and the class of [type]. If the class of [type] requires RTI, | 3011 // resolved) and the class of [type]. If the class of [type] requires RTI, |
| 3009 // then the class of the type variable does too. | 3012 // then the class of the type variable does too. |
| 3010 ClassElement contextClass = Types.getClassContext(type); | 3013 ClassElement contextClass = Types.getClassContext(type); |
| 3011 if (contextClass != null) { | 3014 if (contextClass != null) { |
| 3012 backend.rti.registerRtiDependency(type.element, contextClass); | 3015 backend.rti.registerRtiDependency(type.element, contextClass); |
| 3013 } | 3016 } |
| 3014 } | 3017 } |
| 3015 | 3018 |
| 3016 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. | 3019 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. |
| 3017 void onIsCheck(DartType type, TransformedWorldImpact transformed) { | 3020 void onIsCheck(ResolutionDartType type, TransformedWorldImpact transformed) { |
| 3018 registerRequiredType(type); | 3021 registerRequiredType(type); |
| 3019 type.computeUnaliased(backend.resolution); | 3022 type.computeUnaliased(backend.resolution); |
| 3020 type = type.unaliased; | 3023 type = type.unaliased; |
| 3021 registerBackendImpact(transformed, impacts.typeCheck); | 3024 registerBackendImpact(transformed, impacts.typeCheck); |
| 3022 | 3025 |
| 3023 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; | 3026 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; |
| 3024 if (inCheckedMode) { | 3027 if (inCheckedMode) { |
| 3025 registerBackendImpact(transformed, impacts.checkedModeTypeCheck); | 3028 registerBackendImpact(transformed, impacts.checkedModeTypeCheck); |
| 3026 } | 3029 } |
| 3027 if (type.isMalformed) { | 3030 if (type.isMalformed) { |
| 3028 registerBackendImpact(transformed, impacts.malformedTypeCheck); | 3031 registerBackendImpact(transformed, impacts.malformedTypeCheck); |
| 3029 } | 3032 } |
| 3030 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { | 3033 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { |
| 3031 registerBackendImpact(transformed, impacts.genericTypeCheck); | 3034 registerBackendImpact(transformed, impacts.genericTypeCheck); |
| 3032 if (inCheckedMode) { | 3035 if (inCheckedMode) { |
| 3033 registerBackendImpact(transformed, impacts.genericCheckedModeTypeCheck); | 3036 registerBackendImpact(transformed, impacts.genericCheckedModeTypeCheck); |
| 3034 } | 3037 } |
| 3035 if (type.isTypeVariable) { | 3038 if (type.isTypeVariable) { |
| 3036 registerBackendImpact(transformed, impacts.typeVariableTypeCheck); | 3039 registerBackendImpact(transformed, impacts.typeVariableTypeCheck); |
| 3037 if (inCheckedMode) { | 3040 if (inCheckedMode) { |
| 3038 registerBackendImpact( | 3041 registerBackendImpact( |
| 3039 transformed, impacts.typeVariableCheckedModeTypeCheck); | 3042 transformed, impacts.typeVariableCheckedModeTypeCheck); |
| 3040 } | 3043 } |
| 3041 } | 3044 } |
| 3042 } | 3045 } |
| 3043 if (type is FunctionType) { | 3046 if (type is ResolutionFunctionType) { |
| 3044 registerBackendImpact(transformed, impacts.functionTypeCheck); | 3047 registerBackendImpact(transformed, impacts.functionTypeCheck); |
| 3045 } | 3048 } |
| 3046 if (type.element != null && backend.isNative(type.element)) { | 3049 if (type.element != null && backend.isNative(type.element)) { |
| 3047 registerBackendImpact(transformed, impacts.nativeTypeCheck); | 3050 registerBackendImpact(transformed, impacts.nativeTypeCheck); |
| 3048 } | 3051 } |
| 3049 } | 3052 } |
| 3050 | 3053 |
| 3051 void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) { | 3054 void onIsCheckForCodegen( |
| 3055 ResolutionDartType type, TransformedWorldImpact transformed) { |
| 3052 type = type.unaliased; | 3056 type = type.unaliased; |
| 3053 registerBackendImpact(transformed, impacts.typeCheck); | 3057 registerBackendImpact(transformed, impacts.typeCheck); |
| 3054 | 3058 |
| 3055 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; | 3059 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; |
| 3056 // [registerIsCheck] is also called for checked mode checks, so we | 3060 // [registerIsCheck] is also called for checked mode checks, so we |
| 3057 // need to register checked mode helpers. | 3061 // need to register checked mode helpers. |
| 3058 if (inCheckedMode) { | 3062 if (inCheckedMode) { |
| 3059 // All helpers are added to resolution queue in enqueueHelpers. These | 3063 // All helpers are added to resolution queue in enqueueHelpers. These |
| 3060 // calls to [enqueue] with the resolution enqueuer serve as assertions | 3064 // calls to [enqueue] with the resolution enqueuer serve as assertions |
| 3061 // that the helper was in fact added. | 3065 // that the helper was in fact added. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3084 // [:defineProperty:] is compiled. | 3088 // [:defineProperty:] is compiled. |
| 3085 registerBackendImpact(transformed, impacts.nativeTypeCheck); | 3089 registerBackendImpact(transformed, impacts.nativeTypeCheck); |
| 3086 } | 3090 } |
| 3087 } | 3091 } |
| 3088 | 3092 |
| 3089 @override | 3093 @override |
| 3090 WorldImpact transformCodegenImpact(CodegenImpact impact) { | 3094 WorldImpact transformCodegenImpact(CodegenImpact impact) { |
| 3091 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); | 3095 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); |
| 3092 | 3096 |
| 3093 for (TypeUse typeUse in impact.typeUses) { | 3097 for (TypeUse typeUse in impact.typeUses) { |
| 3094 DartType type = typeUse.type; | 3098 ResolutionDartType type = typeUse.type; |
| 3095 switch (typeUse.kind) { | 3099 switch (typeUse.kind) { |
| 3096 case TypeUseKind.INSTANTIATION: | 3100 case TypeUseKind.INSTANTIATION: |
| 3097 backend.lookupMapAnalysis.registerInstantiatedType(type); | 3101 backend.lookupMapAnalysis.registerInstantiatedType(type); |
| 3098 break; | 3102 break; |
| 3099 case TypeUseKind.IS_CHECK: | 3103 case TypeUseKind.IS_CHECK: |
| 3100 onIsCheckForCodegen(type, transformed); | 3104 onIsCheckForCodegen(type, transformed); |
| 3101 break; | 3105 break; |
| 3102 default: | 3106 default: |
| 3103 } | 3107 } |
| 3104 } | 3108 } |
| 3105 | 3109 |
| 3106 for (ConstantValue constant in impact.compileTimeConstants) { | 3110 for (ConstantValue constant in impact.compileTimeConstants) { |
| 3107 backend.computeImpactForCompileTimeConstant(constant, transformed, false); | 3111 backend.computeImpactForCompileTimeConstant(constant, transformed, false); |
| 3108 backend.addCompileTimeConstantForEmission(constant); | 3112 backend.addCompileTimeConstantForEmission(constant); |
| 3109 } | 3113 } |
| 3110 | 3114 |
| 3111 for (Pair<DartType, DartType> check | 3115 for (Pair<ResolutionDartType, ResolutionDartType> check |
| 3112 in impact.typeVariableBoundsSubtypeChecks) { | 3116 in impact.typeVariableBoundsSubtypeChecks) { |
| 3113 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); | 3117 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); |
| 3114 } | 3118 } |
| 3115 | 3119 |
| 3116 for (StaticUse staticUse in impact.staticUses) { | 3120 for (StaticUse staticUse in impact.staticUses) { |
| 3117 switch (staticUse.kind) { | 3121 switch (staticUse.kind) { |
| 3118 case StaticUseKind.CLOSURE: | 3122 case StaticUseKind.CLOSURE: |
| 3119 LocalFunctionElement closure = staticUse.element; | 3123 LocalFunctionElement closure = staticUse.element; |
| 3120 if (backend.methodNeedsRti(closure)) { | 3124 if (backend.methodNeedsRti(closure)) { |
| 3121 registerBackendImpact(transformed, impacts.computeSignature); | 3125 registerBackendImpact(transformed, impacts.computeSignature); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3273 @override | 3277 @override |
| 3274 bool isNativeClass(ClassElement element) { | 3278 bool isNativeClass(ClassElement element) { |
| 3275 return helpers.backend.isNative(element); | 3279 return helpers.backend.isNative(element); |
| 3276 } | 3280 } |
| 3277 | 3281 |
| 3278 @override | 3282 @override |
| 3279 bool isNativeMember(MemberElement element) { | 3283 bool isNativeMember(MemberElement element) { |
| 3280 return helpers.backend.isNative(element); | 3284 return helpers.backend.isNative(element); |
| 3281 } | 3285 } |
| 3282 } | 3286 } |
| OLD | NEW |