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

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

Issue 18181009: Make closures in constructor initializers read type variables directly. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add VM crash and modify test. Created 7 years, 5 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 3258 matching lines...) Expand 10 before | Expand all | Expand 10 after
3269 HInstruction target = localsHandler.readThis(); 3269 HInstruction target = localsHandler.readThis();
3270 pushInvokeStatic(null, 3270 pushInvokeStatic(null,
3271 backend.getGetRuntimeTypeArgument(), 3271 backend.getGetRuntimeTypeArgument(),
3272 [target, 3272 [target,
3273 substitutionName, 3273 substitutionName,
3274 graph.addConstantInt(index, compiler)], 3274 graph.addConstantInt(index, compiler)],
3275 HType.UNKNOWN); 3275 HType.UNKNOWN);
3276 return pop(); 3276 return pop();
3277 } 3277 }
3278 3278
3279 // TODO(karlklose): this is needed to avoid a bug where the resolved type is
3280 // not stored on a type annotation in the closure translator. Remove when
ngeoffray 2013/07/12 12:09:25 Not sure I understand this comment. What does it m
karlklose 2013/07/12 12:22:54 The wording isn't the best, I agree. With storing
ngeoffray 2013/07/12 12:27:39 So that's a bug in the resolver?
3281 // fixed.
3282 bool hasDirectLocal(Element element) {
3283 return !localsHandler.isAccessedDirectly(element) ||
3284 localsHandler.directLocals[element] != null;
3285 }
3286
3279 /** 3287 /**
3280 * Helper to create an instruction that gets the value of a type variable. 3288 * Helper to create an instruction that gets the value of a type variable.
3281 */ 3289 */
3282 HInstruction addTypeVariableReference(TypeVariableType type) { 3290 HInstruction addTypeVariableReference(TypeVariableType type) {
3283 Element member = currentElement; 3291 Element member = currentElement;
3284 bool isClosure = member.enclosingElement.isClosure(); 3292 bool isClosure = member.enclosingElement.isClosure();
3285 if (isClosure) { 3293 if (isClosure) {
3286 ClosureClassElement closureClass = member.enclosingElement; 3294 ClosureClassElement closureClass = member.enclosingElement;
3287 member = closureClass.methodElement; 3295 member = closureClass.methodElement;
3288 member = member.getOutermostEnclosingMemberOrTopLevel(); 3296 member = member.getOutermostEnclosingMemberOrTopLevel();
3289 } 3297 }
3290 bool isInConstructorContext = member.isConstructor() || 3298 bool isInConstructorContext = member.isConstructor() ||
3291 member.isGenerativeConstructorBody() || 3299 member.isGenerativeConstructorBody();
3292 member.isField();
3293 if (isClosure) { 3300 if (isClosure) {
3294 if (member.isFactoryConstructor()) { 3301 if (member.isFactoryConstructor() ||
3302 (isInConstructorContext && hasDirectLocal(type.element))) {
3295 // The type variable is used from a closure in a factory constructor. 3303 // The type variable is used from a closure in a factory constructor.
3296 // The value of the type argument is stored as a local on the closure 3304 // The value of the type argument is stored as a local on the closure
3297 // itself. 3305 // itself.
3298 return localsHandler.readLocal(type.element); 3306 return localsHandler.readLocal(type.element);
3299 } else if (member.isFunction() || 3307 } else if (member.isFunction() ||
3300 member.isGetter() || 3308 member.isGetter() ||
3301 member.isSetter() || 3309 member.isSetter() ||
3302 member.isConstructor() || 3310 isInConstructorContext) {
3303 member.isGenerativeConstructorBody()) {
3304 // The type variable is stored on the "enclosing object" and needs to be 3311 // The type variable is stored on the "enclosing object" and needs to be
3305 // accessed using the this-reference in the closure. 3312 // accessed using the this-reference in the closure.
3306 return readTypeVariable(member.getEnclosingClass(), type.element); 3313 return readTypeVariable(member.getEnclosingClass(), type.element);
3307 } else { 3314 } else {
3308 assert(member.isField()); 3315 assert(member.isField());
3309 // The type variable is stored in a parameter of the method. 3316 // The type variable is stored in a parameter of the method.
3310 return localsHandler.readLocal(type.element); 3317 return localsHandler.readLocal(type.element);
3311 } 3318 }
3312 } else if (isInConstructorContext) { 3319 } else if (isInConstructorContext || member.isField()) {
3313 // The type variable is stored in a parameter of the method. 3320 // The type variable is stored in a parameter of the method.
3314 return localsHandler.readLocal(type.element); 3321 return localsHandler.readLocal(type.element);
3315 } else if (member.isInstanceMember()) { 3322 } else if (member.isInstanceMember()) {
3316 // The type variable is stored on the object. 3323 // The type variable is stored on the object.
3317 return readTypeVariable(member.getEnclosingClass(), 3324 return readTypeVariable(member.getEnclosingClass(),
3318 type.element); 3325 type.element);
3319 } else { 3326 } else {
3320 // TODO(ngeoffray): Match the VM behavior and throw an 3327 // TODO(ngeoffray): Match the VM behavior and throw an
3321 // exception at runtime. 3328 // exception at runtime.
3322 compiler.cancel('Unimplemented unresolved type variable', 3329 compiler.cancel('Unimplemented unresolved type variable',
(...skipping 2108 matching lines...) Expand 10 before | Expand all | Expand 10 after
5431 new HSubGraphBlockInformation(elseBranch.graph)); 5438 new HSubGraphBlockInformation(elseBranch.graph));
5432 5439
5433 HBasicBlock conditionStartBlock = conditionBranch.block; 5440 HBasicBlock conditionStartBlock = conditionBranch.block;
5434 conditionStartBlock.setBlockFlow(info, joinBlock); 5441 conditionStartBlock.setBlockFlow(info, joinBlock);
5435 SubGraph conditionGraph = conditionBranch.graph; 5442 SubGraph conditionGraph = conditionBranch.graph;
5436 HIf branch = conditionGraph.end.last; 5443 HIf branch = conditionGraph.end.last;
5437 assert(branch is HIf); 5444 assert(branch is HIf);
5438 branch.blockInformation = conditionStartBlock.blockFlow; 5445 branch.blockInformation = conditionStartBlock.blockFlow;
5439 } 5446 }
5440 } 5447 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/closure.dart ('k') | tests/language/closure_in_constructor_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698