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 /** Helper to create an instruction to get the value of a type variable. */ | |
|
floitsch
2012/10/10 13:04:44
.. instruction that gets ...
karlklose
2012/10/10 13:44:45
Done.
| |
| 2741 void addTypeVariableReference(TypeVariableType type) { | |
| 2736 Element member = work.element; | 2742 Element member = work.element; |
| 2737 if (member.enclosingElement.isClosure()) { | 2743 if (member.enclosingElement.isClosure()) { |
| 2738 member = (member.enclosingElement as ClosureClassElement).methodElement; | 2744 ClosureClassElement closureClass = member.enclosingElement; |
| 2745 member = closureClass.methodElement; | |
| 2739 member = member.getOutermostEnclosingMemberOrTopLevel(); | 2746 member = member.getOutermostEnclosingMemberOrTopLevel(); |
| 2740 } | 2747 } |
| 2741 if (member.isFactoryConstructor()) { | 2748 if (member.isFactoryConstructor()) { |
| 2742 // The type variable is stored in a parameter of the | 2749 // The type variable is stored in a parameter of the factory. |
| 2743 // factory. | 2750 inputs.add(localsHandler.readLocal(type.element)); |
| 2744 return localsHandler.readLocal(argument.element); | |
| 2745 } else if (member.isInstanceMember() | 2751 } else if (member.isInstanceMember() |
| 2746 || member.isGenerativeConstructor()) { | 2752 || member.isGenerativeConstructor()) { |
| 2747 // The type variable is stored in [this]. | 2753 // The type variable is stored in [this]. |
| 2748 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), | 2754 if (typeInfo == null) { |
| 2755 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), | |
| 2749 localsHandler.readThis()); | 2756 localsHandler.readThis()); |
|
floitsch
2012/10/10 13:04:44
indentation.
karlklose
2012/10/10 13:44:45
Done.
| |
| 2750 HInstruction typeInfo = pop(); | 2757 typeInfo = pop(); |
| 2758 } | |
| 2751 HInstruction foreign = new HForeign( | 2759 HInstruction foreign = new HForeign( |
| 2752 new LiteralDartString('#.$argument'), | 2760 new LiteralDartString('#.${type.name.slowToString()}'), |
| 2753 new LiteralDartString('String'), | 2761 new LiteralDartString('String'), |
| 2754 <HInstruction>[typeInfo]); | 2762 <HInstruction>[typeInfo]); |
| 2755 add(foreign); | 2763 add(foreign); |
| 2756 return foreign; | 2764 inputs.add(foreign); |
| 2757 } else { | 2765 } else { |
| 2758 // TODO(ngeoffray): Match the VM behavior and throw an | 2766 // TODO(ngeoffray): Match the VM behavior and throw an |
| 2759 // exception at runtime. | 2767 // exception at runtime. |
| 2760 compiler.cancel('Unimplemented unresolved type variable', | 2768 compiler.cancel('Unimplemented unresolved type variable', |
| 2761 node: currentNode); | 2769 node: currentNode); |
| 2762 } | 2770 } |
| 2763 } else { | |
| 2764 // The type variable is a type (e.g. int). | |
| 2765 return graph.addConstantString( | |
| 2766 new LiteralDartString('$argument'), currentNode, constantSystem); | |
| 2767 } | 2771 } |
| 2772 | |
| 2773 /** | |
| 2774 * Helper to build an instruction that builds the string representation for | |
| 2775 * this type, where type variables are substituted by their runtime value. | |
|
floitsch
2012/10/10 13:04:44
Add example output (of the template).
karlklose
2012/10/10 13:44:45
Done.
| |
| 2776 */ | |
| 2777 void buildTypeString(DartType type, {isInQuotes: false}) { | |
| 2778 if (type is TypeVariableType) { | |
| 2779 addTypeVariableReference(type); | |
| 2780 template.add(isInQuotes ? "' + # +'" : "#"); | |
| 2781 } else if (type is InterfaceType) { | |
| 2782 bool isFirstVariable = true; | |
| 2783 InterfaceType interfaceType = type; | |
| 2784 bool hasTypeArguments = !interfaceType.arguments.isEmpty(); | |
| 2785 if (!isInQuotes) template.add("'"); | |
| 2786 template.add("${type.element.name.slowToString()}"); | |
| 2787 if (hasTypeArguments) { | |
| 2788 template.add("<"); | |
| 2789 for (DartType argument in interfaceType.arguments) { | |
| 2790 if (!isFirstVariable) { | |
| 2791 template.add(", "); | |
| 2792 } | |
| 2793 buildTypeString(argument, isInQuotes: true); | |
| 2794 isFirstVariable = false; | |
|
floitsch
2012/10/10 13:04:44
move isFirstVariable up into the if.
karlklose
2012/10/10 13:44:45
Done, moved into else branch.
| |
| 2795 } | |
| 2796 template.add(">"); | |
| 2797 } | |
| 2798 if (!isInQuotes) template.add("'"); | |
| 2799 } else { | |
|
floitsch
2012/10/10 13:04:44
add explanation what it must be. for example.
asse
karlklose
2012/10/10 13:44:45
Done.
| |
| 2800 if (!isInQuotes) template.add("'"); | |
| 2801 // TODO(karlklose): handle typedefs. | |
| 2802 template.add(argument.toString()); | |
| 2803 if (!isInQuotes) template.add("'"); | |
| 2804 } | |
| 2805 } | |
| 2806 | |
| 2807 buildTypeString(argument, isInQuotes: false); | |
| 2808 HInstruction result = | |
| 2809 new HForeign(new LiteralDartString("$template"), | |
| 2810 new LiteralDartString('String'), | |
| 2811 inputs); | |
| 2812 add(result); | |
| 2813 return result; | |
| 2768 } | 2814 } |
| 2769 | 2815 |
| 2770 void handleListConstructor(InterfaceType type, | 2816 void handleListConstructor(InterfaceType type, |
| 2771 Node currentNode, | 2817 Node currentNode, |
| 2772 HInstruction newObject) { | 2818 HInstruction newObject) { |
| 2773 if (!compiler.world.needsRti(type.element)) return; | 2819 if (!compiler.world.needsRti(type.element)) return; |
| 2774 List<HInstruction> inputs = <HInstruction>[]; | 2820 List<HInstruction> inputs = <HInstruction>[]; |
| 2775 type.arguments.forEach((DartType argument) { | 2821 type.arguments.forEach((DartType argument) { |
| 2776 inputs.add(analyzeTypeArgument(argument, currentNode)); | 2822 inputs.add(analyzeTypeArgument(argument, currentNode)); |
| 2777 }); | 2823 }); |
| (...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4398 new HSubGraphBlockInformation(elseBranch.graph)); | 4444 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4399 | 4445 |
| 4400 HBasicBlock conditionStartBlock = conditionBranch.block; | 4446 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4401 conditionStartBlock.setBlockFlow(info, joinBlock); | 4447 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4402 SubGraph conditionGraph = conditionBranch.graph; | 4448 SubGraph conditionGraph = conditionBranch.graph; |
| 4403 HIf branch = conditionGraph.end.last; | 4449 HIf branch = conditionGraph.end.last; |
| 4404 assert(branch is HIf); | 4450 assert(branch is HIf); |
| 4405 branch.blockInformation = conditionStartBlock.blockFlow; | 4451 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4406 } | 4452 } |
| 4407 } | 4453 } |
| OLD | NEW |