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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 emitter = backend.emitter, | 150 emitter = backend.emitter, |
151 functionsCalledInLoop = new Set<FunctionElement>(), | 151 functionsCalledInLoop = new Set<FunctionElement>(), |
152 selectorsCalledInLoop = new Map<SourceString, Selector>(), | 152 selectorsCalledInLoop = new Map<SourceString, Selector>(), |
153 backend = backend, | 153 backend = backend, |
154 super(backend.compiler); | 154 super(backend.compiler); |
155 | 155 |
156 HGraph build(WorkItem work) { | 156 HGraph build(WorkItem work) { |
157 return measure(() { | 157 return measure(() { |
158 FunctionElement element = work.element; | 158 FunctionElement element = work.element; |
159 HInstruction.idCounter = 0; | 159 HInstruction.idCounter = 0; |
160 SsaBuilder builder = new SsaBuilder(this, work); | 160 ConstantSystem constantSystem = |
| 161 compiler.constantHandler.constantSystem; |
| 162 SsaBuilder builder = new SsaBuilder(constantSystem, this, work); |
161 HGraph graph; | 163 HGraph graph; |
162 ElementKind kind = element.kind; | 164 ElementKind kind = element.kind; |
163 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { | 165 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { |
164 graph = compileConstructor(builder, work); | 166 graph = compileConstructor(builder, work); |
165 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || | 167 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || |
166 kind === ElementKind.FUNCTION || | 168 kind === ElementKind.FUNCTION || |
167 kind === ElementKind.GETTER || | 169 kind === ElementKind.GETTER || |
168 kind === ElementKind.SETTER) { | 170 kind === ElementKind.SETTER) { |
169 graph = builder.buildMethod(work.element); | 171 graph = builder.buildMethod(work.element); |
170 } | 172 } |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 result.add(element); | 797 result.add(element); |
796 } | 798 } |
797 return (result === null) ? const <LabelElement>[] : result; | 799 return (result === null) ? const <LabelElement>[] : result; |
798 } | 800 } |
799 } | 801 } |
800 | 802 |
801 class SsaBuilder extends ResolvedVisitor implements Visitor { | 803 class SsaBuilder extends ResolvedVisitor implements Visitor { |
802 final SsaBuilderTask builder; | 804 final SsaBuilderTask builder; |
803 final Interceptors interceptors; | 805 final Interceptors interceptors; |
804 final WorkItem work; | 806 final WorkItem work; |
| 807 final ConstantSystem constantSystem; |
805 bool methodInterceptionEnabled; | 808 bool methodInterceptionEnabled; |
806 HGraph graph; | 809 HGraph graph; |
807 LocalsHandler localsHandler; | 810 LocalsHandler localsHandler; |
808 HInstruction rethrowableException; | 811 HInstruction rethrowableException; |
809 Map<Element, HParameterValue> parameters; | 812 Map<Element, HParameterValue> parameters; |
810 | 813 |
811 Map<TargetElement, JumpHandler> jumpTargets; | 814 Map<TargetElement, JumpHandler> jumpTargets; |
812 | 815 |
813 /** | 816 /** |
814 * Variables stored in the current activation. These variables are | 817 * Variables stored in the current activation. These variables are |
(...skipping 10 matching lines...) Expand all Loading... |
825 HBasicBlock current; | 828 HBasicBlock current; |
826 // The most recently opened block. Has the same value as [current] while | 829 // The most recently opened block. Has the same value as [current] while |
827 // the block is open, but unlike [current], it isn't cleared when the current | 830 // the block is open, but unlike [current], it isn't cleared when the current |
828 // block is closed. | 831 // block is closed. |
829 HBasicBlock lastOpenedBlock; | 832 HBasicBlock lastOpenedBlock; |
830 | 833 |
831 LibraryElement get currentLibrary => work.element.getLibrary(); | 834 LibraryElement get currentLibrary => work.element.getLibrary(); |
832 Compiler get compiler => builder.compiler; | 835 Compiler get compiler => builder.compiler; |
833 CodeEmitterTask get emitter => builder.emitter; | 836 CodeEmitterTask get emitter => builder.emitter; |
834 | 837 |
835 SsaBuilder(SsaBuilderTask builder, WorkItem work) | 838 SsaBuilder(this.constantSystem, SsaBuilderTask builder, WorkItem work) |
836 : this.builder = builder, | 839 : this.builder = builder, |
837 this.work = work, | 840 this.work = work, |
838 interceptors = builder.interceptors, | 841 interceptors = builder.interceptors, |
839 methodInterceptionEnabled = true, | 842 methodInterceptionEnabled = true, |
840 graph = new HGraph(), | 843 graph = new HGraph(), |
841 stack = new List<HInstruction>(), | 844 stack = new List<HInstruction>(), |
842 activationVariables = new Map<Element, HLocalValue>(), | 845 activationVariables = new Map<Element, HLocalValue>(), |
843 jumpTargets = new Map<TargetElement, JumpHandler>(), | 846 jumpTargets = new Map<TargetElement, JumpHandler>(), |
844 parameters = new Map<Element, HParameterValue>(), | 847 parameters = new Map<Element, HParameterValue>(), |
845 inliningStack = <InliningState>[], | 848 inliningStack = <InliningState>[], |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 compiledArguments); | 926 compiledArguments); |
924 assert(succeeded); | 927 assert(succeeded); |
925 | 928 |
926 InliningState state = | 929 InliningState state = |
927 new InliningState(function, returnElement, elements, stack); | 930 new InliningState(function, returnElement, elements, stack); |
928 inliningStack.add(state); | 931 inliningStack.add(state); |
929 stack = <HInstruction>[]; | 932 stack = <HInstruction>[]; |
930 returnElement = new Element(const SourceString("result"), | 933 returnElement = new Element(const SourceString("result"), |
931 ElementKind.VARIABLE, | 934 ElementKind.VARIABLE, |
932 function); | 935 function); |
933 localsHandler.updateLocal(returnElement, graph.addConstantNull()); | 936 Constant constantNull = constantSystem.createNull(); |
| 937 localsHandler.updateLocal(returnElement, graph.addConstant(constantNull)); |
934 elements = compiler.enqueuer.resolution.getCachedElements(function); | 938 elements = compiler.enqueuer.resolution.getCachedElements(function); |
935 FunctionSignature signature = function.computeSignature(compiler); | 939 FunctionSignature signature = function.computeSignature(compiler); |
936 int index = 0; | 940 int index = 0; |
937 signature.forEachParameter((Element parameter) { | 941 signature.forEachParameter((Element parameter) { |
938 HInstruction argument = compiledArguments[index++]; | 942 HInstruction argument = compiledArguments[index++]; |
939 localsHandler.updateLocal(parameter, argument); | 943 localsHandler.updateLocal(parameter, argument); |
940 potentiallyCheckType(argument, parameter); | 944 potentiallyCheckType(argument, parameter); |
941 }); | 945 }); |
942 return state; | 946 return state; |
943 } | 947 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 Map<Element, HInstruction> fieldValues) { | 1109 Map<Element, HInstruction> fieldValues) { |
1106 classElement.forEachInstanceField( | 1110 classElement.forEachInstanceField( |
1107 includeBackendMembers: true, | 1111 includeBackendMembers: true, |
1108 includeSuperMembers: false, | 1112 includeSuperMembers: false, |
1109 f: (ClassElement enclosingClass, Element member) { | 1113 f: (ClassElement enclosingClass, Element member) { |
1110 TreeElements definitions = compiler.analyzeElement(member); | 1114 TreeElements definitions = compiler.analyzeElement(member); |
1111 Node node = member.parseNode(compiler); | 1115 Node node = member.parseNode(compiler); |
1112 SendSet assignment = node.asSendSet(); | 1116 SendSet assignment = node.asSendSet(); |
1113 HInstruction value; | 1117 HInstruction value; |
1114 if (assignment === null) { | 1118 if (assignment === null) { |
1115 value = graph.addConstantNull(); | 1119 value = graph.addConstant(constantSystem.createNull()); |
1116 } else { | 1120 } else { |
1117 Node right = assignment.arguments.head; | 1121 Node right = assignment.arguments.head; |
1118 TreeElements savedElements = elements; | 1122 TreeElements savedElements = elements; |
1119 elements = definitions; | 1123 elements = definitions; |
1120 right.accept(this); | 1124 right.accept(this); |
1121 elements = savedElements; | 1125 elements = savedElements; |
1122 value = pop(); | 1126 value = pop(); |
1123 } | 1127 } |
1124 fieldValues[member] = value; | 1128 fieldValues[member] = value; |
1125 }); | 1129 }); |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1587 Node initializer = node.initializer; | 1591 Node initializer = node.initializer; |
1588 if (initializer !== null) { | 1592 if (initializer !== null) { |
1589 visit(initializer); | 1593 visit(initializer); |
1590 if (initializer.asExpression() !== null) { | 1594 if (initializer.asExpression() !== null) { |
1591 pop(); | 1595 pop(); |
1592 } | 1596 } |
1593 } | 1597 } |
1594 } | 1598 } |
1595 HInstruction buildCondition() { | 1599 HInstruction buildCondition() { |
1596 if (node.condition === null) { | 1600 if (node.condition === null) { |
1597 return graph.addConstantBool(true); | 1601 return graph.addConstant(constantSystem.createBool(true)); |
1598 } | 1602 } |
1599 visit(node.condition); | 1603 visit(node.condition); |
1600 return popBoolified(); | 1604 return popBoolified(); |
1601 } | 1605 } |
1602 void buildUpdate() { | 1606 void buildUpdate() { |
1603 for (Expression expression in node.update) { | 1607 for (Expression expression in node.update) { |
1604 visit(expression); | 1608 visit(expression); |
1605 assert(!isAborted()); | 1609 assert(!isAborted()); |
1606 // The result of the update instruction isn't used, and can just | 1610 // The result of the update instruction isn't used, and can just |
1607 // be dropped. | 1611 // be dropped. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 assert(node.argumentsNode is Prefix); | 1779 assert(node.argumentsNode is Prefix); |
1776 visit(node.receiver); | 1780 visit(node.receiver); |
1777 HNot not = new HNot(popBoolified()); | 1781 HNot not = new HNot(popBoolified()); |
1778 pushWithPosition(not, node); | 1782 pushWithPosition(not, node); |
1779 } | 1783 } |
1780 | 1784 |
1781 void visitUnary(Send node, Operator op) { | 1785 void visitUnary(Send node, Operator op) { |
1782 String value = op.source.stringValue; | 1786 String value = op.source.stringValue; |
1783 if (value === '?') { | 1787 if (value === '?') { |
1784 // TODO(ahe): Implement argument definition test. | 1788 // TODO(ahe): Implement argument definition test. |
1785 stack.add(graph.addConstantBool(true)); | 1789 stack.add(graph.addConstant(constantSystem.createBool(true))); |
1786 return; | 1790 return; |
1787 } | 1791 } |
1788 assert(node.argumentsNode is Prefix); | 1792 assert(node.argumentsNode is Prefix); |
1789 visit(node.receiver); | 1793 visit(node.receiver); |
1790 assert(op.token.kind !== PLUS_TOKEN); | 1794 assert(op.token.kind !== PLUS_TOKEN); |
1791 HInstruction operand = pop(); | 1795 HInstruction operand = pop(); |
1792 | 1796 |
1793 HInstruction target = | 1797 HInstruction target = |
1794 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); | 1798 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); |
1795 add(target); | 1799 add(target); |
1796 HInvokeUnary result; | 1800 HInvokeUnary result; |
1797 switch (value) { | 1801 switch (value) { |
1798 case "-": result = new HNegate(target, operand); break; | 1802 case "-": result = new HNegate(target, operand); break; |
1799 case "~": result = new HBitNot(target, operand); break; | 1803 case "~": result = new HBitNot(target, operand); break; |
1800 default: | 1804 default: |
1801 compiler.internalError('Unexpected unary operator: $value.', node: op); | 1805 compiler.internalError('Unexpected unary operator: $value.', node: op); |
1802 break; | 1806 break; |
1803 } | 1807 } |
1804 // See if we can constant-fold right away. This avoids rewrites later on. | 1808 // See if we can constant-fold right away. This avoids rewrites later on. |
1805 if (operand is HConstant) { | 1809 if (operand is HConstant) { |
1806 HConstant constant = operand; | 1810 HConstant constant = operand; |
1807 Constant folded = result.operation.fold(constant.constant); | 1811 Constant folded = |
| 1812 result.operation(constantSystem).fold(constant.constant); |
1808 if (folded !== null) { | 1813 if (folded !== null) { |
1809 stack.add(graph.addConstant(folded)); | 1814 stack.add(graph.addConstant(folded)); |
1810 return; | 1815 return; |
1811 } | 1816 } |
1812 } | 1817 } |
1813 pushWithPosition(result, node); | 1818 pushWithPosition(result, node); |
1814 } | 1819 } |
1815 | 1820 |
1816 void visitBinary(HInstruction left, Operator op, HInstruction right) { | 1821 void visitBinary(HInstruction left, Operator op, HInstruction right) { |
1817 Element element = interceptors.getOperatorInterceptor(op); | 1822 Element element = interceptors.getOperatorInterceptor(op); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 HInstruction typeInfo = null; | 2085 HInstruction typeInfo = null; |
2081 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { | 2086 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { |
2082 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); | 2087 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); |
2083 typeInfo = pop(); | 2088 typeInfo = pop(); |
2084 } | 2089 } |
2085 if (type.element.kind === ElementKind.TYPE_VARIABLE) { | 2090 if (type.element.kind === ElementKind.TYPE_VARIABLE) { |
2086 // TODO(karlklose): We emulate the behavior of the old frog | 2091 // TODO(karlklose): We emulate the behavior of the old frog |
2087 // compiler and answer true to any is check involving a type variable | 2092 // compiler and answer true to any is check involving a type variable |
2088 // -- both is T and is !T -- until we have a proper implementation of | 2093 // -- both is T and is !T -- until we have a proper implementation of |
2089 // reified generics. | 2094 // reified generics. |
2090 stack.add(graph.addConstantBool(true)); | 2095 stack.add(graph.addConstant(constantSystem.createBool(true))); |
2091 } else { | 2096 } else { |
2092 HInstruction instruction; | 2097 HInstruction instruction; |
2093 if (typeInfo !== null) { | 2098 if (typeInfo !== null) { |
2094 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); | 2099 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); |
2095 } else { | 2100 } else { |
2096 instruction = new HIs(type, expression); | 2101 instruction = new HIs(type, expression); |
2097 } | 2102 } |
2098 if (isNot) { | 2103 if (isNot) { |
2099 add(instruction); | 2104 add(instruction); |
2100 instruction = new HNot(instruction); | 2105 instruction = new HNot(instruction); |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2409 generateSuperNoSuchMethodSend(Send node) { | 2414 generateSuperNoSuchMethodSend(Send node) { |
2410 ClassElement cls = work.element.getEnclosingClass(); | 2415 ClassElement cls = work.element.getEnclosingClass(); |
2411 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); | 2416 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); |
2412 HStatic target = new HStatic(element); | 2417 HStatic target = new HStatic(element); |
2413 add(target); | 2418 add(target); |
2414 HInstruction self = localsHandler.readThis(); | 2419 HInstruction self = localsHandler.readThis(); |
2415 Identifier identifier = node.selector.asIdentifier(); | 2420 Identifier identifier = node.selector.asIdentifier(); |
2416 String name = identifier.source.slowToString(); | 2421 String name = identifier.source.slowToString(); |
2417 // TODO(ahe): Add the arguments to this list. | 2422 // TODO(ahe): Add the arguments to this list. |
2418 push(new HLiteralList([])); | 2423 push(new HLiteralList([])); |
| 2424 Constant nameConstant = |
| 2425 constantSystem.createString(new DartString.literal(name), node); |
2419 var inputs = <HInstruction>[ | 2426 var inputs = <HInstruction>[ |
2420 target, | 2427 target, |
2421 self, | 2428 self, |
2422 graph.addConstantString(new DartString.literal(name), node), | 2429 graph.addConstant(nameConstant), |
2423 pop()]; | 2430 pop()]; |
2424 push(new HInvokeSuper(inputs)); | 2431 push(new HInvokeSuper(inputs)); |
2425 } | 2432 } |
2426 | 2433 |
2427 visitSend(Send node) { | 2434 visitSend(Send node) { |
2428 Element element = elements[node]; | 2435 Element element = elements[node]; |
2429 if (element !== null && element === work.element) { | 2436 if (element !== null && element === work.element) { |
2430 graph.isRecursiveMethod = true; | 2437 graph.isRecursiveMethod = true; |
2431 } | 2438 } |
2432 super.visitSend(node); | 2439 super.visitSend(node); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2480 add(foreign); | 2487 add(foreign); |
2481 return foreign; | 2488 return foreign; |
2482 } else { | 2489 } else { |
2483 // TODO(ngeoffray): Match the VM behavior and throw an | 2490 // TODO(ngeoffray): Match the VM behavior and throw an |
2484 // exception at runtime. | 2491 // exception at runtime. |
2485 compiler.cancel('Unimplemented unresolved type variable', | 2492 compiler.cancel('Unimplemented unresolved type variable', |
2486 node: currentNode); | 2493 node: currentNode); |
2487 } | 2494 } |
2488 } else { | 2495 } else { |
2489 // The type variable is a type (e.g. int). | 2496 // The type variable is a type (e.g. int). |
2490 return graph.addConstantString( | 2497 return graph.addConstant( |
2491 new LiteralDartString('$argument'), currentNode); | 2498 constantSystem.createString(new LiteralDartString('$argument'), |
| 2499 currentNode)); |
2492 } | 2500 } |
2493 } | 2501 } |
2494 | 2502 |
2495 visitNewSend(Send node) { | 2503 visitNewSend(Send node) { |
2496 computeType(element) { | 2504 computeType(element) { |
2497 Element originalElement = elements[node]; | 2505 Element originalElement = elements[node]; |
2498 if (originalElement.getEnclosingClass() === compiler.listClass) { | 2506 if (originalElement.getEnclosingClass() === compiler.listClass) { |
2499 if (node.arguments.isEmpty()) { | 2507 if (node.arguments.isEmpty()) { |
2500 return HType.EXTENDABLE_ARRAY; | 2508 return HType.EXTENDABLE_ARRAY; |
2501 } else { | 2509 } else { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2535 | 2543 |
2536 HType elementType = computeType(constructor); | 2544 HType elementType = computeType(constructor); |
2537 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2545 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
2538 pushWithPosition(newInstance, node); | 2546 pushWithPosition(newInstance, node); |
2539 } | 2547 } |
2540 | 2548 |
2541 visitStaticSend(Send node) { | 2549 visitStaticSend(Send node) { |
2542 Selector selector = elements.getSelector(node); | 2550 Selector selector = elements.getSelector(node); |
2543 Element element = elements[node]; | 2551 Element element = elements[node]; |
2544 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { | 2552 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { |
2545 stack.add(graph.addConstantNull()); | 2553 stack.add(graph.addConstant(constantSystem.createNull())); |
2546 return; | 2554 return; |
2547 } | 2555 } |
2548 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); | 2556 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); |
2549 | 2557 |
2550 if (tryInlineMethod(element, selector, node.arguments)) return; | 2558 if (tryInlineMethod(element, selector, node.arguments)) return; |
2551 | 2559 |
2552 HInstruction target = new HStatic(element); | 2560 HInstruction target = new HStatic(element); |
2553 add(target); | 2561 add(target); |
2554 var inputs = <HInstruction>[]; | 2562 var inputs = <HInstruction>[]; |
2555 inputs.add(target); | 2563 inputs.add(target); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2598 if (selector.receiver is TypeAnnotation) { | 2606 if (selector.receiver is TypeAnnotation) { |
2599 return selector.receiver; | 2607 return selector.receiver; |
2600 } | 2608 } |
2601 } else { | 2609 } else { |
2602 compiler.internalError("malformed send in new expression"); | 2610 compiler.internalError("malformed send in new expression"); |
2603 } | 2611 } |
2604 } | 2612 } |
2605 | 2613 |
2606 void generateRuntimeError(Node node, String message) { | 2614 void generateRuntimeError(Node node, String message) { |
2607 DartString messageObject = new DartString.literal(message); | 2615 DartString messageObject = new DartString.literal(message); |
2608 HInstruction errorMessage = graph.addConstantString(messageObject, node); | 2616 Constant messageConstant = |
| 2617 constantSystem.createString(messageObject, node); |
| 2618 HInstruction errorMessage = graph.addConstant(messageConstant); |
2609 Element helper = interceptors.getThrowRuntimeError(); | 2619 Element helper = interceptors.getThrowRuntimeError(); |
2610 pushInvokeHelper1(helper, errorMessage); | 2620 pushInvokeHelper1(helper, errorMessage); |
2611 } | 2621 } |
2612 | 2622 |
2613 visitNewExpression(NewExpression node) { | 2623 visitNewExpression(NewExpression node) { |
2614 Element element = elements[node.send]; | 2624 Element element = elements[node.send]; |
2615 if (element != null && element.isErroneous()) { | 2625 if (element != null && element.isErroneous()) { |
2616 ErroneousElement error = element; | 2626 ErroneousElement error = element; |
2617 Message message = error.errorMessage; | 2627 Message message = error.errorMessage; |
2618 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 2628 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
2619 Element helper = | 2629 Element helper = |
2620 compiler.findHelper(const SourceString('throwNoSuchMethod')); | 2630 compiler.findHelper(const SourceString('throwNoSuchMethod')); |
2621 DartString receiverLiteral = new DartString.literal(''); | 2631 DartString receiverLiteral = new DartString.literal(''); |
2622 HInstruction receiver = graph.addConstantString(receiverLiteral, node); | 2632 Constant receiverConstant = |
| 2633 constantSystem.createString(receiverLiteral, node); |
| 2634 HInstruction receiver = graph.addConstant(receiverConstant); |
2623 String constructorName = 'constructor ${message.arguments[0]}'; | 2635 String constructorName = 'constructor ${message.arguments[0]}'; |
2624 DartString nameLiteral = new DartString.literal(constructorName); | 2636 DartString nameLiteral = new DartString.literal(constructorName); |
2625 HInstruction name = graph.addConstantString(nameLiteral, node.send); | 2637 Constant nameConstant = |
| 2638 constantSystem.createString(nameLiteral, node.send); |
| 2639 HInstruction name = graph.addConstant(nameConstant); |
2626 List<HInstruction> inputs = <HInstruction>[]; | 2640 List<HInstruction> inputs = <HInstruction>[]; |
2627 node.send.arguments.forEach((argumentNode) { | 2641 node.send.arguments.forEach((argumentNode) { |
2628 visit(argumentNode); | 2642 visit(argumentNode); |
2629 HInstruction value = pop(); | 2643 HInstruction value = pop(); |
2630 inputs.add(value); | 2644 inputs.add(value); |
2631 }); | 2645 }); |
2632 HInstruction arguments = new HLiteralList(inputs); | 2646 HInstruction arguments = new HLiteralList(inputs); |
2633 add(arguments); | 2647 add(arguments); |
2634 pushInvokeHelper3(helper, receiver, name, arguments); | 2648 pushInvokeHelper3(helper, receiver, name, arguments); |
2635 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { | 2649 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2684 HInstruction index; | 2698 HInstruction index; |
2685 bool isCompoundAssignment = op.source.stringValue.endsWith('='); | 2699 bool isCompoundAssignment = op.source.stringValue.endsWith('='); |
2686 // Compound assignments are considered as being prefix. | 2700 // Compound assignments are considered as being prefix. |
2687 bool isPrefix = !node.isPostfix; | 2701 bool isPrefix = !node.isPostfix; |
2688 Element getter = elements[node.selector]; | 2702 Element getter = elements[node.selector]; |
2689 if (isCompoundAssignment) { | 2703 if (isCompoundAssignment) { |
2690 value = pop(); | 2704 value = pop(); |
2691 index = pop(); | 2705 index = pop(); |
2692 } else { | 2706 } else { |
2693 index = pop(); | 2707 index = pop(); |
2694 value = graph.addConstantInt(1); | 2708 value = graph.addConstant(constantSystem.createInt(1)); |
2695 } | 2709 } |
2696 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); | 2710 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); |
2697 add(indexMethod); | 2711 add(indexMethod); |
2698 HInstruction left = new HIndex(indexMethod, receiver, index); | 2712 HInstruction left = new HIndex(indexMethod, receiver, index); |
2699 add(left); | 2713 add(left); |
2700 Element opElement = elements[op]; | 2714 Element opElement = elements[op]; |
2701 visitBinary(left, op, value); | 2715 visitBinary(left, op, value); |
2702 value = pop(); | 2716 value = pop(); |
2703 HInstruction assign = new HIndexAssign( | 2717 HInstruction assign = new HIndexAssign( |
2704 target, receiver, index, value); | 2718 target, receiver, index, value); |
(...skipping 29 matching lines...) Expand all Loading... |
2734 generateInstanceGetterWithCompiledReceiver(node, receiver); | 2748 generateInstanceGetterWithCompiledReceiver(node, receiver); |
2735 } else { | 2749 } else { |
2736 generateGetter(node, elements[node.selector]); | 2750 generateGetter(node, elements[node.selector]); |
2737 } | 2751 } |
2738 HInstruction left = pop(); | 2752 HInstruction left = pop(); |
2739 HInstruction right; | 2753 HInstruction right; |
2740 if (isCompoundAssignment) { | 2754 if (isCompoundAssignment) { |
2741 visit(node.argumentsNode); | 2755 visit(node.argumentsNode); |
2742 right = pop(); | 2756 right = pop(); |
2743 } else { | 2757 } else { |
2744 right = graph.addConstantInt(1); | 2758 right = graph.addConstant(constantSystem.createInt(1)); |
2745 } | 2759 } |
2746 visitBinary(left, op, right); | 2760 visitBinary(left, op, right); |
2747 HInstruction operation = pop(); | 2761 HInstruction operation = pop(); |
2748 assert(operation !== null); | 2762 assert(operation !== null); |
2749 if (Elements.isInstanceSend(node, elements)) { | 2763 if (Elements.isInstanceSend(node, elements)) { |
2750 assert(receiver !== null); | 2764 assert(receiver !== null); |
2751 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); | 2765 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); |
2752 } else { | 2766 } else { |
2753 assert(receiver === null); | 2767 assert(receiver === null); |
2754 generateSetter(node, element, operation); | 2768 generateSetter(node, element, operation); |
2755 } | 2769 } |
2756 if (!isPrefix) { | 2770 if (!isPrefix) { |
2757 pop(); | 2771 pop(); |
2758 stack.add(left); | 2772 stack.add(left); |
2759 } | 2773 } |
2760 } | 2774 } |
2761 } | 2775 } |
2762 | 2776 |
2763 void visitLiteralInt(LiteralInt node) { | 2777 void visitLiteralInt(LiteralInt node) { |
2764 stack.add(graph.addConstantInt(node.value)); | 2778 stack.add(graph.addConstant(constantSystem.createInt(node.value))); |
2765 } | 2779 } |
2766 | 2780 |
2767 void visitLiteralDouble(LiteralDouble node) { | 2781 void visitLiteralDouble(LiteralDouble node) { |
2768 stack.add(graph.addConstantDouble(node.value)); | 2782 stack.add(graph.addConstant(constantSystem.createDouble(node.value))); |
2769 } | 2783 } |
2770 | 2784 |
2771 void visitLiteralBool(LiteralBool node) { | 2785 void visitLiteralBool(LiteralBool node) { |
2772 stack.add(graph.addConstantBool(node.value)); | 2786 stack.add(graph.addConstant(constantSystem.createBool(node.value))); |
2773 } | 2787 } |
2774 | 2788 |
2775 void visitLiteralString(LiteralString node) { | 2789 void visitLiteralString(LiteralString node) { |
2776 stack.add(graph.addConstantString(node.dartString, node)); | 2790 Constant constant = constantSystem.createString(node.dartString, node); |
| 2791 stack.add(graph.addConstant(constant)); |
2777 } | 2792 } |
2778 | 2793 |
2779 void visitStringJuxtaposition(StringJuxtaposition node) { | 2794 void visitStringJuxtaposition(StringJuxtaposition node) { |
2780 if (!node.isInterpolation) { | 2795 if (!node.isInterpolation) { |
2781 // This is a simple string with no interpolations. | 2796 // This is a simple string with no interpolations. |
2782 stack.add(graph.addConstantString(node.dartString, node)); | 2797 Constant constant = constantSystem.createString(node.dartString, node); |
| 2798 stack.add(graph.addConstant(constant)); |
2783 return; | 2799 return; |
2784 } | 2800 } |
2785 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 2801 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
2786 stringBuilder.visit(node); | 2802 stringBuilder.visit(node); |
2787 stack.add(stringBuilder.result); | 2803 stack.add(stringBuilder.result); |
2788 } | 2804 } |
2789 | 2805 |
2790 void visitLiteralNull(LiteralNull node) { | 2806 void visitLiteralNull(LiteralNull node) { |
2791 stack.add(graph.addConstantNull()); | 2807 stack.add(graph.addConstant(constantSystem.createNull())); |
2792 } | 2808 } |
2793 | 2809 |
2794 visitNodeList(NodeList node) { | 2810 visitNodeList(NodeList node) { |
2795 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 2811 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
2796 if (isAborted()) { | 2812 if (isAborted()) { |
2797 compiler.reportWarning(link.head, 'dead code'); | 2813 compiler.reportWarning(link.head, 'dead code'); |
2798 } else { | 2814 } else { |
2799 visit(link.head); | 2815 visit(link.head); |
2800 } | 2816 } |
2801 } | 2817 } |
(...skipping 19 matching lines...) Expand all Loading... |
2821 dup(); | 2837 dup(); |
2822 } | 2838 } |
2823 | 2839 |
2824 visitReturn(Return node) { | 2840 visitReturn(Return node) { |
2825 if (node.getBeginToken().stringValue === 'native') { | 2841 if (node.getBeginToken().stringValue === 'native') { |
2826 native.handleSsaNative(this, node.expression); | 2842 native.handleSsaNative(this, node.expression); |
2827 return; | 2843 return; |
2828 } | 2844 } |
2829 HInstruction value; | 2845 HInstruction value; |
2830 if (node.expression === null) { | 2846 if (node.expression === null) { |
2831 value = graph.addConstantNull(); | 2847 value = graph.addConstant(constantSystem.createNull()); |
2832 } else { | 2848 } else { |
2833 visit(node.expression); | 2849 visit(node.expression); |
2834 value = pop(); | 2850 value = pop(); |
2835 } | 2851 } |
2836 if (!inliningStack.isEmpty()) { | 2852 if (!inliningStack.isEmpty()) { |
2837 localsHandler.updateLocal(returnElement, value); | 2853 localsHandler.updateLocal(returnElement, value); |
2838 } else { | 2854 } else { |
2839 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); | 2855 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); |
2840 } | 2856 } |
2841 } | 2857 } |
2842 | 2858 |
2843 visitThrow(Throw node) { | 2859 visitThrow(Throw node) { |
2844 if (node.expression === null) { | 2860 if (node.expression === null) { |
2845 HInstruction exception = rethrowableException; | 2861 HInstruction exception = rethrowableException; |
2846 if (exception === null) { | 2862 if (exception === null) { |
2847 exception = graph.addConstantNull(); | 2863 exception = graph.addConstant(constantSystem.createNull()); |
2848 compiler.reportError(node, | 2864 compiler.reportError(node, |
2849 'throw without expression outside catch block'); | 2865 'throw without expression outside catch block'); |
2850 } | 2866 } |
2851 close(new HThrow(exception, isRethrow: true)); | 2867 close(new HThrow(exception, isRethrow: true)); |
2852 } else { | 2868 } else { |
2853 visit(node.expression); | 2869 visit(node.expression); |
2854 close(new HThrow(pop())); | 2870 close(new HThrow(pop())); |
2855 } | 2871 } |
2856 } | 2872 } |
2857 | 2873 |
2858 visitTypeAnnotation(TypeAnnotation node) { | 2874 visitTypeAnnotation(TypeAnnotation node) { |
2859 compiler.internalError('visiting type annotation in SSA builder', | 2875 compiler.internalError('visiting type annotation in SSA builder', |
2860 node: node); | 2876 node: node); |
2861 } | 2877 } |
2862 | 2878 |
2863 visitVariableDefinitions(VariableDefinitions node) { | 2879 visitVariableDefinitions(VariableDefinitions node) { |
2864 for (Link<Node> link = node.definitions.nodes; | 2880 for (Link<Node> link = node.definitions.nodes; |
2865 !link.isEmpty(); | 2881 !link.isEmpty(); |
2866 link = link.tail) { | 2882 link = link.tail) { |
2867 Node definition = link.head; | 2883 Node definition = link.head; |
2868 if (definition is Identifier) { | 2884 if (definition is Identifier) { |
2869 HInstruction initialValue = graph.addConstantNull(); | 2885 HInstruction initialValue = |
| 2886 graph.addConstant(constantSystem.createNull()); |
2870 localsHandler.updateLocal(elements[definition], initialValue); | 2887 localsHandler.updateLocal(elements[definition], initialValue); |
2871 } else { | 2888 } else { |
2872 assert(definition is SendSet); | 2889 assert(definition is SendSet); |
2873 visitSendSet(definition); | 2890 visitSendSet(definition); |
2874 pop(); // Discard value. | 2891 pop(); // Discard value. |
2875 } | 2892 } |
2876 } | 2893 } |
2877 } | 2894 } |
2878 | 2895 |
2879 visitLiteralList(LiteralList node) { | 2896 visitLiteralList(LiteralList node) { |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3457 compiler.cancel('On with unresolved type', | 3474 compiler.cancel('On with unresolved type', |
3458 node: catchBlock.type); | 3475 node: catchBlock.type); |
3459 } | 3476 } |
3460 HInstruction condition = new HIs(type, unwrappedException); | 3477 HInstruction condition = new HIs(type, unwrappedException); |
3461 push(condition); | 3478 push(condition); |
3462 } | 3479 } |
3463 else { | 3480 else { |
3464 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 3481 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
3465 HInstruction condition = null; | 3482 HInstruction condition = null; |
3466 if (declaration.type == null) { | 3483 if (declaration.type == null) { |
3467 condition = graph.addConstantBool(true); | 3484 condition = graph.addConstant(constantSystem.createBool(true)); |
3468 stack.add(condition); | 3485 stack.add(condition); |
3469 } else { | 3486 } else { |
3470 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 3487 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
3471 // "if" condition above and this "else" branch should be deleted as | 3488 // "if" condition above and this "else" branch should be deleted as |
3472 // type of declared variable won't matter for the catch | 3489 // type of declared variable won't matter for the catch |
3473 // condition | 3490 // condition |
3474 DartType type = elements.getType(declaration.type); | 3491 DartType type = elements.getType(declaration.type); |
3475 if (type == null) { | 3492 if (type == null) { |
3476 compiler.cancel('Catch with unresolved type', node: catchBlock); | 3493 compiler.cancel('Catch with unresolved type', node: catchBlock); |
3477 } | 3494 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3568 if (element === builder.compiler.intClass) return HType.INTEGER; | 3585 if (element === builder.compiler.intClass) return HType.INTEGER; |
3569 if (element === builder.compiler.listClass) return HType.READABLE_ARRAY; | 3586 if (element === builder.compiler.listClass) return HType.READABLE_ARRAY; |
3570 if (element === builder.compiler.nullClass) return HType.NULL; | 3587 if (element === builder.compiler.nullClass) return HType.NULL; |
3571 if (element === builder.compiler.stringClass) return HType.STRING; | 3588 if (element === builder.compiler.stringClass) return HType.STRING; |
3572 return HType.UNKNOWN; | 3589 return HType.UNKNOWN; |
3573 } | 3590 } |
3574 | 3591 |
3575 /** HACK HACK HACK */ | 3592 /** HACK HACK HACK */ |
3576 void hackAroundPossiblyAbortingBody(Node statement, void body()) { | 3593 void hackAroundPossiblyAbortingBody(Node statement, void body()) { |
3577 visitCondition() { | 3594 visitCondition() { |
3578 stack.add(graph.addConstantBool(true)); | 3595 stack.add(graph.addConstant(constantSystem.createBool(true))); |
3579 } | 3596 } |
3580 buildBody() { | 3597 buildBody() { |
3581 // TODO(lrn): Make sure to take continue into account. | 3598 // TODO(lrn): Make sure to take continue into account. |
3582 body(); | 3599 body(); |
3583 } | 3600 } |
3584 handleIf(statement, visitCondition, buildBody, null); | 3601 handleIf(statement, visitCondition, buildBody, null); |
3585 } | 3602 } |
3586 } | 3603 } |
3587 | 3604 |
3588 /** | 3605 /** |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3856 builder.push(new HNot(builder.pop())); | 3873 builder.push(new HNot(builder.pop())); |
3857 } | 3874 } |
3858 } | 3875 } |
3859 | 3876 |
3860 void visitThen() { | 3877 void visitThen() { |
3861 right(); | 3878 right(); |
3862 boolifiedRight = builder.popBoolified(); | 3879 boolifiedRight = builder.popBoolified(); |
3863 } | 3880 } |
3864 | 3881 |
3865 handleIf(visitCondition, visitThen, null); | 3882 handleIf(visitCondition, visitThen, null); |
| 3883 HConstant notIsAnd = |
| 3884 builder.graph.addConstant(builder.constantSystem.createBool(!isAnd)); |
3866 HPhi result = new HPhi.manyInputs(null, | 3885 HPhi result = new HPhi.manyInputs(null, |
3867 <HInstruction>[boolifiedRight, builder.graph.addConstantBool(!isAnd)]); | 3886 <HInstruction>[boolifiedRight, notIsAnd]); |
3868 builder.current.addPhi(result); | 3887 builder.current.addPhi(result); |
3869 builder.stack.add(result); | 3888 builder.stack.add(result); |
3870 } | 3889 } |
3871 | 3890 |
3872 void handleLogicalAndOrWithLeftNode(Node left, | 3891 void handleLogicalAndOrWithLeftNode(Node left, |
3873 void visitRight(), | 3892 void visitRight(), |
3874 [bool isAnd]) { | 3893 [bool isAnd]) { |
3875 // This method is similar to [handleLogicalAndOr] but optimizes the case | 3894 // This method is similar to [handleLogicalAndOr] but optimizes the case |
3876 // where left is a logical "and" or logical "or". | 3895 // where left is a logical "and" or logical "or". |
3877 // | 3896 // |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3944 new HSubGraphBlockInformation(elseBranch.graph)); | 3963 new HSubGraphBlockInformation(elseBranch.graph)); |
3945 | 3964 |
3946 HBasicBlock conditionStartBlock = conditionBranch.block; | 3965 HBasicBlock conditionStartBlock = conditionBranch.block; |
3947 conditionStartBlock.setBlockFlow(info, joinBlock); | 3966 conditionStartBlock.setBlockFlow(info, joinBlock); |
3948 SubGraph conditionGraph = conditionBranch.graph; | 3967 SubGraph conditionGraph = conditionBranch.graph; |
3949 HIf branch = conditionGraph.end.last; | 3968 HIf branch = conditionGraph.end.last; |
3950 assert(branch is HIf); | 3969 assert(branch is HIf); |
3951 branch.blockInformation = conditionStartBlock.blockFlow; | 3970 branch.blockInformation = conditionStartBlock.blockFlow; |
3952 } | 3971 } |
3953 } | 3972 } |
OLD | NEW |