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 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1982 | 1982 |
| 1983 HInstruction generateInstanceSendReceiver(Send send) { | 1983 HInstruction generateInstanceSendReceiver(Send send) { |
| 1984 assert(Elements.isInstanceSend(send, elements)); | 1984 assert(Elements.isInstanceSend(send, elements)); |
| 1985 if (send.receiver == null) { | 1985 if (send.receiver == null) { |
| 1986 return localsHandler.readThis(); | 1986 return localsHandler.readThis(); |
| 1987 } | 1987 } |
| 1988 visit(send.receiver); | 1988 visit(send.receiver); |
| 1989 return pop(); | 1989 return pop(); |
| 1990 } | 1990 } |
| 1991 | 1991 |
| 1992 String getTargetName(ErroneousElement error, [String prefix]) { | |
|
ngeoffray
2012/09/07 08:12:46
How about
String getTargetName(error, [String pre
karlklose
2012/09/07 09:24:01
Done.
| |
| 1993 String targetName = error.targetName.slowToString(); | |
| 1994 if (prefix != null) { | |
| 1995 return prefix.concat(targetName); | |
| 1996 } | |
| 1997 return targetName; | |
| 1998 } | |
| 1999 | |
| 1992 void generateInstanceGetterWithCompiledReceiver(Send send, | 2000 void generateInstanceGetterWithCompiledReceiver(Send send, |
| 1993 HInstruction receiver) { | 2001 HInstruction receiver) { |
| 1994 assert(Elements.isInstanceSend(send, elements)); | 2002 assert(Elements.isInstanceSend(send, elements)); |
| 1995 // TODO(kasperl): This is a convoluted way of checking if we're | 2003 // TODO(kasperl): This is a convoluted way of checking if we're |
| 1996 // generating code for a compound assignment. If we are, we need | 2004 // generating code for a compound assignment. If we are, we need |
| 1997 // to get the selector from the mapping for the AST selector node. | 2005 // to get the selector from the mapping for the AST selector node. |
| 1998 Selector selector = (send.asSendSet() === null) | 2006 Selector selector = (send.asSendSet() === null) |
| 1999 ? elements.getSelector(send) | 2007 ? elements.getSelector(send) |
| 2000 : elements.getSelector(send.selector); | 2008 : elements.getSelector(send.selector); |
| 2001 assert(selector.isGetter()); | 2009 assert(selector.isGetter()); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2032 push(new HInvokeStatic(<HInstruction>[pop()])); | 2040 push(new HInvokeStatic(<HInstruction>[pop()])); |
| 2033 } | 2041 } |
| 2034 } | 2042 } |
| 2035 } else if (Elements.isInstanceSend(send, elements)) { | 2043 } else if (Elements.isInstanceSend(send, elements)) { |
| 2036 HInstruction receiver = generateInstanceSendReceiver(send); | 2044 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2037 generateInstanceGetterWithCompiledReceiver(send, receiver); | 2045 generateInstanceGetterWithCompiledReceiver(send, receiver); |
| 2038 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 2046 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 2039 push(new HStatic(element)); | 2047 push(new HStatic(element)); |
| 2040 // TODO(ahe): This should be registered in codegen. | 2048 // TODO(ahe): This should be registered in codegen. |
| 2041 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); | 2049 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); |
| 2050 } else if (Element.isErroneousElement(element)) { | |
| 2051 // An erroneous element indicates an unresolved static getter. | |
| 2052 generateThrowNoSuchMethod(send, | |
| 2053 getTargetName(element, 'get '), | |
| 2054 const EmptyLink<Node>()); | |
| 2042 } else { | 2055 } else { |
| 2043 stack.add(localsHandler.readLocal(element)); | 2056 stack.add(localsHandler.readLocal(element)); |
| 2044 } | 2057 } |
| 2045 } | 2058 } |
| 2046 | 2059 |
| 2047 void generateInstanceSetterWithCompiledReceiver(Send send, | 2060 void generateInstanceSetterWithCompiledReceiver(Send send, |
| 2048 HInstruction receiver, | 2061 HInstruction receiver, |
| 2049 HInstruction value) { | 2062 HInstruction value) { |
| 2050 assert(Elements.isInstanceSend(send, elements)); | 2063 assert(Elements.isInstanceSend(send, elements)); |
| 2051 Selector selector = elements.getSelector(send); | 2064 Selector selector = elements.getSelector(send); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2072 HStatic target = new HStatic(element); | 2085 HStatic target = new HStatic(element); |
| 2073 add(target); | 2086 add(target); |
| 2074 add(new HInvokeStatic(<HInstruction>[target, value])); | 2087 add(new HInvokeStatic(<HInstruction>[target, value])); |
| 2075 } else { | 2088 } else { |
| 2076 add(new HStaticStore(element, value)); | 2089 add(new HStaticStore(element, value)); |
| 2077 } | 2090 } |
| 2078 stack.add(value); | 2091 stack.add(value); |
| 2079 } else if (element === null || Elements.isInstanceField(element)) { | 2092 } else if (element === null || Elements.isInstanceField(element)) { |
| 2080 HInstruction receiver = generateInstanceSendReceiver(send); | 2093 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2081 generateInstanceSetterWithCompiledReceiver(send, receiver, value); | 2094 generateInstanceSetterWithCompiledReceiver(send, receiver, value); |
| 2095 } else if (Element.isErroneousElement(element)) { | |
| 2096 // An erroneous element indicates an unresolved static setter. | |
| 2097 generateThrowNoSuchMethod(send, | |
| 2098 getTargetName(element, 'set '), | |
| 2099 send.arguments); | |
| 2082 } else { | 2100 } else { |
| 2083 stack.add(value); | 2101 stack.add(value); |
| 2084 // If the value does not already have a name, give it here. | 2102 // If the value does not already have a name, give it here. |
| 2085 if (value.sourceElement === null) { | 2103 if (value.sourceElement === null) { |
| 2086 value.sourceElement = element; | 2104 value.sourceElement = element; |
| 2087 } | 2105 } |
| 2088 HInstruction checked = potentiallyCheckType(value, element); | 2106 HInstruction checked = potentiallyCheckType(value, element); |
| 2089 if (checked !== value) { | 2107 if (checked !== value) { |
| 2090 pop(); | 2108 pop(); |
| 2091 stack.add(checked); | 2109 stack.add(checked); |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2631 }); | 2649 }); |
| 2632 | 2650 |
| 2633 HType elementType = computeType(constructor); | 2651 HType elementType = computeType(constructor); |
| 2634 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2652 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| 2635 pushWithPosition(newInstance, node); | 2653 pushWithPosition(newInstance, node); |
| 2636 } | 2654 } |
| 2637 | 2655 |
| 2638 visitStaticSend(Send node) { | 2656 visitStaticSend(Send node) { |
| 2639 Selector selector = elements.getSelector(node); | 2657 Selector selector = elements.getSelector(node); |
| 2640 Element element = elements[node]; | 2658 Element element = elements[node]; |
| 2659 if (element.isErroneous()) { | |
| 2660 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments); | |
| 2661 return; | |
| 2662 } | |
| 2641 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { | 2663 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { |
| 2642 stack.add(graph.addConstantNull()); | 2664 stack.add(graph.addConstantNull()); |
| 2643 return; | 2665 return; |
| 2644 } | 2666 } |
| 2645 compiler.ensure(!element.isGenerativeConstructor()); | 2667 compiler.ensure(!element.isGenerativeConstructor()); |
| 2646 if (element.isFunction()) { | 2668 if (element.isFunction()) { |
| 2647 if (tryInlineMethod(element, selector, node.arguments)) return; | 2669 if (tryInlineMethod(element, selector, node.arguments)) return; |
| 2648 | 2670 |
| 2649 HInstruction target = new HStatic(element); | 2671 HInstruction target = new HStatic(element); |
| 2650 add(target); | 2672 add(target); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2681 compiler.internalError(reason, node: node); | 2703 compiler.internalError(reason, node: node); |
| 2682 } | 2704 } |
| 2683 | 2705 |
| 2684 void generateRuntimeError(Node node, String message) { | 2706 void generateRuntimeError(Node node, String message) { |
| 2685 DartString messageObject = new DartString.literal(message); | 2707 DartString messageObject = new DartString.literal(message); |
| 2686 HInstruction errorMessage = graph.addConstantString(messageObject, node); | 2708 HInstruction errorMessage = graph.addConstantString(messageObject, node); |
| 2687 Element helper = interceptors.getThrowRuntimeError(); | 2709 Element helper = interceptors.getThrowRuntimeError(); |
| 2688 pushInvokeHelper1(helper, errorMessage); | 2710 pushInvokeHelper1(helper, errorMessage); |
| 2689 } | 2711 } |
| 2690 | 2712 |
| 2713 void generateThrowNoSuchMethod(Node diagnosticNode, | |
| 2714 String methodName, | |
| 2715 [Link<Node> argumentNodes, | |
| 2716 List<HInstruction> argumentValues]) { | |
| 2717 Element helper = | |
| 2718 compiler.findHelper(const SourceString('throwNoSuchMethod')); | |
| 2719 HInstruction receiver = | |
| 2720 graph.addConstantString(new DartString.empty(), diagnosticNode); | |
| 2721 DartString dartString = new DartString.literal(methodName); | |
| 2722 HInstruction name = graph.addConstantString(dartString, diagnosticNode); | |
| 2723 if (argumentValues == null) { | |
| 2724 argumentValues = <HInstruction>[]; | |
| 2725 argumentNodes.forEach((argumentNode) { | |
| 2726 visit(argumentNode); | |
| 2727 HInstruction value = pop(); | |
| 2728 argumentValues.add(value); | |
| 2729 }); | |
| 2730 } | |
| 2731 HInstruction arguments = new HLiteralList(argumentValues); | |
| 2732 add(arguments); | |
| 2733 pushInvokeHelper3(helper, receiver, name, arguments); | |
| 2734 } | |
| 2735 | |
| 2691 visitNewExpression(NewExpression node) { | 2736 visitNewExpression(NewExpression node) { |
| 2692 Element element = elements[node.send]; | 2737 Element element = elements[node.send]; |
| 2693 if (element != null && element.isErroneous()) { | 2738 if (Element.isErroneousElement(element)) { |
| 2694 ErroneousElement error = element; | 2739 ErroneousElement error = element; |
| 2695 Message message = error.errorMessage; | 2740 Message message = error.errorMessage; |
| 2696 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 2741 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 2697 Element helper = | 2742 generateThrowNoSuchMethod(node.send, |
| 2698 compiler.findHelper(const SourceString('throwNoSuchMethod')); | 2743 getTargetName(error, 'constructor'), |
| 2699 DartString receiverLiteral = new DartString.literal(''); | 2744 node.send.arguments); |
| 2700 HInstruction receiver = graph.addConstantString(receiverLiteral, node); | |
| 2701 String constructorName = 'constructor ${message.arguments[0]}'; | |
| 2702 DartString nameLiteral = new DartString.literal(constructorName); | |
| 2703 HInstruction name = graph.addConstantString(nameLiteral, node.send); | |
| 2704 List<HInstruction> inputs = <HInstruction>[]; | |
| 2705 node.send.arguments.forEach((argumentNode) { | |
| 2706 visit(argumentNode); | |
| 2707 HInstruction value = pop(); | |
| 2708 inputs.add(value); | |
| 2709 }); | |
| 2710 HInstruction arguments = new HLiteralList(inputs); | |
| 2711 add(arguments); | |
| 2712 pushInvokeHelper3(helper, receiver, name, arguments); | |
| 2713 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { | 2745 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { |
| 2714 generateRuntimeError(node.send, message.message); | 2746 generateRuntimeError(node.send, message.message); |
| 2715 } else { | 2747 } else { |
| 2716 compiler.internalError('unexpected unresolved constructor call', | 2748 compiler.internalError('unexpected unresolved constructor call', |
| 2717 node: node); | 2749 node: node); |
| 2718 } | 2750 } |
| 2719 } else if (node.isConst()) { | 2751 } else if (node.isConst()) { |
| 2720 // TODO(karlklose): add type representation | 2752 // TODO(karlklose): add type representation |
| 2721 ConstantHandler handler = compiler.constantHandler; | 2753 ConstantHandler handler = compiler.constantHandler; |
| 2722 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 2754 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3072 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 3104 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); |
| 3073 | 3105 |
| 3074 Element variable; | 3106 Element variable; |
| 3075 if (node.declaredIdentifier.asSend() !== null) { | 3107 if (node.declaredIdentifier.asSend() !== null) { |
| 3076 variable = elements[node.declaredIdentifier]; | 3108 variable = elements[node.declaredIdentifier]; |
| 3077 } else { | 3109 } else { |
| 3078 assert(node.declaredIdentifier.asVariableDefinitions() !== null); | 3110 assert(node.declaredIdentifier.asVariableDefinitions() !== null); |
| 3079 VariableDefinitions variableDefinitions = node.declaredIdentifier; | 3111 VariableDefinitions variableDefinitions = node.declaredIdentifier; |
| 3080 variable = elements[variableDefinitions.definitions.nodes.head]; | 3112 variable = elements[variableDefinitions.definitions.nodes.head]; |
| 3081 } | 3113 } |
| 3082 localsHandler.updateLocal(variable, pop()); | 3114 HInstruction oldVariable = pop(); |
| 3115 if (variable.isErroneous()) { | |
| 3116 generateThrowNoSuchMethod(node, | |
| 3117 getTargetName(variable, 'set '), | |
| 3118 argumentValues: <HInstruction>[oldVariable]); | |
| 3119 pop(); | |
| 3120 } else { | |
| 3121 localsHandler.updateLocal(variable, oldVariable); | |
| 3122 } | |
| 3083 | 3123 |
| 3084 visit(node.body); | 3124 visit(node.body); |
| 3085 } | 3125 } |
| 3086 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); | 3126 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); |
| 3087 } | 3127 } |
| 3088 | 3128 |
| 3089 visitLabel(Label node) { | 3129 visitLabel(Label node) { |
| 3090 compiler.internalError('SsaBuilder.visitLabel', node: node); | 3130 compiler.internalError('SsaBuilder.visitLabel', node: node); |
| 3091 } | 3131 } |
| 3092 | 3132 |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4026 new HSubGraphBlockInformation(elseBranch.graph)); | 4066 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4027 | 4067 |
| 4028 HBasicBlock conditionStartBlock = conditionBranch.block; | 4068 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4029 conditionStartBlock.setBlockFlow(info, joinBlock); | 4069 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4030 SubGraph conditionGraph = conditionBranch.graph; | 4070 SubGraph conditionGraph = conditionBranch.graph; |
| 4031 HIf branch = conditionGraph.end.last; | 4071 HIf branch = conditionGraph.end.last; |
| 4032 assert(branch is HIf); | 4072 assert(branch is HIf); |
| 4033 branch.blockInformation = conditionStartBlock.blockFlow; | 4073 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4034 } | 4074 } |
| 4035 } | 4075 } |
| OLD | NEW |