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

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

Issue 10908142: Add runtimeType() to Object which returns canonicalized instances of Type. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Refactor. Created 8 years, 3 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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 includeBackendMembers: true, 1235 includeBackendMembers: true,
1236 includeSuperMembers: true, 1236 includeSuperMembers: true,
1237 f: (ClassElement enclosingClass, Element member) { 1237 f: (ClassElement enclosingClass, Element member) {
1238 constructorArguments.add( 1238 constructorArguments.add(
1239 potentiallyCheckType(fieldValues[member], member)); 1239 potentiallyCheckType(fieldValues[member], member));
1240 }); 1240 });
1241 1241
1242 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); 1242 HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
1243 add(newObject); 1243 add(newObject);
1244 1244
1245 // If the class has type variables, create the runtime type 1245 // Create the runtime type information, if needed.
1246 // information with the type parameters provided. 1246 if (needsRuntimeTypeInfo(classElement)) {
1247 if (!classElement.typeVariables.isEmpty()) { 1247 List<HInstruction> inputs = <HInstruction>[];
1248 List<HInstruction> rtiInputs = <HInstruction>[];
1249 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1248 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1250 rtiInputs.add(localsHandler.directLocals[typeVariable.element]); 1249 inputs.add(localsHandler.directLocals[typeVariable.element]);
1251 }); 1250 });
1252 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject); 1251 callSetRuntimeTypeInfo(classElement, inputs, newObject);
1253 } 1252 }
1254 1253
1255 // Generate calls to the constructor bodies. 1254 // Generate calls to the constructor bodies.
1256 for (int index = constructors.length - 1; index >= 0; index--) { 1255 for (int index = constructors.length - 1; index >= 0; index--) {
1257 FunctionElement constructor = constructors[index]; 1256 FunctionElement constructor = constructors[index];
1258 ConstructorBodyElement body = getConstructorBody(constructor); 1257 ConstructorBodyElement body = getConstructorBody(constructor);
1259 if (body === null) continue; 1258 if (body === null) continue;
1260 List bodyCallInputs = <HInstruction>[]; 1259 List bodyCallInputs = <HInstruction>[];
1261 bodyCallInputs.add(newObject); 1260 bodyCallInputs.add(newObject);
1262 int arity = body.functionSignature.parameterCount; 1261 int arity = body.functionSignature.parameterCount;
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 } else { 2630 } else {
2632 // The type variable is a type (e.g. int). 2631 // The type variable is a type (e.g. int).
2633 return graph.addConstantString( 2632 return graph.addConstantString(
2634 new LiteralDartString('$argument'), currentNode, constantSystem); 2633 new LiteralDartString('$argument'), currentNode, constantSystem);
2635 } 2634 }
2636 } 2635 }
2637 2636
2638 void handleListConstructor(InterfaceType type, 2637 void handleListConstructor(InterfaceType type,
2639 Node currentNode, 2638 Node currentNode,
2640 HInstruction newObject) { 2639 HInstruction newObject) {
2641 if (type.arguments.isEmpty()) return; 2640 if (!needsRuntimeTypeInfo(type.element)) return;
2642 List<HInstruction> inputs = <HInstruction>[]; 2641 List<HInstruction> inputs = <HInstruction>[];
2643 type.arguments.forEach((DartType argument) { 2642 type.arguments.forEach((DartType argument) {
2644 inputs.add(analyzeTypeArgument(argument, currentNode)); 2643 inputs.add(analyzeTypeArgument(argument, currentNode));
2645 }); 2644 });
2646 callSetRuntimeTypeInfo(type.element, inputs, newObject); 2645 callSetRuntimeTypeInfo(type.element, inputs, newObject);
2647 } 2646 }
2648 2647
2648 // Runtime type information is required if the type has type
2649 // variables or if the program calls [runtimeType].
2650 // TODO(karlklose): it is unnecessary for type variables that
2651 // can never match an is-Check.
2652 bool needsRuntimeTypeInfo(ClassElement element) {
2653 bool classHasTypeVariables = !element.typeVariables.isEmpty();
2654 bool runtimeTypeIsUsed = compiler.enabledRuntimeType;
2655 return (classHasTypeVariables || runtimeTypeIsUsed);
2656 }
2657
2649 void callSetRuntimeTypeInfo(ClassElement element, 2658 void callSetRuntimeTypeInfo(ClassElement element,
2650 List<HInstruction> inputs, 2659 List<HInstruction> rtiInputs,
2651 HInstruction newObject) { 2660 HInstruction newObject) {
2652 List<String> typeVariables = <String>[]; 2661 bool classHasTypeVariables = !element.typeVariables.isEmpty();
2653 element.typeVariables.forEach((TypeVariableType typeVariable) { 2662 bool runtimeTypeIsUsed = compiler.enabledRuntimeType;
2654 typeVariables.add("'$typeVariable': #");
2655 });
2656 2663
2657 String jsCode = '{ ${Strings.join(typeVariables, ', ')} }'; 2664 // Construct the runtime type information.
2658 HInstruction typeInfo = new HForeign(new LiteralDartString(jsCode), 2665 HInstruction runtimeType;
2659 new LiteralDartString('Object'), 2666 HInstruction typeInfo;
kasperl 2012/09/14 12:35:37 Isn't this typeInfo variable unused (shadowed)?
karlklose 2012/09/17 14:50:37 Done, removed.
2660 inputs); 2667 StringBuffer runtimeCode = new StringBuffer();
2661 add(typeInfo); 2668 List<HInstruction> runtimeCodeInputs = <HInstruction>[];
2669 if (runtimeTypeIsUsed) {
2670 String runtimeTypeString =
2671 RuntimeTypeInformation.generateRuntimeTypeString(element,
2672 rtiInputs.length);
2673 runtimeType =
kasperl 2012/09/14 12:35:37 Can't you declare runtimeType here?
karlklose 2012/09/17 14:50:37 Done.
2674 new HForeign(new LiteralDartString(runtimeTypeString),
2675 new LiteralDartString('String'),
2676 rtiInputs);
2677 add(runtimeType);
2678 runtimeCodeInputs.add(runtimeType);
2679 runtimeCode.add('runtimeType: #');
2680 }
2681 if (classHasTypeVariables) {
2682 if (runtimeTypeIsUsed) runtimeCode.add(', ');
2683 String typeVariablesString =
2684 RuntimeTypeInformation.generateTypeVariableString(element,
2685 rtiInputs.length);
2686 HInstruction typeInfo =
kasperl 2012/09/14 12:35:37 Add a helper for this creation of a new foreign st
karlklose 2012/09/17 14:50:37 Done.
2687 new HForeign(new LiteralDartString(typeVariablesString),
2688 new LiteralDartString('String'),
2689 rtiInputs);
2690 add(typeInfo);
2691 runtimeCodeInputs.add(typeInfo);
2692 runtimeCode.add('#');
2693 }
2694 HInstruction runtimeInfo =
2695 new HForeign(new LiteralDartString("{$runtimeCode}"),
2696 new LiteralDartString('Object'),
2697 runtimeCodeInputs);
2698 add(runtimeInfo);
2699
2700 // Set the runtime type information on the object.
2662 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); 2701 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo();
2663 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); 2702 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement);
2664 add(typeInfoSetter); 2703 add(typeInfoSetter);
2665 add(new HInvokeStatic(<HInstruction>[typeInfoSetter, newObject, typeInfo])); 2704 add(new HInvokeStatic(
2705 <HInstruction>[typeInfoSetter, newObject, runtimeInfo]));
2666 } 2706 }
2667 2707
2668 visitNewSend(Send node) { 2708 visitNewSend(Send node) {
2669 bool isListConstructor = false; 2709 bool isListConstructor = false;
2670 computeType(element) { 2710 computeType(element) {
2671 Element originalElement = elements[node]; 2711 Element originalElement = elements[node];
2672 if (originalElement.getEnclosingClass() === compiler.listClass) { 2712 if (originalElement.getEnclosingClass() === compiler.listClass) {
2673 isListConstructor = true; 2713 isListConstructor = true;
2674 if (node.arguments.isEmpty()) { 2714 if (node.arguments.isEmpty()) {
2675 return HType.EXTENDABLE_ARRAY; 2715 return HType.EXTENDABLE_ARRAY;
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after
4188 new HSubGraphBlockInformation(elseBranch.graph)); 4228 new HSubGraphBlockInformation(elseBranch.graph));
4189 4229
4190 HBasicBlock conditionStartBlock = conditionBranch.block; 4230 HBasicBlock conditionStartBlock = conditionBranch.block;
4191 conditionStartBlock.setBlockFlow(info, joinBlock); 4231 conditionStartBlock.setBlockFlow(info, joinBlock);
4192 SubGraph conditionGraph = conditionBranch.graph; 4232 SubGraph conditionGraph = conditionBranch.graph;
4193 HIf branch = conditionGraph.end.last; 4233 HIf branch = conditionGraph.end.last;
4194 assert(branch is HIf); 4234 assert(branch is HIf);
4195 branch.blockInformation = conditionStartBlock.blockFlow; 4235 branch.blockInformation = conditionStartBlock.blockFlow;
4196 } 4236 }
4197 } 4237 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698