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