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

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

Issue 11861007: Move indexSet and unary operators to the new interceptor mechanism. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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 2281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 Element fieldCheck = 2292 Element fieldCheck =
2293 parameterClosureData.parametersWithSentinel[element]; 2293 parameterClosureData.parametersWithSentinel[element];
2294 stack.add(localsHandler.readLocal(fieldCheck)); 2294 stack.add(localsHandler.readLocal(fieldCheck));
2295 return; 2295 return;
2296 } 2296 }
2297 assert(node.argumentsNode is Prefix); 2297 assert(node.argumentsNode is Prefix);
2298 visit(node.receiver); 2298 visit(node.receiver);
2299 assert(!identical(op.token.kind, PLUS_TOKEN)); 2299 assert(!identical(op.token.kind, PLUS_TOKEN));
2300 HInstruction operand = pop(); 2300 HInstruction operand = pop();
2301 2301
2302 HInstruction target =
2303 new HStatic(interceptors.getPrefixOperatorInterceptor(op));
2304 add(target);
2305 HInvokeUnary result;
2306 String value = op.source.stringValue;
2307 switch (value) {
2308 case "-": result = new HNegate(target, operand); break;
2309 case "~": result = new HBitNot(target, operand); break;
2310 default:
2311 compiler.internalError('Unexpected unary operator: $value.', node: op);
2312 break;
2313 }
2314 // See if we can constant-fold right away. This avoids rewrites later on. 2302 // See if we can constant-fold right away. This avoids rewrites later on.
2315 if (operand is HConstant) { 2303 if (operand is HConstant) {
2304 UnaryOperation operation = constantSystem.lookupUnary(op.source);
2316 HConstant constant = operand; 2305 HConstant constant = operand;
2317 Constant folded = 2306 Constant folded = operation.fold(constant.constant);
2318 result.operation(constantSystem).fold(constant.constant);
2319 if (folded != null) { 2307 if (folded != null) {
2320 stack.add(graph.addConstant(folded)); 2308 stack.add(graph.addConstant(folded));
2321 return; 2309 return;
2322 } 2310 }
2323 } 2311 }
2312
2313 HInvokeDynamicMethod result =
2314 buildInvokeDynamic(node, elements.getSelector(node), operand, []);
2324 pushWithPosition(result, node); 2315 pushWithPosition(result, node);
2325 } 2316 }
2326 2317
2327 void visitBinary(HInstruction left, Operator op, HInstruction right) { 2318 void visitBinary(HInstruction left, Operator op, HInstruction right) {
2328 Element element = interceptors.getOperatorInterceptor(op); 2319 Element element = interceptors.getOperatorInterceptor(op);
2329 assert(element != null); 2320 assert(element != null);
2330 HInstruction target = new HStatic(element); 2321 HInstruction target = new HStatic(element);
2331 add(target); 2322 add(target);
2332 switch (op.source.stringValue) { 2323 switch (op.source.stringValue) {
2333 case "+": 2324 case "+":
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after
3633 // on type arguments. 3624 // on type arguments.
3634 generateRuntimeError(node, '$type is malformed: $reasons'); 3625 generateRuntimeError(node, '$type is malformed: $reasons');
3635 } else { 3626 } else {
3636 // TODO(karlklose): move this type registration to the codegen. 3627 // TODO(karlklose): move this type registration to the codegen.
3637 compiler.codegenWorld.instantiatedTypes.add(type); 3628 compiler.codegenWorld.instantiatedTypes.add(type);
3638 visitNewSend(node.send, type); 3629 visitNewSend(node.send, type);
3639 } 3630 }
3640 } 3631 }
3641 } 3632 }
3642 3633
3643 HInvokeDynamicMethod buildInvokeDynamicWithOneArgument( 3634 HInvokeDynamicMethod buildInvokeDynamic(Node node,
3644 Node node, Selector selector, HInstruction receiver, HInstruction arg0) { 3635 Selector selector,
3636 HInstruction receiver,
3637 List<HInstruction> arguments) {
3645 Set<ClassElement> interceptedClasses = 3638 Set<ClassElement> interceptedClasses =
3646 getInterceptedClassesOn(node, selector); 3639 getInterceptedClassesOn(node, selector);
3647 List<HInstruction> inputs = <HInstruction>[]; 3640 List<HInstruction> inputs = <HInstruction>[];
3648 if (interceptedClasses != null) { 3641 if (interceptedClasses != null) {
3649 inputs.add(invokeInterceptor(interceptedClasses, receiver, node)); 3642 inputs.add(invokeInterceptor(interceptedClasses, receiver, node));
3650 } 3643 }
3651 inputs.add(receiver); 3644 inputs.add(receiver);
3652 inputs.add(arg0); 3645 inputs.addAll(arguments);
3653 return new HInvokeDynamicMethod(selector, inputs); 3646 return new HInvokeDynamicMethod(selector, inputs);
3654 } 3647 }
3655 3648
3656 visitSendSet(SendSet node) { 3649 visitSendSet(SendSet node) {
3657 Element element = elements[node]; 3650 Element element = elements[node];
3658 if (!Elements.isUnresolved(element) && element.impliesType()) { 3651 if (!Elements.isUnresolved(element) && element.impliesType()) {
3659 Identifier selector = node.selector; 3652 Identifier selector = node.selector;
3660 generateThrowNoSuchMethod(node, selector.source.slowToString(), 3653 generateThrowNoSuchMethod(node, selector.source.slowToString(),
3661 argumentNodes: node.arguments); 3654 argumentNodes: node.arguments);
3662 return; 3655 return;
3663 } 3656 }
3664 Operator op = node.assignmentOperator; 3657 Operator op = node.assignmentOperator;
3665 if (node.isSuperCall) { 3658 if (node.isSuperCall) {
3666 if (element == null) return generateSuperNoSuchMethodSend(node); 3659 if (element == null) return generateSuperNoSuchMethodSend(node);
3667 HInstruction target = new HStatic(element); 3660 HInstruction target = new HStatic(element);
3668 HInstruction context = localsHandler.readThis(); 3661 HInstruction context = localsHandler.readThis();
3669 add(target); 3662 add(target);
3670 var inputs = <HInstruction>[target, context]; 3663 var inputs = <HInstruction>[target, context];
3671 addDynamicSendArgumentsToList(node, inputs); 3664 addDynamicSendArgumentsToList(node, inputs);
3672 if (!identical(node.assignmentOperator.source.stringValue, '=')) { 3665 if (!identical(node.assignmentOperator.source.stringValue, '=')) {
3673 compiler.unimplemented('complex super assignment', 3666 compiler.unimplemented('complex super assignment',
3674 node: node.assignmentOperator); 3667 node: node.assignmentOperator);
3675 } 3668 }
3676 push(new HInvokeSuper(inputs, isSetter: true)); 3669 push(new HInvokeSuper(inputs, isSetter: true));
3677 } else if (node.isIndex) { 3670 } else if (node.isIndex) {
3678 if (!methodInterceptionEnabled) { 3671 if (!methodInterceptionEnabled) {
3679 assert(identical(op.source.stringValue, '=')); 3672 assert(identical(op.source.stringValue, '='));
3680 visitDynamicSend(node); 3673 visitDynamicSend(node);
3674 } else if (const SourceString("=") == op.source) {
3675 visitDynamicSend(node);
3676 HInvokeDynamicMethod method = pop();
3677 // Push the value.
3678 stack.add(method.inputs.last);
3681 } else { 3679 } else {
3682 HStatic target = new HStatic(
3683 interceptors.getIndexAssignmentInterceptor());
3684 add(target);
3685 visit(node.receiver); 3680 visit(node.receiver);
3686 HInstruction receiver = pop(); 3681 HInstruction receiver = pop();
3687 visit(node.argumentsNode); 3682 visit(node.argumentsNode);
3688 if (const SourceString("=") == op.source) { 3683 HInstruction value;
3689 HInstruction value = pop(); 3684 HInstruction index;
3690 HInstruction index = pop(); 3685 // Compound assignments are considered as being prefix.
3691 add(new HIndexAssign(target, receiver, index, value)); 3686 bool isCompoundAssignment = op.source.stringValue.endsWith('=');
3687 bool isPrefix = !node.isPostfix;
3688 Element getter = elements[node.selector];
3689 if (isCompoundAssignment) {
3690 value = pop();
3691 index = pop();
3692 } else {
3693 index = pop();
3694 value = graph.addConstantInt(1, constantSystem);
3695 }
3696
3697 HInvokeDynamicMethod left = buildInvokeDynamic(
3698 node, new Selector.index(), receiver, [index]);
3699 add(left);
3700 visitBinary(left, op, value);
3701 value = pop();
3702 HInvokeDynamicMethod assign = buildInvokeDynamic(
3703 node, new Selector.indexSet(), receiver, [index, value]);
3704 add(assign);
3705 if (isPrefix) {
3692 stack.add(value); 3706 stack.add(value);
3693 } else { 3707 } else {
3694 HInstruction value; 3708 stack.add(left);
3695 HInstruction index;
3696 bool isCompoundAssignment = op.source.stringValue.endsWith('=');
3697 // Compound assignments are considered as being prefix.
3698 bool isPrefix = !node.isPostfix;
3699 Element getter = elements[node.selector];
3700 if (isCompoundAssignment) {
3701 value = pop();
3702 index = pop();
3703 } else {
3704 index = pop();
3705 value = graph.addConstantInt(1, constantSystem);
3706 }
3707
3708 HInvokeDynamicMethod left = buildInvokeDynamicWithOneArgument(
3709 node, new Selector.index(), receiver, index);
3710 add(left);
3711 Element opElement = elements[op];
3712 visitBinary(left, op, value);
3713 value = pop();
3714 HInstruction assign = new HIndexAssign(
3715 target, receiver, index, value);
3716 add(assign);
3717 if (isPrefix) {
3718 stack.add(value);
3719 } else {
3720 stack.add(left);
3721 }
3722 } 3709 }
3723 } 3710 }
3724 } else if (const SourceString("=") == op.source) { 3711 } else if (const SourceString("=") == op.source) {
3725 Element element = elements[node]; 3712 Element element = elements[node];
3726 Link<Node> link = node.arguments; 3713 Link<Node> link = node.arguments;
3727 assert(!link.isEmpty && link.tail.isEmpty); 3714 assert(!link.isEmpty && link.tail.isEmpty);
3728 visit(link.head); 3715 visit(link.head);
3729 HInstruction value = pop(); 3716 HInstruction value = pop();
3730 generateSetter(node, element, value); 3717 generateSetter(node, element, value);
3731 } else if (identical(op.source.stringValue, "is")) { 3718 } else if (identical(op.source.stringValue, "is")) {
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after
5101 new HSubGraphBlockInformation(elseBranch.graph)); 5088 new HSubGraphBlockInformation(elseBranch.graph));
5102 5089
5103 HBasicBlock conditionStartBlock = conditionBranch.block; 5090 HBasicBlock conditionStartBlock = conditionBranch.block;
5104 conditionStartBlock.setBlockFlow(info, joinBlock); 5091 conditionStartBlock.setBlockFlow(info, joinBlock);
5105 SubGraph conditionGraph = conditionBranch.graph; 5092 SubGraph conditionGraph = conditionBranch.graph;
5106 HIf branch = conditionGraph.end.last; 5093 HIf branch = conditionGraph.end.last;
5107 assert(branch is HIf); 5094 assert(branch is HIf);
5108 branch.blockInformation = conditionStartBlock.blockFlow; 5095 branch.blockInformation = conditionStartBlock.blockFlow;
5109 } 5096 }
5110 } 5097 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698