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 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1313 f: (ClassElement enclosingClass, Element member) { | 1313 f: (ClassElement enclosingClass, Element member) { |
| 1314 constructorArguments.add( | 1314 constructorArguments.add( |
| 1315 potentiallyCheckType(fieldValues[member], member)); | 1315 potentiallyCheckType(fieldValues[member], member)); |
| 1316 }); | 1316 }); |
| 1317 | 1317 |
| 1318 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); | 1318 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
| 1319 add(newObject); | 1319 add(newObject); |
| 1320 | 1320 |
| 1321 // Create the runtime type information, if needed. | 1321 // Create the runtime type information, if needed. |
| 1322 InterfaceType type = classElement.computeType(compiler); | 1322 InterfaceType type = classElement.computeType(compiler); |
| 1323 List<HInstruction> inputs = <HInstruction>[]; | 1323 List<HInstruction> inputs = <HInstruction>[]; |
| 1324 if (compiler.world.needsRti(classElement)) { | 1324 if (compiler.world.needsRti(classElement)) { |
| 1325 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 1325 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1326 inputs.add(localsHandler.directLocals[typeVariable.element]); | 1326 inputs.add(localsHandler.directLocals[typeVariable.element]); |
| 1327 }); | 1327 }); |
| 1328 callSetRuntimeTypeInfo(classElement, inputs, newObject); | 1328 callSetRuntimeTypeInfo(classElement, inputs, newObject); |
| 1329 } | 1329 } |
| 1330 | 1330 |
| 1331 // Generate calls to the constructor bodies. | 1331 // Generate calls to the constructor bodies. |
| 1332 for (int index = constructors.length - 1; index >= 0; index--) { | 1332 for (int index = constructors.length - 1; index >= 0; index--) { |
| 1333 FunctionElement constructor = constructors[index]; | 1333 FunctionElement constructor = constructors[index]; |
| 1334 assert(invariant(functionElement, constructor.isImplementation)); | 1334 assert(invariant(functionElement, constructor.isImplementation)); |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2725 } else { | 2725 } else { |
| 2726 target = new HInvokeSuper(inputs); | 2726 target = new HInvokeSuper(inputs); |
| 2727 add(target); | 2727 add(target); |
| 2728 inputs = <HInstruction>[target]; | 2728 inputs = <HInstruction>[target]; |
| 2729 addDynamicSendArgumentsToList(node, inputs); | 2729 addDynamicSendArgumentsToList(node, inputs); |
| 2730 push(new HInvokeClosure(selector, inputs)); | 2730 push(new HInvokeClosure(selector, inputs)); |
| 2731 } | 2731 } |
| 2732 } | 2732 } |
| 2733 | 2733 |
| 2734 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { | 2734 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| 2735 if (argument.element.isTypeVariable()) { | 2735 // These variables are shared between invocations of the helper methods. |
| 2736 HInstruction typeInfo; | |
| 2737 StringBuffer template = new StringBuffer(); | |
| 2738 List<HInstruction> inputs = <HInstruction>[]; | |
| 2739 | |
| 2740 /** | |
| 2741 * Helper to create an instruction that gets the value of a type variable. | |
| 2742 */ | |
| 2743 void addTypeVariableReference(TypeVariableType type) { | |
| 2736 Element member = work.element; | 2744 Element member = work.element; |
| 2737 if (member.enclosingElement.isClosure()) { | 2745 if (member.enclosingElement.isClosure()) { |
| 2738 member = (member.enclosingElement as ClosureClassElement).methodElement; | 2746 ClosureClassElement closureClass = member.enclosingElement; |
| 2747 member = closureClass.methodElement; | |
| 2739 member = member.getOutermostEnclosingMemberOrTopLevel(); | 2748 member = member.getOutermostEnclosingMemberOrTopLevel(); |
| 2740 } | 2749 } |
| 2741 if (member.isFactoryConstructor()) { | 2750 if (member.isFactoryConstructor()) { |
| 2742 // The type variable is stored in a parameter of the | 2751 // The type variable is stored in a parameter of the factory. |
| 2743 // factory. | 2752 inputs.add(localsHandler.readLocal(type.element)); |
| 2744 return localsHandler.readLocal(argument.element); | |
| 2745 } else if (member.isInstanceMember() | 2753 } else if (member.isInstanceMember() |
| 2746 || member.isGenerativeConstructor()) { | 2754 || member.isGenerativeConstructor()) { |
| 2747 // The type variable is stored in [this]. | 2755 // The type variable is stored in [this]. |
| 2748 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), | 2756 if (typeInfo == null) { |
| 2749 localsHandler.readThis()); | 2757 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), |
| 2750 HInstruction typeInfo = pop(); | 2758 localsHandler.readThis()); |
| 2759 typeInfo = pop(); | |
| 2760 } | |
| 2751 HInstruction foreign = new HForeign( | 2761 HInstruction foreign = new HForeign( |
| 2752 new LiteralDartString('#.$argument'), | 2762 new LiteralDartString('#.${type.name.slowToString()}'), |
| 2753 new LiteralDartString('String'), | 2763 new LiteralDartString('String'), |
| 2754 <HInstruction>[typeInfo]); | 2764 <HInstruction>[typeInfo]); |
| 2755 add(foreign); | 2765 add(foreign); |
| 2756 return foreign; | 2766 inputs.add(foreign); |
| 2757 } else { | 2767 } else { |
| 2758 // TODO(ngeoffray): Match the VM behavior and throw an | 2768 // TODO(ngeoffray): Match the VM behavior and throw an |
| 2759 // exception at runtime. | 2769 // exception at runtime. |
| 2760 compiler.cancel('Unimplemented unresolved type variable', | 2770 compiler.cancel('Unimplemented unresolved type variable', |
| 2761 node: currentNode); | 2771 node: currentNode); |
| 2762 } | 2772 } |
| 2763 } else { | |
| 2764 // The type variable is a type (e.g. int). | |
| 2765 return graph.addConstantString( | |
| 2766 new LiteralDartString('$argument'), currentNode, constantSystem); | |
| 2767 } | 2773 } |
| 2774 | |
| 2775 /** | |
| 2776 * Helper to build an instruction that builds the string representation for | |
| 2777 * this type, where type variables are substituted by their runtime value. | |
| 2778 * | |
| 2779 * Examples: | |
| 2780 * Type Template Inputs | |
| 2781 * int 'int' [] | |
| 2782 * C<int, int> 'C<int, int>' [] | |
| 2783 * Var # [getRuntimeType(this).Var] | |
| 2784 * C<int, D<Var>> 'C<int, D<' + # + '>>' [getRuntimeType(this).Var] | |
| 2785 */ | |
| 2786 void buildTypeString(DartType type, {isInQuotes: false}) { | |
|
ngeoffray
2012/10/15 12:05:20
Could you move the non-ssa parts of this helper in
| |
| 2787 if (type is TypeVariableType) { | |
| 2788 addTypeVariableReference(type); | |
| 2789 template.add(isInQuotes ? "' + # +'" : "#"); | |
| 2790 } else if (type is InterfaceType) { | |
| 2791 bool isFirstVariable = true; | |
| 2792 InterfaceType interfaceType = type; | |
| 2793 bool hasTypeArguments = !interfaceType.arguments.isEmpty(); | |
| 2794 if (!isInQuotes) template.add("'"); | |
| 2795 template.add("${type.element.name.slowToString()}"); | |
| 2796 if (hasTypeArguments) { | |
| 2797 template.add("<"); | |
| 2798 for (DartType argument in interfaceType.arguments) { | |
| 2799 if (!isFirstVariable) { | |
| 2800 template.add(", "); | |
| 2801 } else { | |
| 2802 isFirstVariable = false; | |
| 2803 } | |
| 2804 buildTypeString(argument, isInQuotes: true); | |
| 2805 } | |
| 2806 template.add(">"); | |
| 2807 } | |
| 2808 if (!isInQuotes) template.add("'"); | |
| 2809 } else { | |
| 2810 assert(type is TypedefType); | |
| 2811 if (!isInQuotes) template.add("'"); | |
| 2812 template.add(argument.toString()); | |
| 2813 if (!isInQuotes) template.add("'"); | |
| 2814 } | |
| 2815 } | |
| 2816 | |
| 2817 buildTypeString(argument, isInQuotes: false); | |
| 2818 HInstruction result = | |
| 2819 new HForeign(new LiteralDartString("$template"), | |
| 2820 new LiteralDartString('String'), | |
| 2821 inputs); | |
| 2822 add(result); | |
| 2823 return result; | |
| 2768 } | 2824 } |
| 2769 | 2825 |
| 2770 void handleListConstructor(InterfaceType type, | 2826 void handleListConstructor(InterfaceType type, |
| 2771 Node currentNode, | 2827 Node currentNode, |
| 2772 HInstruction newObject) { | 2828 HInstruction newObject) { |
| 2773 if (!compiler.world.needsRti(type.element)) return; | 2829 if (!compiler.world.needsRti(type.element)) return; |
| 2774 List<HInstruction> inputs = <HInstruction>[]; | 2830 List<HInstruction> inputs = <HInstruction>[]; |
| 2775 type.arguments.forEach((DartType argument) { | 2831 type.arguments.forEach((DartType argument) { |
| 2776 inputs.add(analyzeTypeArgument(argument, currentNode)); | 2832 inputs.add(analyzeTypeArgument(argument, currentNode)); |
| 2777 }); | 2833 }); |
| (...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4398 new HSubGraphBlockInformation(elseBranch.graph)); | 4454 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4399 | 4455 |
| 4400 HBasicBlock conditionStartBlock = conditionBranch.block; | 4456 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4401 conditionStartBlock.setBlockFlow(info, joinBlock); | 4457 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4402 SubGraph conditionGraph = conditionBranch.graph; | 4458 SubGraph conditionGraph = conditionBranch.graph; |
| 4403 HIf branch = conditionGraph.end.last; | 4459 HIf branch = conditionGraph.end.last; |
| 4404 assert(branch is HIf); | 4460 assert(branch is HIf); |
| 4405 branch.blockInformation = conditionStartBlock.blockFlow; | 4461 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4406 } | 4462 } |
| 4407 } | 4463 } |
| OLD | NEW |