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

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: 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) {
ngeoffray 2012/09/14 07:30:21 I believe you could move the creation of the strin
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': #"); 2663
2664 // Prepare the format strings for the reified type variables and the
2665 // runtime type, if necessary.
2666 String runtimeTypeString = "'${element.name.slowToString()}";
kasperl 2012/09/14 07:26:48 Move the computation of the runtimeTypeString into
2667 String typeVariablesString = '';
2668 bool firstVariable = true;
2669 int numberOfVariables = 0;
2670 element.typeVariables.forEach((TypeVariableType variable) {
2671 String name = variable.name.slowToString();
2672 String value = (numberOfVariables < rtiInputs.length) ? '#' : "'Dynamic'";
2673 if (runtimeTypeIsUsed) {
2674 if (firstVariable) {
2675 runtimeTypeString = "$runtimeTypeString<' + $value";
2676 } else {
2677 runtimeTypeString = "$runtimeTypeString + ', ' + $value";
2678 }
2679 }
2680 if (!firstVariable) {
2681 typeVariablesString = '$typeVariablesString, ';
2682 }
2683 typeVariablesString = "$typeVariablesString'$name': $value";
2684 firstVariable = false;
2685 numberOfVariables++;
2655 }); 2686 });
2687 if (classHasTypeVariables) {
2688 runtimeTypeString = "$runtimeTypeString + '>";
2689 }
2690 runtimeTypeString = "$runtimeTypeString'";
2656 2691
2657 String jsCode = '{ ${Strings.join(typeVariables, ', ')} }'; 2692 // Construct the runtime type information.
2658 HInstruction typeInfo = new HForeign(new LiteralDartString(jsCode), 2693 HInstruction runtimeType;
2659 new LiteralDartString('Object'), 2694 HInstruction typeInfo;
2660 inputs); 2695 String runtimeCode = '{';
kasperl 2012/09/14 07:26:48 Use StringBuffer.
2661 add(typeInfo); 2696 List<HInstruction> runtimeCodeInputs = <HInstruction>[];
2697 if (runtimeTypeIsUsed) {
2698 runtimeType =
2699 new HForeign(new LiteralDartString(runtimeTypeString),
2700 new LiteralDartString('String'),
2701 rtiInputs);
2702 add(runtimeType);
2703 runtimeCodeInputs.add(runtimeType);
2704 runtimeCode = runtimeCode.concat('runtimeType: #');
2705 }
2706 if (classHasTypeVariables) {
2707 if (runtimeTypeIsUsed) runtimeCode = runtimeCode.concat(', ');
2708 HInstruction typeInfo =
2709 new HForeign(new LiteralDartString(typeVariablesString),
2710 new LiteralDartString('String'),
2711 rtiInputs);
2712 add(typeInfo);
2713 runtimeCodeInputs.add(typeInfo);
2714 runtimeCode = runtimeCode.concat('#');
2715 }
2716 runtimeCode = runtimeCode.concat('}');
2717 HInstruction runtimeInfo =
2718 new HForeign(new LiteralDartString(runtimeCode),
2719 new LiteralDartString('Object'),
2720 runtimeCodeInputs);
2721 add(runtimeInfo);
2722
2723 // Set the runtime type information on the object.
2662 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); 2724 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo();
2663 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); 2725 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement);
2664 add(typeInfoSetter); 2726 add(typeInfoSetter);
2665 add(new HInvokeStatic(<HInstruction>[typeInfoSetter, newObject, typeInfo])); 2727 add(new HInvokeStatic(
2728 <HInstruction>[typeInfoSetter, newObject, runtimeInfo]));
2666 } 2729 }
2667 2730
2668 visitNewSend(Send node) { 2731 visitNewSend(Send node) {
2669 bool isListConstructor = false; 2732 bool isListConstructor = false;
2670 computeType(element) { 2733 computeType(element) {
2671 Element originalElement = elements[node]; 2734 Element originalElement = elements[node];
2672 if (originalElement.getEnclosingClass() === compiler.listClass) { 2735 if (originalElement.getEnclosingClass() === compiler.listClass) {
2673 isListConstructor = true; 2736 isListConstructor = true;
2674 if (node.arguments.isEmpty()) { 2737 if (node.arguments.isEmpty()) {
2675 return HType.EXTENDABLE_ARRAY; 2738 return HType.EXTENDABLE_ARRAY;
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after
4188 new HSubGraphBlockInformation(elseBranch.graph)); 4251 new HSubGraphBlockInformation(elseBranch.graph));
4189 4252
4190 HBasicBlock conditionStartBlock = conditionBranch.block; 4253 HBasicBlock conditionStartBlock = conditionBranch.block;
4191 conditionStartBlock.setBlockFlow(info, joinBlock); 4254 conditionStartBlock.setBlockFlow(info, joinBlock);
4192 SubGraph conditionGraph = conditionBranch.graph; 4255 SubGraph conditionGraph = conditionBranch.graph;
4193 HIf branch = conditionGraph.end.last; 4256 HIf branch = conditionGraph.end.last;
4194 assert(branch is HIf); 4257 assert(branch is HIf);
4195 branch.blockInformation = conditionStartBlock.blockFlow; 4258 branch.blockInformation = conditionStartBlock.blockFlow;
4196 } 4259 }
4197 } 4260 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698