| OLD | NEW |
| 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 2520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2531 } else { | 2531 } else { |
| 2532 instruction = new HInvokeDynamicSetter( | 2532 instruction = new HInvokeDynamicSetter( |
| 2533 selector, null, receiver, value, !hasSetter); | 2533 selector, null, receiver, value, !hasSetter); |
| 2534 } | 2534 } |
| 2535 addWithPosition(instruction, location); | 2535 addWithPosition(instruction, location); |
| 2536 stack.add(value); | 2536 stack.add(value); |
| 2537 } | 2537 } |
| 2538 | 2538 |
| 2539 void generateNonInstanceSetter(SendSet send, | 2539 void generateNonInstanceSetter(SendSet send, |
| 2540 Element element, | 2540 Element element, |
| 2541 HInstruction value) { | 2541 HInstruction value, |
| 2542 assert(!Elements.isInstanceSend(send, elements)); | 2542 {Node location}) { |
| 2543 assert(send == null || !Elements.isInstanceSend(send, elements)); |
| 2544 if (location == null) { |
| 2545 assert(send != null); |
| 2546 location = send; |
| 2547 } |
| 2543 if (Elements.isStaticOrTopLevelField(element)) { | 2548 if (Elements.isStaticOrTopLevelField(element)) { |
| 2544 if (element.isSetter()) { | 2549 if (element.isSetter()) { |
| 2545 HStatic target = new HStatic(element); | 2550 HStatic target = new HStatic(element); |
| 2546 add(target); | 2551 add(target); |
| 2547 addWithPosition( | 2552 addWithPosition( |
| 2548 new HInvokeStatic(<HInstruction>[target, value], HType.UNKNOWN), | 2553 new HInvokeStatic(<HInstruction>[target, value], HType.UNKNOWN), |
| 2549 send); | 2554 location); |
| 2550 } else { | 2555 } else { |
| 2551 value = potentiallyCheckType(value, element.computeType(compiler)); | 2556 value = potentiallyCheckType(value, element.computeType(compiler)); |
| 2552 addWithPosition(new HStaticStore(element, value), send); | 2557 addWithPosition(new HStaticStore(element, value), location); |
| 2553 } | 2558 } |
| 2554 stack.add(value); | 2559 stack.add(value); |
| 2555 } else if (Elements.isErroneousElement(element)) { | 2560 } else if (Elements.isErroneousElement(element)) { |
| 2556 // An erroneous element indicates an unresolved static setter. | 2561 // An erroneous element indicates an unresolved static setter. |
| 2557 generateThrowNoSuchMethod(send, | 2562 generateThrowNoSuchMethod( |
| 2558 getTargetName(element, 'set'), | 2563 location, |
| 2559 argumentNodes: send.arguments); | 2564 getTargetName(element, 'set'), |
| 2565 argumentNodes: (send == null ? const Link<Node>() : send.arguments)); |
| 2560 } else { | 2566 } else { |
| 2561 stack.add(value); | 2567 stack.add(value); |
| 2562 // If the value does not already have a name, give it here. | 2568 // If the value does not already have a name, give it here. |
| 2563 if (value.sourceElement == null) { | 2569 if (value.sourceElement == null) { |
| 2564 value.sourceElement = element; | 2570 value.sourceElement = element; |
| 2565 } | 2571 } |
| 2566 HInstruction checked = potentiallyCheckType( | 2572 HInstruction checked = potentiallyCheckType( |
| 2567 value, element.computeType(compiler)); | 2573 value, element.computeType(compiler)); |
| 2568 if (!identical(checked, value)) { | 2574 if (!identical(checked, value)) { |
| 2569 pop(); | 2575 pop(); |
| (...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4114 HInstruction buildCondition() { | 4120 HInstruction buildCondition() { |
| 4115 Selector selector = compiler.moveNextSelector; | 4121 Selector selector = compiler.moveNextSelector; |
| 4116 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); | 4122 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); |
| 4117 return popBoolified(); | 4123 return popBoolified(); |
| 4118 } | 4124 } |
| 4119 void buildBody() { | 4125 void buildBody() { |
| 4120 Selector call = compiler.currentSelector; | 4126 Selector call = compiler.currentSelector; |
| 4121 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); | 4127 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); |
| 4122 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); | 4128 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); |
| 4123 | 4129 |
| 4124 Element variable = elements[node.declaredIdentifier]; | 4130 Node identifier = node.declaredIdentifier; |
| 4125 Selector selector = elements.getSelector(node.declaredIdentifier); | 4131 Element variable = elements[identifier]; |
| 4132 Selector selector = elements.getSelector(identifier); |
| 4126 | 4133 |
| 4127 HInstruction oldVariable = pop(); | 4134 HInstruction value = pop(); |
| 4128 if (Elements.isUnresolved(variable)) { | 4135 if (identifier.asSend() != null |
| 4129 if (Elements.isInStaticContext(currentElement)) { | 4136 && Elements.isInstanceSend(identifier, elements)) { |
| 4130 generateThrowNoSuchMethod( | 4137 HInstruction receiver = generateInstanceSendReceiver(identifier); |
| 4131 node.declaredIdentifier, | 4138 assert(receiver != null); |
| 4132 'set ${selector.name.slowToString()}', | 4139 generateInstanceSetterWithCompiledReceiver( |
| 4133 argumentValues: <HInstruction>[oldVariable]); | 4140 null, |
| 4134 } else { | 4141 receiver, |
| 4135 // The setter may have been defined in a subclass. | 4142 value, |
| 4136 generateInstanceSetterWithCompiledReceiver( | 4143 selector: selector, |
| 4137 null, | 4144 location: identifier); |
| 4138 localsHandler.readThis(), | |
| 4139 oldVariable, | |
| 4140 selector: selector, | |
| 4141 location: node.declaredIdentifier); | |
| 4142 } | |
| 4143 pop(); | |
| 4144 } else { | 4145 } else { |
| 4145 localsHandler.updateLocal(variable, oldVariable); | 4146 generateNonInstanceSetter(null, variable, value, location: identifier); |
| 4146 } | 4147 } |
| 4148 pop(); // Pop the value pushed by the setter call. |
| 4147 | 4149 |
| 4148 visit(node.body); | 4150 visit(node.body); |
| 4149 } | 4151 } |
| 4150 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); | 4152 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); |
| 4151 } | 4153 } |
| 4152 | 4154 |
| 4153 visitLabel(Label node) { | 4155 visitLabel(Label node) { |
| 4154 compiler.internalError('SsaBuilder.visitLabel', node: node); | 4156 compiler.internalError('SsaBuilder.visitLabel', node: node); |
| 4155 } | 4157 } |
| 4156 | 4158 |
| (...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5235 new HSubGraphBlockInformation(elseBranch.graph)); | 5237 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5236 | 5238 |
| 5237 HBasicBlock conditionStartBlock = conditionBranch.block; | 5239 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5238 conditionStartBlock.setBlockFlow(info, joinBlock); | 5240 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5239 SubGraph conditionGraph = conditionBranch.graph; | 5241 SubGraph conditionGraph = conditionBranch.graph; |
| 5240 HIf branch = conditionGraph.end.last; | 5242 HIf branch = conditionGraph.end.last; |
| 5241 assert(branch is HIf); | 5243 assert(branch is HIf); |
| 5242 branch.blockInformation = conditionStartBlock.blockFlow; | 5244 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5243 } | 5245 } |
| 5244 } | 5246 } |
| OLD | NEW |