Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |