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

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;
2305 String value = op.source.stringValue;
2306 switch (value) {
2307 case '-': operation = constantSystem.negate; break;
kasperl 2013/01/15 07:06:12 Maybe this code would be nicer to have on the cons
ngeoffray 2013/01/15 08:56:09 Done.
2308 case '~': operation = constantSystem.bitNot; break;
2309 default:
2310 compiler.internalError('Unexpected unary operator: $value.',
2311 node: op);
2312 break;
2313 }
2314
2316 HConstant constant = operand; 2315 HConstant constant = operand;
2317 Constant folded = 2316 Constant folded = operation.fold(constant.constant);
2318 result.operation(constantSystem).fold(constant.constant);
2319 if (folded != null) { 2317 if (folded != null) {
2320 stack.add(graph.addConstant(folded)); 2318 stack.add(graph.addConstant(folded));
2321 return; 2319 return;
2322 } 2320 }
2323 } 2321 }
2322
2323 HInvokeDynamicMethod result
2324 = buildInvokeDynamic(node, elements.getSelector(node), operand, []);
kasperl 2013/01/15 07:06:12 We usually put = on the previous line.
ngeoffray 2013/01/15 08:56:09 Done.
2324 pushWithPosition(result, node); 2325 pushWithPosition(result, node);
2325 } 2326 }
2326 2327
2327 void visitBinary(HInstruction left, Operator op, HInstruction right) { 2328 void visitBinary(HInstruction left, Operator op, HInstruction right) {
2328 Element element = interceptors.getOperatorInterceptor(op); 2329 Element element = interceptors.getOperatorInterceptor(op);
2329 assert(element != null); 2330 assert(element != null);
2330 HInstruction target = new HStatic(element); 2331 HInstruction target = new HStatic(element);
2331 add(target); 2332 add(target);
2332 switch (op.source.stringValue) { 2333 switch (op.source.stringValue) {
2333 case "+": 2334 case "+":
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after
3633 // on type arguments. 3634 // on type arguments.
3634 generateRuntimeError(node, '$type is malformed: $reasons'); 3635 generateRuntimeError(node, '$type is malformed: $reasons');
3635 } else { 3636 } else {
3636 // TODO(karlklose): move this type registration to the codegen. 3637 // TODO(karlklose): move this type registration to the codegen.
3637 compiler.codegenWorld.instantiatedTypes.add(type); 3638 compiler.codegenWorld.instantiatedTypes.add(type);
3638 visitNewSend(node.send, type); 3639 visitNewSend(node.send, type);
3639 } 3640 }
3640 } 3641 }
3641 } 3642 }
3642 3643
3643 HInvokeDynamicMethod buildInvokeDynamicWithOneArgument( 3644 HInvokeDynamicMethod buildInvokeDynamic(Node node,
3644 Node node, Selector selector, HInstruction receiver, HInstruction arg0) { 3645 Selector selector,
3646 HInstruction receiver,
3647 List<HInstruction> arguments) {
3645 Set<ClassElement> interceptedClasses = 3648 Set<ClassElement> interceptedClasses =
3646 getInterceptedClassesOn(node, selector); 3649 getInterceptedClassesOn(node, selector);
3647 List<HInstruction> inputs = <HInstruction>[]; 3650 List<HInstruction> inputs = <HInstruction>[];
3648 if (interceptedClasses != null) { 3651 if (interceptedClasses != null) {
3649 inputs.add(invokeInterceptor(interceptedClasses, receiver, node)); 3652 inputs.add(invokeInterceptor(interceptedClasses, receiver, node));
3650 } 3653 }
3651 inputs.add(receiver); 3654 inputs.add(receiver);
3652 inputs.add(arg0); 3655 inputs.addAll(arguments);
3653 return new HInvokeDynamicMethod(selector, inputs); 3656 return new HInvokeDynamicMethod(selector, inputs);
3654 } 3657 }
3655 3658
3656 visitSendSet(SendSet node) { 3659 visitSendSet(SendSet node) {
3657 Element element = elements[node]; 3660 Element element = elements[node];
3658 if (!Elements.isUnresolved(element) && element.impliesType()) { 3661 if (!Elements.isUnresolved(element) && element.impliesType()) {
3659 Identifier selector = node.selector; 3662 Identifier selector = node.selector;
3660 generateThrowNoSuchMethod(node, selector.source.slowToString(), 3663 generateThrowNoSuchMethod(node, selector.source.slowToString(),
3661 argumentNodes: node.arguments); 3664 argumentNodes: node.arguments);
3662 return; 3665 return;
3663 } 3666 }
3664 Operator op = node.assignmentOperator; 3667 Operator op = node.assignmentOperator;
3665 if (node.isSuperCall) { 3668 if (node.isSuperCall) {
3666 if (element == null) return generateSuperNoSuchMethodSend(node); 3669 if (element == null) return generateSuperNoSuchMethodSend(node);
3667 HInstruction target = new HStatic(element); 3670 HInstruction target = new HStatic(element);
3668 HInstruction context = localsHandler.readThis(); 3671 HInstruction context = localsHandler.readThis();
3669 add(target); 3672 add(target);
3670 var inputs = <HInstruction>[target, context]; 3673 var inputs = <HInstruction>[target, context];
3671 addDynamicSendArgumentsToList(node, inputs); 3674 addDynamicSendArgumentsToList(node, inputs);
3672 if (!identical(node.assignmentOperator.source.stringValue, '=')) { 3675 if (!identical(node.assignmentOperator.source.stringValue, '=')) {
3673 compiler.unimplemented('complex super assignment', 3676 compiler.unimplemented('complex super assignment',
3674 node: node.assignmentOperator); 3677 node: node.assignmentOperator);
3675 } 3678 }
3676 push(new HInvokeSuper(inputs, isSetter: true)); 3679 push(new HInvokeSuper(inputs, isSetter: true));
3677 } else if (node.isIndex) { 3680 } else if (node.isIndex) {
3678 if (!methodInterceptionEnabled) { 3681 if (!methodInterceptionEnabled) {
3679 assert(identical(op.source.stringValue, '=')); 3682 assert(identical(op.source.stringValue, '='));
3680 visitDynamicSend(node); 3683 visitDynamicSend(node);
3684 } else if (const SourceString("=") == op.source) {
3685 visitDynamicSend(node);
3686 HInvokeDynamicMethod method = pop();
3687 // Push the value.
3688 stack.add(method.inputs.last);
3681 } else { 3689 } else {
3682 HStatic target = new HStatic(
3683 interceptors.getIndexAssignmentInterceptor());
3684 add(target);
3685 visit(node.receiver); 3690 visit(node.receiver);
3686 HInstruction receiver = pop(); 3691 HInstruction receiver = pop();
3687 visit(node.argumentsNode); 3692 visit(node.argumentsNode);
3688 if (const SourceString("=") == op.source) { 3693 HInstruction value;
3689 HInstruction value = pop(); 3694 HInstruction index;
3690 HInstruction index = pop(); 3695 // Compound assignments are considered as being prefix.
3691 add(new HIndexAssign(target, receiver, index, value)); 3696 bool isCompoundAssignment = op.source.stringValue.endsWith('=');
3697 bool isPrefix = !node.isPostfix;
3698 Element getter = elements[node.selector];
3699 if (isCompoundAssignment) {
3700 value = pop();
3701 index = pop();
3702 } else {
3703 index = pop();
3704 value = graph.addConstantInt(1, constantSystem);
3705 }
3706
3707 HInvokeDynamicMethod left = buildInvokeDynamic(
3708 node, new Selector.index(), receiver, [index]);
3709 add(left);
3710 visitBinary(left, op, value);
3711 value = pop();
3712 HInvokeDynamicMethod assign = buildInvokeDynamic(
3713 node, new Selector.indexSet(), receiver, [index, value]);
3714 add(assign);
3715 if (isPrefix) {
3692 stack.add(value); 3716 stack.add(value);
3693 } else { 3717 } else {
3694 HInstruction value; 3718 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 } 3719 }
3723 } 3720 }
3724 } else if (const SourceString("=") == op.source) { 3721 } else if (const SourceString("=") == op.source) {
3725 Element element = elements[node]; 3722 Element element = elements[node];
3726 Link<Node> link = node.arguments; 3723 Link<Node> link = node.arguments;
3727 assert(!link.isEmpty && link.tail.isEmpty); 3724 assert(!link.isEmpty && link.tail.isEmpty);
3728 visit(link.head); 3725 visit(link.head);
3729 HInstruction value = pop(); 3726 HInstruction value = pop();
3730 generateSetter(node, element, value); 3727 generateSetter(node, element, value);
3731 } else if (identical(op.source.stringValue, "is")) { 3728 } else if (identical(op.source.stringValue, "is")) {
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after
5101 new HSubGraphBlockInformation(elseBranch.graph)); 5098 new HSubGraphBlockInformation(elseBranch.graph));
5102 5099
5103 HBasicBlock conditionStartBlock = conditionBranch.block; 5100 HBasicBlock conditionStartBlock = conditionBranch.block;
5104 conditionStartBlock.setBlockFlow(info, joinBlock); 5101 conditionStartBlock.setBlockFlow(info, joinBlock);
5105 SubGraph conditionGraph = conditionBranch.graph; 5102 SubGraph conditionGraph = conditionBranch.graph;
5106 HIf branch = conditionGraph.end.last; 5103 HIf branch = conditionGraph.end.last;
5107 assert(branch is HIf); 5104 assert(branch is HIf);
5108 branch.blockInformation = conditionStartBlock.blockFlow; 5105 branch.blockInformation = conditionStartBlock.blockFlow;
5109 } 5106 }
5110 } 5107 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698