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

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

Issue 12207081: Add a type kind to TypedSelector. A typed selector can either be (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // [readLocal] uses the [boxElement] to find its box. By replacing it 241 // [readLocal] uses the [boxElement] to find its box. By replacing it
242 // behind its back we can still get to the old values. 242 // behind its back we can still get to the old values.
243 updateLocal(boxElement, oldBox); 243 updateLocal(boxElement, oldBox);
244 HInstruction oldValue = readLocal(boxedVariable); 244 HInstruction oldValue = readLocal(boxedVariable);
245 updateLocal(boxElement, newBox); 245 updateLocal(boxElement, newBox);
246 updateLocal(boxedVariable, oldValue); 246 updateLocal(boxedVariable, oldValue);
247 } 247 }
248 updateLocal(boxElement, newBox); 248 updateLocal(boxElement, newBox);
249 } 249 }
250 250
251 HType cachedTypeOfThis;
252
253 HType computeTypeOfThis() {
254 Element element = closureData.thisElement;
255 ClassElement cls = element.enclosingElement.getEnclosingClass();
256 Compiler compiler = builder.compiler;
257 DartType type = cls.computeType(compiler);
258 if (compiler.world.isUsedAsMixin(cls)) {
259 // If the enclosing class is used as a mixin, [:this:] can be
260 // of the class that mixins the enclosing class. These two
261 // classes do not have a subclass relationship, so, for
262 // simplicity, we mark the type as an interface type.
263 cachedTypeOfThis = new HType.nonNullSubtype(type, compiler);
264 } else {
265 cachedTypeOfThis = new HType.nonNullSubclass(type, compiler);
266 }
267 return cachedTypeOfThis;
268 }
269
251 /** 270 /**
252 * Documentation wanted -- johnniwinther 271 * Documentation wanted -- johnniwinther
253 * 272 *
254 * Invariant: [function] must be an implementation element. 273 * Invariant: [function] must be an implementation element.
255 */ 274 */
256 void startFunction(Element element, Expression node) { 275 void startFunction(Element element, Expression node) {
257 assert(invariant(node, element.isImplementation)); 276 assert(invariant(node, element.isImplementation));
258 Compiler compiler = builder.compiler; 277 Compiler compiler = builder.compiler;
259 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 278 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
260 element, node, builder.elements); 279 element, node, builder.elements);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 // Inside closure redirect references to itself to [:this:]. 313 // Inside closure redirect references to itself to [:this:].
295 HThis thisInstruction = new HThis(closureData.thisElement); 314 HThis thisInstruction = new HThis(closureData.thisElement);
296 builder.graph.thisInstruction = thisInstruction; 315 builder.graph.thisInstruction = thisInstruction;
297 builder.graph.entry.addAtEntry(thisInstruction); 316 builder.graph.entry.addAtEntry(thisInstruction);
298 updateLocal(closureData.closureElement, thisInstruction); 317 updateLocal(closureData.closureElement, thisInstruction);
299 } else if (element.isInstanceMember() 318 } else if (element.isInstanceMember()
300 || element.isGenerativeConstructor()) { 319 || element.isGenerativeConstructor()) {
301 // Once closures have been mapped to classes their instance members might 320 // Once closures have been mapped to classes their instance members might
302 // not have any thisElement if the closure was created inside a static 321 // not have any thisElement if the closure was created inside a static
303 // context. 322 // context.
304 ClassElement cls = element.getEnclosingClass(); 323 HThis thisInstruction = new HThis(
305 DartType type = cls.computeType(builder.compiler); 324 closureData.thisElement, computeTypeOfThis());
306 HThis thisInstruction = new HThis(closureData.thisElement,
307 new HBoundedType.nonNull(type));
308 builder.graph.thisInstruction = thisInstruction; 325 builder.graph.thisInstruction = thisInstruction;
309 builder.graph.entry.addAtEntry(thisInstruction); 326 builder.graph.entry.addAtEntry(thisInstruction);
310 directLocals[closureData.thisElement] = thisInstruction; 327 directLocals[closureData.thisElement] = thisInstruction;
311 } 328 }
312 329
313 // If this method is an intercepted method, add the extra 330 // If this method is an intercepted method, add the extra
314 // parameter to it, that is the actual receiver. 331 // parameter to it, that is the actual receiver.
315 ClassElement cls = element.getEnclosingClass(); 332 ClassElement cls = element.getEnclosingClass();
316 if (builder.backend.isInterceptorClass(cls)) { 333 if (builder.backend.isInterceptorClass(cls)) {
317 HType type = HType.UNKNOWN; 334 HType type = HType.UNKNOWN;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 return lookup; 426 return lookup;
410 } else { 427 } else {
411 assert(isUsedInTry(element)); 428 assert(isUsedInTry(element));
412 HLocalValue local = getLocal(element); 429 HLocalValue local = getLocal(element);
413 HInstruction variable = new HLocalGet(element, local); 430 HInstruction variable = new HLocalGet(element, local);
414 builder.add(variable); 431 builder.add(variable);
415 return variable; 432 return variable;
416 } 433 }
417 } 434 }
418 435
419 HType cachedTypeOfThis;
420
421 HInstruction readThis() { 436 HInstruction readThis() {
422 HInstruction res = readLocal(closureData.thisElement); 437 HInstruction res = readLocal(closureData.thisElement);
423 if (res.guaranteedType == null) { 438 if (res.guaranteedType == null) {
424 if (cachedTypeOfThis == null) { 439 if (cachedTypeOfThis == null) {
425 assert(closureData.isClosure()); 440 computeTypeOfThis();
426 Element element = closureData.thisElement;
427 ClassElement cls = element.enclosingElement.getEnclosingClass();
428 DartType type = cls.computeType(builder.compiler);
429 cachedTypeOfThis = new HBoundedType.nonNull(type);
430 } 441 }
431 res.guaranteedType = cachedTypeOfThis; 442 res.guaranteedType = cachedTypeOfThis;
432 } 443 }
433 return res; 444 return res;
434 } 445 }
435 446
436 HLocalValue getLocal(Element element) { 447 HLocalValue getLocal(Element element) {
437 // If the element is a parameter, we already have a 448 // If the element is a parameter, we already have a
438 // HParameterValue for it. We cannot create another one because 449 // HParameterValue for it. We cannot create another one because
439 // it could then have another name than the real parameter. And 450 // it could then have another name than the real parameter. And
(...skipping 3573 matching lines...) Expand 10 before | Expand all | Expand 10 after
4013 List<HInstruction> inputs = <HInstruction>[]; 4024 List<HInstruction> inputs = <HInstruction>[];
4014 for (Link<Node> link = node.entries.nodes; 4025 for (Link<Node> link = node.entries.nodes;
4015 !link.isEmpty; 4026 !link.isEmpty;
4016 link = link.tail) { 4027 link = link.tail) {
4017 visit(link.head); 4028 visit(link.head);
4018 inputs.addLast(pop()); 4029 inputs.addLast(pop());
4019 inputs.addLast(pop()); 4030 inputs.addLast(pop());
4020 } 4031 }
4021 HLiteralList keyValuePairs = new HLiteralList(inputs); 4032 HLiteralList keyValuePairs = new HLiteralList(inputs);
4022 add(keyValuePairs); 4033 add(keyValuePairs);
4034 DartType mapType = compiler.mapLiteralClass.computeType(compiler);
4035 // TODO(ngeoffray): Use the actual implementation type of a map
4036 // literal.
4023 pushInvokeHelper1(backend.getMapMaker(), keyValuePairs, 4037 pushInvokeHelper1(backend.getMapMaker(), keyValuePairs,
4024 new HType.fromBoundedType(compiler.mapClass.computeType(compiler), 4038 new HType.nonNullSubtype(mapType, compiler));
4025 compiler,
4026 false));
4027 } 4039 }
4028 4040
4029 visitLiteralMapEntry(LiteralMapEntry node) { 4041 visitLiteralMapEntry(LiteralMapEntry node) {
4030 visit(node.value); 4042 visit(node.value);
4031 visit(node.key); 4043 visit(node.key);
4032 } 4044 }
4033 4045
4034 visitNamedArgument(NamedArgument node) { 4046 visitNamedArgument(NamedArgument node) {
4035 visit(node.expression); 4047 visit(node.expression);
4036 } 4048 }
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
4604 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 4616 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
4605 } 4617 }
4606 4618
4607 visitTypeVariable(TypeVariable node) { 4619 visitTypeVariable(TypeVariable node) {
4608 compiler.internalError('SsaBuilder.visitTypeVariable'); 4620 compiler.internalError('SsaBuilder.visitTypeVariable');
4609 } 4621 }
4610 4622
4611 HType mapBaseType(BaseType baseType) { 4623 HType mapBaseType(BaseType baseType) {
4612 if (!baseType.isClass()) return HType.UNKNOWN; 4624 if (!baseType.isClass()) return HType.UNKNOWN;
4613 ClassBaseType classBaseType = baseType; 4625 ClassBaseType classBaseType = baseType;
4614 return new HType.fromBoundedType( 4626 ClassElement cls = classBaseType.element;
4615 classBaseType.element.computeType(compiler), compiler, false); 4627 // Special case the list and map classes that are used as types
4628 // for literals in the type inferrer.
4629 if (cls == compiler.listClass) {
4630 return HType.READABLE_ARRAY;
4631 } else if (cls == compiler.mapClass) {
4632 // TODO(ngeoffray): get the actual implementation of a map
4633 // literal.
4634 return new HType.nonNullSubtype(
4635 compiler.mapLiteralClass.computeType(compiler), compiler);
4636 } else {
4637 return new HType.nonNullExactClass(
4638 cls.computeType(compiler), compiler);
4639 }
4616 } 4640 }
4617 4641
4618 HType mapInferredType(ConcreteType concreteType) { 4642 HType mapInferredType(ConcreteType concreteType) {
4619 if (concreteType == null) return HType.UNKNOWN; 4643 if (concreteType == null) return HType.UNKNOWN;
4620 HType ssaType = HType.CONFLICTING; 4644 HType ssaType = HType.CONFLICTING;
4621 for (BaseType baseType in concreteType.baseTypes) { 4645 for (BaseType baseType in concreteType.baseTypes) {
4622 ssaType = ssaType.union(mapBaseType(baseType), compiler); 4646 ssaType = ssaType.union(mapBaseType(baseType), compiler);
4623 } 4647 }
4624 assert(!ssaType.isConflicting()); 4648 assert(!ssaType.isConflicting());
4625 return ssaType; 4649 return ssaType;
4626 } 4650 }
4627 4651
4652 // [type] is either an instance of [DartType] or special objects
4653 // like [native.SpecialType.JsObject], or [native.SpecialType.JsArray].
4628 HType mapNativeType(type) { 4654 HType mapNativeType(type) {
4629 if (type == native.SpecialType.JsObject) { 4655 if (type == native.SpecialType.JsObject) {
4630 return new HBoundedType.exact( 4656 return new HType.nonNullExactClass(
4631 compiler.objectClass.computeType(compiler)); 4657 compiler.objectClass.computeType(compiler), compiler);
4632 } else if (type == native.SpecialType.JsArray) { 4658 } else if (type == native.SpecialType.JsArray) {
4633 return HType.READABLE_ARRAY; 4659 return HType.READABLE_ARRAY;
4634 } else { 4660 } else {
4635 return new HType.fromBoundedType(type, compiler, false); 4661 return new HType.nonNullSubclass(type, compiler);
4636 } 4662 }
4637 } 4663 }
4638 4664
4639 HType mapNativeBehaviorType(native.NativeBehavior nativeBehavior) { 4665 HType mapNativeBehaviorType(native.NativeBehavior nativeBehavior) {
4640 if (nativeBehavior.typesInstantiated.isEmpty) return HType.UNKNOWN; 4666 if (nativeBehavior.typesInstantiated.isEmpty) return HType.UNKNOWN;
4641 4667
4642 HType ssaType = HType.CONFLICTING; 4668 HType ssaType = HType.CONFLICTING;
4643 for (final type in nativeBehavior.typesInstantiated) { 4669 for (final type in nativeBehavior.typesInstantiated) {
4644 ssaType = ssaType.union(mapNativeType(type), compiler); 4670 ssaType = ssaType.union(mapNativeType(type), compiler);
4645 } 4671 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
5025 new HSubGraphBlockInformation(elseBranch.graph)); 5051 new HSubGraphBlockInformation(elseBranch.graph));
5026 5052
5027 HBasicBlock conditionStartBlock = conditionBranch.block; 5053 HBasicBlock conditionStartBlock = conditionBranch.block;
5028 conditionStartBlock.setBlockFlow(info, joinBlock); 5054 conditionStartBlock.setBlockFlow(info, joinBlock);
5029 SubGraph conditionGraph = conditionBranch.graph; 5055 SubGraph conditionGraph = conditionBranch.graph;
5030 HIf branch = conditionGraph.end.last; 5056 HIf branch = conditionGraph.end.last;
5031 assert(branch is HIf); 5057 assert(branch is HIf);
5032 branch.blockInformation = conditionStartBlock.blockFlow; 5058 branch.blockInformation = conditionStartBlock.blockFlow;
5033 } 5059 }
5034 } 5060 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698