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 Element element = work.element; | 158 Element element = work.element; |
159 HInstruction.idCounter = 0; | 159 HInstruction.idCounter = 0; |
160 SsaBuilder builder = new SsaBuilder(this, work); | 160 ConstantSystem constantSystem = compiler.backend.constantSystem; |
| 161 SsaBuilder builder = new SsaBuilder(constantSystem, this, work); |
161 HGraph graph; | 162 HGraph graph; |
162 ElementKind kind = element.kind; | 163 ElementKind kind = element.kind; |
163 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { | 164 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { |
164 graph = compileConstructor(builder, work); | 165 graph = compileConstructor(builder, work); |
165 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || | 166 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || |
166 kind === ElementKind.FUNCTION || | 167 kind === ElementKind.FUNCTION || |
167 kind === ElementKind.GETTER || | 168 kind === ElementKind.GETTER || |
168 kind === ElementKind.SETTER) { | 169 kind === ElementKind.SETTER) { |
169 graph = builder.buildMethod(work.element); | 170 graph = builder.buildMethod(work.element); |
170 } else if (kind === ElementKind.FIELD) { | 171 } else if (kind === ElementKind.FIELD) { |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 result.add(element); | 801 result.add(element); |
801 } | 802 } |
802 return (result === null) ? const <LabelElement>[] : result; | 803 return (result === null) ? const <LabelElement>[] : result; |
803 } | 804 } |
804 } | 805 } |
805 | 806 |
806 class SsaBuilder extends ResolvedVisitor implements Visitor { | 807 class SsaBuilder extends ResolvedVisitor implements Visitor { |
807 final SsaBuilderTask builder; | 808 final SsaBuilderTask builder; |
808 final Interceptors interceptors; | 809 final Interceptors interceptors; |
809 final WorkItem work; | 810 final WorkItem work; |
| 811 final ConstantSystem constantSystem; |
810 bool methodInterceptionEnabled; | 812 bool methodInterceptionEnabled; |
811 HGraph graph; | 813 HGraph graph; |
812 LocalsHandler localsHandler; | 814 LocalsHandler localsHandler; |
813 HInstruction rethrowableException; | 815 HInstruction rethrowableException; |
814 Map<Element, HParameterValue> parameters; | 816 Map<Element, HParameterValue> parameters; |
815 | 817 |
816 Map<TargetElement, JumpHandler> jumpTargets; | 818 Map<TargetElement, JumpHandler> jumpTargets; |
817 | 819 |
818 /** | 820 /** |
819 * Variables stored in the current activation. These variables are | 821 * Variables stored in the current activation. These variables are |
(...skipping 11 matching lines...) Expand all Loading... |
831 // The most recently opened block. Has the same value as [current] while | 833 // The most recently opened block. Has the same value as [current] while |
832 // the block is open, but unlike [current], it isn't cleared when the current | 834 // the block is open, but unlike [current], it isn't cleared when the current |
833 // block is closed. | 835 // block is closed. |
834 HBasicBlock lastOpenedBlock; | 836 HBasicBlock lastOpenedBlock; |
835 | 837 |
836 LibraryElement get currentLibrary => work.element.getLibrary(); | 838 LibraryElement get currentLibrary => work.element.getLibrary(); |
837 Element get currentElement => work.element; | 839 Element get currentElement => work.element; |
838 Compiler get compiler => builder.compiler; | 840 Compiler get compiler => builder.compiler; |
839 CodeEmitterTask get emitter => builder.emitter; | 841 CodeEmitterTask get emitter => builder.emitter; |
840 | 842 |
841 SsaBuilder(SsaBuilderTask builder, WorkItem work) | 843 SsaBuilder(this.constantSystem, SsaBuilderTask builder, WorkItem work) |
842 : this.builder = builder, | 844 : this.builder = builder, |
843 this.work = work, | 845 this.work = work, |
844 interceptors = builder.interceptors, | 846 interceptors = builder.interceptors, |
845 methodInterceptionEnabled = true, | 847 methodInterceptionEnabled = true, |
846 graph = new HGraph(), | 848 graph = new HGraph(), |
847 stack = new List<HInstruction>(), | 849 stack = new List<HInstruction>(), |
848 activationVariables = new Map<Element, HLocalValue>(), | 850 activationVariables = new Map<Element, HLocalValue>(), |
849 jumpTargets = new Map<TargetElement, JumpHandler>(), | 851 jumpTargets = new Map<TargetElement, JumpHandler>(), |
850 parameters = new Map<Element, HParameterValue>(), | 852 parameters = new Map<Element, HParameterValue>(), |
851 inliningStack = <InliningState>[], | 853 inliningStack = <InliningState>[], |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 compiledArguments); | 945 compiledArguments); |
944 assert(succeeded); | 946 assert(succeeded); |
945 | 947 |
946 InliningState state = | 948 InliningState state = |
947 new InliningState(function, returnElement, elements, stack); | 949 new InliningState(function, returnElement, elements, stack); |
948 inliningStack.add(state); | 950 inliningStack.add(state); |
949 stack = <HInstruction>[]; | 951 stack = <HInstruction>[]; |
950 returnElement = new Element(const SourceString("result"), | 952 returnElement = new Element(const SourceString("result"), |
951 ElementKind.VARIABLE, | 953 ElementKind.VARIABLE, |
952 function); | 954 function); |
953 localsHandler.updateLocal(returnElement, graph.addConstantNull()); | 955 localsHandler.updateLocal(returnElement, |
| 956 graph.addConstantNull(constantSystem)); |
954 elements = compiler.enqueuer.resolution.getCachedElements(function); | 957 elements = compiler.enqueuer.resolution.getCachedElements(function); |
955 FunctionSignature signature = function.computeSignature(compiler); | 958 FunctionSignature signature = function.computeSignature(compiler); |
956 int index = 0; | 959 int index = 0; |
957 signature.forEachParameter((Element parameter) { | 960 signature.forEachParameter((Element parameter) { |
958 HInstruction argument = compiledArguments[index++]; | 961 HInstruction argument = compiledArguments[index++]; |
959 localsHandler.updateLocal(parameter, argument); | 962 localsHandler.updateLocal(parameter, argument); |
960 potentiallyCheckType(argument, parameter); | 963 potentiallyCheckType(argument, parameter); |
961 }); | 964 }); |
962 return state; | 965 return state; |
963 } | 966 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 Map<Element, HInstruction> fieldValues) { | 1132 Map<Element, HInstruction> fieldValues) { |
1130 classElement.forEachInstanceField( | 1133 classElement.forEachInstanceField( |
1131 includeBackendMembers: true, | 1134 includeBackendMembers: true, |
1132 includeSuperMembers: false, | 1135 includeSuperMembers: false, |
1133 f: (ClassElement enclosingClass, Element member) { | 1136 f: (ClassElement enclosingClass, Element member) { |
1134 TreeElements definitions = compiler.analyzeElement(member); | 1137 TreeElements definitions = compiler.analyzeElement(member); |
1135 Node node = member.parseNode(compiler); | 1138 Node node = member.parseNode(compiler); |
1136 SendSet assignment = node.asSendSet(); | 1139 SendSet assignment = node.asSendSet(); |
1137 HInstruction value; | 1140 HInstruction value; |
1138 if (assignment === null) { | 1141 if (assignment === null) { |
1139 value = graph.addConstantNull(); | 1142 value = graph.addConstantNull(constantSystem); |
1140 } else { | 1143 } else { |
1141 Node right = assignment.arguments.head; | 1144 Node right = assignment.arguments.head; |
1142 TreeElements savedElements = elements; | 1145 TreeElements savedElements = elements; |
1143 elements = definitions; | 1146 elements = definitions; |
1144 right.accept(this); | 1147 right.accept(this); |
1145 elements = savedElements; | 1148 elements = savedElements; |
1146 value = pop(); | 1149 value = pop(); |
1147 } | 1150 } |
1148 fieldValues[member] = value; | 1151 fieldValues[member] = value; |
1149 }); | 1152 }); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 // foo([a = 42]) { | 1265 // foo([a = 42]) { |
1263 // var t1 = a === sentinel; | 1266 // var t1 = a === sentinel; |
1264 // if (t1) a = 42; | 1267 // if (t1) a = 42; |
1265 // if (!t1) print('parameter passed ' + a); | 1268 // if (!t1) print('parameter passed ' + a); |
1266 // } | 1269 // } |
1267 | 1270 |
1268 // Fetch the original default value of [element]; | 1271 // Fetch the original default value of [element]; |
1269 ConstantHandler handler = compiler.constantHandler; | 1272 ConstantHandler handler = compiler.constantHandler; |
1270 Constant constant = handler.compileVariable(element); | 1273 Constant constant = handler.compileVariable(element); |
1271 HConstant defaultValue = constant == null | 1274 HConstant defaultValue = constant == null |
1272 ? graph.addConstantNull() | 1275 ? graph.addConstantNull(constantSystem) |
1273 : graph.addConstant(constant); | 1276 : graph.addConstant(constant); |
1274 | 1277 |
1275 // Emit the equality check with the sentinel. | 1278 // Emit the equality check with the sentinel. |
1276 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL); | 1279 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL); |
1277 Element equalsHelper = interceptors.getTripleEqualsInterceptor(); | 1280 Element equalsHelper = interceptors.getTripleEqualsInterceptor(); |
1278 HInstruction target = new HStatic(equalsHelper); | 1281 HInstruction target = new HStatic(equalsHelper); |
1279 add(target); | 1282 add(target); |
1280 HInstruction operand = parameters[element]; | 1283 HInstruction operand = parameters[element]; |
1281 HInstruction check = new HIdentity(target, sentinel, operand); | 1284 HInstruction check = new HIdentity(target, sentinel, operand); |
1282 add(check); | 1285 add(check); |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1663 Node initializer = node.initializer; | 1666 Node initializer = node.initializer; |
1664 if (initializer !== null) { | 1667 if (initializer !== null) { |
1665 visit(initializer); | 1668 visit(initializer); |
1666 if (initializer.asExpression() !== null) { | 1669 if (initializer.asExpression() !== null) { |
1667 pop(); | 1670 pop(); |
1668 } | 1671 } |
1669 } | 1672 } |
1670 } | 1673 } |
1671 HInstruction buildCondition() { | 1674 HInstruction buildCondition() { |
1672 if (node.condition === null) { | 1675 if (node.condition === null) { |
1673 return graph.addConstantBool(true); | 1676 return graph.addConstantBool(true, constantSystem); |
1674 } | 1677 } |
1675 visit(node.condition); | 1678 visit(node.condition); |
1676 return popBoolified(); | 1679 return popBoolified(); |
1677 } | 1680 } |
1678 void buildUpdate() { | 1681 void buildUpdate() { |
1679 for (Expression expression in node.update) { | 1682 for (Expression expression in node.update) { |
1680 visit(expression); | 1683 visit(expression); |
1681 assert(!isAborted()); | 1684 assert(!isAborted()); |
1682 // The result of the update instruction isn't used, and can just | 1685 // The result of the update instruction isn't used, and can just |
1683 // be dropped. | 1686 // be dropped. |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1878 switch (value) { | 1881 switch (value) { |
1879 case "-": result = new HNegate(target, operand); break; | 1882 case "-": result = new HNegate(target, operand); break; |
1880 case "~": result = new HBitNot(target, operand); break; | 1883 case "~": result = new HBitNot(target, operand); break; |
1881 default: | 1884 default: |
1882 compiler.internalError('Unexpected unary operator: $value.', node: op); | 1885 compiler.internalError('Unexpected unary operator: $value.', node: op); |
1883 break; | 1886 break; |
1884 } | 1887 } |
1885 // See if we can constant-fold right away. This avoids rewrites later on. | 1888 // See if we can constant-fold right away. This avoids rewrites later on. |
1886 if (operand is HConstant) { | 1889 if (operand is HConstant) { |
1887 HConstant constant = operand; | 1890 HConstant constant = operand; |
1888 Constant folded = result.operation.fold(constant.constant); | 1891 Constant folded = |
| 1892 result.operation(constantSystem).fold(constant.constant); |
1889 if (folded !== null) { | 1893 if (folded !== null) { |
1890 stack.add(graph.addConstant(folded)); | 1894 stack.add(graph.addConstant(folded)); |
1891 return; | 1895 return; |
1892 } | 1896 } |
1893 } | 1897 } |
1894 pushWithPosition(result, node); | 1898 pushWithPosition(result, node); |
1895 } | 1899 } |
1896 | 1900 |
1897 void visitBinary(HInstruction left, Operator op, HInstruction right) { | 1901 void visitBinary(HInstruction left, Operator op, HInstruction right) { |
1898 Element element = interceptors.getOperatorInterceptor(op); | 1902 Element element = interceptors.getOperatorInterceptor(op); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2167 HInstruction typeInfo = null; | 2171 HInstruction typeInfo = null; |
2168 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { | 2172 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { |
2169 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); | 2173 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); |
2170 typeInfo = pop(); | 2174 typeInfo = pop(); |
2171 } | 2175 } |
2172 if (type.element.isTypeVariable()) { | 2176 if (type.element.isTypeVariable()) { |
2173 // TODO(karlklose): We emulate the behavior of the old frog | 2177 // TODO(karlklose): We emulate the behavior of the old frog |
2174 // compiler and answer true to any is check involving a type variable | 2178 // compiler and answer true to any is check involving a type variable |
2175 // -- both is T and is !T -- until we have a proper implementation of | 2179 // -- both is T and is !T -- until we have a proper implementation of |
2176 // reified generics. | 2180 // reified generics. |
2177 stack.add(graph.addConstantBool(true)); | 2181 stack.add(graph.addConstantBool(true, constantSystem)); |
2178 } else { | 2182 } else { |
2179 HInstruction instruction; | 2183 HInstruction instruction; |
2180 if (typeInfo !== null) { | 2184 if (typeInfo !== null) { |
2181 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); | 2185 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); |
2182 } else { | 2186 } else { |
2183 instruction = new HIs(type, expression); | 2187 instruction = new HIs(type, expression); |
2184 } | 2188 } |
2185 if (isNot) { | 2189 if (isNot) { |
2186 add(instruction); | 2190 add(instruction); |
2187 instruction = new HNot(instruction); | 2191 instruction = new HNot(instruction); |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 generateSuperNoSuchMethodSend(Send node) { | 2507 generateSuperNoSuchMethodSend(Send node) { |
2504 ClassElement cls = work.element.getEnclosingClass(); | 2508 ClassElement cls = work.element.getEnclosingClass(); |
2505 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); | 2509 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); |
2506 HStatic target = new HStatic(element); | 2510 HStatic target = new HStatic(element); |
2507 add(target); | 2511 add(target); |
2508 HInstruction self = localsHandler.readThis(); | 2512 HInstruction self = localsHandler.readThis(); |
2509 Identifier identifier = node.selector.asIdentifier(); | 2513 Identifier identifier = node.selector.asIdentifier(); |
2510 String name = identifier.source.slowToString(); | 2514 String name = identifier.source.slowToString(); |
2511 // TODO(ahe): Add the arguments to this list. | 2515 // TODO(ahe): Add the arguments to this list. |
2512 push(new HLiteralList([])); | 2516 push(new HLiteralList([])); |
| 2517 Constant nameConstant = |
| 2518 constantSystem.createString(new DartString.literal(name), node); |
2513 var inputs = <HInstruction>[ | 2519 var inputs = <HInstruction>[ |
2514 target, | 2520 target, |
2515 self, | 2521 self, |
2516 graph.addConstantString(new DartString.literal(name), node), | 2522 graph.addConstant(nameConstant), |
2517 pop()]; | 2523 pop()]; |
2518 push(new HInvokeSuper(inputs)); | 2524 push(new HInvokeSuper(inputs)); |
2519 } | 2525 } |
2520 | 2526 |
2521 visitSend(Send node) { | 2527 visitSend(Send node) { |
2522 Element element = elements[node]; | 2528 Element element = elements[node]; |
2523 if (element !== null && element === work.element) { | 2529 if (element !== null && element === work.element) { |
2524 graph.isRecursiveMethod = true; | 2530 graph.isRecursiveMethod = true; |
2525 } | 2531 } |
2526 super.visitSend(node); | 2532 super.visitSend(node); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2574 return foreign; | 2580 return foreign; |
2575 } else { | 2581 } else { |
2576 // TODO(ngeoffray): Match the VM behavior and throw an | 2582 // TODO(ngeoffray): Match the VM behavior and throw an |
2577 // exception at runtime. | 2583 // exception at runtime. |
2578 compiler.cancel('Unimplemented unresolved type variable', | 2584 compiler.cancel('Unimplemented unresolved type variable', |
2579 node: currentNode); | 2585 node: currentNode); |
2580 } | 2586 } |
2581 } else { | 2587 } else { |
2582 // The type variable is a type (e.g. int). | 2588 // The type variable is a type (e.g. int). |
2583 return graph.addConstantString( | 2589 return graph.addConstantString( |
2584 new LiteralDartString('$argument'), currentNode); | 2590 new LiteralDartString('$argument'), currentNode, constantSystem); |
2585 } | 2591 } |
2586 } | 2592 } |
2587 | 2593 |
2588 visitNewSend(Send node) { | 2594 visitNewSend(Send node) { |
2589 computeType(element) { | 2595 computeType(element) { |
2590 Element originalElement = elements[node]; | 2596 Element originalElement = elements[node]; |
2591 if (originalElement.getEnclosingClass() === compiler.listClass) { | 2597 if (originalElement.getEnclosingClass() === compiler.listClass) { |
2592 if (node.arguments.isEmpty()) { | 2598 if (node.arguments.isEmpty()) { |
2593 return HType.EXTENDABLE_ARRAY; | 2599 return HType.EXTENDABLE_ARRAY; |
2594 } else { | 2600 } else { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2632 | 2638 |
2633 HType elementType = computeType(constructor); | 2639 HType elementType = computeType(constructor); |
2634 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2640 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
2635 pushWithPosition(newInstance, node); | 2641 pushWithPosition(newInstance, node); |
2636 } | 2642 } |
2637 | 2643 |
2638 visitStaticSend(Send node) { | 2644 visitStaticSend(Send node) { |
2639 Selector selector = elements.getSelector(node); | 2645 Selector selector = elements.getSelector(node); |
2640 Element element = elements[node]; | 2646 Element element = elements[node]; |
2641 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { | 2647 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { |
2642 stack.add(graph.addConstantNull()); | 2648 stack.add(graph.addConstantNull(constantSystem)); |
2643 return; | 2649 return; |
2644 } | 2650 } |
2645 compiler.ensure(!element.isGenerativeConstructor()); | 2651 compiler.ensure(!element.isGenerativeConstructor()); |
2646 if (element.isFunction()) { | 2652 if (element.isFunction()) { |
2647 if (tryInlineMethod(element, selector, node.arguments)) return; | 2653 if (tryInlineMethod(element, selector, node.arguments)) return; |
2648 | 2654 |
2649 HInstruction target = new HStatic(element); | 2655 HInstruction target = new HStatic(element); |
2650 add(target); | 2656 add(target); |
2651 var inputs = <HInstruction>[target]; | 2657 var inputs = <HInstruction>[target]; |
2652 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 2658 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
(...skipping 23 matching lines...) Expand all Loading... |
2676 generateGetter(node, elements[node]); | 2682 generateGetter(node, elements[node]); |
2677 } | 2683 } |
2678 | 2684 |
2679 // TODO(antonm): migrate rest of SsaBuilder to internalError. | 2685 // TODO(antonm): migrate rest of SsaBuilder to internalError. |
2680 internalError(String reason, [Node node]) { | 2686 internalError(String reason, [Node node]) { |
2681 compiler.internalError(reason, node: node); | 2687 compiler.internalError(reason, node: node); |
2682 } | 2688 } |
2683 | 2689 |
2684 void generateRuntimeError(Node node, String message) { | 2690 void generateRuntimeError(Node node, String message) { |
2685 DartString messageObject = new DartString.literal(message); | 2691 DartString messageObject = new DartString.literal(message); |
2686 HInstruction errorMessage = graph.addConstantString(messageObject, node); | 2692 Constant messageConstant = |
| 2693 constantSystem.createString(messageObject, node); |
| 2694 HInstruction errorMessage = graph.addConstant(messageConstant); |
2687 Element helper = interceptors.getThrowRuntimeError(); | 2695 Element helper = interceptors.getThrowRuntimeError(); |
2688 pushInvokeHelper1(helper, errorMessage); | 2696 pushInvokeHelper1(helper, errorMessage); |
2689 } | 2697 } |
2690 | 2698 |
2691 visitNewExpression(NewExpression node) { | 2699 visitNewExpression(NewExpression node) { |
2692 Element element = elements[node.send]; | 2700 Element element = elements[node.send]; |
2693 if (element != null && element.isErroneous()) { | 2701 if (element != null && element.isErroneous()) { |
2694 ErroneousElement error = element; | 2702 ErroneousElement error = element; |
2695 Message message = error.errorMessage; | 2703 Message message = error.errorMessage; |
2696 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 2704 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
2697 Element helper = | 2705 Element helper = |
2698 compiler.findHelper(const SourceString('throwNoSuchMethod')); | 2706 compiler.findHelper(const SourceString('throwNoSuchMethod')); |
2699 DartString receiverLiteral = new DartString.literal(''); | 2707 DartString receiverLiteral = new DartString.literal(''); |
2700 HInstruction receiver = graph.addConstantString(receiverLiteral, node); | 2708 Constant receiverConstant = |
| 2709 constantSystem.createString(receiverLiteral, node); |
| 2710 HInstruction receiver = graph.addConstant(receiverConstant); |
2701 String constructorName = 'constructor ${message.arguments[0]}'; | 2711 String constructorName = 'constructor ${message.arguments[0]}'; |
2702 DartString nameLiteral = new DartString.literal(constructorName); | 2712 DartString nameLiteral = new DartString.literal(constructorName); |
2703 HInstruction name = graph.addConstantString(nameLiteral, node.send); | 2713 Constant nameConstant = |
| 2714 constantSystem.createString(nameLiteral, node.send); |
| 2715 HInstruction name = graph.addConstant(nameConstant); |
2704 List<HInstruction> inputs = <HInstruction>[]; | 2716 List<HInstruction> inputs = <HInstruction>[]; |
2705 node.send.arguments.forEach((argumentNode) { | 2717 node.send.arguments.forEach((argumentNode) { |
2706 visit(argumentNode); | 2718 visit(argumentNode); |
2707 HInstruction value = pop(); | 2719 HInstruction value = pop(); |
2708 inputs.add(value); | 2720 inputs.add(value); |
2709 }); | 2721 }); |
2710 HInstruction arguments = new HLiteralList(inputs); | 2722 HInstruction arguments = new HLiteralList(inputs); |
2711 add(arguments); | 2723 add(arguments); |
2712 pushInvokeHelper3(helper, receiver, name, arguments); | 2724 pushInvokeHelper3(helper, receiver, name, arguments); |
2713 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { | 2725 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2762 HInstruction index; | 2774 HInstruction index; |
2763 bool isCompoundAssignment = op.source.stringValue.endsWith('='); | 2775 bool isCompoundAssignment = op.source.stringValue.endsWith('='); |
2764 // Compound assignments are considered as being prefix. | 2776 // Compound assignments are considered as being prefix. |
2765 bool isPrefix = !node.isPostfix; | 2777 bool isPrefix = !node.isPostfix; |
2766 Element getter = elements[node.selector]; | 2778 Element getter = elements[node.selector]; |
2767 if (isCompoundAssignment) { | 2779 if (isCompoundAssignment) { |
2768 value = pop(); | 2780 value = pop(); |
2769 index = pop(); | 2781 index = pop(); |
2770 } else { | 2782 } else { |
2771 index = pop(); | 2783 index = pop(); |
2772 value = graph.addConstantInt(1); | 2784 value = graph.addConstantInt(1, constantSystem); |
2773 } | 2785 } |
2774 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); | 2786 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); |
2775 add(indexMethod); | 2787 add(indexMethod); |
2776 HInstruction left = new HIndex(indexMethod, receiver, index); | 2788 HInstruction left = new HIndex(indexMethod, receiver, index); |
2777 add(left); | 2789 add(left); |
2778 Element opElement = elements[op]; | 2790 Element opElement = elements[op]; |
2779 visitBinary(left, op, value); | 2791 visitBinary(left, op, value); |
2780 value = pop(); | 2792 value = pop(); |
2781 HInstruction assign = new HIndexAssign( | 2793 HInstruction assign = new HIndexAssign( |
2782 target, receiver, index, value); | 2794 target, receiver, index, value); |
(...skipping 29 matching lines...) Expand all Loading... |
2812 generateInstanceGetterWithCompiledReceiver(node, receiver); | 2824 generateInstanceGetterWithCompiledReceiver(node, receiver); |
2813 } else { | 2825 } else { |
2814 generateGetter(node, elements[node.selector]); | 2826 generateGetter(node, elements[node.selector]); |
2815 } | 2827 } |
2816 HInstruction left = pop(); | 2828 HInstruction left = pop(); |
2817 HInstruction right; | 2829 HInstruction right; |
2818 if (isCompoundAssignment) { | 2830 if (isCompoundAssignment) { |
2819 visit(node.argumentsNode); | 2831 visit(node.argumentsNode); |
2820 right = pop(); | 2832 right = pop(); |
2821 } else { | 2833 } else { |
2822 right = graph.addConstantInt(1); | 2834 right = graph.addConstantInt(1, constantSystem); |
2823 } | 2835 } |
2824 visitBinary(left, op, right); | 2836 visitBinary(left, op, right); |
2825 HInstruction operation = pop(); | 2837 HInstruction operation = pop(); |
2826 assert(operation !== null); | 2838 assert(operation !== null); |
2827 if (Elements.isInstanceSend(node, elements)) { | 2839 if (Elements.isInstanceSend(node, elements)) { |
2828 assert(receiver !== null); | 2840 assert(receiver !== null); |
2829 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); | 2841 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); |
2830 } else { | 2842 } else { |
2831 assert(receiver === null); | 2843 assert(receiver === null); |
2832 generateSetter(node, element, operation); | 2844 generateSetter(node, element, operation); |
2833 } | 2845 } |
2834 if (!isPrefix) { | 2846 if (!isPrefix) { |
2835 pop(); | 2847 pop(); |
2836 stack.add(left); | 2848 stack.add(left); |
2837 } | 2849 } |
2838 } | 2850 } |
2839 } | 2851 } |
2840 | 2852 |
2841 void visitLiteralInt(LiteralInt node) { | 2853 void visitLiteralInt(LiteralInt node) { |
2842 stack.add(graph.addConstantInt(node.value)); | 2854 stack.add(graph.addConstantInt(node.value, constantSystem)); |
2843 } | 2855 } |
2844 | 2856 |
2845 void visitLiteralDouble(LiteralDouble node) { | 2857 void visitLiteralDouble(LiteralDouble node) { |
2846 stack.add(graph.addConstantDouble(node.value)); | 2858 stack.add(graph.addConstantDouble(node.value, constantSystem)); |
2847 } | 2859 } |
2848 | 2860 |
2849 void visitLiteralBool(LiteralBool node) { | 2861 void visitLiteralBool(LiteralBool node) { |
2850 stack.add(graph.addConstantBool(node.value)); | 2862 stack.add(graph.addConstantBool(node.value, constantSystem)); |
2851 } | 2863 } |
2852 | 2864 |
2853 void visitLiteralString(LiteralString node) { | 2865 void visitLiteralString(LiteralString node) { |
2854 stack.add(graph.addConstantString(node.dartString, node)); | 2866 stack.add(graph.addConstantString(node.dartString, node, constantSystem)); |
2855 } | 2867 } |
2856 | 2868 |
2857 void visitStringJuxtaposition(StringJuxtaposition node) { | 2869 void visitStringJuxtaposition(StringJuxtaposition node) { |
2858 if (!node.isInterpolation) { | 2870 if (!node.isInterpolation) { |
2859 // This is a simple string with no interpolations. | 2871 // This is a simple string with no interpolations. |
2860 stack.add(graph.addConstantString(node.dartString, node)); | 2872 stack.add(graph.addConstantString(node.dartString, node, constantSystem)); |
2861 return; | 2873 return; |
2862 } | 2874 } |
2863 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 2875 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
2864 stringBuilder.visit(node); | 2876 stringBuilder.visit(node); |
2865 stack.add(stringBuilder.result); | 2877 stack.add(stringBuilder.result); |
2866 } | 2878 } |
2867 | 2879 |
2868 void visitLiteralNull(LiteralNull node) { | 2880 void visitLiteralNull(LiteralNull node) { |
2869 stack.add(graph.addConstantNull()); | 2881 stack.add(graph.addConstantNull(constantSystem)); |
2870 } | 2882 } |
2871 | 2883 |
2872 visitNodeList(NodeList node) { | 2884 visitNodeList(NodeList node) { |
2873 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 2885 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
2874 if (isAborted()) { | 2886 if (isAborted()) { |
2875 compiler.reportWarning(link.head, 'dead code'); | 2887 compiler.reportWarning(link.head, 'dead code'); |
2876 } else { | 2888 } else { |
2877 visit(link.head); | 2889 visit(link.head); |
2878 } | 2890 } |
2879 } | 2891 } |
(...skipping 19 matching lines...) Expand all Loading... |
2899 dup(); | 2911 dup(); |
2900 } | 2912 } |
2901 | 2913 |
2902 visitReturn(Return node) { | 2914 visitReturn(Return node) { |
2903 if (node.getBeginToken().stringValue === 'native') { | 2915 if (node.getBeginToken().stringValue === 'native') { |
2904 native.handleSsaNative(this, node.expression); | 2916 native.handleSsaNative(this, node.expression); |
2905 return; | 2917 return; |
2906 } | 2918 } |
2907 HInstruction value; | 2919 HInstruction value; |
2908 if (node.expression === null) { | 2920 if (node.expression === null) { |
2909 value = graph.addConstantNull(); | 2921 value = graph.addConstantNull(constantSystem); |
2910 } else { | 2922 } else { |
2911 visit(node.expression); | 2923 visit(node.expression); |
2912 value = pop(); | 2924 value = pop(); |
2913 } | 2925 } |
2914 if (!inliningStack.isEmpty()) { | 2926 if (!inliningStack.isEmpty()) { |
2915 localsHandler.updateLocal(returnElement, value); | 2927 localsHandler.updateLocal(returnElement, value); |
2916 } else { | 2928 } else { |
2917 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); | 2929 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); |
2918 } | 2930 } |
2919 } | 2931 } |
2920 | 2932 |
2921 visitThrow(Throw node) { | 2933 visitThrow(Throw node) { |
2922 if (node.expression === null) { | 2934 if (node.expression === null) { |
2923 HInstruction exception = rethrowableException; | 2935 HInstruction exception = rethrowableException; |
2924 if (exception === null) { | 2936 if (exception === null) { |
2925 exception = graph.addConstantNull(); | 2937 exception = graph.addConstantNull(constantSystem); |
2926 compiler.reportError(node, | 2938 compiler.reportError(node, |
2927 'throw without expression outside catch block'); | 2939 'throw without expression outside catch block'); |
2928 } | 2940 } |
2929 close(new HThrow(exception, isRethrow: true)); | 2941 close(new HThrow(exception, isRethrow: true)); |
2930 } else { | 2942 } else { |
2931 visit(node.expression); | 2943 visit(node.expression); |
2932 close(new HThrow(pop())); | 2944 close(new HThrow(pop())); |
2933 } | 2945 } |
2934 } | 2946 } |
2935 | 2947 |
2936 visitTypeAnnotation(TypeAnnotation node) { | 2948 visitTypeAnnotation(TypeAnnotation node) { |
2937 compiler.internalError('visiting type annotation in SSA builder', | 2949 compiler.internalError('visiting type annotation in SSA builder', |
2938 node: node); | 2950 node: node); |
2939 } | 2951 } |
2940 | 2952 |
2941 visitVariableDefinitions(VariableDefinitions node) { | 2953 visitVariableDefinitions(VariableDefinitions node) { |
2942 for (Link<Node> link = node.definitions.nodes; | 2954 for (Link<Node> link = node.definitions.nodes; |
2943 !link.isEmpty(); | 2955 !link.isEmpty(); |
2944 link = link.tail) { | 2956 link = link.tail) { |
2945 Node definition = link.head; | 2957 Node definition = link.head; |
2946 if (definition is Identifier) { | 2958 if (definition is Identifier) { |
2947 HInstruction initialValue = graph.addConstantNull(); | 2959 HInstruction initialValue = graph.addConstantNull(constantSystem); |
2948 localsHandler.updateLocal(elements[definition], initialValue); | 2960 localsHandler.updateLocal(elements[definition], initialValue); |
2949 } else { | 2961 } else { |
2950 assert(definition is SendSet); | 2962 assert(definition is SendSet); |
2951 visitSendSet(definition); | 2963 visitSendSet(definition); |
2952 pop(); // Discard value. | 2964 pop(); // Discard value. |
2953 } | 2965 } |
2954 } | 2966 } |
2955 } | 2967 } |
2956 | 2968 |
2957 visitLiteralList(LiteralList node) { | 2969 visitLiteralList(LiteralList node) { |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3535 compiler.cancel('On with unresolved type', | 3547 compiler.cancel('On with unresolved type', |
3536 node: catchBlock.type); | 3548 node: catchBlock.type); |
3537 } | 3549 } |
3538 HInstruction condition = new HIs(type, unwrappedException); | 3550 HInstruction condition = new HIs(type, unwrappedException); |
3539 push(condition); | 3551 push(condition); |
3540 } | 3552 } |
3541 else { | 3553 else { |
3542 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 3554 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
3543 HInstruction condition = null; | 3555 HInstruction condition = null; |
3544 if (declaration.type == null) { | 3556 if (declaration.type == null) { |
3545 condition = graph.addConstantBool(true); | 3557 condition = graph.addConstantBool(true, constantSystem); |
3546 stack.add(condition); | 3558 stack.add(condition); |
3547 } else { | 3559 } else { |
3548 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 3560 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
3549 // "if" condition above and this "else" branch should be deleted as | 3561 // "if" condition above and this "else" branch should be deleted as |
3550 // type of declared variable won't matter for the catch | 3562 // type of declared variable won't matter for the catch |
3551 // condition. | 3563 // condition. |
3552 DartType type = elements.getType(declaration.type); | 3564 DartType type = elements.getType(declaration.type); |
3553 if (type == null) { | 3565 if (type == null) { |
3554 compiler.cancel('Catch with unresolved type', node: catchBlock); | 3566 compiler.cancel('Catch with unresolved type', node: catchBlock); |
3555 } | 3567 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3646 if (element === builder.compiler.intClass) return HType.INTEGER; | 3658 if (element === builder.compiler.intClass) return HType.INTEGER; |
3647 if (element === builder.compiler.listClass) return HType.READABLE_ARRAY; | 3659 if (element === builder.compiler.listClass) return HType.READABLE_ARRAY; |
3648 if (element === builder.compiler.nullClass) return HType.NULL; | 3660 if (element === builder.compiler.nullClass) return HType.NULL; |
3649 if (element === builder.compiler.stringClass) return HType.STRING; | 3661 if (element === builder.compiler.stringClass) return HType.STRING; |
3650 return HType.UNKNOWN; | 3662 return HType.UNKNOWN; |
3651 } | 3663 } |
3652 | 3664 |
3653 /** HACK HACK HACK */ | 3665 /** HACK HACK HACK */ |
3654 void hackAroundPossiblyAbortingBody(Node statement, void body()) { | 3666 void hackAroundPossiblyAbortingBody(Node statement, void body()) { |
3655 visitCondition() { | 3667 visitCondition() { |
3656 stack.add(graph.addConstantBool(true)); | 3668 stack.add(graph.addConstantBool(true, constantSystem)); |
3657 } | 3669 } |
3658 buildBody() { | 3670 buildBody() { |
3659 // TODO(lrn): Make sure to take continue into account. | 3671 // TODO(lrn): Make sure to take continue into account. |
3660 body(); | 3672 body(); |
3661 } | 3673 } |
3662 handleIf(statement, visitCondition, buildBody, null); | 3674 handleIf(statement, visitCondition, buildBody, null); |
3663 } | 3675 } |
3664 } | 3676 } |
3665 | 3677 |
3666 /** | 3678 /** |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 builder.push(new HNot(builder.pop())); | 3950 builder.push(new HNot(builder.pop())); |
3939 } | 3951 } |
3940 } | 3952 } |
3941 | 3953 |
3942 void visitThen() { | 3954 void visitThen() { |
3943 right(); | 3955 right(); |
3944 boolifiedRight = builder.popBoolified(); | 3956 boolifiedRight = builder.popBoolified(); |
3945 } | 3957 } |
3946 | 3958 |
3947 handleIf(visitCondition, visitThen, null); | 3959 handleIf(visitCondition, visitThen, null); |
| 3960 HConstant notIsAnd = |
| 3961 builder.graph.addConstantBool(!isAnd, builder.constantSystem); |
3948 HPhi result = new HPhi.manyInputs(null, | 3962 HPhi result = new HPhi.manyInputs(null, |
3949 <HInstruction>[boolifiedRight, builder.graph.addConstantBool(!isAnd)]); | 3963 <HInstruction>[boolifiedRight, notIsAnd]); |
3950 builder.current.addPhi(result); | 3964 builder.current.addPhi(result); |
3951 builder.stack.add(result); | 3965 builder.stack.add(result); |
3952 } | 3966 } |
3953 | 3967 |
3954 void handleLogicalAndOrWithLeftNode(Node left, | 3968 void handleLogicalAndOrWithLeftNode(Node left, |
3955 void visitRight(), | 3969 void visitRight(), |
3956 [bool isAnd]) { | 3970 [bool isAnd]) { |
3957 // This method is similar to [handleLogicalAndOr] but optimizes the case | 3971 // This method is similar to [handleLogicalAndOr] but optimizes the case |
3958 // where left is a logical "and" or logical "or". | 3972 // where left is a logical "and" or logical "or". |
3959 // | 3973 // |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4026 new HSubGraphBlockInformation(elseBranch.graph)); | 4040 new HSubGraphBlockInformation(elseBranch.graph)); |
4027 | 4041 |
4028 HBasicBlock conditionStartBlock = conditionBranch.block; | 4042 HBasicBlock conditionStartBlock = conditionBranch.block; |
4029 conditionStartBlock.setBlockFlow(info, joinBlock); | 4043 conditionStartBlock.setBlockFlow(info, joinBlock); |
4030 SubGraph conditionGraph = conditionBranch.graph; | 4044 SubGraph conditionGraph = conditionBranch.graph; |
4031 HIf branch = conditionGraph.end.last; | 4045 HIf branch = conditionGraph.end.last; |
4032 assert(branch is HIf); | 4046 assert(branch is HIf); |
4033 branch.blockInformation = conditionStartBlock.blockFlow; | 4047 branch.blockInformation = conditionStartBlock.blockFlow; |
4034 } | 4048 } |
4035 } | 4049 } |
OLD | NEW |