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

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

Issue 10809004: Attach source map positions to returns, sends, and some operators. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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/compiler/dart2js/source_mapping_test.dart » ('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 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 HBasicBlock newBlock = addNewBlock(); 1158 HBasicBlock newBlock = addNewBlock();
1159 if (!isAborted()) goto(current, newBlock); 1159 if (!isAborted()) goto(current, newBlock);
1160 open(newBlock); 1160 open(newBlock);
1161 return newBlock; 1161 return newBlock;
1162 } 1162 }
1163 1163
1164 void add(HInstruction instruction) { 1164 void add(HInstruction instruction) {
1165 current.add(instruction); 1165 current.add(instruction);
1166 } 1166 }
1167 1167
1168 void addWithPosition(HInstruction instruction, Node node) {
1169 add(attachPosition(instruction, node));
1170 }
1171
1168 void push(HInstruction instruction) { 1172 void push(HInstruction instruction) {
1169 add(instruction); 1173 add(instruction);
1170 stack.add(instruction); 1174 stack.add(instruction);
1171 } 1175 }
1172 1176
1177 void pushWithPosition(HInstruction instruction, Node node) {
1178 push(attachPosition(instruction, node));
1179 }
1180
1173 HInstruction pop() { 1181 HInstruction pop() {
1174 return stack.removeLast(); 1182 return stack.removeLast();
1175 } 1183 }
1176 1184
1177 void dup() { 1185 void dup() {
1178 stack.add(stack.last()); 1186 stack.add(stack.last());
1179 } 1187 }
1180 1188
1181 HBoolify popBoolified() { 1189 HBoolify popBoolified() {
1182 HBoolify boolified = new HBoolify(pop()); 1190 HBoolify boolified = new HBoolify(pop());
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 node.receiver, 1591 node.receiver,
1584 () { visit(node.argumentsNode); }, 1592 () { visit(node.argumentsNode); },
1585 isAnd: (const SourceString("&&") == op.source)); 1593 isAnd: (const SourceString("&&") == op.source));
1586 } 1594 }
1587 1595
1588 1596
1589 void visitLogicalNot(Send node) { 1597 void visitLogicalNot(Send node) {
1590 assert(node.argumentsNode is Prefix); 1598 assert(node.argumentsNode is Prefix);
1591 visit(node.receiver); 1599 visit(node.receiver);
1592 HNot not = new HNot(popBoolified()); 1600 HNot not = new HNot(popBoolified());
1593 push(not); 1601 pushWithPosition(not, node);
1594 } 1602 }
1595 1603
1596 void visitUnary(Send node, Operator op) { 1604 void visitUnary(Send node, Operator op) {
1597 assert(node.argumentsNode is Prefix); 1605 assert(node.argumentsNode is Prefix);
1598 visit(node.receiver); 1606 visit(node.receiver);
1599 assert(op.token.kind !== PLUS_TOKEN); 1607 assert(op.token.kind !== PLUS_TOKEN);
1600 HInstruction operand = pop(); 1608 HInstruction operand = pop();
1601 1609
1602 HInstruction target = attachPosition( 1610 HInstruction target =
1603 new HStatic(interceptors.getPrefixOperatorInterceptor(op)), node); 1611 new HStatic(interceptors.getPrefixOperatorInterceptor(op));
1604 add(target); 1612 add(target);
1605 HInvokeUnary result; 1613 HInvokeUnary result;
1606 String value = op.source.stringValue; 1614 String value = op.source.stringValue;
1607 switch (value) { 1615 switch (value) {
1608 case "-": result = new HNegate(target, operand); break; 1616 case "-": result = new HNegate(target, operand); break;
1609 case "~": result = new HBitNot(target, operand); break; 1617 case "~": result = new HBitNot(target, operand); break;
1610 default: 1618 default:
1611 compiler.internalError('Unexpected unary operator: $value.', node: op); 1619 compiler.internalError('Unexpected unary operator: $value.', node: op);
1612 break; 1620 break;
1613 } 1621 }
1614 // See if we can constant-fold right away. This avoids rewrites later on. 1622 // See if we can constant-fold right away. This avoids rewrites later on.
1615 if (operand is HConstant) { 1623 if (operand is HConstant) {
1616 HConstant constant = operand; 1624 HConstant constant = operand;
1617 Constant folded = result.operation.fold(constant.constant); 1625 Constant folded = result.operation.fold(constant.constant);
1618 if (folded !== null) { 1626 if (folded !== null) {
1619 stack.add(graph.addConstant(folded)); 1627 stack.add(graph.addConstant(folded));
1620 return; 1628 return;
1621 } 1629 }
1622 } 1630 }
1623 push(result); 1631 pushWithPosition(result, node);
1624 } 1632 }
1625 1633
1626 void visitBinary(HInstruction left, Operator op, HInstruction right) { 1634 void visitBinary(HInstruction left, Operator op, HInstruction right) {
1627 Element element = interceptors.getOperatorInterceptor(op); 1635 Element element = interceptors.getOperatorInterceptor(op);
1628 assert(element != null); 1636 assert(element != null);
1629 HInstruction target = new HStatic(element); 1637 HInstruction target = new HStatic(element);
1630 add(target); 1638 add(target);
1631 switch (op.source.stringValue) { 1639 switch (op.source.stringValue) {
1632 case "+": 1640 case "+":
1633 case "++": 1641 case "++":
1634 case "+=": 1642 case "+=":
1635 push(new HAdd(target, left, right)); 1643 pushWithPosition(new HAdd(target, left, right), op);
1636 break; 1644 break;
1637 case "-": 1645 case "-":
1638 case "--": 1646 case "--":
1639 case "-=": 1647 case "-=":
1640 push(new HSubtract(target, left, right)); 1648 pushWithPosition(new HSubtract(target, left, right), op);
1641 break; 1649 break;
1642 case "*": 1650 case "*":
1643 case "*=": 1651 case "*=":
1644 push(new HMultiply(target, left, right)); 1652 pushWithPosition(new HMultiply(target, left, right), op);
1645 break; 1653 break;
1646 case "/": 1654 case "/":
1647 case "/=": 1655 case "/=":
1648 push(new HDivide(target, left, right)); 1656 pushWithPosition(new HDivide(target, left, right), op);
1649 break; 1657 break;
1650 case "~/": 1658 case "~/":
1651 case "~/=": 1659 case "~/=":
1652 push(new HTruncatingDivide(target, left, right)); 1660 pushWithPosition(new HTruncatingDivide(target, left, right), op);
1653 break; 1661 break;
1654 case "%": 1662 case "%":
1655 case "%=": 1663 case "%=":
1656 push(new HModulo(target, left, right)); 1664 pushWithPosition(new HModulo(target, left, right), op);
1657 break; 1665 break;
1658 case "<<": 1666 case "<<":
1659 case "<<=": 1667 case "<<=":
1660 push(new HShiftLeft(target, left, right)); 1668 pushWithPosition(new HShiftLeft(target, left, right), op);
1661 break; 1669 break;
1662 case ">>": 1670 case ">>":
1663 case ">>=": 1671 case ">>=":
1664 push(new HShiftRight(target, left, right)); 1672 pushWithPosition(new HShiftRight(target, left, right), op);
1665 break; 1673 break;
1666 case "|": 1674 case "|":
1667 case "|=": 1675 case "|=":
1668 push(new HBitOr(target, left, right)); 1676 pushWithPosition(new HBitOr(target, left, right), op);
1669 break; 1677 break;
1670 case "&": 1678 case "&":
1671 case "&=": 1679 case "&=":
1672 push(new HBitAnd(target, left, right)); 1680 pushWithPosition(new HBitAnd(target, left, right), op);
1673 break; 1681 break;
1674 case "^": 1682 case "^":
1675 case "^=": 1683 case "^=":
1676 push(new HBitXor(target, left, right)); 1684 pushWithPosition(new HBitXor(target, left, right), op);
1677 break; 1685 break;
1678 case "==": 1686 case "==":
1679 push(new HEquals(target, left, right)); 1687 pushWithPosition(new HEquals(target, left, right), op);
1680 break; 1688 break;
1681 case "===": 1689 case "===":
1682 push(new HIdentity(target, left, right)); 1690 pushWithPosition(new HIdentity(target, left, right), op);
1683 break; 1691 break;
1684 case "!==": 1692 case "!==":
1685 HIdentity eq = new HIdentity(target, left, right); 1693 HIdentity eq = new HIdentity(target, left, right);
1686 add(eq); 1694 add(eq);
1687 push(new HNot(eq)); 1695 pushWithPosition(new HNot(eq), op);
1688 break; 1696 break;
1689 case "<": 1697 case "<":
1690 push(new HLess(target, left, right)); 1698 pushWithPosition(new HLess(target, left, right), op);
1691 break; 1699 break;
1692 case "<=": 1700 case "<=":
1693 push(new HLessEqual(target, left, right)); 1701 pushWithPosition(new HLessEqual(target, left, right), op);
1694 break; 1702 break;
1695 case ">": 1703 case ">":
1696 push(new HGreater(target, left, right)); 1704 pushWithPosition(new HGreater(target, left, right), op);
1697 break; 1705 break;
1698 case ">=": 1706 case ">=":
1699 push(new HGreaterEqual(target, left, right)); 1707 pushWithPosition(new HGreaterEqual(target, left, right), op);
1700 break; 1708 break;
1701 case "!=": 1709 case "!=":
1702 HEquals eq = new HEquals(target, left, right); 1710 HEquals eq = new HEquals(target, left, right);
1703 add(eq); 1711 add(eq);
1704 HBoolify bl = new HBoolify(eq); 1712 HBoolify bl = new HBoolify(eq);
1705 add(bl); 1713 add(bl);
1706 push(new HNot(bl)); 1714 pushWithPosition(new HNot(bl), op);
1707 break; 1715 break;
1708 default: compiler.unimplemented("SsaBuilder.visitBinary"); 1716 default: compiler.unimplemented("SsaBuilder.visitBinary");
1709 } 1717 }
1710 } 1718 }
1711 1719
1712 HInstruction generateInstanceSendReceiver(Send send) { 1720 HInstruction generateInstanceSendReceiver(Send send) {
1713 assert(Elements.isInstanceSend(send, elements)); 1721 assert(Elements.isInstanceSend(send, elements));
1714 if (send.receiver == null) { 1722 if (send.receiver == null) {
1715 return localsHandler.readThis(); 1723 return localsHandler.readThis();
1716 } 1724 }
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2005 if (node.receiver === null) { 2013 if (node.receiver === null) {
2006 inputs.add(localsHandler.readThis()); 2014 inputs.add(localsHandler.readThis());
2007 } else { 2015 } else {
2008 visit(node.receiver); 2016 visit(node.receiver);
2009 inputs.add(pop()); 2017 inputs.add(pop());
2010 } 2018 }
2011 2019
2012 addDynamicSendArgumentsToList(node, inputs); 2020 addDynamicSendArgumentsToList(node, inputs);
2013 2021
2014 // The first entry in the inputs list is the receiver. 2022 // The first entry in the inputs list is the receiver.
2015 push(new HInvokeDynamicMethod(selector, dartMethodName, inputs)); 2023 pushWithPosition(new HInvokeDynamicMethod(selector, dartMethodName, inputs),
2024 node);
2016 2025
2017 if (isNotEquals) { 2026 if (isNotEquals) {
2018 HNot not = new HNot(popBoolified()); 2027 HNot not = new HNot(popBoolified());
2019 push(not); 2028 push(not);
2020 } 2029 }
2021 } 2030 }
2022 2031
2023 visitClosureSend(Send node) { 2032 visitClosureSend(Send node) {
2024 Selector selector = elements.getSelector(node); 2033 Selector selector = elements.getSelector(node);
2025 assert(node.receiver === null); 2034 assert(node.receiver === null);
2026 Element element = elements[node]; 2035 Element element = elements[node];
2027 HInstruction closureTarget; 2036 HInstruction closureTarget;
2028 if (element === null) { 2037 if (element === null) {
2029 visit(node.selector); 2038 visit(node.selector);
2030 closureTarget = pop(); 2039 closureTarget = pop();
2031 } else { 2040 } else {
2032 assert(Elements.isLocal(element)); 2041 assert(Elements.isLocal(element));
2033 closureTarget = localsHandler.readLocal(element); 2042 closureTarget = localsHandler.readLocal(element);
2034 } 2043 }
2035 var inputs = <HInstruction>[]; 2044 var inputs = <HInstruction>[];
2036 inputs.add(closureTarget); 2045 inputs.add(closureTarget);
2037 addDynamicSendArgumentsToList(node, inputs); 2046 addDynamicSendArgumentsToList(node, inputs);
2038 push(new HInvokeClosure(selector, inputs)); 2047 pushWithPosition(new HInvokeClosure(selector, inputs), node);
2039 } 2048 }
2040 2049
2041 void handleForeignJs(Send node) { 2050 void handleForeignJs(Send node) {
2042 Link<Node> link = node.arguments; 2051 Link<Node> link = node.arguments;
2043 // If the invoke is on foreign code, don't visit the first 2052 // If the invoke is on foreign code, don't visit the first
2044 // argument, which is the type, and the second argument, 2053 // argument, which is the type, and the second argument,
2045 // which is the foreign code. 2054 // which is the foreign code.
2046 if (link.isEmpty() || link.isEmpty()) { 2055 if (link.isEmpty() || link.isEmpty()) {
2047 compiler.cancel('At least two arguments expected', 2056 compiler.cancel('At least two arguments expected',
2048 node: node.argumentsNode); 2057 node: node.argumentsNode);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2285 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2277 element, inputs); 2286 element, inputs);
2278 if (!succeeded) { 2287 if (!succeeded) {
2279 // TODO(ngeoffray): Match the VM behavior and throw an 2288 // TODO(ngeoffray): Match the VM behavior and throw an
2280 // exception at runtime. 2289 // exception at runtime.
2281 compiler.cancel('Unimplemented non-matching static call', node: node); 2290 compiler.cancel('Unimplemented non-matching static call', node: node);
2282 } 2291 }
2283 2292
2284 HType elementType = computeType(element); 2293 HType elementType = computeType(element);
2285 HInstruction newInstance = new HInvokeStatic(selector, inputs, elementType); 2294 HInstruction newInstance = new HInvokeStatic(selector, inputs, elementType);
2286 push(newInstance); 2295 pushWithPosition(newInstance, node);
2287 2296
2288 TypeAnnotation annotation = getTypeAnnotationFromSend(node); 2297 TypeAnnotation annotation = getTypeAnnotationFromSend(node);
2289 Type type = elements.getType(annotation); 2298 Type type = elements.getType(annotation);
2290 generateSetRuntimeTypeInformation(newInstance, type); 2299 generateSetRuntimeTypeInformation(newInstance, type);
2291 } 2300 }
2292 2301
2293 generateSetRuntimeTypeInformation(HInstruction instance, Type type) { 2302 generateSetRuntimeTypeInformation(HInstruction instance, Type type) {
2294 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { 2303 if (compiler.codegenWorld.rti.hasTypeArguments(type)) {
2295 String typeString = compiler.codegenWorld.rti.asJsString(type); 2304 String typeString = compiler.codegenWorld.rti.asJsString(type);
2296 HInstruction typeInfo = new HForeign(new LiteralDartString(typeString), 2305 HInstruction typeInfo = new HForeign(new LiteralDartString(typeString),
(...skipping 22 matching lines...) Expand all
2319 var inputs = <HInstruction>[]; 2328 var inputs = <HInstruction>[];
2320 inputs.add(target); 2329 inputs.add(target);
2321 if (element.kind == ElementKind.FUNCTION) { 2330 if (element.kind == ElementKind.FUNCTION) {
2322 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2331 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2323 element, inputs); 2332 element, inputs);
2324 if (!succeeded) { 2333 if (!succeeded) {
2325 // TODO(ngeoffray): Match the VM behavior and throw an 2334 // TODO(ngeoffray): Match the VM behavior and throw an
2326 // exception at runtime. 2335 // exception at runtime.
2327 compiler.cancel('Unimplemented non-matching static call', node: node); 2336 compiler.cancel('Unimplemented non-matching static call', node: node);
2328 } 2337 }
2329 push(new HInvokeStatic(selector, inputs)); 2338 pushWithPosition(new HInvokeStatic(selector, inputs), node);
2330 } else { 2339 } else {
2331 if (element.kind == ElementKind.GETTER) { 2340 if (element.kind == ElementKind.GETTER) {
2332 target = new HInvokeStatic(Selector.GETTER, inputs); 2341 target = new HInvokeStatic(Selector.GETTER, inputs);
2333 add(target); 2342 add(target);
2334 inputs = <HInstruction>[target]; 2343 inputs = <HInstruction>[target];
2335 } 2344 }
2336 addDynamicSendArgumentsToList(node, inputs); 2345 addDynamicSendArgumentsToList(node, inputs);
2337 push(new HInvokeClosure(selector, inputs)); 2346 pushWithPosition(new HInvokeClosure(selector, inputs), node);
2338 } 2347 }
2339 } 2348 }
2340 2349
2341 visitGetterSend(Send node) { 2350 visitGetterSend(Send node) {
2342 generateGetter(node, elements[node]); 2351 generateGetter(node, elements[node]);
2343 } 2352 }
2344 2353
2345 // TODO(antonm): migrate rest of SsaBuilder to internalError. 2354 // TODO(antonm): migrate rest of SsaBuilder to internalError.
2346 internalError(String reason, [Node node]) { 2355 internalError(String reason, [Node node]) {
2347 compiler.internalError(reason, node: node); 2356 compiler.internalError(reason, node: node);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 native.handleSsaNative(this, node.expression); 2556 native.handleSsaNative(this, node.expression);
2548 return; 2557 return;
2549 } 2558 }
2550 HInstruction value; 2559 HInstruction value;
2551 if (node.expression === null) { 2560 if (node.expression === null) {
2552 value = graph.addConstantNull(); 2561 value = graph.addConstantNull();
2553 } else { 2562 } else {
2554 visit(node.expression); 2563 visit(node.expression);
2555 value = pop(); 2564 value = pop();
2556 } 2565 }
2557 close(new HReturn(value)).addSuccessor(graph.exit); 2566 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit);
2558 } 2567 }
2559 2568
2560 visitThrow(Throw node) { 2569 visitThrow(Throw node) {
2561 if (node.expression === null) { 2570 if (node.expression === null) {
2562 HInstruction exception = rethrowableException; 2571 HInstruction exception = rethrowableException;
2563 if (exception === null) { 2572 if (exception === null) {
2564 exception = graph.addConstantNull(); 2573 exception = graph.addConstantNull();
2565 compiler.reportError(node, 2574 compiler.reportError(node,
2566 'throw without expression outside catch block'); 2575 'throw without expression outside catch block');
2567 } 2576 }
(...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after
3574 new HSubGraphBlockInformation(elseBranch.graph)); 3583 new HSubGraphBlockInformation(elseBranch.graph));
3575 3584
3576 HBasicBlock conditionStartBlock = conditionBranch.block; 3585 HBasicBlock conditionStartBlock = conditionBranch.block;
3577 conditionStartBlock.setBlockFlow(info, joinBlock); 3586 conditionStartBlock.setBlockFlow(info, joinBlock);
3578 SubGraph conditionGraph = conditionBranch.graph; 3587 SubGraph conditionGraph = conditionBranch.graph;
3579 HIf branch = conditionGraph.end.last; 3588 HIf branch = conditionGraph.end.last;
3580 assert(branch is HIf); 3589 assert(branch is HIf);
3581 branch.blockInformation = conditionStartBlock.blockFlow; 3590 branch.blockInformation = conditionStartBlock.blockFlow;
3582 } 3591 }
3583 } 3592 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/source_mapping_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698