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

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

Issue 13866010: Correctly compile unresolved for-in loops. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added unit test Created 7 years, 8 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 4009 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698