Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2672063003: Implement SuperPropertySet and SuperNoSuchMethod. (Closed)
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_adapter.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698