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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 12374094: Implement complex super assignment. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
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 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 3028 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); 3039 stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
3040 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { 3040 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
3041 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); 3041 stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
3042 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { 3042 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
3043 handleForeignDartObjectJsConstructorFunction(node); 3043 handleForeignDartObjectJsConstructorFunction(node);
3044 } else { 3044 } else {
3045 throw "Unknown foreign: ${selector}"; 3045 throw "Unknown foreign: ${selector}";
3046 } 3046 }
3047 } 3047 }
3048 3048
3049 generateSuperNoSuchMethodSend(Send node) { 3049 generateSuperNoSuchMethodSend(Send node,
3050 Selector selector = elements.getSelector(node); 3050 Selector selector,
3051 List<HInstruction> arguments) {
3051 SourceString name = selector.name; 3052 SourceString name = selector.name;
3052 3053
3053 ClassElement cls = currentElement.getEnclosingClass(); 3054 ClassElement cls = currentElement.getEnclosingClass();
3054 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); 3055 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
3055 if (element.enclosingElement.declaration != compiler.objectClass) { 3056 if (element.enclosingElement.declaration != compiler.objectClass) {
3056 // Register the call as dynamic if [:noSuchMethod:] on the super class 3057 // Register the call as dynamic if [:noSuchMethod:] on the super class
3057 // is _not_ the default implementation from [:Object:]. 3058 // is _not_ the default implementation from [:Object:], in case
3058 compiler.enqueuer.codegen.registerDynamicInvocation(name, selector); 3059 // the [:noSuchMethod:] implementation does an [:invokeOn:] on
3059 } 3060 // the invocation mirror.
3061 if (selector.isGetter()) {
kasperl 2013/03/05 07:32:36 Could this logic be moved to the enqueuer? If we h
ngeoffray 2013/03/05 08:46:25 Done.
3062 compiler.enqueuer.codegen.registerDynamicGetter(name, selector);
3063 } else if (selector.isSetter()) {
3064 compiler.enqueuer.codegen.registerDynamicSetter(name, selector);
3065 } else {
3066 compiler.enqueuer.codegen.registerDynamicInvocation(name, selector);
3067 }
3068 }
3060 HStatic target = new HStatic(element); 3069 HStatic target = new HStatic(element);
3061 add(target); 3070 add(target);
3062 HInstruction self = localsHandler.readThis(); 3071 HInstruction self = localsHandler.readThis();
3063 Constant nameConstant = constantSystem.createString( 3072 Constant nameConstant = constantSystem.createString(
3064 new DartString.literal(name.slowToString()), node); 3073 new DartString.literal(name.slowToString()), node);
3065 3074
3066 String internalName = backend.namer.invocationName(selector); 3075 String internalName = backend.namer.invocationName(selector);
3067 Constant internalNameConstant = 3076 Constant internalNameConstant =
3068 constantSystem.createString(new DartString.literal(internalName), node); 3077 constantSystem.createString(new DartString.literal(internalName), node);
3069 3078
3070 Element createInvocationMirror = backend.getCreateInvocationMirror(); 3079 Element createInvocationMirror = backend.getCreateInvocationMirror();
3071
3072 var arguments = new List<HInstruction>();
3073 if (node.argumentsNode != null) {
3074 addGenericSendArgumentsToList(node.arguments, arguments);
3075 }
3076 var argumentsInstruction = new HLiteralList(arguments); 3080 var argumentsInstruction = new HLiteralList(arguments);
3077 add(argumentsInstruction); 3081 add(argumentsInstruction);
3078 3082
3079 var argumentNames = new List<HInstruction>(); 3083 var argumentNames = new List<HInstruction>();
3080 for (SourceString argumentName in selector.namedArguments) { 3084 for (SourceString argumentName in selector.namedArguments) {
3081 Constant argumentNameConstant = 3085 Constant argumentNameConstant =
3082 constantSystem.createString(new DartString.literal( 3086 constantSystem.createString(new DartString.literal(
3083 argumentName.slowToString()), node); 3087 argumentName.slowToString()), node);
3084 argumentNames.add(graph.addConstant(argumentNameConstant)); 3088 argumentNames.add(graph.addConstant(argumentNameConstant));
3085 } 3089 }
(...skipping 24 matching lines...) Expand all
3110 if (element != null && identical(element, currentElement)) { 3114 if (element != null && identical(element, currentElement)) {
3111 graph.isRecursiveMethod = true; 3115 graph.isRecursiveMethod = true;
3112 } 3116 }
3113 super.visitSend(node); 3117 super.visitSend(node);
3114 } 3118 }
3115 3119
3116 visitSuperSend(Send node) { 3120 visitSuperSend(Send node) {
3117 Selector selector = elements.getSelector(node); 3121 Selector selector = elements.getSelector(node);
3118 Element element = elements[node]; 3122 Element element = elements[node];
3119 if (Elements.isUnresolved(element)) { 3123 if (Elements.isUnresolved(element)) {
3120 return generateSuperNoSuchMethodSend(node); 3124 List<HInstruction> arguments = <HInstruction>[];
3125 if (!node.isPropertyAccess) {
3126 addGenericSendArgumentsToList(node.arguments, arguments);
3127 }
3128 return generateSuperNoSuchMethodSend(node, selector, arguments);
3121 } 3129 }
3122 // TODO(5346): Try to avoid the need for calling [declaration] before 3130 // TODO(5346): Try to avoid the need for calling [declaration] before
3123 // creating an [HStatic]. 3131 // creating an [HStatic].
3124 HInstruction target = new HStatic(element.declaration); 3132 HInstruction target = new HStatic(element.declaration);
3125 HInstruction context = localsHandler.readThis(); 3133 HInstruction context = localsHandler.readThis();
3126 add(target); 3134 add(target);
3127 var inputs = <HInstruction>[target, context]; 3135 var inputs = <HInstruction>[target, context];
3128 if (backend.isInterceptedMethod(element)) { 3136 if (backend.isInterceptedMethod(element)) {
3129 inputs.add(context); 3137 inputs.add(context);
3130 } 3138 }
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
3581 3589
3582 visitSendSet(SendSet node) { 3590 visitSendSet(SendSet node) {
3583 Element element = elements[node]; 3591 Element element = elements[node];
3584 if (!Elements.isUnresolved(element) && element.impliesType()) { 3592 if (!Elements.isUnresolved(element) && element.impliesType()) {
3585 Identifier selector = node.selector; 3593 Identifier selector = node.selector;
3586 generateThrowNoSuchMethod(node, selector.source.slowToString(), 3594 generateThrowNoSuchMethod(node, selector.source.slowToString(),
3587 argumentNodes: node.arguments); 3595 argumentNodes: node.arguments);
3588 return; 3596 return;
3589 } 3597 }
3590 Operator op = node.assignmentOperator; 3598 Operator op = node.assignmentOperator;
3591 if (node.isSuperCall) { 3599 if (node.isSuperCall) {
kasperl 2013/03/05 07:32:36 Think about if some of this could be shared with t
3600 HInstruction toPush;
kasperl 2013/03/05 07:32:36 I'd call this the value/result or something like t
ngeoffray 2013/03/05 08:46:25 Done.
3601 List<HInstruction> setterInputs = <HInstruction>[];
3602 HInstruction context = localsHandler.readThis();
3603 if (!Elements.isUnresolved(element)) {
3604 HInstruction target = new HStatic(element);
kasperl 2013/03/05 07:32:36 Is any of this refactorable? The resolved target/g
ngeoffray 2013/03/05 08:46:25 Done.
3605 add(target);
3606 setterInputs.add(target);
3607 setterInputs.add(context);
3608 if (backend.isInterceptedMethod(element)) {
3609 setterInputs.add(context);
3610 }
3611 }
3612 if (identical(node.assignmentOperator.source.stringValue, '=')) {
3613 addDynamicSendArgumentsToList(node, setterInputs);
3614 toPush = setterInputs.last;
3615 } else {
3616 Element getter = elements[node.selector];
3617 List<HInstruction> getterInputs = <HInstruction>[];
3618 if (!Elements.isUnresolved(getter)) {
3619 HInstruction getterTarget = new HStatic(getter);
3620 add(getterTarget);
3621 getterInputs.add(getterTarget);
3622 getterInputs.add(context);
3623 if (backend.isInterceptedMethod(getter)) {
3624 getterInputs.add(context);
3625 }
3626 }
3627 Link<Node> arguments = node.arguments;
kasperl 2013/03/05 07:32:36 Add a comment that explains what you're dealing wi
ngeoffray 2013/03/05 08:46:25 Done.
3628 if (node.isIndex) {
3629 visit(arguments.head);
3630 arguments = arguments.tail;
3631 HInstruction index = pop();
3632 getterInputs.add(index);
3633 setterInputs.add(index);
3634 }
3635 HInstruction getterInstruction;
kasperl 2013/03/05 07:32:36 Could this (the computation of the getterInstructi
ngeoffray 2013/03/05 08:46:25 Done.
3636 if (Elements.isUnresolved(getter)) {
3637 generateSuperNoSuchMethodSend(
3638 node,
3639 elements.getGetterSelectorInComplexSendSet(node),
3640 getterInputs);
3641 getterInstruction = pop();
3642 } else {
3643 getterInstruction = new HInvokeSuper(getterInputs);
3644 add(getterInstruction);
3645 }
3646 HInstruction rhs;
kasperl 2013/03/05 07:32:36 Do we have code like this elsewhere in the builder
ngeoffray 2013/03/05 08:46:25 Yes, refactored.
3647 if (node.isPrefix || node.isPostfix) {
3648 rhs = graph.addConstantInt(1, constantSystem);
3649 } else {
3650 visit(arguments.head);
3651 assert(arguments.tail.isEmpty);
3652 rhs = pop();
3653 }
3654 visitBinary(getterInstruction, op, rhs,
3655 elements.getOperatorSelectorInComplexSendSet(node), node);
3656 setterInputs.add(pop());
3657
3658 if (node.isPostfix) {
3659 toPush = getterInstruction;
3660 } else {
3661 toPush = setterInputs.last;
3662 }
3663 }
3592 if (Elements.isUnresolved(element)) { 3664 if (Elements.isUnresolved(element)) {
3593 return generateSuperNoSuchMethodSend(node); 3665 generateSuperNoSuchMethodSend(
3666 node, elements.getSelector(node), setterInputs);
3667 pop();
3668 } else {
3669 add(new HInvokeSuper(setterInputs, isSetter: true));
3594 } 3670 }
3595 HInstruction target = new HStatic(element); 3671 stack.add(toPush);
3596 HInstruction context = localsHandler.readThis();
3597 add(target);
3598 var inputs = <HInstruction>[target, context];
3599 addDynamicSendArgumentsToList(node, inputs);
3600 if (!identical(node.assignmentOperator.source.stringValue, '=')) {
3601 compiler.unimplemented('complex super assignment',
3602 node: node.assignmentOperator);
3603 }
3604 push(new HInvokeSuper(inputs, isSetter: true));
3605 } else if (node.isIndex) { 3672 } else if (node.isIndex) {
3606 if (const SourceString("=") == op.source) { 3673 if (const SourceString("=") == op.source) {
3607 // TODO(kasperl): We temporarily disable inlining because the 3674 // TODO(kasperl): We temporarily disable inlining because the
3608 // code here cannot deal with it yet. 3675 // code here cannot deal with it yet.
3609 visitDynamicSend(node, inline: false); 3676 visitDynamicSend(node, inline: false);
3610 HInvokeDynamicMethod method = pop(); 3677 HInvokeDynamicMethod method = pop();
3611 // Push the value. 3678 // Push the value.
3612 stack.add(method.inputs.last); 3679 stack.add(method.inputs.last);
3613 } else { 3680 } else {
3614 visit(node.receiver); 3681 visit(node.receiver);
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after
5035 new HSubGraphBlockInformation(elseBranch.graph)); 5102 new HSubGraphBlockInformation(elseBranch.graph));
5036 5103
5037 HBasicBlock conditionStartBlock = conditionBranch.block; 5104 HBasicBlock conditionStartBlock = conditionBranch.block;
5038 conditionStartBlock.setBlockFlow(info, joinBlock); 5105 conditionStartBlock.setBlockFlow(info, joinBlock);
5039 SubGraph conditionGraph = conditionBranch.graph; 5106 SubGraph conditionGraph = conditionBranch.graph;
5040 HIf branch = conditionGraph.end.last; 5107 HIf branch = conditionGraph.end.last;
5041 assert(branch is HIf); 5108 assert(branch is HIf);
5042 branch.blockInformation = conditionStartBlock.blockFlow; 5109 branch.blockInformation = conditionStartBlock.blockFlow;
5043 } 5110 }
5044 } 5111 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698