Chromium Code Reviews| 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 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 779 * Returns `true` if [member] is called from a subclass via `super`. | 779 * Returns `true` if [member] is called from a subclass via `super`. |
| 780 */ | 780 */ |
| 781 bool isAliasedSuperMember(FunctionElement member) { | 781 bool isAliasedSuperMember(FunctionElement member) { |
| 782 return aliasedSuperMembers.contains(member); | 782 return aliasedSuperMembers.contains(member); |
| 783 } | 783 } |
| 784 | 784 |
| 785 /// Returns `true` if [element] is part of JsInterop. | 785 /// Returns `true` if [element] is part of JsInterop. |
| 786 @override | 786 @override |
| 787 bool isJsInterop(Element element) => nativeData.isJsInterop(element); | 787 bool isJsInterop(Element element) => nativeData.isJsInterop(element); |
| 788 | 788 |
| 789 /// Returns `true` if [element] is a JsInterop class. | |
| 790 bool isJsInteropClass(ClassElement element) => isJsInterop(element); | |
| 791 | |
| 792 /// Returns `true` if [element] is a JsInterop method. | |
| 793 bool isJsInteropMethod(MethodElement element) => isJsInterop(element); | |
| 794 | |
| 789 /// Whether [element] corresponds to a native JavaScript construct either | 795 /// Whether [element] corresponds to a native JavaScript construct either |
| 790 /// through the native mechanism (`@Native(...)` or the `native` pseudo | 796 /// through the native mechanism (`@Native(...)` or the `native` pseudo |
| 791 /// keyword) which is only allowed for internal libraries or via the typed | 797 /// keyword) which is only allowed for internal libraries or via the typed |
| 792 /// JavaScriptInterop mechanism which is allowed for user libraries. | 798 /// JavaScriptInterop mechanism which is allowed for user libraries. |
| 793 @override | 799 @override |
| 794 bool isNative(Entity element) => nativeData.isNative(element); | 800 bool isNative(Entity element) => nativeData.isNative(element); |
| 795 | 801 |
| 796 /// Returns the [NativeBehavior] for calling the native [method]. | 802 /// Returns the [NativeBehavior] for calling the native [method]. |
| 797 native.NativeBehavior getNativeMethodBehavior(MethodElement method) { | 803 native.NativeBehavior getNativeMethodBehavior(MethodElement method) { |
| 798 return nativeData.getNativeMethodBehavior(method); | 804 return nativeData.getNativeMethodBehavior(method); |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1616 String name = getCheckedModeHelperNameInternal(type, | 1622 String name = getCheckedModeHelperNameInternal(type, |
| 1617 typeCast: typeCast, nativeCheckOnly: nativeCheckOnly); | 1623 typeCast: typeCast, nativeCheckOnly: nativeCheckOnly); |
| 1618 if (name == null) return null; | 1624 if (name == null) return null; |
| 1619 CheckedModeHelper helper = checkedModeHelperByName[name]; | 1625 CheckedModeHelper helper = checkedModeHelperByName[name]; |
| 1620 assert(helper != null); | 1626 assert(helper != null); |
| 1621 return helper; | 1627 return helper; |
| 1622 } | 1628 } |
| 1623 | 1629 |
| 1624 String getCheckedModeHelperNameInternal(ResolutionDartType type, | 1630 String getCheckedModeHelperNameInternal(ResolutionDartType type, |
| 1625 {bool typeCast, bool nativeCheckOnly}) { | 1631 {bool typeCast, bool nativeCheckOnly}) { |
| 1626 assert(type.kind != ResolutionTypeKind.TYPEDEF); | 1632 assert(!type.isDynamic); |
| 1633 assert(!type.isTypedef); | |
| 1627 if (type.isMalformed) { | 1634 if (type.isMalformed) { |
| 1628 // The same error is thrown for type test and type cast of a malformed | 1635 // The same error is thrown for type test and type cast of a malformed |
| 1629 // type so we only need one check method. | 1636 // type so we only need one check method. |
| 1630 return 'checkMalformedType'; | 1637 return 'checkMalformedType'; |
| 1638 } else if (type.isVoid) { | |
|
Siggi Cherem (dart-lang)
2017/01/20 17:00:15
while we are here, we could clean up this function
Johnni Winther
2017/01/23 10:00:09
I like it; it's much more readable. I've merge it
| |
| 1639 assert(!typeCast); // Cannot cast to void. | |
| 1640 if (nativeCheckOnly) return null; | |
| 1641 return 'voidTypeCheck'; | |
| 1642 } else if (type.isTypeVariable) { | |
| 1643 return typeCast | |
| 1644 ? 'subtypeOfRuntimeTypeCast' | |
| 1645 : 'assertSubtypeOfRuntimeType'; | |
| 1646 } else if (type.isFunctionType) { | |
| 1647 return null; | |
| 1631 } | 1648 } |
| 1632 Element element = type.element; | 1649 assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, |
| 1650 message: "Unexpected type: $type (${type.kind})")); | |
| 1651 ClassElement element = type.element; | |
| 1633 bool nativeCheck = | 1652 bool nativeCheck = |
| 1634 nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); | 1653 nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); |
| 1635 | 1654 |
| 1636 // TODO(13955), TODO(9731). The test for non-primitive types should use an | 1655 // TODO(13955), TODO(9731). The test for non-primitive types should use an |
| 1637 // interceptor. The interceptor should be an argument to HTypeConversion so | 1656 // interceptor. The interceptor should be an argument to HTypeConversion so |
| 1638 // that it can be optimized by standard interceptor optimizations. | 1657 // that it can be optimized by standard interceptor optimizations. |
| 1639 nativeCheck = true; | 1658 nativeCheck = true; |
| 1640 | 1659 |
| 1641 if (type.isVoid) { | 1660 if (element == helpers.jsStringClass || |
| 1642 assert(!typeCast); // Cannot cast to void. | |
| 1643 if (nativeCheckOnly) return null; | |
| 1644 return 'voidTypeCheck'; | |
| 1645 } else if (element == helpers.jsStringClass || | |
| 1646 element == commonElements.stringClass) { | 1661 element == commonElements.stringClass) { |
| 1647 if (nativeCheckOnly) return null; | 1662 if (nativeCheckOnly) return null; |
| 1648 return typeCast ? 'stringTypeCast' : 'stringTypeCheck'; | 1663 return typeCast ? 'stringTypeCast' : 'stringTypeCheck'; |
| 1649 } else if (element == helpers.jsDoubleClass || | 1664 } else if (element == helpers.jsDoubleClass || |
| 1650 element == commonElements.doubleClass) { | 1665 element == commonElements.doubleClass) { |
| 1651 if (nativeCheckOnly) return null; | 1666 if (nativeCheckOnly) return null; |
| 1652 return typeCast ? 'doubleTypeCast' : 'doubleTypeCheck'; | 1667 return typeCast ? 'doubleTypeCast' : 'doubleTypeCheck'; |
| 1653 } else if (element == helpers.jsNumberClass || | 1668 } else if (element == helpers.jsNumberClass || |
| 1654 element == commonElements.numClass) { | 1669 element == commonElements.numClass) { |
| 1655 if (nativeCheckOnly) return null; | 1670 if (nativeCheckOnly) return null; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1682 : 'stringSuperNativeTypeCheck'; | 1697 : 'stringSuperNativeTypeCheck'; |
| 1683 } else { | 1698 } else { |
| 1684 return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck'; | 1699 return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck'; |
| 1685 } | 1700 } |
| 1686 } else if ((element == commonElements.listClass || | 1701 } else if ((element == commonElements.listClass || |
| 1687 element == helpers.jsArrayClass) && | 1702 element == helpers.jsArrayClass) && |
| 1688 type.treatAsRaw) { | 1703 type.treatAsRaw) { |
| 1689 if (nativeCheckOnly) return null; | 1704 if (nativeCheckOnly) return null; |
| 1690 return typeCast ? 'listTypeCast' : 'listTypeCheck'; | 1705 return typeCast ? 'listTypeCast' : 'listTypeCheck'; |
| 1691 } else { | 1706 } else { |
| 1692 if (commonElements.isListSupertype(element)) { | 1707 if (commonElements.isListSupertype(element)) { |
|
Siggi Cherem (dart-lang)
2017/01/20 17:00:15
if we don't remove the elses, we should at least r
Johnni Winther
2017/01/23 10:00:09
Acknowledged.
| |
| 1693 if (nativeCheck) { | 1708 if (nativeCheck) { |
| 1694 return typeCast | 1709 return typeCast |
| 1695 ? 'listSuperNativeTypeCast' | 1710 ? 'listSuperNativeTypeCast' |
| 1696 : 'listSuperNativeTypeCheck'; | 1711 : 'listSuperNativeTypeCheck'; |
| 1697 } else { | 1712 } else { |
| 1698 return typeCast ? 'listSuperTypeCast' : 'listSuperTypeCheck'; | 1713 return typeCast ? 'listSuperTypeCast' : 'listSuperTypeCheck'; |
| 1699 } | 1714 } |
| 1700 } else { | 1715 } else { |
| 1701 if (type.isInterfaceType && !type.treatAsRaw) { | 1716 if (type.isInterfaceType && !type.treatAsRaw) { |
| 1702 return typeCast ? 'subtypeCast' : 'assertSubtype'; | 1717 return typeCast ? 'subtypeCast' : 'assertSubtype'; |
| 1703 } else if (type.isTypeVariable) { | |
| 1704 return typeCast | |
| 1705 ? 'subtypeOfRuntimeTypeCast' | |
| 1706 : 'assertSubtypeOfRuntimeType'; | |
| 1707 } else if (type.isFunctionType) { | |
| 1708 return null; | |
| 1709 } else { | 1718 } else { |
| 1710 if (nativeCheck) { | 1719 if (nativeCheck) { |
| 1711 // TODO(karlklose): can we get rid of this branch when we use | 1720 // TODO(karlklose): can we get rid of this branch when we use |
| 1712 // interceptors? | 1721 // interceptors? |
| 1713 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; | 1722 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; |
| 1714 } else { | 1723 } else { |
| 1715 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; | 1724 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; |
| 1716 } | 1725 } |
| 1717 } | 1726 } |
| 1718 } | 1727 } |
| (...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3055 if (type is ResolutionFunctionType) { | 3064 if (type is ResolutionFunctionType) { |
| 3056 registerBackendImpact(transformed, impacts.functionTypeCheck); | 3065 registerBackendImpact(transformed, impacts.functionTypeCheck); |
| 3057 } | 3066 } |
| 3058 if (type.element != null && backend.isNative(type.element)) { | 3067 if (type.element != null && backend.isNative(type.element)) { |
| 3059 registerBackendImpact(transformed, impacts.nativeTypeCheck); | 3068 registerBackendImpact(transformed, impacts.nativeTypeCheck); |
| 3060 } | 3069 } |
| 3061 } | 3070 } |
| 3062 | 3071 |
| 3063 void onIsCheckForCodegen( | 3072 void onIsCheckForCodegen( |
| 3064 ResolutionDartType type, TransformedWorldImpact transformed) { | 3073 ResolutionDartType type, TransformedWorldImpact transformed) { |
| 3074 if (type.isDynamic) return; | |
| 3065 type = type.unaliased; | 3075 type = type.unaliased; |
| 3066 registerBackendImpact(transformed, impacts.typeCheck); | 3076 registerBackendImpact(transformed, impacts.typeCheck); |
| 3067 | 3077 |
| 3068 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; | 3078 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; |
| 3069 // [registerIsCheck] is also called for checked mode checks, so we | 3079 // [registerIsCheck] is also called for checked mode checks, so we |
| 3070 // need to register checked mode helpers. | 3080 // need to register checked mode helpers. |
| 3071 if (inCheckedMode) { | 3081 if (inCheckedMode) { |
| 3072 // All helpers are added to resolution queue in enqueueHelpers. These | 3082 // All helpers are added to resolution queue in enqueueHelpers. These |
| 3073 // calls to [enqueue] with the resolution enqueuer serve as assertions | 3083 // calls to [enqueue] with the resolution enqueuer serve as assertions |
| 3074 // that the helper was in fact added. | 3084 // that the helper was in fact added. |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3286 @override | 3296 @override |
| 3287 bool isNativeClass(ClassElement element) { | 3297 bool isNativeClass(ClassElement element) { |
| 3288 return helpers.backend.isNative(element); | 3298 return helpers.backend.isNative(element); |
| 3289 } | 3299 } |
| 3290 | 3300 |
| 3291 @override | 3301 @override |
| 3292 bool isNativeMember(MemberElement element) { | 3302 bool isNativeMember(MemberElement element) { |
| 3293 return helpers.backend.isNative(element); | 3303 return helpers.backend.isNative(element); |
| 3294 } | 3304 } |
| 3295 } | 3305 } |
| OLD | NEW |