Chromium Code Reviews| 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 4009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4020 // Generate a structure equivalent to: | 4020 // Generate a structure equivalent to: |
| 4021 // Iterator<E> $iter = <iterable>.iterator; | 4021 // Iterator<E> $iter = <iterable>.iterator; |
| 4022 // while ($iter.moveNext()) { | 4022 // while ($iter.moveNext()) { |
| 4023 // E <declaredIdentifier> = $iter.current; | 4023 // E <declaredIdentifier> = $iter.current; |
| 4024 // <body> | 4024 // <body> |
| 4025 // } | 4025 // } |
| 4026 | 4026 |
| 4027 // The iterator is shared between initializer, condition and body. | 4027 // The iterator is shared between initializer, condition and body. |
| 4028 HInstruction iterator; | 4028 HInstruction iterator; |
| 4029 void buildInitializer() { | 4029 void buildInitializer() { |
| 4030 Selector selector = elements.getIteratorSelector(node); | 4030 Selector selector = compiler.iteratorSelector; |
| 4031 Set<ClassElement> interceptedClasses = | 4031 Set<ClassElement> interceptedClasses = |
| 4032 backend.getInterceptedClassesOn(selector.name); | 4032 backend.getInterceptedClassesOn(selector.name); |
| 4033 visit(node.expression); | 4033 visit(node.expression); |
| 4034 HInstruction receiver = pop(); | 4034 HInstruction receiver = pop(); |
| 4035 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 4035 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
| 4036 if (interceptedClasses == null) { | 4036 if (interceptedClasses == null) { |
| 4037 iterator = | 4037 iterator = |
| 4038 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter); | 4038 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter); |
| 4039 } else { | 4039 } else { |
| 4040 HInterceptor interceptor = | 4040 HInterceptor interceptor = |
| 4041 invokeInterceptor(interceptedClasses, receiver, null); | 4041 invokeInterceptor(interceptedClasses, receiver, null); |
| 4042 iterator = | 4042 iterator = |
| 4043 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter); | 4043 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter); |
| 4044 // Add the receiver as an argument to the getter call on the | 4044 // Add the receiver as an argument to the getter call on the |
| 4045 // interceptor. | 4045 // interceptor. |
| 4046 iterator.inputs.add(receiver); | 4046 iterator.inputs.add(receiver); |
| 4047 } | 4047 } |
| 4048 add(iterator); | 4048 add(iterator); |
| 4049 } | 4049 } |
| 4050 HInstruction buildCondition() { | 4050 HInstruction buildCondition() { |
| 4051 Selector selector = elements.getMoveNextSelector(node); | 4051 Selector selector = compiler.moveNextSelector; |
| 4052 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); | 4052 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); |
| 4053 return popBoolified(); | 4053 return popBoolified(); |
| 4054 } | 4054 } |
| 4055 void buildBody() { | 4055 void buildBody() { |
| 4056 Selector call = elements.getCurrentSelector(node); | 4056 Selector call = compiler.currentSelector; |
| 4057 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); | 4057 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); |
| 4058 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); | 4058 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); |
| 4059 | 4059 |
| 4060 Element variable; | 4060 Element variable = elements[node.declaredIdentifier]; |
| 4061 if (node.declaredIdentifier.asSend() != null) { | 4061 Selector selector = elements.getSelector(node.declaredIdentifier); |
| 4062 variable = elements[node.declaredIdentifier]; | 4062 |
| 4063 } else { | |
| 4064 assert(node.declaredIdentifier.asVariableDefinitions() != null); | |
| 4065 VariableDefinitions variableDefinitions = node.declaredIdentifier; | |
| 4066 variable = elements[variableDefinitions.definitions.nodes.head]; | |
| 4067 } | |
| 4068 HInstruction oldVariable = pop(); | 4063 HInstruction oldVariable = pop(); |
| 4069 if (variable.isErroneous()) { | 4064 if (Elements.isUnresolved(variable)) { |
| 4070 generateThrowNoSuchMethod(node, | 4065 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector); |
| 4071 getTargetName(variable, 'set'), | 4066 Set<ClassElement> interceptedClasses = |
| 4072 argumentValues: <HInstruction>[oldVariable]); | 4067 backend.getInterceptedClassesOn(selector.name); |
| 4073 pop(); | 4068 HInstruction receiver = localsHandler.readThis(); |
| 4069 if (interceptedClasses != null) { | |
| 4070 // If we're using an interceptor class, emit a call to the | |
| 4071 // getInterceptor method and then the actual dynamic call on the | |
| 4072 // interceptor object. | |
| 4073 HInstruction instruction = | |
| 4074 invokeInterceptor(interceptedClasses, receiver, null); | |
| 4075 instruction = new HInvokeDynamicSetter( | |
| 4076 selector, null, instruction, receiver, !hasSetter); | |
| 4077 // Add the value as an argument to the setter call on the | |
| 4078 // interceptor. | |
| 4079 instruction.inputs.add(oldVariable); | |
| 4080 addWithPosition(instruction, node.declaredIdentifier); | |
| 4081 } else { | |
| 4082 addWithPosition( | |
|
kasperl
2013/04/10 08:34:54
Maybe compute the instruction before calling addWi
ahe
2013/04/10 15:02:19
I rewrote generateInstanceSetterWithCompiledReceiv
| |
| 4083 new HInvokeDynamicSetter( | |
| 4084 selector, null, receiver, oldVariable, !hasSetter), | |
| 4085 node.declaredIdentifier); | |
| 4086 } | |
| 4074 } else { | 4087 } else { |
| 4075 localsHandler.updateLocal(variable, oldVariable); | 4088 localsHandler.updateLocal(variable, oldVariable); |
| 4076 } | 4089 } |
| 4077 | 4090 |
| 4078 visit(node.body); | 4091 visit(node.body); |
| 4079 } | 4092 } |
| 4080 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); | 4093 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); |
| 4081 } | 4094 } |
| 4082 | 4095 |
| 4083 visitLabel(Label node) { | 4096 visitLabel(Label node) { |
| (...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5162 new HSubGraphBlockInformation(elseBranch.graph)); | 5175 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5163 | 5176 |
| 5164 HBasicBlock conditionStartBlock = conditionBranch.block; | 5177 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5165 conditionStartBlock.setBlockFlow(info, joinBlock); | 5178 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5166 SubGraph conditionGraph = conditionBranch.graph; | 5179 SubGraph conditionGraph = conditionBranch.graph; |
| 5167 HIf branch = conditionGraph.end.last; | 5180 HIf branch = conditionGraph.end.last; |
| 5168 assert(branch is HIf); | 5181 assert(branch is HIf); |
| 5169 branch.blockInformation = conditionStartBlock.blockFlow; | 5182 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5170 } | 5183 } |
| 5171 } | 5184 } |
| OLD | NEW |