| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 import '../js_backend/backend.dart' show JavaScriptBackend; | 24 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 25 import '../kernel/kernel.dart'; | 25 import '../kernel/kernel.dart'; |
| 26 import '../native/native.dart' as native; | 26 import '../native/native.dart' as native; |
| 27 import '../resolution/tree_elements.dart'; | 27 import '../resolution/tree_elements.dart'; |
| 28 import '../tree/dartstring.dart'; | 28 import '../tree/dartstring.dart'; |
| 29 import '../tree/nodes.dart' show Node; | 29 import '../tree/nodes.dart' show Node; |
| 30 import '../types/masks.dart'; | 30 import '../types/masks.dart'; |
| 31 import '../universe/call_structure.dart' show CallStructure; | 31 import '../universe/call_structure.dart' show CallStructure; |
| 32 import '../universe/selector.dart'; | 32 import '../universe/selector.dart'; |
| 33 import '../universe/side_effects.dart' show SideEffects; | 33 import '../universe/side_effects.dart' show SideEffects; |
| 34 import '../universe/use.dart' show StaticUse; | 34 import '../universe/use.dart' show DynamicUse, StaticUse; |
| 35 import '../world.dart'; | 35 import '../world.dart'; |
| 36 import 'graph_builder.dart'; | 36 import 'graph_builder.dart'; |
| 37 import 'jump_handler.dart'; | 37 import 'jump_handler.dart'; |
| 38 import 'kernel_ast_adapter.dart'; | 38 import 'kernel_ast_adapter.dart'; |
| 39 import 'kernel_string_builder.dart'; | 39 import 'kernel_string_builder.dart'; |
| 40 import 'locals_handler.dart'; | 40 import 'locals_handler.dart'; |
| 41 import 'loop_handler.dart'; | 41 import 'loop_handler.dart'; |
| 42 import 'nodes.dart'; | 42 import 'nodes.dart'; |
| 43 import 'ssa_branch_builder.dart'; | 43 import 'ssa_branch_builder.dart'; |
| 44 import 'switch_continue_analysis.dart'; | 44 import 'switch_continue_analysis.dart'; |
| (...skipping 1856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 _pushDynamicInvocation( | 1901 _pushDynamicInvocation( |
| 1902 propertySet, | 1902 propertySet, |
| 1903 astAdapter.typeOfSet(propertySet, closedWorld), | 1903 astAdapter.typeOfSet(propertySet, closedWorld), |
| 1904 <HInstruction>[receiver, value]); | 1904 <HInstruction>[receiver, value]); |
| 1905 | 1905 |
| 1906 pop(); | 1906 pop(); |
| 1907 stack.add(value); | 1907 stack.add(value); |
| 1908 } | 1908 } |
| 1909 | 1909 |
| 1910 @override | 1910 @override |
| 1911 void visitSuperPropertySet(ir.SuperPropertySet propertySet) { |
| 1912 propertySet.value.accept(this); |
| 1913 HInstruction value = pop(); |
| 1914 |
| 1915 if (propertySet.interfaceTarget == null) { |
| 1916 _generateSuperNoSuchMethod( |
| 1917 propertySet, |
| 1918 astAdapter.getSelector(propertySet).name + "=", |
| 1919 <HInstruction>[value]); |
| 1920 } else { |
| 1921 _buildInvokeSuper( |
| 1922 astAdapter.getSelector(propertySet), |
| 1923 _containingClass(propertySet), |
| 1924 propertySet.interfaceTarget, |
| 1925 <HInstruction>[value]); |
| 1926 } |
| 1927 } |
| 1928 |
| 1929 @override |
| 1911 void visitVariableSet(ir.VariableSet variableSet) { | 1930 void visitVariableSet(ir.VariableSet variableSet) { |
| 1912 variableSet.value.accept(this); | 1931 variableSet.value.accept(this); |
| 1913 HInstruction value = pop(); | 1932 HInstruction value = pop(); |
| 1914 _visitLocalSetter(variableSet.variable, value); | 1933 _visitLocalSetter(variableSet.variable, value); |
| 1915 } | 1934 } |
| 1916 | 1935 |
| 1917 @override | 1936 @override |
| 1918 void visitVariableDeclaration(ir.VariableDeclaration declaration) { | 1937 void visitVariableDeclaration(ir.VariableDeclaration declaration) { |
| 1919 Local local = astAdapter.getLocal(declaration); | 1938 Local local = astAdapter.getLocal(declaration); |
| 1920 if (declaration.initializer == null) { | 1939 if (declaration.initializer == null) { |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2627 } | 2646 } |
| 2628 | 2647 |
| 2629 static ir.Class _containingClass(ir.TreeNode node) { | 2648 static ir.Class _containingClass(ir.TreeNode node) { |
| 2630 while (node != null) { | 2649 while (node != null) { |
| 2631 if (node is ir.Class) return node; | 2650 if (node is ir.Class) return node; |
| 2632 node = node.parent; | 2651 node = node.parent; |
| 2633 } | 2652 } |
| 2634 return null; | 2653 return null; |
| 2635 } | 2654 } |
| 2636 | 2655 |
| 2637 HInstruction _buildInvokeSuper( | 2656 /// Find the applicable NoSuchMethod method for an object of this particular |
| 2638 ir.Expression invocation, List<HInstruction> arguments) { | 2657 /// class. |
| 2639 // Invocation is either a method invocation or a property get/set. | 2658 ir.Procedure _findNoSuchMethodInClass(ir.Class cls) { |
| 2640 // TODO(efortuna): Common interface? | 2659 // TODO(efortuna): If we find ourselves doing this sort of calculation |
| 2660 // often, rewrite what is done with the original element class where we call |
| 2661 // lookupSuperMember. |
| 2662 ir.Procedure noSuchMethod = null; |
| 2663 while (cls != null && cls != astAdapter.objectClass) { |
| 2664 for (ir.Procedure procedure in cls.procedures) { |
| 2665 // TODO(efortuna): Do we need to check mixin classes as well? |
| 2666 if (procedure.name.name == Identifiers.noSuchMethod_ && |
| 2667 Selectors.noSuchMethod_ |
| 2668 .signatureApplies(astAdapter.getElement(procedure))) { |
| 2669 noSuchMethod = procedure; |
| 2670 } |
| 2671 } |
| 2672 cls = cls.superclass; |
| 2673 } |
| 2674 |
| 2675 if (noSuchMethod == null) { |
| 2676 // There is no matching overloaded NoSuchMethod function in the containing |
| 2677 // class. Look on the Object class itself. |
| 2678 for (ir.Procedure procedure in astAdapter.objectClass.procedures) { |
| 2679 if (procedure.name.name == Identifiers.noSuchMethod_) { |
| 2680 noSuchMethod = procedure; |
| 2681 } |
| 2682 } |
| 2683 } |
| 2684 assert(noSuchMethod != null); |
| 2685 return noSuchMethod; |
| 2686 } |
| 2687 |
| 2688 void _generateSuperNoSuchMethod(ir.Expression invocation, String publicName, |
| 2689 List<HInstruction> arguments) { |
| 2690 Selector selector = astAdapter.getSelector(invocation); |
| 2691 ir.Class cls = _containingClass(invocation).superclass; |
| 2692 assert(cls != null); |
| 2693 ir.Procedure noSuchMethod = _findNoSuchMethodInClass(cls); |
| 2694 if (backend.hasInvokeOnSupport && |
| 2695 _containingClass(noSuchMethod) != astAdapter.objectClass) { |
| 2696 // Register the call as dynamic if [noSuchMethod] on the super |
| 2697 // class is _not_ the default implementation from [Object] (it might be |
| 2698 // overridden in the super class, but it might have a different number of |
| 2699 // arguments), in case the [noSuchMethod] implementation calls |
| 2700 // [JSInvocationMirror._invokeOn]. |
| 2701 // TODO(johnniwinther): Register this more precisely. |
| 2702 registry?.registerDynamicUse(new DynamicUse(selector, null)); |
| 2703 } |
| 2704 |
| 2705 ConstantValue nameConstant = |
| 2706 backend.constantSystem.createString(new DartString.literal(publicName)); |
| 2707 |
| 2708 js.Name internalName = backend.namer.invocationName(selector); |
| 2709 |
| 2710 var argumentsInstruction = |
| 2711 new HLiteralList(arguments, commonMasks.extendableArrayType); |
| 2712 add(argumentsInstruction); |
| 2713 |
| 2714 var argumentNames = new List<HInstruction>(); |
| 2715 for (String argumentName in selector.namedArguments) { |
| 2716 ConstantValue argumentNameConstant = backend.constantSystem |
| 2717 .createString(new DartString.literal(argumentName)); |
| 2718 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); |
| 2719 } |
| 2720 var argumentNamesInstruction = |
| 2721 new HLiteralList(argumentNames, commonMasks.extendableArrayType); |
| 2722 add(argumentNamesInstruction); |
| 2723 |
| 2724 ConstantValue kindConstant = |
| 2725 backend.constantSystem.createInt(selector.invocationMirrorKind); |
| 2726 |
| 2727 _pushStaticInvocation( |
| 2728 astAdapter.createInvocationMirror, |
| 2729 [ |
| 2730 graph.addConstant(nameConstant, closedWorld), |
| 2731 graph.addConstantStringFromName(internalName, closedWorld), |
| 2732 graph.addConstant(kindConstant, closedWorld), |
| 2733 argumentsInstruction, |
| 2734 argumentNamesInstruction |
| 2735 ], |
| 2736 commonMasks.dynamicType); |
| 2737 |
| 2738 _buildInvokeSuper(Selectors.noSuchMethod_, _containingClass(invocation), |
| 2739 noSuchMethod, <HInstruction>[pop()]); |
| 2740 } |
| 2741 |
| 2742 HInstruction _buildInvokeSuper(Selector selector, ir.Class containingClass, |
| 2743 ir.Member interfaceTarget, List<HInstruction> arguments) { |
| 2641 // TODO(efortuna): Add source information. | 2744 // TODO(efortuna): Add source information. |
| 2642 Selector selector = astAdapter.getSelector(invocation); | |
| 2643 HInstruction receiver = localsHandler.readThis(); | 2745 HInstruction receiver = localsHandler.readThis(); |
| 2644 ir.Class surroundingClass = _containingClass(invocation); | |
| 2645 | 2746 |
| 2646 List<HInstruction> inputs = <HInstruction>[]; | 2747 List<HInstruction> inputs = <HInstruction>[]; |
| 2647 if (astAdapter.isIntercepted(invocation)) { | 2748 if (astAdapter.isInterceptedSelector(selector)) { |
| 2648 inputs.add(_interceptorFor(receiver)); | 2749 inputs.add(_interceptorFor(receiver)); |
| 2649 } | 2750 } |
| 2650 inputs.add(receiver); | 2751 inputs.add(receiver); |
| 2651 inputs.addAll(arguments); | 2752 inputs.addAll(arguments); |
| 2652 | 2753 |
| 2653 ir.Member interfaceTarget = invocation is ir.SuperMethodInvocation | |
| 2654 ? (invocation as ir.SuperMethodInvocation).interfaceTarget | |
| 2655 : (invocation as ir.SuperPropertyGet).interfaceTarget; | |
| 2656 | |
| 2657 HInstruction instruction = new HInvokeSuper( | 2754 HInstruction instruction = new HInvokeSuper( |
| 2658 astAdapter.getMember(interfaceTarget), | 2755 astAdapter.getMember(interfaceTarget), |
| 2659 astAdapter.getClass(surroundingClass), | 2756 astAdapter.getClass(containingClass), |
| 2660 selector, | 2757 selector, |
| 2661 inputs, | 2758 inputs, |
| 2662 astAdapter.returnTypeOf(interfaceTarget), | 2759 astAdapter.returnTypeOf(interfaceTarget), |
| 2663 null, | 2760 null, |
| 2664 isSetter: selector.isSetter || selector.isIndexSet); | 2761 isSetter: selector.isSetter || selector.isIndexSet); |
| 2665 instruction.sideEffects = | 2762 instruction.sideEffects = |
| 2666 closedWorld.getSideEffectsOfSelector(selector, null); | 2763 closedWorld.getSideEffectsOfSelector(selector, null); |
| 2667 push(instruction); | 2764 push(instruction); |
| 2668 return instruction; | 2765 return instruction; |
| 2669 } | 2766 } |
| 2670 | 2767 |
| 2671 @override | 2768 @override |
| 2672 void visitSuperPropertyGet(ir.SuperPropertyGet propertyGet) { | 2769 void visitSuperPropertyGet(ir.SuperPropertyGet propertyGet) { |
| 2673 _buildInvokeSuper(propertyGet, const <HInstruction>[]); | 2770 if (propertyGet.interfaceTarget == null) { |
| 2771 _generateSuperNoSuchMethod(propertyGet, |
| 2772 astAdapter.getSelector(propertyGet).name, const <HInstruction>[]); |
| 2773 } else { |
| 2774 _buildInvokeSuper( |
| 2775 astAdapter.getSelector(propertyGet), |
| 2776 _containingClass(propertyGet), |
| 2777 propertyGet.interfaceTarget, const <HInstruction>[]); |
| 2778 } |
| 2674 } | 2779 } |
| 2675 | 2780 |
| 2676 @override | 2781 @override |
| 2677 void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) { | 2782 void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) { |
| 2678 List<HInstruction> arguments = _visitArgumentsForStaticTarget( | 2783 List<HInstruction> arguments = _visitArgumentsForStaticTarget( |
| 2679 invocation.interfaceTarget.function, invocation.arguments); | 2784 invocation.interfaceTarget.function, invocation.arguments); |
| 2680 _buildInvokeSuper(invocation, arguments); | 2785 _buildInvokeSuper(astAdapter.getSelector(invocation), |
| 2786 _containingClass(invocation), invocation.interfaceTarget, arguments); |
| 2681 } | 2787 } |
| 2682 | 2788 |
| 2683 @override | 2789 @override |
| 2684 void visitConstructorInvocation(ir.ConstructorInvocation invocation) { | 2790 void visitConstructorInvocation(ir.ConstructorInvocation invocation) { |
| 2685 ir.Constructor target = invocation.target; | 2791 ir.Constructor target = invocation.target; |
| 2686 // TODO(sra): For JS-interop targets, process arguments differently. | 2792 // TODO(sra): For JS-interop targets, process arguments differently. |
| 2687 List<HInstruction> arguments = | 2793 List<HInstruction> arguments = |
| 2688 _visitArgumentsForStaticTarget(target.function, invocation.arguments); | 2794 _visitArgumentsForStaticTarget(target.function, invocation.arguments); |
| 2689 TypeMask typeMask = new TypeMask.nonNullExact( | 2795 TypeMask typeMask = new TypeMask.nonNullExact( |
| 2690 astAdapter.getClass(target.enclosingClass), closedWorld); | 2796 astAdapter.getClass(target.enclosingClass), closedWorld); |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3115 enterBlock.setBlockFlow( | 3221 enterBlock.setBlockFlow( |
| 3116 new HTryBlockInformation( | 3222 new HTryBlockInformation( |
| 3117 kernelBuilder.wrapStatementGraph(bodyGraph), | 3223 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 3118 exception, | 3224 exception, |
| 3119 kernelBuilder.wrapStatementGraph(catchGraph), | 3225 kernelBuilder.wrapStatementGraph(catchGraph), |
| 3120 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3226 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 3121 exitBlock); | 3227 exitBlock); |
| 3122 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3228 kernelBuilder.inTryStatement = previouslyInTryStatement; |
| 3123 } | 3229 } |
| 3124 } | 3230 } |
| OLD | NEW |