| 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 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 List<HInstruction> stack; | 839 List<HInstruction> stack; |
| 840 | 840 |
| 841 // The current block to add instructions to. Might be null, if we are | 841 // The current block to add instructions to. Might be null, if we are |
| 842 // visiting dead code. | 842 // visiting dead code. |
| 843 HBasicBlock current; | 843 HBasicBlock current; |
| 844 // The most recently opened block. Has the same value as [current] while | 844 // The most recently opened block. Has the same value as [current] while |
| 845 // the block is open, but unlike [current], it isn't cleared when the current | 845 // the block is open, but unlike [current], it isn't cleared when the current |
| 846 // block is closed. | 846 // block is closed. |
| 847 HBasicBlock lastOpenedBlock; | 847 HBasicBlock lastOpenedBlock; |
| 848 | 848 |
| 849 List<Element> sourceElementStack; |
| 850 |
| 849 LibraryElement get currentLibrary => work.element.getLibrary(); | 851 LibraryElement get currentLibrary => work.element.getLibrary(); |
| 850 Element get currentElement => work.element; | 852 Element get currentElement => work.element; |
| 851 Compiler get compiler => builder.compiler; | 853 Compiler get compiler => builder.compiler; |
| 852 CodeEmitterTask get emitter => builder.emitter; | 854 CodeEmitterTask get emitter => builder.emitter; |
| 853 | 855 |
| 854 SsaBuilder(this.constantSystem, SsaBuilderTask builder, WorkItem work) | 856 SsaBuilder(this.constantSystem, SsaBuilderTask builder, WorkItem work) |
| 855 : this.builder = builder, | 857 : this.builder = builder, |
| 856 this.backend = builder.backend, | 858 this.backend = builder.backend, |
| 857 this.work = work, | 859 this.work = work, |
| 858 interceptors = builder.interceptors, | 860 interceptors = builder.interceptors, |
| 859 methodInterceptionEnabled = true, | 861 methodInterceptionEnabled = true, |
| 860 graph = new HGraph(), | 862 graph = new HGraph(), |
| 861 stack = new List<HInstruction>(), | 863 stack = new List<HInstruction>(), |
| 862 activationVariables = new Map<Element, HLocalValue>(), | 864 activationVariables = new Map<Element, HLocalValue>(), |
| 863 jumpTargets = new Map<TargetElement, JumpHandler>(), | 865 jumpTargets = new Map<TargetElement, JumpHandler>(), |
| 864 parameters = new Map<Element, HParameterValue>(), | 866 parameters = new Map<Element, HParameterValue>(), |
| 867 sourceElementStack = <Element>[work.element], |
| 865 inliningStack = <InliningState>[], | 868 inliningStack = <InliningState>[], |
| 866 super(work.resolutionTree) { | 869 super(work.resolutionTree) { |
| 867 localsHandler = new LocalsHandler(this); | 870 localsHandler = new LocalsHandler(this); |
| 868 } | 871 } |
| 869 | 872 |
| 870 static const MAX_INLINING_DEPTH = 3; | 873 static const MAX_INLINING_DEPTH = 3; |
| 871 static const MAX_INLINING_SOURCE_SIZE = 100; | 874 static const MAX_INLINING_SOURCE_SIZE = 100; |
| 872 List<InliningState> inliningStack; | 875 List<InliningState> inliningStack; |
| 873 Element returnElement = null; | 876 Element returnElement = null; |
| 874 | 877 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 List<HInstruction> compiledArguments = new List<HInstruction>(); | 956 List<HInstruction> compiledArguments = new List<HInstruction>(); |
| 954 bool succeeded = addStaticSendArgumentsToList(selector, | 957 bool succeeded = addStaticSendArgumentsToList(selector, |
| 955 arguments, | 958 arguments, |
| 956 function, | 959 function, |
| 957 compiledArguments); | 960 compiledArguments); |
| 958 assert(succeeded); | 961 assert(succeeded); |
| 959 | 962 |
| 960 InliningState state = | 963 InliningState state = |
| 961 new InliningState(function, returnElement, elements, stack); | 964 new InliningState(function, returnElement, elements, stack); |
| 962 inliningStack.add(state); | 965 inliningStack.add(state); |
| 966 sourceElementStack.add(function); |
| 963 stack = <HInstruction>[]; | 967 stack = <HInstruction>[]; |
| 964 returnElement = new Element(const SourceString("result"), | 968 returnElement = new Element(const SourceString("result"), |
| 965 ElementKind.VARIABLE, | 969 ElementKind.VARIABLE, |
| 966 function); | 970 function); |
| 967 localsHandler.updateLocal(returnElement, | 971 localsHandler.updateLocal(returnElement, |
| 968 graph.addConstantNull(constantSystem)); | 972 graph.addConstantNull(constantSystem)); |
| 969 elements = compiler.enqueuer.resolution.getCachedElements(function); | 973 elements = compiler.enqueuer.resolution.getCachedElements(function); |
| 970 FunctionSignature signature = function.computeSignature(compiler); | 974 FunctionSignature signature = function.computeSignature(compiler); |
| 971 int index = 0; | 975 int index = 0; |
| 972 signature.forEachParameter((Element parameter) { | 976 signature.forEachParameter((Element parameter) { |
| 973 HInstruction argument = compiledArguments[index++]; | 977 HInstruction argument = compiledArguments[index++]; |
| 974 localsHandler.updateLocal(parameter, argument); | 978 localsHandler.updateLocal(parameter, argument); |
| 975 potentiallyCheckType(argument, parameter); | 979 potentiallyCheckType(argument, parameter); |
| 976 }); | 980 }); |
| 977 return state; | 981 return state; |
| 978 } | 982 } |
| 979 | 983 |
| 980 void leaveInlinedMethod(InliningState state) { | 984 void leaveInlinedMethod(InliningState state) { |
| 981 InliningState poppedState = inliningStack.removeLast(); | 985 InliningState poppedState = inliningStack.removeLast(); |
| 982 assert(state == poppedState); | 986 assert(state == poppedState); |
| 987 FunctionElement poppedElement = sourceElementStack.removeLast(); |
| 988 assert(poppedElement == poppedState.function); |
| 983 elements = state.oldElements; | 989 elements = state.oldElements; |
| 984 stack.add(localsHandler.readLocal(returnElement)); | 990 stack.add(localsHandler.readLocal(returnElement)); |
| 985 returnElement = state.oldReturnElement; | 991 returnElement = state.oldReturnElement; |
| 986 assert(stack.length == 1); | 992 assert(stack.length == 1); |
| 987 state.oldStack.add(stack[0]); | 993 state.oldStack.add(stack[0]); |
| 988 stack = state.oldStack; | 994 stack = state.oldStack; |
| 989 } | 995 } |
| 990 | 996 |
| 991 bool tryInlineMethod(Element element, | 997 bool tryInlineMethod(Element element, |
| 992 Selector selector, | 998 Selector selector, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 Selector selector = elements.getSelector(call); | 1106 Selector selector = elements.getSelector(call); |
| 1101 Link<Node> arguments = call.arguments; | 1107 Link<Node> arguments = call.arguments; |
| 1102 inlineSuperOrRedirect(target, selector, arguments, constructors, | 1108 inlineSuperOrRedirect(target, selector, arguments, constructors, |
| 1103 fieldValues); | 1109 fieldValues); |
| 1104 foundSuperOrRedirect = true; | 1110 foundSuperOrRedirect = true; |
| 1105 } else { | 1111 } else { |
| 1106 // A field initializer. | 1112 // A field initializer. |
| 1107 SendSet init = link.head; | 1113 SendSet init = link.head; |
| 1108 Link<Node> arguments = init.arguments; | 1114 Link<Node> arguments = init.arguments; |
| 1109 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); | 1115 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); |
| 1116 sourceElementStack.add(constructor); |
| 1110 visit(arguments.head); | 1117 visit(arguments.head); |
| 1118 sourceElementStack.removeLast(); |
| 1111 fieldValues[elements[init]] = pop(); | 1119 fieldValues[elements[init]] = pop(); |
| 1112 } | 1120 } |
| 1113 } | 1121 } |
| 1114 } | 1122 } |
| 1115 | 1123 |
| 1116 if (!foundSuperOrRedirect) { | 1124 if (!foundSuperOrRedirect) { |
| 1117 // No super initializer found. Try to find the default constructor if | 1125 // No super initializer found. Try to find the default constructor if |
| 1118 // the class is not Object. | 1126 // the class is not Object. |
| 1119 ClassElement enclosingClass = constructor.getEnclosingClass(); | 1127 ClassElement enclosingClass = constructor.getEnclosingClass(); |
| 1120 ClassElement superClass = enclosingClass.superclass; | 1128 ClassElement superClass = enclosingClass.superclass; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1434 stack.add(stack.last()); | 1442 stack.add(stack.last()); |
| 1435 } | 1443 } |
| 1436 | 1444 |
| 1437 HBoolify popBoolified() { | 1445 HBoolify popBoolified() { |
| 1438 HBoolify boolified = new HBoolify(pop()); | 1446 HBoolify boolified = new HBoolify(pop()); |
| 1439 add(boolified); | 1447 add(boolified); |
| 1440 return boolified; | 1448 return boolified; |
| 1441 } | 1449 } |
| 1442 | 1450 |
| 1443 HInstruction attachPosition(HInstruction target, Node node) { | 1451 HInstruction attachPosition(HInstruction target, Node node) { |
| 1444 target.sourcePosition = node.getBeginToken(); | 1452 target.sourcePosition = sourceFileLocationForToken(node.getBeginToken()); |
| 1445 return target; | 1453 return target; |
| 1446 } | 1454 } |
| 1447 | 1455 |
| 1456 SourceFileLocation sourceFileLocationForToken(Token token) { |
| 1457 Element element = sourceElementStack.last(); |
| 1458 // TODO(johnniwinther): remove the 'element.patch' hack. |
| 1459 if (element is FunctionElement) { |
| 1460 FunctionElement functionElement = element; |
| 1461 if (functionElement.patch != null) element = functionElement.patch; |
| 1462 } |
| 1463 SourceFile sourceFile = element.getCompilationUnit().script.file; |
| 1464 return new SourceFileLocation(sourceFile, token); |
| 1465 } |
| 1466 |
| 1448 void visit(Node node) { | 1467 void visit(Node node) { |
| 1449 if (node !== null) node.accept(this); | 1468 if (node !== null) node.accept(this); |
| 1450 } | 1469 } |
| 1451 | 1470 |
| 1452 visitBlock(Block node) { | 1471 visitBlock(Block node) { |
| 1453 for (Link<Node> link = node.statements.nodes; | 1472 for (Link<Node> link = node.statements.nodes; |
| 1454 !link.isEmpty(); | 1473 !link.isEmpty(); |
| 1455 link = link.tail) { | 1474 link = link.tail) { |
| 1456 visit(link.head); | 1475 visit(link.head); |
| 1457 if (isAborted()) { | 1476 if (isAborted()) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1636 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); | 1655 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| 1637 HLoopBlockInformation info = | 1656 HLoopBlockInformation info = |
| 1638 new HLoopBlockInformation( | 1657 new HLoopBlockInformation( |
| 1639 HLoopBlockInformation.loopType(loop), | 1658 HLoopBlockInformation.loopType(loop), |
| 1640 wrapExpressionGraph(initializerGraph), | 1659 wrapExpressionGraph(initializerGraph), |
| 1641 wrapExpressionGraph(conditionExpression), | 1660 wrapExpressionGraph(conditionExpression), |
| 1642 wrapStatementGraph(bodyGraph), | 1661 wrapStatementGraph(bodyGraph), |
| 1643 wrapExpressionGraph(updateGraph), | 1662 wrapExpressionGraph(updateGraph), |
| 1644 conditionBlock.loopInformation.target, | 1663 conditionBlock.loopInformation.target, |
| 1645 conditionBlock.loopInformation.labels, | 1664 conditionBlock.loopInformation.labels, |
| 1646 loop); | 1665 sourceFileLocationForToken(loop.getBeginToken()), |
| 1666 sourceFileLocationForToken(loop.getEndToken())); |
| 1647 | 1667 |
| 1648 startBlock.setBlockFlow(info, current); | 1668 startBlock.setBlockFlow(info, current); |
| 1649 loopInfo.loopBlockInformation = info; | 1669 loopInfo.loopBlockInformation = info; |
| 1650 } | 1670 } |
| 1651 | 1671 |
| 1652 visitFor(For node) { | 1672 visitFor(For node) { |
| 1653 assert(node.body !== null); | 1673 assert(node.body !== null); |
| 1654 void buildInitializer() { | 1674 void buildInitializer() { |
| 1655 if (node.initializer === null) return; | 1675 if (node.initializer === null) return; |
| 1656 Node initializer = node.initializer; | 1676 Node initializer = node.initializer; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 | 1784 |
| 1765 HLoopBlockInformation loopBlockInfo = | 1785 HLoopBlockInformation loopBlockInfo = |
| 1766 new HLoopBlockInformation( | 1786 new HLoopBlockInformation( |
| 1767 HLoopBlockInformation.DO_WHILE_LOOP, | 1787 HLoopBlockInformation.DO_WHILE_LOOP, |
| 1768 null, | 1788 null, |
| 1769 wrapExpressionGraph(conditionExpression), | 1789 wrapExpressionGraph(conditionExpression), |
| 1770 wrapStatementGraph(bodyGraph), | 1790 wrapStatementGraph(bodyGraph), |
| 1771 null, | 1791 null, |
| 1772 loopEntryBlock.loopInformation.target, | 1792 loopEntryBlock.loopInformation.target, |
| 1773 loopEntryBlock.loopInformation.labels, | 1793 loopEntryBlock.loopInformation.labels, |
| 1774 node); | 1794 sourceFileLocationForToken(node.getBeginToken()), |
| 1795 sourceFileLocationForToken(node.getEndToken())); |
| 1775 loopEntryBlock.setBlockFlow(loopBlockInfo, current); | 1796 loopEntryBlock.setBlockFlow(loopBlockInfo, current); |
| 1776 loopInfo.loopBlockInformation = loopBlockInfo; | 1797 loopInfo.loopBlockInformation = loopBlockInfo; |
| 1777 } | 1798 } |
| 1778 | 1799 |
| 1779 visitFunctionExpression(FunctionExpression node) { | 1800 visitFunctionExpression(FunctionExpression node) { |
| 1780 ClosureClassMap nestedClosureData = | 1801 ClosureClassMap nestedClosureData = |
| 1781 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 1802 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
| 1782 assert(nestedClosureData !== null); | 1803 assert(nestedClosureData !== null); |
| 1783 assert(nestedClosureData.closureClassElement !== null); | 1804 assert(nestedClosureData.closureClassElement !== null); |
| 1784 ClassElement closureClassElement = | 1805 ClassElement closureClassElement = |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2710 Element helper = interceptors.getThrowRuntimeError(); | 2731 Element helper = interceptors.getThrowRuntimeError(); |
| 2711 pushInvokeHelper1(helper, errorMessage); | 2732 pushInvokeHelper1(helper, errorMessage); |
| 2712 } | 2733 } |
| 2713 | 2734 |
| 2714 void generateThrowNoSuchMethod(Node diagnosticNode, | 2735 void generateThrowNoSuchMethod(Node diagnosticNode, |
| 2715 String methodName, | 2736 String methodName, |
| 2716 [Link<Node> argumentNodes, | 2737 [Link<Node> argumentNodes, |
| 2717 List<HInstruction> argumentValues]) { | 2738 List<HInstruction> argumentValues]) { |
| 2718 Element helper = | 2739 Element helper = |
| 2719 compiler.findHelper(const SourceString('throwNoSuchMethod')); | 2740 compiler.findHelper(const SourceString('throwNoSuchMethod')); |
| 2720 Constant receiverConstant = | 2741 Constant receiverConstant = |
| 2721 constantSystem.createString(new DartString.empty(), diagnosticNode); | 2742 constantSystem.createString(new DartString.empty(), diagnosticNode); |
| 2722 HInstruction receiver = graph.addConstant(receiverConstant); | 2743 HInstruction receiver = graph.addConstant(receiverConstant); |
| 2723 DartString dartString = new DartString.literal(methodName); | 2744 DartString dartString = new DartString.literal(methodName); |
| 2724 Constant nameConstant = | 2745 Constant nameConstant = |
| 2725 constantSystem.createString(dartString, diagnosticNode); | 2746 constantSystem.createString(dartString, diagnosticNode); |
| 2726 HInstruction name = graph.addConstant(nameConstant); | 2747 HInstruction name = graph.addConstant(nameConstant); |
| 2727 if (argumentValues == null) { | 2748 if (argumentValues == null) { |
| 2728 argumentValues = <HInstruction>[]; | 2749 argumentValues = <HInstruction>[]; |
| 2729 argumentNodes.forEach((argumentNode) { | 2750 argumentNodes.forEach((argumentNode) { |
| 2730 visit(argumentNode); | 2751 visit(argumentNode); |
| (...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4072 new HSubGraphBlockInformation(elseBranch.graph)); | 4093 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4073 | 4094 |
| 4074 HBasicBlock conditionStartBlock = conditionBranch.block; | 4095 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4075 conditionStartBlock.setBlockFlow(info, joinBlock); | 4096 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4076 SubGraph conditionGraph = conditionBranch.graph; | 4097 SubGraph conditionGraph = conditionBranch.graph; |
| 4077 HIf branch = conditionGraph.end.last; | 4098 HIf branch = conditionGraph.end.last; |
| 4078 assert(branch is HIf); | 4099 assert(branch is HIf); |
| 4079 branch.blockInformation = conditionStartBlock.blockFlow; | 4100 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4080 } | 4101 } |
| 4081 } | 4102 } |
| OLD | NEW |