| 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 import '../common.dart'; | 5 import '../common.dart'; |
| 6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 7 import '../common/tasks.dart' show CompilerTask; | 7 import '../common/tasks.dart' show CompilerTask; |
| 8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 1638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 } | 1649 } |
| 1650 | 1650 |
| 1651 TypeMask getOptimizedSelectorFor( | 1651 TypeMask getOptimizedSelectorFor( |
| 1652 HInvokeDynamic node, Selector selector, TypeMask mask) { | 1652 HInvokeDynamic node, Selector selector, TypeMask mask) { |
| 1653 if (node.element != null) { | 1653 if (node.element != null) { |
| 1654 // Create an artificial type mask to make sure only | 1654 // Create an artificial type mask to make sure only |
| 1655 // [node.element] will be enqueued. We're not using the receiver | 1655 // [node.element] will be enqueued. We're not using the receiver |
| 1656 // type because our optimizations might end up in a state where the | 1656 // type because our optimizations might end up in a state where the |
| 1657 // invoke dynamic knows more than the receiver. | 1657 // invoke dynamic knows more than the receiver. |
| 1658 ClassElement enclosing = node.element.enclosingClass; | 1658 ClassElement enclosing = node.element.enclosingClass; |
| 1659 if (compiler.world.isInstantiated(enclosing)) { | 1659 if (compiler.closedWorld.isInstantiated(enclosing)) { |
| 1660 return new TypeMask.nonNullExact(enclosing.declaration, compiler.world); | 1660 return new TypeMask.nonNullExact( |
| 1661 enclosing.declaration, compiler.closedWorld); |
| 1661 } else { | 1662 } else { |
| 1662 // The element is mixed in so a non-null subtype mask is the most | 1663 // The element is mixed in so a non-null subtype mask is the most |
| 1663 // precise we have. | 1664 // precise we have. |
| 1664 assert(invariant(node, compiler.world.isUsedAsMixin(enclosing), | 1665 assert(invariant(node, compiler.closedWorld.isUsedAsMixin(enclosing), |
| 1665 message: "Element ${node.element} from $enclosing expected " | 1666 message: "Element ${node.element} from $enclosing expected " |
| 1666 "to be mixed in.")); | 1667 "to be mixed in.")); |
| 1667 return new TypeMask.nonNullSubtype( | 1668 return new TypeMask.nonNullSubtype( |
| 1668 enclosing.declaration, compiler.world); | 1669 enclosing.declaration, compiler.closedWorld); |
| 1669 } | 1670 } |
| 1670 } | 1671 } |
| 1671 // If [JSInvocationMirror._invokeOn] is enabled, and this call | 1672 // If [JSInvocationMirror._invokeOn] is enabled, and this call |
| 1672 // might hit a `noSuchMethod`, we register an untyped selector. | 1673 // might hit a `noSuchMethod`, we register an untyped selector. |
| 1673 return compiler.world.extendMaskIfReachesAll(selector, mask); | 1674 return compiler.closedWorld.extendMaskIfReachesAll(selector, mask); |
| 1674 } | 1675 } |
| 1675 | 1676 |
| 1676 void registerMethodInvoke(HInvokeDynamic node) { | 1677 void registerMethodInvoke(HInvokeDynamic node) { |
| 1677 Selector selector = node.selector; | 1678 Selector selector = node.selector; |
| 1678 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); | 1679 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); |
| 1679 | 1680 |
| 1680 // If we don't know what we're calling or if we are calling a getter, | 1681 // If we don't know what we're calling or if we are calling a getter, |
| 1681 // we need to register that fact that we may be calling a closure | 1682 // we need to register that fact that we may be calling a closure |
| 1682 // with the same arguments. | 1683 // with the same arguments. |
| 1683 Element target = node.element; | 1684 Element target = node.element; |
| (...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2701 void emitIsViaInterceptor( | 2702 void emitIsViaInterceptor( |
| 2702 HIsViaInterceptor node, SourceInformation sourceInformation, | 2703 HIsViaInterceptor node, SourceInformation sourceInformation, |
| 2703 {bool negative: false}) { | 2704 {bool negative: false}) { |
| 2704 checkTypeViaProperty( | 2705 checkTypeViaProperty( |
| 2705 node.interceptor, node.typeExpression, sourceInformation, | 2706 node.interceptor, node.typeExpression, sourceInformation, |
| 2706 negative: negative); | 2707 negative: negative); |
| 2707 } | 2708 } |
| 2708 | 2709 |
| 2709 js.Expression generateReceiverOrArgumentTypeTest( | 2710 js.Expression generateReceiverOrArgumentTypeTest( |
| 2710 HInstruction input, TypeMask checkedType) { | 2711 HInstruction input, TypeMask checkedType) { |
| 2711 ClassWorld classWorld = compiler.world; | 2712 ClassWorld classWorld = compiler.closedWorld; |
| 2712 TypeMask inputType = input.instructionType; | 2713 TypeMask inputType = input.instructionType; |
| 2713 // Figure out if it is beneficial to turn this into a null check. | 2714 // Figure out if it is beneficial to turn this into a null check. |
| 2714 // V8 generally prefers 'typeof' checks, but for integers and | 2715 // V8 generally prefers 'typeof' checks, but for integers and |
| 2715 // indexable primitives we cannot compile this test into a single | 2716 // indexable primitives we cannot compile this test into a single |
| 2716 // typeof check so the null check is cheaper. | 2717 // typeof check so the null check is cheaper. |
| 2717 bool isIntCheck = checkedType.containsOnlyInt(classWorld); | 2718 bool isIntCheck = checkedType.containsOnlyInt(classWorld); |
| 2718 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler); | 2719 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler); |
| 2719 bool turnIntoNullCheck = !turnIntoNumCheck && | 2720 bool turnIntoNullCheck = !turnIntoNumCheck && |
| 2720 (checkedType.nullable() == inputType) && | 2721 (checkedType.nullable() == inputType) && |
| 2721 (isIntCheck || | 2722 (isIntCheck || |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2741 // input is !string | 2742 // input is !string |
| 2742 checkString(input, '!==', input.sourceInformation); | 2743 checkString(input, '!==', input.sourceInformation); |
| 2743 return pop(); | 2744 return pop(); |
| 2744 } | 2745 } |
| 2745 reporter.internalError(input, 'Unexpected check: $checkedType.'); | 2746 reporter.internalError(input, 'Unexpected check: $checkedType.'); |
| 2746 return null; | 2747 return null; |
| 2747 } | 2748 } |
| 2748 | 2749 |
| 2749 void visitTypeConversion(HTypeConversion node) { | 2750 void visitTypeConversion(HTypeConversion node) { |
| 2750 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { | 2751 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { |
| 2751 ClassWorld classWorld = compiler.world; | 2752 ClassWorld classWorld = compiler.closedWorld; |
| 2752 // An int check if the input is not int or null, is not | 2753 // An int check if the input is not int or null, is not |
| 2753 // sufficient for doing an argument or receiver check. | 2754 // sufficient for doing an argument or receiver check. |
| 2754 assert(compiler.options.trustTypeAnnotations || | 2755 assert(compiler.options.trustTypeAnnotations || |
| 2755 !node.checkedType.containsOnlyInt(classWorld) || | 2756 !node.checkedType.containsOnlyInt(classWorld) || |
| 2756 node.checkedInput.isIntegerOrNull(compiler)); | 2757 node.checkedInput.isIntegerOrNull(compiler)); |
| 2757 js.Expression test = generateReceiverOrArgumentTypeTest( | 2758 js.Expression test = generateReceiverOrArgumentTypeTest( |
| 2758 node.checkedInput, node.checkedType); | 2759 node.checkedInput, node.checkedType); |
| 2759 js.Block oldContainer = currentContainer; | 2760 js.Block oldContainer = currentContainer; |
| 2760 js.Statement body = new js.Block.empty(); | 2761 js.Statement body = new js.Block.empty(); |
| 2761 currentContainer = body; | 2762 currentContainer = body; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2908 // We expect only flat types for the INSTANCE representation. | 2909 // We expect only flat types for the INSTANCE representation. |
| 2909 assert( | 2910 assert( |
| 2910 node.dartType == (node.dartType.element as ClassElement).thisType); | 2911 node.dartType == (node.dartType.element as ClassElement).thisType); |
| 2911 registry.registerInstantiatedClass(coreClasses.listClass); | 2912 registry.registerInstantiatedClass(coreClasses.listClass); |
| 2912 push(new js.ArrayInitializer(arguments) | 2913 push(new js.ArrayInitializer(arguments) |
| 2913 .withSourceInformation(node.sourceInformation)); | 2914 .withSourceInformation(node.sourceInformation)); |
| 2914 } | 2915 } |
| 2915 } | 2916 } |
| 2916 | 2917 |
| 2917 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { | 2918 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { |
| 2918 ClassWorld classWorld = compiler.world; | 2919 ClassWorld classWorld = compiler.closedWorld; |
| 2919 if (classWorld.isUsedAsMixin(cls)) return true; | 2920 if (classWorld.isUsedAsMixin(cls)) return true; |
| 2920 | 2921 |
| 2921 return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) { | 2922 return compiler.closedWorld.anyStrictSubclassOf(cls, |
| 2923 (ClassElement subclass) { |
| 2922 return !backend.rti.isTrivialSubstitution(subclass, cls); | 2924 return !backend.rti.isTrivialSubstitution(subclass, cls); |
| 2923 }); | 2925 }); |
| 2924 } | 2926 } |
| 2925 | 2927 |
| 2926 void visitReadTypeVariable(HReadTypeVariable node) { | 2928 void visitReadTypeVariable(HReadTypeVariable node) { |
| 2927 TypeVariableElement element = node.dartType.element; | 2929 TypeVariableElement element = node.dartType.element; |
| 2928 Element helperElement = helpers.convertRtiToRuntimeType; | 2930 Element helperElement = helpers.convertRtiToRuntimeType; |
| 2929 registry.registerStaticUse( | 2931 registry.registerStaticUse( |
| 2930 new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG)); | 2932 new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG)); |
| 2931 | 2933 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2989 registry.registerStaticUse(new StaticUse.staticInvoke( | 2991 registry.registerStaticUse(new StaticUse.staticInvoke( |
| 2990 helper, new CallStructure.unnamed(argumentCount))); | 2992 helper, new CallStructure.unnamed(argumentCount))); |
| 2991 return backend.emitter.staticFunctionAccess(helper); | 2993 return backend.emitter.staticFunctionAccess(helper); |
| 2992 } | 2994 } |
| 2993 | 2995 |
| 2994 @override | 2996 @override |
| 2995 void visitRef(HRef node) { | 2997 void visitRef(HRef node) { |
| 2996 visit(node.value); | 2998 visit(node.value); |
| 2997 } | 2999 } |
| 2998 } | 3000 } |
| OLD | NEW |