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 |