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

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: More tests. 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
« no previous file with comments | « no previous file | tests/language/language-leg.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/language-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698