| 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 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 | 1058 |
| 1059 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); | 1059 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
| 1060 add(newObject); | 1060 add(newObject); |
| 1061 // Generate calls to the constructor bodies. | 1061 // Generate calls to the constructor bodies. |
| 1062 for (int index = constructors.length - 1; index >= 0; index--) { | 1062 for (int index = constructors.length - 1; index >= 0; index--) { |
| 1063 FunctionElement constructor = constructors[index]; | 1063 FunctionElement constructor = constructors[index]; |
| 1064 ConstructorBodyElement body = getConstructorBody(constructor); | 1064 ConstructorBodyElement body = getConstructorBody(constructor); |
| 1065 if (body === null) continue; | 1065 if (body === null) continue; |
| 1066 List bodyCallInputs = <HInstruction>[]; | 1066 List bodyCallInputs = <HInstruction>[]; |
| 1067 bodyCallInputs.add(newObject); | 1067 bodyCallInputs.add(newObject); |
| 1068 int arity = body.functionSignature.parameterCount; |
| 1068 body.functionSignature.forEachParameter((parameter) { | 1069 body.functionSignature.forEachParameter((parameter) { |
| 1069 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 1070 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| 1070 }); | 1071 }); |
| 1071 // TODO(ahe): The constructor name is statically resolved. See | 1072 // TODO(ahe): The constructor name is statically resolved. See |
| 1072 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner | 1073 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner |
| 1073 // way to do this? | 1074 // way to do this? |
| 1074 SourceString methodName = new SourceString(compiler.namer.getName(body)); | 1075 SourceString name = new SourceString(compiler.namer.getName(body)); |
| 1075 add(new HInvokeDynamicMethod(null, methodName, bodyCallInputs)); | 1076 // TODO(kasperl): This seems fishy. We shouldn't be inventing all |
| 1077 // these selectors. Maybe the resolver can do more of the work |
| 1078 // for us here? |
| 1079 LibraryElement library = body.getLibrary(); |
| 1080 Selector selector = new Selector.call(name, library, arity); |
| 1081 add(new HInvokeDynamicMethod(selector, bodyCallInputs)); |
| 1076 } | 1082 } |
| 1077 close(new HReturn(newObject)).addSuccessor(graph.exit); | 1083 close(new HReturn(newObject)).addSuccessor(graph.exit); |
| 1078 return closeFunction(); | 1084 return closeFunction(); |
| 1079 } | 1085 } |
| 1080 | 1086 |
| 1081 void openFunction(FunctionElement functionElement, | 1087 void openFunction(FunctionElement functionElement, |
| 1082 FunctionExpression node) { | 1088 FunctionExpression node) { |
| 1083 HBasicBlock block = graph.addNewBlock(); | 1089 HBasicBlock block = graph.addNewBlock(); |
| 1084 open(graph.entry); | 1090 open(graph.entry); |
| 1085 | 1091 |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1738 if (send.receiver == null) { | 1744 if (send.receiver == null) { |
| 1739 return localsHandler.readThis(); | 1745 return localsHandler.readThis(); |
| 1740 } | 1746 } |
| 1741 visit(send.receiver); | 1747 visit(send.receiver); |
| 1742 return pop(); | 1748 return pop(); |
| 1743 } | 1749 } |
| 1744 | 1750 |
| 1745 void generateInstanceGetterWithCompiledReceiver(Send send, | 1751 void generateInstanceGetterWithCompiledReceiver(Send send, |
| 1746 HInstruction receiver) { | 1752 HInstruction receiver) { |
| 1747 assert(Elements.isInstanceSend(send, elements)); | 1753 assert(Elements.isInstanceSend(send, elements)); |
| 1748 SourceString getterName = send.selector.asIdentifier().source; | 1754 // TODO(kasperl): This is a convoluted way of checking if we're |
| 1749 Selector selector = elements.getSelector(send); | 1755 // generating code for a compound assignment. If we are, we need |
| 1756 // to get the selector from the mapping for the AST selector node. |
| 1757 Selector selector = (send.asSendSet() === null) |
| 1758 ? elements.getSelector(send) |
| 1759 : elements.getSelector(send.selector); |
| 1760 assert(selector.isGetter()); |
| 1761 SourceString getterName = selector.name; |
| 1750 Element staticInterceptor = null; | 1762 Element staticInterceptor = null; |
| 1751 if (methodInterceptionEnabled) { | 1763 if (methodInterceptionEnabled) { |
| 1752 staticInterceptor = interceptors.getStaticGetInterceptor(getterName); | 1764 staticInterceptor = interceptors.getStaticGetInterceptor(getterName); |
| 1753 } | 1765 } |
| 1754 if (staticInterceptor != null) { | 1766 if (staticInterceptor != null) { |
| 1755 HStatic target = new HStatic(staticInterceptor); | 1767 HStatic target = new HStatic(staticInterceptor); |
| 1756 add(target); | 1768 add(target); |
| 1757 List<HInstruction> inputs = <HInstruction>[target, receiver]; | 1769 List<HInstruction> inputs = <HInstruction>[target, receiver]; |
| 1758 push(new HInvokeInterceptor(selector, getterName, inputs, getter: true)); | 1770 push(new HInvokeInterceptor(selector, getterName, inputs, getter: true)); |
| 1759 } else { | 1771 } else { |
| 1760 push(new HInvokeDynamicGetter(selector, null, getterName, receiver)); | 1772 push(new HInvokeDynamicGetter(selector, null, receiver)); |
| 1761 } | 1773 } |
| 1762 } | 1774 } |
| 1763 | 1775 |
| 1764 void generateGetter(Send send, Element element) { | 1776 void generateGetter(Send send, Element element) { |
| 1765 if (Elements.isStaticOrTopLevelField(element)) { | 1777 if (Elements.isStaticOrTopLevelField(element)) { |
| 1766 if (element.kind == ElementKind.FIELD && !element.isAssignable()) { | 1778 if (element.kind == ElementKind.FIELD && !element.isAssignable()) { |
| 1767 // A static final. Get its constant value and inline it. | 1779 // A static final. Get its constant value and inline it. |
| 1768 Constant value = compiler.constantHandler.compileVariable(element); | 1780 Constant value = compiler.constantHandler.compileVariable(element); |
| 1769 stack.add(graph.addConstant(value)); | 1781 stack.add(graph.addConstant(value)); |
| 1770 } else { | 1782 } else { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1782 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); | 1794 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); |
| 1783 } else { | 1795 } else { |
| 1784 stack.add(localsHandler.readLocal(element)); | 1796 stack.add(localsHandler.readLocal(element)); |
| 1785 } | 1797 } |
| 1786 } | 1798 } |
| 1787 | 1799 |
| 1788 void generateInstanceSetterWithCompiledReceiver(Send send, | 1800 void generateInstanceSetterWithCompiledReceiver(Send send, |
| 1789 HInstruction receiver, | 1801 HInstruction receiver, |
| 1790 HInstruction value) { | 1802 HInstruction value) { |
| 1791 assert(Elements.isInstanceSend(send, elements)); | 1803 assert(Elements.isInstanceSend(send, elements)); |
| 1792 SourceString dartSetterName = send.selector.asIdentifier().source; | |
| 1793 Selector selector = elements.getSelector(send); | 1804 Selector selector = elements.getSelector(send); |
| 1805 assert(selector.isSetter()); |
| 1806 SourceString setterName = selector.name; |
| 1794 Element staticInterceptor = null; | 1807 Element staticInterceptor = null; |
| 1795 if (methodInterceptionEnabled) { | 1808 if (methodInterceptionEnabled) { |
| 1796 staticInterceptor = interceptors.getStaticSetInterceptor(dartSetterName); | 1809 staticInterceptor = interceptors.getStaticSetInterceptor(setterName); |
| 1797 } | 1810 } |
| 1798 if (staticInterceptor != null) { | 1811 if (staticInterceptor != null) { |
| 1799 HStatic target = new HStatic(staticInterceptor); | 1812 HStatic target = new HStatic(staticInterceptor); |
| 1800 add(target); | 1813 add(target); |
| 1801 List<HInstruction> inputs = <HInstruction>[target, receiver, value]; | 1814 List<HInstruction> inputs = <HInstruction>[target, receiver, value]; |
| 1802 add(new HInvokeInterceptor( | 1815 add(new HInvokeInterceptor( |
| 1803 selector, dartSetterName, inputs, setter: true)); | 1816 selector, setterName, inputs, setter: true)); |
| 1804 } else { | 1817 } else { |
| 1805 add(new HInvokeDynamicSetter(selector, null, dartSetterName, | 1818 add(new HInvokeDynamicSetter(selector, null, receiver, value)); |
| 1806 receiver, value)); | |
| 1807 } | 1819 } |
| 1808 stack.add(value); | 1820 stack.add(value); |
| 1809 } | 1821 } |
| 1810 | 1822 |
| 1811 void generateSetter(SendSet send, Element element, HInstruction value) { | 1823 void generateSetter(SendSet send, Element element, HInstruction value) { |
| 1812 if (Elements.isStaticOrTopLevelField(element)) { | 1824 if (Elements.isStaticOrTopLevelField(element)) { |
| 1813 if (element.kind == ElementKind.SETTER) { | 1825 if (element.kind == ElementKind.SETTER) { |
| 1814 HStatic target = new HStatic(element); | 1826 HStatic target = new HStatic(element); |
| 1815 add(target); | 1827 add(target); |
| 1816 add(new HInvokeStatic(<HInstruction>[target, value])); | 1828 add(new HInvokeStatic(<HInstruction>[target, value])); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2046 if (node.receiver === null) { | 2058 if (node.receiver === null) { |
| 2047 inputs.add(localsHandler.readThis()); | 2059 inputs.add(localsHandler.readThis()); |
| 2048 } else { | 2060 } else { |
| 2049 visit(node.receiver); | 2061 visit(node.receiver); |
| 2050 inputs.add(pop()); | 2062 inputs.add(pop()); |
| 2051 } | 2063 } |
| 2052 | 2064 |
| 2053 addDynamicSendArgumentsToList(node, inputs); | 2065 addDynamicSendArgumentsToList(node, inputs); |
| 2054 | 2066 |
| 2055 // The first entry in the inputs list is the receiver. | 2067 // The first entry in the inputs list is the receiver. |
| 2056 pushWithPosition(new HInvokeDynamicMethod(selector, dartMethodName, inputs), | 2068 pushWithPosition(new HInvokeDynamicMethod(selector, inputs), node); |
| 2057 node); | |
| 2058 | 2069 |
| 2059 if (isNotEquals) { | 2070 if (isNotEquals) { |
| 2060 HNot not = new HNot(popBoolified()); | 2071 HNot not = new HNot(popBoolified()); |
| 2061 push(not); | 2072 push(not); |
| 2062 } | 2073 } |
| 2063 } | 2074 } |
| 2064 | 2075 |
| 2065 visitClosureSend(Send node) { | 2076 visitClosureSend(Send node) { |
| 2066 Selector selector = elements.getSelector(node); | 2077 Selector selector = elements.getSelector(node); |
| 2067 assert(node.receiver === null); | 2078 assert(node.receiver === null); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2204 visit(closure); | 2215 visit(closure); |
| 2205 List<HInstruction> inputs = <HInstruction>[pop()]; | 2216 List<HInstruction> inputs = <HInstruction>[pop()]; |
| 2206 String invocationName = compiler.namer.closureInvocationName( | 2217 String invocationName = compiler.namer.closureInvocationName( |
| 2207 new Selector.callClosure(params.requiredParameterCount)); | 2218 new Selector.callClosure(params.requiredParameterCount)); |
| 2208 push(new HForeign(new DartString.literal('#.$invocationName'), | 2219 push(new HForeign(new DartString.literal('#.$invocationName'), |
| 2209 const LiteralDartString('var'), | 2220 const LiteralDartString('var'), |
| 2210 inputs)); | 2221 inputs)); |
| 2211 } | 2222 } |
| 2212 | 2223 |
| 2213 visitForeignSend(Send node) { | 2224 visitForeignSend(Send node) { |
| 2214 Element element = elements[node]; | 2225 Selector selector = elements.getSelector(node); |
| 2215 if (element.name == const SourceString('JS')) { | 2226 SourceString name = selector.name; |
| 2227 if (name == const SourceString('JS')) { |
| 2216 handleForeignJs(node); | 2228 handleForeignJs(node); |
| 2217 } else if (element.name == const SourceString('UNINTERCEPTED')) { | 2229 } else if (name == const SourceString('UNINTERCEPTED')) { |
| 2218 handleForeignUnintercepted(node); | 2230 handleForeignUnintercepted(node); |
| 2219 } else if (element.name == const SourceString('JS_HAS_EQUALS')) { | 2231 } else if (name == const SourceString('JS_HAS_EQUALS')) { |
| 2220 handleForeignJsHasEquals(node); | 2232 handleForeignJsHasEquals(node); |
| 2221 } else if (element.name == const SourceString('JS_CURRENT_ISOLATE')) { | 2233 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { |
| 2222 handleForeignJsCurrentIsolate(node); | 2234 handleForeignJsCurrentIsolate(node); |
| 2223 } else if (element.name == const SourceString('JS_CALL_IN_ISOLATE')) { | 2235 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { |
| 2224 handleForeignJsCallInIsolate(node); | 2236 handleForeignJsCallInIsolate(node); |
| 2225 } else if (element.name == const SourceString('DART_CLOSURE_TO_JS')) { | 2237 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { |
| 2226 handleForeignDartClosureToJs(node); | 2238 handleForeignDartClosureToJs(node); |
| 2227 } else { | 2239 } else { |
| 2228 throw "Unknown foreign: ${node.selector}"; | 2240 throw "Unknown foreign: ${selector}"; |
| 2229 } | 2241 } |
| 2230 } | 2242 } |
| 2231 | 2243 |
| 2232 generateSuperNoSuchMethodSend(Send node) { | 2244 generateSuperNoSuchMethodSend(Send node) { |
| 2233 ClassElement cls = work.element.getEnclosingClass(); | 2245 ClassElement cls = work.element.getEnclosingClass(); |
| 2234 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); | 2246 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); |
| 2235 HStatic target = new HStatic(element); | 2247 HStatic target = new HStatic(element); |
| 2236 add(target); | 2248 add(target); |
| 2237 HInstruction self = localsHandler.readThis(); | 2249 HInstruction self = localsHandler.readThis(); |
| 2238 Identifier identifier = node.selector.asIdentifier(); | 2250 Identifier identifier = node.selector.asIdentifier(); |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2741 SourceString iteratorName = const SourceString("iterator"); | 2753 SourceString iteratorName = const SourceString("iterator"); |
| 2742 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); | 2754 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); |
| 2743 assert(interceptor != null); | 2755 assert(interceptor != null); |
| 2744 visit(node.expression); | 2756 visit(node.expression); |
| 2745 pushInvokeHelper1(interceptor, pop()); | 2757 pushInvokeHelper1(interceptor, pop()); |
| 2746 iterator = pop(); | 2758 iterator = pop(); |
| 2747 } | 2759 } |
| 2748 HInstruction buildCondition() { | 2760 HInstruction buildCondition() { |
| 2749 SourceString name = const SourceString('hasNext'); | 2761 SourceString name = const SourceString('hasNext'); |
| 2750 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 2762 Selector call = new Selector.call(name, work.element.getLibrary(), 0); |
| 2751 push(new HInvokeDynamicMethod(call, name, <HInstruction>[iterator])); | 2763 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); |
| 2752 return popBoolified(); | 2764 return popBoolified(); |
| 2753 } | 2765 } |
| 2754 void buildBody() { | 2766 void buildBody() { |
| 2755 SourceString name = const SourceString('next'); | 2767 SourceString name = const SourceString('next'); |
| 2756 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 2768 Selector call = new Selector.call(name, work.element.getLibrary(), 0); |
| 2757 push(new HInvokeDynamicMethod(call, name, <HInstruction>[iterator])); | 2769 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); |
| 2758 | 2770 |
| 2759 Element variable; | 2771 Element variable; |
| 2760 if (node.declaredIdentifier.asSend() !== null) { | 2772 if (node.declaredIdentifier.asSend() !== null) { |
| 2761 variable = elements[node.declaredIdentifier]; | 2773 variable = elements[node.declaredIdentifier]; |
| 2762 } else { | 2774 } else { |
| 2763 assert(node.declaredIdentifier.asVariableDefinitions() !== null); | 2775 assert(node.declaredIdentifier.asVariableDefinitions() !== null); |
| 2764 VariableDefinitions variableDefinitions = node.declaredIdentifier; | 2776 VariableDefinitions variableDefinitions = node.declaredIdentifier; |
| 2765 variable = elements[variableDefinitions.definitions.nodes.head]; | 2777 variable = elements[variableDefinitions.definitions.nodes.head]; |
| 2766 } | 2778 } |
| 2767 localsHandler.updateLocal(variable, pop()); | 2779 localsHandler.updateLocal(variable, pop()); |
| (...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3629 new HSubGraphBlockInformation(elseBranch.graph)); | 3641 new HSubGraphBlockInformation(elseBranch.graph)); |
| 3630 | 3642 |
| 3631 HBasicBlock conditionStartBlock = conditionBranch.block; | 3643 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 3632 conditionStartBlock.setBlockFlow(info, joinBlock); | 3644 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 3633 SubGraph conditionGraph = conditionBranch.graph; | 3645 SubGraph conditionGraph = conditionBranch.graph; |
| 3634 HIf branch = conditionGraph.end.last; | 3646 HIf branch = conditionGraph.end.last; |
| 3635 assert(branch is HIf); | 3647 assert(branch is HIf); |
| 3636 branch.blockInformation = conditionStartBlock.blockFlow; | 3648 branch.blockInformation = conditionStartBlock.blockFlow; |
| 3637 } | 3649 } |
| 3638 } | 3650 } |
| OLD | NEW |