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 1946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1957 | 1957 |
| 1958 HInstruction generateInstanceSendReceiver(Send send) { | 1958 HInstruction generateInstanceSendReceiver(Send send) { |
| 1959 assert(Elements.isInstanceSend(send, elements)); | 1959 assert(Elements.isInstanceSend(send, elements)); |
| 1960 if (send.receiver == null) { | 1960 if (send.receiver == null) { |
| 1961 return localsHandler.readThis(); | 1961 return localsHandler.readThis(); |
| 1962 } | 1962 } |
| 1963 visit(send.receiver); | 1963 visit(send.receiver); |
| 1964 return pop(); | 1964 return pop(); |
| 1965 } | 1965 } |
| 1966 | 1966 |
| 1967 String getTargetName(ErroneousElement error, [String prefix]) { | |
| 1968 String targetName = error.errorMessage.arguments[0].toString(); | |
| 1969 if (prefix != null) { | |
| 1970 return prefix.concat(targetName); | |
| 1971 } | |
| 1972 return targetName; | |
| 1973 } | |
| 1974 | |
| 1967 void generateInstanceGetterWithCompiledReceiver(Send send, | 1975 void generateInstanceGetterWithCompiledReceiver(Send send, |
| 1968 HInstruction receiver) { | 1976 HInstruction receiver) { |
| 1969 assert(Elements.isInstanceSend(send, elements)); | 1977 assert(Elements.isInstanceSend(send, elements)); |
| 1970 // TODO(kasperl): This is a convoluted way of checking if we're | 1978 // TODO(kasperl): This is a convoluted way of checking if we're |
| 1971 // generating code for a compound assignment. If we are, we need | 1979 // generating code for a compound assignment. If we are, we need |
| 1972 // to get the selector from the mapping for the AST selector node. | 1980 // to get the selector from the mapping for the AST selector node. |
| 1973 Selector selector = (send.asSendSet() === null) | 1981 Selector selector = (send.asSendSet() === null) |
| 1974 ? elements.getSelector(send) | 1982 ? elements.getSelector(send) |
| 1975 : elements.getSelector(send.selector); | 1983 : elements.getSelector(send.selector); |
| 1976 assert(selector.isGetter()); | 1984 assert(selector.isGetter()); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2001 push(new HInvokeStatic(<HInstruction>[pop()])); | 2009 push(new HInvokeStatic(<HInstruction>[pop()])); |
| 2002 } | 2010 } |
| 2003 } | 2011 } |
| 2004 } else if (Elements.isInstanceSend(send, elements)) { | 2012 } else if (Elements.isInstanceSend(send, elements)) { |
| 2005 HInstruction receiver = generateInstanceSendReceiver(send); | 2013 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2006 generateInstanceGetterWithCompiledReceiver(send, receiver); | 2014 generateInstanceGetterWithCompiledReceiver(send, receiver); |
| 2007 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 2015 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 2008 push(new HStatic(element)); | 2016 push(new HStatic(element)); |
| 2009 // TODO(ahe): This should be registered in codegen. | 2017 // TODO(ahe): This should be registered in codegen. |
| 2010 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); | 2018 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); |
| 2019 } else if (element != null && Element.isInvalid(element)) { | |
| 2020 // An erroneous element indicates an unresolved static getter. | |
| 2021 generateThrowNoSuchMethod(send, | |
| 2022 getTargetName(element, 'get '), | |
| 2023 const EmptyLink<Node>()); | |
| 2011 } else { | 2024 } else { |
| 2012 stack.add(localsHandler.readLocal(element)); | 2025 stack.add(localsHandler.readLocal(element)); |
| 2013 } | 2026 } |
| 2014 } | 2027 } |
| 2015 | 2028 |
| 2016 void generateInstanceSetterWithCompiledReceiver(Send send, | 2029 void generateInstanceSetterWithCompiledReceiver(Send send, |
| 2017 HInstruction receiver, | 2030 HInstruction receiver, |
| 2018 HInstruction value) { | 2031 HInstruction value) { |
| 2019 assert(Elements.isInstanceSend(send, elements)); | 2032 assert(Elements.isInstanceSend(send, elements)); |
| 2020 Selector selector = elements.getSelector(send); | 2033 Selector selector = elements.getSelector(send); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2041 HStatic target = new HStatic(element); | 2054 HStatic target = new HStatic(element); |
| 2042 add(target); | 2055 add(target); |
| 2043 add(new HInvokeStatic(<HInstruction>[target, value])); | 2056 add(new HInvokeStatic(<HInstruction>[target, value])); |
| 2044 } else { | 2057 } else { |
| 2045 add(new HStaticStore(element, value)); | 2058 add(new HStaticStore(element, value)); |
| 2046 } | 2059 } |
| 2047 stack.add(value); | 2060 stack.add(value); |
| 2048 } else if (element === null || Elements.isInstanceField(element)) { | 2061 } else if (element === null || Elements.isInstanceField(element)) { |
| 2049 HInstruction receiver = generateInstanceSendReceiver(send); | 2062 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2050 generateInstanceSetterWithCompiledReceiver(send, receiver, value); | 2063 generateInstanceSetterWithCompiledReceiver(send, receiver, value); |
| 2064 } else if (element != null && Element.isInvalid(element)) { | |
| 2065 // An erroneous element indicates an unresolved static setter. | |
| 2066 generateThrowNoSuchMethod(send, | |
| 2067 getTargetName(element, 'set '), | |
| 2068 send.arguments); | |
| 2051 } else { | 2069 } else { |
| 2052 stack.add(value); | 2070 stack.add(value); |
| 2053 // If the value does not already have a name, give it here. | 2071 // If the value does not already have a name, give it here. |
| 2054 if (value.sourceElement === null) { | 2072 if (value.sourceElement === null) { |
| 2055 value.sourceElement = element; | 2073 value.sourceElement = element; |
| 2056 } | 2074 } |
| 2057 HInstruction checked = potentiallyCheckType(value, element); | 2075 HInstruction checked = potentiallyCheckType(value, element); |
| 2058 if (checked !== value) { | 2076 if (checked !== value) { |
| 2059 pop(); | 2077 pop(); |
| 2060 stack.add(checked); | 2078 stack.add(checked); |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2601 }); | 2619 }); |
| 2602 | 2620 |
| 2603 HType elementType = computeType(constructor); | 2621 HType elementType = computeType(constructor); |
| 2604 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2622 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| 2605 pushWithPosition(newInstance, node); | 2623 pushWithPosition(newInstance, node); |
| 2606 } | 2624 } |
| 2607 | 2625 |
| 2608 visitStaticSend(Send node) { | 2626 visitStaticSend(Send node) { |
| 2609 Selector selector = elements.getSelector(node); | 2627 Selector selector = elements.getSelector(node); |
| 2610 Element element = elements[node]; | 2628 Element element = elements[node]; |
| 2629 if (element.isErroneous()) { | |
| 2630 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments); | |
| 2631 return; | |
| 2632 } | |
| 2611 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { | 2633 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { |
| 2612 stack.add(graph.addConstantNull()); | 2634 stack.add(graph.addConstantNull()); |
| 2613 return; | 2635 return; |
| 2614 } | 2636 } |
| 2615 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); | 2637 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); |
| 2616 | 2638 |
| 2617 if (tryInlineMethod(element, selector, node.arguments)) return; | 2639 if (tryInlineMethod(element, selector, node.arguments)) return; |
| 2618 | 2640 |
| 2619 HInstruction target = new HStatic(element); | 2641 HInstruction target = new HStatic(element); |
| 2620 add(target); | 2642 add(target); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2656 compiler.internalError(reason, node: node); | 2678 compiler.internalError(reason, node: node); |
| 2657 } | 2679 } |
| 2658 | 2680 |
| 2659 void generateRuntimeError(Node node, String message) { | 2681 void generateRuntimeError(Node node, String message) { |
| 2660 DartString messageObject = new DartString.literal(message); | 2682 DartString messageObject = new DartString.literal(message); |
| 2661 HInstruction errorMessage = graph.addConstantString(messageObject, node); | 2683 HInstruction errorMessage = graph.addConstantString(messageObject, node); |
| 2662 Element helper = interceptors.getThrowRuntimeError(); | 2684 Element helper = interceptors.getThrowRuntimeError(); |
| 2663 pushInvokeHelper1(helper, errorMessage); | 2685 pushInvokeHelper1(helper, errorMessage); |
| 2664 } | 2686 } |
| 2665 | 2687 |
| 2688 void generateThrowNoSuchMethod(Node diagnosticNode, | |
| 2689 String methodName, | |
| 2690 [Link<Node> argumentNodes, | |
| 2691 List<HInstruction> argumentValues]) { | |
| 2692 Element helper = | |
| 2693 compiler.findHelper(const SourceString('throwNoSuchMethod')); | |
| 2694 HInstruction receiver = | |
| 2695 graph.addConstantString(new DartString.empty(), diagnosticNode); | |
| 2696 DartString dartString = new DartString.literal(methodName); | |
| 2697 HInstruction name = graph.addConstantString(dartString, diagnosticNode); | |
| 2698 if (argumentValues == null) { | |
| 2699 argumentValues = <HInstruction>[]; | |
|
kasperl
2012/09/05 11:16:01
Could this be done using argumentNodes.map?
karlklose
2012/09/05 14:53:42
No, this is a Link, which does not have map.
| |
| 2700 argumentNodes.forEach((argumentNode) { | |
| 2701 visit(argumentNode); | |
| 2702 HInstruction value = pop(); | |
| 2703 argumentValues.add(value); | |
| 2704 }); | |
| 2705 } | |
| 2706 HInstruction arguments = new HLiteralList(argumentValues); | |
| 2707 add(arguments); | |
| 2708 pushInvokeHelper3(helper, receiver, name, arguments); | |
| 2709 } | |
| 2710 | |
| 2666 visitNewExpression(NewExpression node) { | 2711 visitNewExpression(NewExpression node) { |
| 2667 Element element = elements[node.send]; | 2712 Element element = elements[node.send]; |
| 2668 if (element != null && element.isErroneous()) { | 2713 if (element != null && element.isErroneous()) { |
| 2669 ErroneousElement error = element; | 2714 ErroneousElement error = element; |
| 2670 Message message = error.errorMessage; | 2715 Message message = error.errorMessage; |
| 2671 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 2716 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 2672 Element helper = | |
| 2673 compiler.findHelper(const SourceString('throwNoSuchMethod')); | |
| 2674 DartString receiverLiteral = new DartString.literal(''); | |
| 2675 HInstruction receiver = graph.addConstantString(receiverLiteral, node); | |
| 2676 String constructorName = 'constructor ${message.arguments[0]}'; | 2717 String constructorName = 'constructor ${message.arguments[0]}'; |
| 2677 DartString nameLiteral = new DartString.literal(constructorName); | 2718 generateThrowNoSuchMethod(node.send, |
| 2678 HInstruction name = graph.addConstantString(nameLiteral, node.send); | 2719 getTargetName(error, 'constructor'), |
| 2679 List<HInstruction> inputs = <HInstruction>[]; | 2720 node.send.arguments); |
| 2680 node.send.arguments.forEach((argumentNode) { | |
| 2681 visit(argumentNode); | |
| 2682 HInstruction value = pop(); | |
| 2683 inputs.add(value); | |
| 2684 }); | |
| 2685 HInstruction arguments = new HLiteralList(inputs); | |
| 2686 add(arguments); | |
| 2687 pushInvokeHelper3(helper, receiver, name, arguments); | |
| 2688 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { | 2721 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { |
| 2689 generateRuntimeError(node.send, message.message); | 2722 generateRuntimeError(node.send, message.message); |
| 2690 } else { | 2723 } else { |
| 2691 compiler.internalError('unexpected unresolved constructor call', | 2724 compiler.internalError('unexpected unresolved constructor call', |
| 2692 node: node); | 2725 node: node); |
| 2693 } | 2726 } |
| 2694 } else if (node.isConst()) { | 2727 } else if (node.isConst()) { |
| 2695 // TODO(karlklose): add type representation | 2728 // TODO(karlklose): add type representation |
| 2696 ConstantHandler handler = compiler.constantHandler; | 2729 ConstantHandler handler = compiler.constantHandler; |
| 2697 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 2730 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3047 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 3080 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); |
| 3048 | 3081 |
| 3049 Element variable; | 3082 Element variable; |
| 3050 if (node.declaredIdentifier.asSend() !== null) { | 3083 if (node.declaredIdentifier.asSend() !== null) { |
| 3051 variable = elements[node.declaredIdentifier]; | 3084 variable = elements[node.declaredIdentifier]; |
| 3052 } else { | 3085 } else { |
| 3053 assert(node.declaredIdentifier.asVariableDefinitions() !== null); | 3086 assert(node.declaredIdentifier.asVariableDefinitions() !== null); |
| 3054 VariableDefinitions variableDefinitions = node.declaredIdentifier; | 3087 VariableDefinitions variableDefinitions = node.declaredIdentifier; |
| 3055 variable = elements[variableDefinitions.definitions.nodes.head]; | 3088 variable = elements[variableDefinitions.definitions.nodes.head]; |
| 3056 } | 3089 } |
| 3057 localsHandler.updateLocal(variable, pop()); | 3090 HInstruction oldVariable = pop(); |
| 3091 if (variable == null) { | |
| 3092 // Do nothing. | |
| 3093 } else if (variable.isErroneous()) { | |
| 3094 generateThrowNoSuchMethod(node, | |
| 3095 getTargetName(variable, 'set '), | |
| 3096 argumentValues: <HInstruction>[oldVariable]); | |
| 3097 pop(); | |
| 3098 } else { | |
| 3099 localsHandler.updateLocal(variable, oldVariable); | |
| 3100 } | |
| 3058 | 3101 |
| 3059 visit(node.body); | 3102 visit(node.body); |
| 3060 } | 3103 } |
| 3061 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); | 3104 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); |
| 3062 } | 3105 } |
| 3063 | 3106 |
| 3064 visitLabel(Label node) { | 3107 visitLabel(Label node) { |
| 3065 compiler.internalError('SsaBuilder.visitLabel', node: node); | 3108 compiler.internalError('SsaBuilder.visitLabel', node: node); |
| 3066 } | 3109 } |
| 3067 | 3110 |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4001 new HSubGraphBlockInformation(elseBranch.graph)); | 4044 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4002 | 4045 |
| 4003 HBasicBlock conditionStartBlock = conditionBranch.block; | 4046 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4004 conditionStartBlock.setBlockFlow(info, joinBlock); | 4047 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4005 SubGraph conditionGraph = conditionBranch.graph; | 4048 SubGraph conditionGraph = conditionBranch.graph; |
| 4006 HIf branch = conditionGraph.end.last; | 4049 HIf branch = conditionGraph.end.last; |
| 4007 assert(branch is HIf); | 4050 assert(branch is HIf); |
| 4008 branch.blockInformation = conditionStartBlock.blockFlow; | 4051 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4009 } | 4052 } |
| 4010 } | 4053 } |
| OLD | NEW |