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

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: Additional problems found during testing. 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 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after
2443 generateThrowNoSuchMethod(send, 2443 generateThrowNoSuchMethod(send,
2444 getTargetName(element, 'get'), 2444 getTargetName(element, 'get'),
2445 argumentNodes: const Link<Node>()); 2445 argumentNodes: const Link<Node>());
2446 } else { 2446 } else {
2447 stack.add(localsHandler.readLocal(element)); 2447 stack.add(localsHandler.readLocal(element));
2448 } 2448 }
2449 } 2449 }
2450 2450
2451 void generateInstanceSetterWithCompiledReceiver(Send send, 2451 void generateInstanceSetterWithCompiledReceiver(Send send,
2452 HInstruction receiver, 2452 HInstruction receiver,
2453 HInstruction value) { 2453 HInstruction value,
2454 assert(Elements.isInstanceSend(send, elements)); 2454 {Selector selector,
2455 Selector selector = elements.getSelector(send); 2455 Node location}) {
2456 assert(send == null || Elements.isInstanceSend(send, elements));
2457 if (selector == null) {
2458 assert(send != null);
2459 selector = elements.getSelector(send);
2460 }
2461 if (location == null) {
2462 assert(send != null);
2463 location = send;
2464 }
2456 assert(selector.isSetter()); 2465 assert(selector.isSetter());
2457 SourceString setterName = selector.name;
2458 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector); 2466 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector);
2459 Set<ClassElement> interceptedClasses = 2467 Set<ClassElement> interceptedClasses =
2460 backend.getInterceptedClassesOn(setterName); 2468 backend.getInterceptedClassesOn(selector.name);
2469 HInstruction instruction;
2461 if (interceptedClasses != null) { 2470 if (interceptedClasses != null) {
2462 // If we're using an interceptor class, emit a call to the 2471 // If we're using an interceptor class, emit a call to the
2463 // getInterceptor method and then the actual dynamic call on the 2472 // getInterceptor method and then the actual dynamic call on the
2464 // interceptor object. 2473 // interceptor object.
2465 HInstruction instruction = 2474 instruction = invokeInterceptor(interceptedClasses, receiver, send);
2466 invokeInterceptor(interceptedClasses, receiver, send);
2467 instruction = new HInvokeDynamicSetter( 2475 instruction = new HInvokeDynamicSetter(
2468 selector, null, instruction, receiver, !hasSetter); 2476 selector, null, instruction, receiver, !hasSetter);
2469 // Add the value as an argument to the setter call on the 2477 // Add the value as an argument to the setter call on the
2470 // interceptor. 2478 // interceptor.
2471 instruction.inputs.add(value); 2479 instruction.inputs.add(value);
2472 addWithPosition(instruction, send);
2473 } else { 2480 } else {
2474 addWithPosition( 2481 instruction = new HInvokeDynamicSetter(
2475 new HInvokeDynamicSetter(selector, null, receiver, value, !hasSetter), 2482 selector, null, receiver, value, !hasSetter);
2476 send);
2477 } 2483 }
2484 addWithPosition(instruction, location);
2478 stack.add(value); 2485 stack.add(value);
2479 } 2486 }
2480 2487
2481 void generateNonInstanceSetter(SendSet send, 2488 void generateNonInstanceSetter(SendSet send,
2482 Element element, 2489 Element element,
2483 HInstruction value) { 2490 HInstruction value) {
2484 assert(!Elements.isInstanceSend(send, elements)); 2491 assert(!Elements.isInstanceSend(send, elements));
2485 if (Elements.isStaticOrTopLevelField(element)) { 2492 if (Elements.isStaticOrTopLevelField(element)) {
2486 if (element.isSetter()) { 2493 if (element.isSetter()) {
2487 HStatic target = new HStatic(element); 2494 HStatic target = new HStatic(element);
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
4020 // Generate a structure equivalent to: 4027 // Generate a structure equivalent to:
4021 // Iterator<E> $iter = <iterable>.iterator; 4028 // Iterator<E> $iter = <iterable>.iterator;
4022 // while ($iter.moveNext()) { 4029 // while ($iter.moveNext()) {
4023 // E <declaredIdentifier> = $iter.current; 4030 // E <declaredIdentifier> = $iter.current;
4024 // <body> 4031 // <body>
4025 // } 4032 // }
4026 4033
4027 // The iterator is shared between initializer, condition and body. 4034 // The iterator is shared between initializer, condition and body.
4028 HInstruction iterator; 4035 HInstruction iterator;
4029 void buildInitializer() { 4036 void buildInitializer() {
4030 Selector selector = elements.getIteratorSelector(node); 4037 Selector selector = compiler.iteratorSelector;
4031 Set<ClassElement> interceptedClasses = 4038 Set<ClassElement> interceptedClasses =
4032 backend.getInterceptedClassesOn(selector.name); 4039 backend.getInterceptedClassesOn(selector.name);
4033 visit(node.expression); 4040 visit(node.expression);
4034 HInstruction receiver = pop(); 4041 HInstruction receiver = pop();
4035 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 4042 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
4036 if (interceptedClasses == null) { 4043 if (interceptedClasses == null) {
4037 iterator = 4044 iterator =
4038 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter); 4045 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter);
4039 } else { 4046 } else {
4040 HInterceptor interceptor = 4047 HInterceptor interceptor =
4041 invokeInterceptor(interceptedClasses, receiver, null); 4048 invokeInterceptor(interceptedClasses, receiver, null);
4042 iterator = 4049 iterator =
4043 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter); 4050 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter);
4044 // Add the receiver as an argument to the getter call on the 4051 // Add the receiver as an argument to the getter call on the
4045 // interceptor. 4052 // interceptor.
4046 iterator.inputs.add(receiver); 4053 iterator.inputs.add(receiver);
4047 } 4054 }
4048 add(iterator); 4055 add(iterator);
4049 } 4056 }
4050 HInstruction buildCondition() { 4057 HInstruction buildCondition() {
4051 Selector selector = elements.getMoveNextSelector(node); 4058 Selector selector = compiler.moveNextSelector;
4052 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); 4059 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator]));
4053 return popBoolified(); 4060 return popBoolified();
4054 } 4061 }
4055 void buildBody() { 4062 void buildBody() {
4056 Selector call = elements.getCurrentSelector(node); 4063 Selector call = compiler.currentSelector;
4057 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); 4064 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call);
4058 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); 4065 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter));
4059 4066
4060 Element variable; 4067 Element variable = elements[node.declaredIdentifier];
4061 if (node.declaredIdentifier.asSend() != null) { 4068 Selector selector = elements.getSelector(node.declaredIdentifier);
4062 variable = elements[node.declaredIdentifier]; 4069
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(); 4070 HInstruction oldVariable = pop();
4069 if (variable.isErroneous()) { 4071 if (Elements.isUnresolved(variable)) {
4070 generateThrowNoSuchMethod(node, 4072 if (Elements.isInStaticContext(currentElement)) {
4071 getTargetName(variable, 'set'), 4073 generateThrowNoSuchMethod(node.declaredIdentifier,
4072 argumentValues: <HInstruction>[oldVariable]); 4074 'set ${selector.name.slowToString()}',
4075 argumentValues: <HInstruction>[oldVariable]) ;
kasperl 2013/04/12 07:33:48 Long line.
4076 } else {
4077 // The setter may have been defined in a subclass.
4078 generateInstanceSetterWithCompiledReceiver(
4079 null,
4080 localsHandler.readThis(),
4081 oldVariable,
4082 selector: selector,
4083 location: node.declaredIdentifier);
4084 }
4073 pop(); 4085 pop();
4074 } else { 4086 } else {
4075 localsHandler.updateLocal(variable, oldVariable); 4087 localsHandler.updateLocal(variable, oldVariable);
4076 } 4088 }
4077 4089
4078 visit(node.body); 4090 visit(node.body);
4079 } 4091 }
4080 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); 4092 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
4081 } 4093 }
4082 4094
(...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after
5162 new HSubGraphBlockInformation(elseBranch.graph)); 5174 new HSubGraphBlockInformation(elseBranch.graph));
5163 5175
5164 HBasicBlock conditionStartBlock = conditionBranch.block; 5176 HBasicBlock conditionStartBlock = conditionBranch.block;
5165 conditionStartBlock.setBlockFlow(info, joinBlock); 5177 conditionStartBlock.setBlockFlow(info, joinBlock);
5166 SubGraph conditionGraph = conditionBranch.graph; 5178 SubGraph conditionGraph = conditionBranch.graph;
5167 HIf branch = conditionGraph.end.last; 5179 HIf branch = conditionGraph.end.last;
5168 assert(branch is HIf); 5180 assert(branch is HIf);
5169 branch.blockInformation = conditionStartBlock.blockFlow; 5181 branch.blockInformation = conditionStartBlock.blockFlow;
5170 } 5182 }
5171 } 5183 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698