| 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 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 HEquals eq = new HEquals(target, left, right); | 1599 HEquals eq = new HEquals(target, left, right); |
| 1600 add(eq); | 1600 add(eq); |
| 1601 HBoolify bl = new HBoolify(eq); | 1601 HBoolify bl = new HBoolify(eq); |
| 1602 add(bl); | 1602 add(bl); |
| 1603 push(new HNot(bl)); | 1603 push(new HNot(bl)); |
| 1604 break; | 1604 break; |
| 1605 default: compiler.unimplemented("SsaBuilder.visitBinary"); | 1605 default: compiler.unimplemented("SsaBuilder.visitBinary"); |
| 1606 } | 1606 } |
| 1607 } | 1607 } |
| 1608 | 1608 |
| 1609 HInstruction generateInstanceSendReceiver(Send send) { |
| 1610 assert(Elements.isInstanceSend(send, elements)); |
| 1611 if (send.receiver == null) { |
| 1612 return localsHandler.readThis(); |
| 1613 } |
| 1614 visit(send.receiver); |
| 1615 return pop(); |
| 1616 } |
| 1617 |
| 1618 void generateInstanceGetterWithCompiledReceiver(Send send, |
| 1619 HInstruction receiver) { |
| 1620 assert(Elements.isInstanceSend(send, elements)); |
| 1621 SourceString getterName = send.selector.asIdentifier().source; |
| 1622 Selector selector = elements.getSelector(send); |
| 1623 Element staticInterceptor = null; |
| 1624 if (methodInterceptionEnabled) { |
| 1625 staticInterceptor = interceptors.getStaticGetInterceptor(getterName); |
| 1626 } |
| 1627 if (staticInterceptor != null) { |
| 1628 HStatic target = new HStatic(staticInterceptor); |
| 1629 add(target); |
| 1630 List<HInstruction> inputs = <HInstruction>[target, receiver]; |
| 1631 push(new HInvokeInterceptor(selector, getterName, true, inputs)); |
| 1632 } else { |
| 1633 push(new HInvokeDynamicGetter(selector, null, getterName, receiver)); |
| 1634 } |
| 1635 } |
| 1636 |
| 1609 void generateGetter(Send send, Element element) { | 1637 void generateGetter(Send send, Element element) { |
| 1610 Selector selector = elements.getSelector(send); | |
| 1611 if (Elements.isStaticOrTopLevelField(element)) { | 1638 if (Elements.isStaticOrTopLevelField(element)) { |
| 1639 Selector selector = elements.getSelector(send); |
| 1612 push(new HStatic(element)); | 1640 push(new HStatic(element)); |
| 1613 if (element.kind == ElementKind.GETTER) { | 1641 if (element.kind == ElementKind.GETTER) { |
| 1614 push(new HInvokeStatic(selector, <HInstruction>[pop()])); | 1642 push(new HInvokeStatic(selector, <HInstruction>[pop()])); |
| 1615 } | 1643 } |
| 1616 } else if (Elements.isInstanceSend(send, elements)) { | 1644 } else if (Elements.isInstanceSend(send, elements)) { |
| 1617 HInstruction receiver; | 1645 HInstruction receiver = generateInstanceSendReceiver(send); |
| 1618 if (send.receiver == null) { | 1646 generateInstanceGetterWithCompiledReceiver(send, receiver); |
| 1619 receiver = localsHandler.readThis(); | |
| 1620 } else { | |
| 1621 visit(send.receiver); | |
| 1622 receiver = pop(); | |
| 1623 } | |
| 1624 SourceString getterName = send.selector.asIdentifier().source; | |
| 1625 Element staticInterceptor = null; | |
| 1626 if (methodInterceptionEnabled) { | |
| 1627 staticInterceptor = interceptors.getStaticGetInterceptor(getterName); | |
| 1628 } | |
| 1629 if (staticInterceptor != null) { | |
| 1630 HStatic target = new HStatic(staticInterceptor); | |
| 1631 add(target); | |
| 1632 List<HInstruction> inputs = <HInstruction>[target, receiver]; | |
| 1633 push(new HInvokeInterceptor(selector, getterName, true, inputs)); | |
| 1634 } else { | |
| 1635 push(new HInvokeDynamicGetter(selector, null, getterName, receiver)); | |
| 1636 } | |
| 1637 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 1647 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 1638 push(new HStatic(element)); | 1648 push(new HStatic(element)); |
| 1639 compiler.registerGetOfStaticFunction(element); | 1649 compiler.registerGetOfStaticFunction(element); |
| 1640 } else { | 1650 } else { |
| 1641 stack.add(localsHandler.readLocal(element)); | 1651 stack.add(localsHandler.readLocal(element)); |
| 1642 } | 1652 } |
| 1643 } | 1653 } |
| 1644 | 1654 |
| 1655 void generateInstanceSetterWithCompiledReceiver(Send send, |
| 1656 HInstruction receiver, |
| 1657 HInstruction value) { |
| 1658 assert(Elements.isInstanceSend(send, elements)); |
| 1659 SourceString dartSetterName = send.selector.asIdentifier().source; |
| 1660 Selector selector = elements.getSelector(send); |
| 1661 Element staticInterceptor = null; |
| 1662 if (methodInterceptionEnabled) { |
| 1663 staticInterceptor = interceptors.getStaticSetInterceptor(dartSetterName); |
| 1664 } |
| 1665 if (staticInterceptor != null) { |
| 1666 HStatic target = new HStatic(staticInterceptor); |
| 1667 add(target); |
| 1668 List<HInstruction> inputs = <HInstruction>[target, receiver, value]; |
| 1669 add(new HInvokeInterceptor(selector, dartSetterName, false, inputs)); |
| 1670 } else { |
| 1671 add(new HInvokeDynamicSetter(selector, null, dartSetterName, |
| 1672 receiver, value)); |
| 1673 } |
| 1674 stack.add(value); |
| 1675 } |
| 1676 |
| 1645 void generateSetter(SendSet send, Element element, HInstruction value) { | 1677 void generateSetter(SendSet send, Element element, HInstruction value) { |
| 1646 Selector selector = elements.getSelector(send); | |
| 1647 if (Elements.isStaticOrTopLevelField(element)) { | 1678 if (Elements.isStaticOrTopLevelField(element)) { |
| 1679 Selector selector = elements.getSelector(send); |
| 1648 if (element.kind == ElementKind.SETTER) { | 1680 if (element.kind == ElementKind.SETTER) { |
| 1649 HStatic target = new HStatic(element); | 1681 HStatic target = new HStatic(element); |
| 1650 add(target); | 1682 add(target); |
| 1651 add(new HInvokeStatic(selector, <HInstruction>[target, value])); | 1683 add(new HInvokeStatic(selector, <HInstruction>[target, value])); |
| 1652 } else { | 1684 } else { |
| 1653 add(new HStaticStore(element, value)); | 1685 add(new HStaticStore(element, value)); |
| 1654 } | 1686 } |
| 1655 stack.add(value); | 1687 stack.add(value); |
| 1656 } else if (element === null || Elements.isInstanceField(element)) { | 1688 } else if (element === null || Elements.isInstanceField(element)) { |
| 1657 SourceString dartSetterName = send.selector.asIdentifier().source; | 1689 HInstruction receiver = generateInstanceSendReceiver(send); |
| 1658 HInstruction receiver; | 1690 generateInstanceSetterWithCompiledReceiver(send, receiver, value); |
| 1659 if (send.receiver == null) { | |
| 1660 receiver = localsHandler.readThis(); | |
| 1661 } else { | |
| 1662 visit(send.receiver); | |
| 1663 receiver = pop(); | |
| 1664 } | |
| 1665 Element staticInterceptor = null; | |
| 1666 if (methodInterceptionEnabled) { | |
| 1667 staticInterceptor = | |
| 1668 interceptors.getStaticSetInterceptor(dartSetterName); | |
| 1669 } | |
| 1670 if (staticInterceptor != null) { | |
| 1671 HStatic target = new HStatic(staticInterceptor); | |
| 1672 add(target); | |
| 1673 List<HInstruction> inputs = <HInstruction>[target, receiver, value]; | |
| 1674 add(new HInvokeInterceptor(selector, dartSetterName, false, inputs)); | |
| 1675 } else { | |
| 1676 add(new HInvokeDynamicSetter(selector, null, dartSetterName, | |
| 1677 receiver, value)); | |
| 1678 } | |
| 1679 stack.add(value); | |
| 1680 } else { | 1691 } else { |
| 1681 localsHandler.updateLocal(element, value); | 1692 localsHandler.updateLocal(element, value); |
| 1682 stack.add(value); | 1693 stack.add(value); |
| 1683 } | 1694 } |
| 1684 } | 1695 } |
| 1685 | 1696 |
| 1686 visitOperatorSend(node) { | 1697 visitOperatorSend(node) { |
| 1687 assert(node.selector is Operator); | 1698 assert(node.selector is Operator); |
| 1688 Operator op = node.selector; | 1699 Operator op = node.selector; |
| 1689 if (const SourceString("[]") == op.source) { | 1700 if (const SourceString("[]") == op.source) { |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2194 generateSetter(node, element, value); | 2205 generateSetter(node, element, value); |
| 2195 } else if (op.source.stringValue === "is") { | 2206 } else if (op.source.stringValue === "is") { |
| 2196 compiler.internalError("is-operator as SendSet", node: op); | 2207 compiler.internalError("is-operator as SendSet", node: op); |
| 2197 } else { | 2208 } else { |
| 2198 assert(const SourceString("++") == op.source || | 2209 assert(const SourceString("++") == op.source || |
| 2199 const SourceString("--") == op.source || | 2210 const SourceString("--") == op.source || |
| 2200 node.assignmentOperator.source.stringValue.endsWith("=")); | 2211 node.assignmentOperator.source.stringValue.endsWith("=")); |
| 2201 Element element = elements[node]; | 2212 Element element = elements[node]; |
| 2202 bool isCompoundAssignment = !node.arguments.isEmpty(); | 2213 bool isCompoundAssignment = !node.arguments.isEmpty(); |
| 2203 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. | 2214 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. |
| 2204 generateGetter(node, elements[node.selector]); | 2215 |
| 2216 // [receiver] is only used if the node is an instance send. |
| 2217 HInstruction receiver = null; |
| 2218 if (Elements.isInstanceSend(node, elements)) { |
| 2219 receiver = generateInstanceSendReceiver(node); |
| 2220 generateInstanceGetterWithCompiledReceiver(node, receiver); |
| 2221 } else { |
| 2222 generateGetter(node, elements[node.selector]); |
| 2223 } |
| 2205 HInstruction left = pop(); | 2224 HInstruction left = pop(); |
| 2206 HInstruction right; | 2225 HInstruction right; |
| 2207 if (isCompoundAssignment) { | 2226 if (isCompoundAssignment) { |
| 2208 visit(node.argumentsNode); | 2227 visit(node.argumentsNode); |
| 2209 right = pop(); | 2228 right = pop(); |
| 2210 } else { | 2229 } else { |
| 2211 right = graph.addConstantInt(1); | 2230 right = graph.addConstantInt(1); |
| 2212 } | 2231 } |
| 2213 visitBinary(left, op, right); | 2232 visitBinary(left, op, right); |
| 2214 HInstruction operation = pop(); | 2233 HInstruction operation = pop(); |
| 2215 assert(operation !== null); | 2234 assert(operation !== null); |
| 2216 generateSetter(node, element, operation); | 2235 if (Elements.isInstanceSend(node, elements)) { |
| 2236 assert(receiver !== null); |
| 2237 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); |
| 2238 } else { |
| 2239 assert(receiver === null); |
| 2240 generateSetter(node, element, operation); |
| 2241 } |
| 2217 if (!isPrefix) { | 2242 if (!isPrefix) { |
| 2218 pop(); | 2243 pop(); |
| 2219 stack.add(left); | 2244 stack.add(left); |
| 2220 } | 2245 } |
| 2221 } | 2246 } |
| 2222 } | 2247 } |
| 2223 | 2248 |
| 2224 void visitLiteralInt(LiteralInt node) { | 2249 void visitLiteralInt(LiteralInt node) { |
| 2225 stack.add(graph.addConstantInt(node.value)); | 2250 stack.add(graph.addConstantInt(node.value)); |
| 2226 } | 2251 } |
| (...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2999 false, | 3024 false, |
| 3000 <HInstruction>[target, input])); | 3025 <HInstruction>[target, input])); |
| 3001 return builder.pop(); | 3026 return builder.pop(); |
| 3002 } | 3027 } |
| 3003 | 3028 |
| 3004 HInstruction result() { | 3029 HInstruction result() { |
| 3005 flushLiterals(); | 3030 flushLiterals(); |
| 3006 return prefix; | 3031 return prefix; |
| 3007 } | 3032 } |
| 3008 } | 3033 } |
| OLD | NEW |