Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(791)

Side by Side Diff: lib/compiler/implementation/ssa/builder.dart

Issue 9979021: Fix instance compound assignment. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/language-leg.status » ('j') | tests/language/src/InstanceCompoundAssignmentOperatorTest.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698