| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 if (element.isMember()) { | 66 if (element.isMember()) { |
| 67 String className = element.getEnclosingClass().name.slowToString(); | 67 String className = element.getEnclosingClass().name.slowToString(); |
| 68 String memberName = element.name.slowToString(); | 68 String memberName = element.name.slowToString(); |
| 69 name = "$className.$memberName"; | 69 name = "$className.$memberName"; |
| 70 if (element.isGenerativeConstructorBody()) { | 70 if (element.isGenerativeConstructorBody()) { |
| 71 name = "$name (body)"; | 71 name = "$name (body)"; |
| 72 } | 72 } |
| 73 } else { | 73 } else { |
| 74 name = "${element.name.slowToString()}"; | 74 name = "${element.name.slowToString()}"; |
| 75 } | 75 } |
| 76 compiler.tracer.traceCompilation(name, work.compilationContext); | 76 compiler.tracer.traceCompilation( |
| 77 name, work.compilationContext, compiler); |
| 77 compiler.tracer.traceGraph('builder', graph); | 78 compiler.tracer.traceGraph('builder', graph); |
| 78 } | 79 } |
| 79 return graph; | 80 return graph; |
| 80 }); | 81 }); |
| 81 } | 82 } |
| 82 | 83 |
| 83 HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) { | 84 HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) { |
| 84 return builder.buildFactory(work.element); | 85 return builder.buildFactory(work.element); |
| 85 } | 86 } |
| 86 } | 87 } |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 823 |
| 823 void generateContinue([LabelElement label]) { | 824 void generateContinue([LabelElement label]) { |
| 824 if (isContinueToSwitchCase(label)) { | 825 if (isContinueToSwitchCase(label)) { |
| 825 // Creates the special instructions 'label = i; continue l;' used in | 826 // Creates the special instructions 'label = i; continue l;' used in |
| 826 // switch statements with continue statements. See | 827 // switch statements with continue statements. See |
| 827 // [SsaBuilder.buildComplexSwitchStatement] for detail. | 828 // [SsaBuilder.buildComplexSwitchStatement] for detail. |
| 828 | 829 |
| 829 assert(label != null); | 830 assert(label != null); |
| 830 HInstruction value = builder.graph.addConstantInt( | 831 HInstruction value = builder.graph.addConstantInt( |
| 831 targetIndexMap[label.target], | 832 targetIndexMap[label.target], |
| 832 builder.constantSystem); | 833 builder.compiler); |
| 833 builder.localsHandler.updateLocal(target, value); | 834 builder.localsHandler.updateLocal(target, value); |
| 834 | 835 |
| 835 assert(label.target.labels.contains(label)); | 836 assert(label.target.labels.contains(label)); |
| 836 HInstruction continueInstruction = new HContinue(target); | 837 HInstruction continueInstruction = new HContinue(target); |
| 837 LocalsHandler locals = new LocalsHandler.from(builder.localsHandler); | 838 LocalsHandler locals = new LocalsHandler.from(builder.localsHandler); |
| 838 builder.close(continueInstruction); | 839 builder.close(continueInstruction); |
| 839 jumps.add(new JumpHandlerEntry(continueInstruction, locals)); | 840 jumps.add(new JumpHandlerEntry(continueInstruction, locals)); |
| 840 } else { | 841 } else { |
| 841 super.generateContinue(label); | 842 super.generateContinue(label); |
| 842 } | 843 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 // If [functionElement] is `operator==` we explicitely add a null check at | 1011 // If [functionElement] is `operator==` we explicitely add a null check at |
| 1011 // the beginning of the method. This is to avoid having call sites do the | 1012 // the beginning of the method. This is to avoid having call sites do the |
| 1012 // null check. | 1013 // null check. |
| 1013 if (name == const SourceString('==')) { | 1014 if (name == const SourceString('==')) { |
| 1014 if (!backend.operatorEqHandlesNullArgument(functionElement)) { | 1015 if (!backend.operatorEqHandlesNullArgument(functionElement)) { |
| 1015 handleIf( | 1016 handleIf( |
| 1016 function, | 1017 function, |
| 1017 () { | 1018 () { |
| 1018 HParameterValue parameter = parameters.values.first; | 1019 HParameterValue parameter = parameters.values.first; |
| 1019 push(new HIdentity( | 1020 push(new HIdentity( |
| 1020 parameter, graph.addConstantNull(constantSystem))); | 1021 parameter, graph.addConstantNull(compiler))); |
| 1021 }, | 1022 }, |
| 1022 () { | 1023 () { |
| 1023 closeAndGotoExit(new HReturn( | 1024 closeAndGotoExit(new HReturn( |
| 1024 graph.addConstantBool(false, constantSystem))); | 1025 graph.addConstantBool(false, compiler))); |
| 1025 }, | 1026 }, |
| 1026 null); | 1027 null); |
| 1027 } | 1028 } |
| 1028 } | 1029 } |
| 1029 function.body.accept(this); | 1030 function.body.accept(this); |
| 1030 return closeFunction(); | 1031 return closeFunction(); |
| 1031 } | 1032 } |
| 1032 | 1033 |
| 1033 HGraph buildLazyInitializer(VariableElement variable) { | 1034 HGraph buildLazyInitializer(VariableElement variable) { |
| 1034 SendSet node = variable.parseNode(compiler); | 1035 SendSet node = variable.parseNode(compiler); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 newLocalsHandler.updateLocal(typeVariable.element, argument); | 1187 newLocalsHandler.updateLocal(typeVariable.element, argument); |
| 1187 }); | 1188 }); |
| 1188 } | 1189 } |
| 1189 assert(argumentIndex == compiledArguments.length); | 1190 assert(argumentIndex == compiledArguments.length); |
| 1190 | 1191 |
| 1191 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 1192 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
| 1192 returnElement = new ElementX(const SourceString("result"), | 1193 returnElement = new ElementX(const SourceString("result"), |
| 1193 ElementKind.VARIABLE, | 1194 ElementKind.VARIABLE, |
| 1194 function); | 1195 function); |
| 1195 newLocalsHandler.updateLocal(returnElement, | 1196 newLocalsHandler.updateLocal(returnElement, |
| 1196 graph.addConstantNull(constantSystem)); | 1197 graph.addConstantNull(compiler)); |
| 1197 elements = compiler.enqueuer.resolution.getCachedElements(function); | 1198 elements = compiler.enqueuer.resolution.getCachedElements(function); |
| 1198 assert(elements != null); | 1199 assert(elements != null); |
| 1199 returnType = signature.returnType; | 1200 returnType = signature.returnType; |
| 1200 stack = <HInstruction>[]; | 1201 stack = <HInstruction>[]; |
| 1201 inliningStack.add(state); | 1202 inliningStack.add(state); |
| 1202 localsHandler = newLocalsHandler; | 1203 localsHandler = newLocalsHandler; |
| 1203 return state; | 1204 return state; |
| 1204 } | 1205 } |
| 1205 | 1206 |
| 1206 void leaveInlinedMethod(InliningState state) { | 1207 void leaveInlinedMethod(InliningState state) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 localsHandler.updateLocal(typeVariables.head.element, | 1347 localsHandler.updateLocal(typeVariables.head.element, |
| 1347 analyzeTypeArgument(argument, callNode)); | 1348 analyzeTypeArgument(argument, callNode)); |
| 1348 typeVariables = typeVariables.tail; | 1349 typeVariables = typeVariables.tail; |
| 1349 }); | 1350 }); |
| 1350 // If the supertype is a raw type, we need to set to null the | 1351 // If the supertype is a raw type, we need to set to null the |
| 1351 // type variables. | 1352 // type variables. |
| 1352 assert(typeVariables.isEmpty | 1353 assert(typeVariables.isEmpty |
| 1353 || superclass.typeVariables == typeVariables); | 1354 || superclass.typeVariables == typeVariables); |
| 1354 while (!typeVariables.isEmpty) { | 1355 while (!typeVariables.isEmpty) { |
| 1355 localsHandler.updateLocal(typeVariables.head.element, | 1356 localsHandler.updateLocal(typeVariables.head.element, |
| 1356 graph.addConstantNull(constantSystem)); | 1357 graph.addConstantNull(compiler)); |
| 1357 typeVariables = typeVariables.tail; | 1358 typeVariables = typeVariables.tail; |
| 1358 } | 1359 } |
| 1359 } | 1360 } |
| 1360 | 1361 |
| 1361 inlinedFrom(constructor, () { | 1362 inlinedFrom(constructor, () { |
| 1362 buildFieldInitializers(constructor.enclosingElement.implementation, | 1363 buildFieldInitializers(constructor.enclosingElement.implementation, |
| 1363 fieldValues); | 1364 fieldValues); |
| 1364 }); | 1365 }); |
| 1365 | 1366 |
| 1366 int index = 0; | 1367 int index = 0; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 Map<Element, HInstruction> fieldValues) { | 1494 Map<Element, HInstruction> fieldValues) { |
| 1494 assert(invariant(classElement, classElement.isImplementation)); | 1495 assert(invariant(classElement, classElement.isImplementation)); |
| 1495 classElement.forEachInstanceField( | 1496 classElement.forEachInstanceField( |
| 1496 (ClassElement enclosingClass, Element member) { | 1497 (ClassElement enclosingClass, Element member) { |
| 1497 compiler.withCurrentElement(member, () { | 1498 compiler.withCurrentElement(member, () { |
| 1498 TreeElements definitions = compiler.analyzeElement(member); | 1499 TreeElements definitions = compiler.analyzeElement(member); |
| 1499 Node node = member.parseNode(compiler); | 1500 Node node = member.parseNode(compiler); |
| 1500 SendSet assignment = node.asSendSet(); | 1501 SendSet assignment = node.asSendSet(); |
| 1501 HInstruction value; | 1502 HInstruction value; |
| 1502 if (assignment == null) { | 1503 if (assignment == null) { |
| 1503 value = graph.addConstantNull(constantSystem); | 1504 value = graph.addConstantNull(compiler); |
| 1504 } else { | 1505 } else { |
| 1505 Node right = assignment.arguments.head; | 1506 Node right = assignment.arguments.head; |
| 1506 TreeElements savedElements = elements; | 1507 TreeElements savedElements = elements; |
| 1507 elements = definitions; | 1508 elements = definitions; |
| 1508 // In case the field initializer uses closures, run the | 1509 // In case the field initializer uses closures, run the |
| 1509 // closure to class mapper. | 1510 // closure to class mapper. |
| 1510 compiler.closureToClassMapper.computeClosureToClassMapping( | 1511 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1511 member, node, elements); | 1512 member, node, elements); |
| 1512 inlinedFrom(member, () => right.accept(this)); | 1513 inlinedFrom(member, () => right.accept(this)); |
| 1513 elements = savedElements; | 1514 elements = savedElements; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1680 // | 1681 // |
| 1681 // foo([a = 42]) { | 1682 // foo([a = 42]) { |
| 1682 // var t1 = identical(a, sentinel); | 1683 // var t1 = identical(a, sentinel); |
| 1683 // if (t1) a = 42; | 1684 // if (t1) a = 42; |
| 1684 // if (!t1) print('parameter passed ' + a); | 1685 // if (!t1) print('parameter passed ' + a); |
| 1685 // } | 1686 // } |
| 1686 | 1687 |
| 1687 // Fetch the original default value of [element]; | 1688 // Fetch the original default value of [element]; |
| 1688 Constant constant = compileVariable(element); | 1689 Constant constant = compileVariable(element); |
| 1689 HConstant defaultValue = constant == null | 1690 HConstant defaultValue = constant == null |
| 1690 ? graph.addConstantNull(constantSystem) | 1691 ? graph.addConstantNull(compiler) |
| 1691 : graph.addConstant(constant); | 1692 : graph.addConstant(constant, compiler); |
| 1692 | 1693 |
| 1693 // Emit the equality check with the sentinel. | 1694 // Emit the equality check with the sentinel. |
| 1694 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL); | 1695 HConstant sentinel = |
| 1696 graph.addConstant(SentinelConstant.SENTINEL, compiler); |
| 1695 HInstruction operand = parameters[element]; | 1697 HInstruction operand = parameters[element]; |
| 1696 check = new HIdentity(sentinel, operand); | 1698 check = new HIdentity(sentinel, operand); |
| 1697 add(check); | 1699 add(check); |
| 1698 | 1700 |
| 1699 // If the check succeeds, we must update the parameter with the | 1701 // If the check succeeds, we must update the parameter with the |
| 1700 // default value. | 1702 // default value. |
| 1701 handleIf(element.parseNode(compiler), | 1703 handleIf(element.parseNode(compiler), |
| 1702 () => stack.add(check), | 1704 () => stack.add(check), |
| 1703 () => localsHandler.updateLocal(element, defaultValue), | 1705 () => localsHandler.updateLocal(element, defaultValue), |
| 1704 null); | 1706 null); |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2246 Node initializer = node.initializer; | 2248 Node initializer = node.initializer; |
| 2247 if (initializer != null) { | 2249 if (initializer != null) { |
| 2248 visit(initializer); | 2250 visit(initializer); |
| 2249 if (initializer.asExpression() != null) { | 2251 if (initializer.asExpression() != null) { |
| 2250 pop(); | 2252 pop(); |
| 2251 } | 2253 } |
| 2252 } | 2254 } |
| 2253 } | 2255 } |
| 2254 HInstruction buildCondition() { | 2256 HInstruction buildCondition() { |
| 2255 if (node.condition == null) { | 2257 if (node.condition == null) { |
| 2256 return graph.addConstantBool(true, constantSystem); | 2258 return graph.addConstantBool(true, compiler); |
| 2257 } | 2259 } |
| 2258 visit(node.condition); | 2260 visit(node.condition); |
| 2259 return popBoolified(); | 2261 return popBoolified(); |
| 2260 } | 2262 } |
| 2261 void buildUpdate() { | 2263 void buildUpdate() { |
| 2262 for (Expression expression in node.update) { | 2264 for (Expression expression in node.update) { |
| 2263 visit(expression); | 2265 visit(expression); |
| 2264 assert(!isAborted()); | 2266 assert(!isAborted()); |
| 2265 // The result of the update instruction isn't used, and can just | 2267 // The result of the update instruction isn't used, and can just |
| 2266 // be dropped. | 2268 // be dropped. |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2507 visit(node.receiver); | 2509 visit(node.receiver); |
| 2508 assert(!identical(op.token.kind, PLUS_TOKEN)); | 2510 assert(!identical(op.token.kind, PLUS_TOKEN)); |
| 2509 HInstruction operand = pop(); | 2511 HInstruction operand = pop(); |
| 2510 | 2512 |
| 2511 // See if we can constant-fold right away. This avoids rewrites later on. | 2513 // See if we can constant-fold right away. This avoids rewrites later on. |
| 2512 if (operand is HConstant) { | 2514 if (operand is HConstant) { |
| 2513 UnaryOperation operation = constantSystem.lookupUnary(op.source); | 2515 UnaryOperation operation = constantSystem.lookupUnary(op.source); |
| 2514 HConstant constant = operand; | 2516 HConstant constant = operand; |
| 2515 Constant folded = operation.fold(constant.constant); | 2517 Constant folded = operation.fold(constant.constant); |
| 2516 if (folded != null) { | 2518 if (folded != null) { |
| 2517 stack.add(graph.addConstant(folded)); | 2519 stack.add(graph.addConstant(folded, compiler)); |
| 2518 return; | 2520 return; |
| 2519 } | 2521 } |
| 2520 } | 2522 } |
| 2521 | 2523 |
| 2522 pushInvokeDynamic(node, elements.getSelector(node), [operand]); | 2524 pushInvokeDynamic(node, elements.getSelector(node), [operand]); |
| 2523 } | 2525 } |
| 2524 | 2526 |
| 2525 void visitBinary(HInstruction left, | 2527 void visitBinary(HInstruction left, |
| 2526 Operator op, | 2528 Operator op, |
| 2527 HInstruction right, | 2529 HInstruction right, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2575 | 2577 |
| 2576 void generateGetter(Send send, Element element) { | 2578 void generateGetter(Send send, Element element) { |
| 2577 if (Elements.isStaticOrTopLevelField(element)) { | 2579 if (Elements.isStaticOrTopLevelField(element)) { |
| 2578 Constant value; | 2580 Constant value; |
| 2579 if (element.isField() && !element.isAssignable()) { | 2581 if (element.isField() && !element.isAssignable()) { |
| 2580 // A static final or const. Get its constant value and inline it if | 2582 // A static final or const. Get its constant value and inline it if |
| 2581 // the value can be compiled eagerly. | 2583 // the value can be compiled eagerly. |
| 2582 value = compileVariable(element); | 2584 value = compileVariable(element); |
| 2583 } | 2585 } |
| 2584 if (value != null) { | 2586 if (value != null) { |
| 2585 stack.add(graph.addConstant(value)); | 2587 stack.add(graph.addConstant(value, compiler)); |
| 2586 } else if (element.isField() && isLazilyInitialized(element)) { | 2588 } else if (element.isField() && isLazilyInitialized(element)) { |
| 2587 HInstruction instruction = new HLazyStatic(element); | 2589 HInstruction instruction = new HLazyStatic(element); |
| 2588 instruction.instructionType = | 2590 instruction.instructionType = |
| 2589 new HType.inferredTypeForElement(element, compiler); | 2591 new HType.inferredTypeForElement(element, compiler); |
| 2590 push(instruction); | 2592 push(instruction); |
| 2591 } else { | 2593 } else { |
| 2592 if (element.isGetter()) { | 2594 if (element.isGetter()) { |
| 2593 pushInvokeStatic(send, element, <HInstruction>[]); | 2595 pushInvokeStatic(send, element, <HInstruction>[]); |
| 2594 } else { | 2596 } else { |
| 2595 // TODO(5346): Try to avoid the need for calling [declaration] before | 2597 // TODO(5346): Try to avoid the need for calling [declaration] before |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 HType type, | 2694 HType type, |
| 2693 List<HInstruction> inputs) { | 2695 List<HInstruction> inputs) { |
| 2694 return new HForeign(js.js.parseForeignJS(code), type, inputs); | 2696 return new HForeign(js.js.parseForeignJS(code), type, inputs); |
| 2695 } | 2697 } |
| 2696 | 2698 |
| 2697 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2699 HInstruction getRuntimeTypeInfo(HInstruction target) { |
| 2698 pushInvokeStatic(null, backend.getGetRuntimeTypeInfo(), [target]); | 2700 pushInvokeStatic(null, backend.getGetRuntimeTypeInfo(), [target]); |
| 2699 return pop(); | 2701 return pop(); |
| 2700 } | 2702 } |
| 2701 | 2703 |
| 2704 HLiteralList buildLiteralList(List<HInstruction> inputs) { |
| 2705 return new HLiteralList(inputs)..instructionType = |
| 2706 backend.extendableArrayType; |
| 2707 } |
| 2708 |
| 2702 // TODO(karlklose): change construction of the representations to be GVN'able | 2709 // TODO(karlklose): change construction of the representations to be GVN'able |
| 2703 // (dartbug.com/7182). | 2710 // (dartbug.com/7182). |
| 2704 HInstruction buildTypeArgumentRepresentations(DartType type) { | 2711 HInstruction buildTypeArgumentRepresentations(DartType type) { |
| 2705 // Compute the representation of the type arguments, including access | 2712 // Compute the representation of the type arguments, including access |
| 2706 // to the runtime type information for type variables as instructions. | 2713 // to the runtime type information for type variables as instructions. |
| 2707 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2714 if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 2708 return new HLiteralList(<HInstruction>[addTypeVariableReference(type)]); | 2715 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); |
| 2709 } else { | 2716 } else { |
| 2710 assert(type.element.isClass()); | 2717 assert(type.element.isClass()); |
| 2711 InterfaceType interface = type; | 2718 InterfaceType interface = type; |
| 2712 List<HInstruction> inputs = <HInstruction>[]; | 2719 List<HInstruction> inputs = <HInstruction>[]; |
| 2713 bool first = true; | 2720 bool first = true; |
| 2714 List<String> templates = <String>[]; | 2721 List<String> templates = <String>[]; |
| 2715 for (DartType argument in interface.typeArguments) { | 2722 for (DartType argument in interface.typeArguments) { |
| 2716 templates.add(rti.getTypeRepresentation(argument, (variable) { | 2723 templates.add(rti.getTypeRepresentation(argument, (variable) { |
| 2717 HInstruction runtimeType = addTypeVariableReference(variable); | 2724 HInstruction runtimeType = addTypeVariableReference(variable); |
| 2718 inputs.add(runtimeType); | 2725 inputs.add(runtimeType); |
| 2719 })); | 2726 })); |
| 2720 } | 2727 } |
| 2721 String template = '[${templates.join(', ')}]'; | 2728 String template = '[${templates.join(', ')}]'; |
| 2722 HInstruction representation = | 2729 HInstruction representation = |
| 2723 createForeign(template, HType.READABLE_ARRAY, inputs); | 2730 createForeign(template, backend.readableArrayType, inputs); |
| 2724 return representation; | 2731 return representation; |
| 2725 } | 2732 } |
| 2726 } | 2733 } |
| 2727 | 2734 |
| 2728 visitOperatorSend(node) { | 2735 visitOperatorSend(node) { |
| 2729 Operator op = node.selector; | 2736 Operator op = node.selector; |
| 2730 if (const SourceString("[]") == op.source) { | 2737 if (const SourceString("[]") == op.source) { |
| 2731 visitDynamicSend(node); | 2738 visitDynamicSend(node); |
| 2732 } else if (const SourceString("&&") == op.source || | 2739 } else if (const SourceString("&&") == op.source || |
| 2733 const SourceString("||") == op.source) { | 2740 const SourceString("||") == op.source) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2792 ClassElement element = type.element; | 2799 ClassElement element = type.element; |
| 2793 Element helper = backend.getCheckSubtype(); | 2800 Element helper = backend.getCheckSubtype(); |
| 2794 HInstruction representations = | 2801 HInstruction representations = |
| 2795 buildTypeArgumentRepresentations(type); | 2802 buildTypeArgumentRepresentations(type); |
| 2796 add(representations); | 2803 add(representations); |
| 2797 String operator = | 2804 String operator = |
| 2798 backend.namer.operatorIs(backend.getImplementationClass(element)); | 2805 backend.namer.operatorIs(backend.getImplementationClass(element)); |
| 2799 HInstruction isFieldName = addConstantString(node, operator); | 2806 HInstruction isFieldName = addConstantString(node, operator); |
| 2800 HInstruction asFieldName = compiler.world.hasAnySubtype(element) | 2807 HInstruction asFieldName = compiler.world.hasAnySubtype(element) |
| 2801 ? addConstantString(node, backend.namer.substitutionName(element)) | 2808 ? addConstantString(node, backend.namer.substitutionName(element)) |
| 2802 : graph.addConstantNull(constantSystem); | 2809 : graph.addConstantNull(compiler); |
| 2803 List<HInstruction> inputs = <HInstruction>[expression, | 2810 List<HInstruction> inputs = <HInstruction>[expression, |
| 2804 isFieldName, | 2811 isFieldName, |
| 2805 representations, | 2812 representations, |
| 2806 asFieldName]; | 2813 asFieldName]; |
| 2807 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); | 2814 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); |
| 2808 HInstruction call = pop(); | 2815 HInstruction call = pop(); |
| 2809 return | 2816 return |
| 2810 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK); | 2817 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK); |
| 2811 } else { | 2818 } else { |
| 2812 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); | 2819 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2851 HInstruction handleConstantForOptionalParameter(Element parameter) { | 2858 HInstruction handleConstantForOptionalParameter(Element parameter) { |
| 2852 Constant constant; | 2859 Constant constant; |
| 2853 Element element = parameter.enclosingElement; | 2860 Element element = parameter.enclosingElement; |
| 2854 TreeElements calleeElements = | 2861 TreeElements calleeElements = |
| 2855 compiler.enqueuer.resolution.getCachedElements(element); | 2862 compiler.enqueuer.resolution.getCachedElements(element); |
| 2856 if (calleeElements.isParameterChecked(parameter)) { | 2863 if (calleeElements.isParameterChecked(parameter)) { |
| 2857 constant = SentinelConstant.SENTINEL; | 2864 constant = SentinelConstant.SENTINEL; |
| 2858 } else { | 2865 } else { |
| 2859 constant = compileConstant(parameter); | 2866 constant = compileConstant(parameter); |
| 2860 } | 2867 } |
| 2861 return graph.addConstant(constant); | 2868 return graph.addConstant(constant, compiler); |
| 2862 } | 2869 } |
| 2863 | 2870 |
| 2864 /** | 2871 /** |
| 2865 * Returns true if the arguments were compatible with the function signature. | 2872 * Returns true if the arguments were compatible with the function signature. |
| 2866 * | 2873 * |
| 2867 * Invariant: [element] must be an implementation element. | 2874 * Invariant: [element] must be an implementation element. |
| 2868 */ | 2875 */ |
| 2869 bool addStaticSendArgumentsToList(Selector selector, | 2876 bool addStaticSendArgumentsToList(Selector selector, |
| 2870 Link<Node> arguments, | 2877 Link<Node> arguments, |
| 2871 FunctionElement element, | 2878 FunctionElement element, |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3134 compiler.enqueuer.codegen.registerSelectorUse(selector); | 3141 compiler.enqueuer.codegen.registerSelectorUse(selector); |
| 3135 } | 3142 } |
| 3136 Constant nameConstant = constantSystem.createString( | 3143 Constant nameConstant = constantSystem.createString( |
| 3137 new DartString.literal(name.slowToString()), node); | 3144 new DartString.literal(name.slowToString()), node); |
| 3138 | 3145 |
| 3139 String internalName = backend.namer.invocationName(selector); | 3146 String internalName = backend.namer.invocationName(selector); |
| 3140 Constant internalNameConstant = | 3147 Constant internalNameConstant = |
| 3141 constantSystem.createString(new DartString.literal(internalName), node); | 3148 constantSystem.createString(new DartString.literal(internalName), node); |
| 3142 | 3149 |
| 3143 Element createInvocationMirror = backend.getCreateInvocationMirror(); | 3150 Element createInvocationMirror = backend.getCreateInvocationMirror(); |
| 3144 var argumentsInstruction = new HLiteralList(arguments); | 3151 var argumentsInstruction = buildLiteralList(arguments); |
| 3145 add(argumentsInstruction); | 3152 add(argumentsInstruction); |
| 3146 | 3153 |
| 3147 var argumentNames = new List<HInstruction>(); | 3154 var argumentNames = new List<HInstruction>(); |
| 3148 for (SourceString argumentName in selector.namedArguments) { | 3155 for (SourceString argumentName in selector.namedArguments) { |
| 3149 Constant argumentNameConstant = | 3156 Constant argumentNameConstant = |
| 3150 constantSystem.createString(new DartString.literal( | 3157 constantSystem.createString(new DartString.literal( |
| 3151 argumentName.slowToString()), node); | 3158 argumentName.slowToString()), node); |
| 3152 argumentNames.add(graph.addConstant(argumentNameConstant)); | 3159 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); |
| 3153 } | 3160 } |
| 3154 var argumentNamesInstruction = new HLiteralList(argumentNames); | 3161 var argumentNamesInstruction = buildLiteralList(argumentNames); |
| 3155 add(argumentNamesInstruction); | 3162 add(argumentNamesInstruction); |
| 3156 | 3163 |
| 3157 Constant kindConstant = | 3164 Constant kindConstant = |
| 3158 constantSystem.createInt(selector.invocationMirrorKind); | 3165 constantSystem.createInt(selector.invocationMirrorKind); |
| 3159 | 3166 |
| 3160 pushInvokeStatic(null, | 3167 pushInvokeStatic(null, |
| 3161 createInvocationMirror, | 3168 createInvocationMirror, |
| 3162 [graph.addConstant(nameConstant), | 3169 [graph.addConstant(nameConstant, compiler), |
| 3163 graph.addConstant(internalNameConstant), | 3170 graph.addConstant(internalNameConstant, compiler), |
| 3164 graph.addConstant(kindConstant), | 3171 graph.addConstant(kindConstant, compiler), |
| 3165 argumentsInstruction, | 3172 argumentsInstruction, |
| 3166 argumentNamesInstruction], | 3173 argumentNamesInstruction], |
| 3167 HType.UNKNOWN); | 3174 HType.UNKNOWN); |
| 3168 | 3175 |
| 3169 var inputs = <HInstruction>[pop()]; | 3176 var inputs = <HInstruction>[pop()]; |
| 3170 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); | 3177 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); |
| 3171 } | 3178 } |
| 3172 | 3179 |
| 3173 visitSend(Send node) { | 3180 visitSend(Send node) { |
| 3174 Element element = elements[node]; | 3181 Element element = elements[node]; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3217 * them as an instance of the type we are testing against (if necessary), and | 3224 * them as an instance of the type we are testing against (if necessary), and |
| 3218 * extract the type argument by the index of the variable in the list of type | 3225 * extract the type argument by the index of the variable in the list of type |
| 3219 * variables for that class. | 3226 * variables for that class. |
| 3220 */ | 3227 */ |
| 3221 HInstruction readTypeVariable(ClassElement cls, | 3228 HInstruction readTypeVariable(ClassElement cls, |
| 3222 TypeVariableElement variable) { | 3229 TypeVariableElement variable) { |
| 3223 assert(currentElement.isInstanceMember()); | 3230 assert(currentElement.isInstanceMember()); |
| 3224 int index = RuntimeTypes.getTypeVariableIndex(variable); | 3231 int index = RuntimeTypes.getTypeVariableIndex(variable); |
| 3225 String substitutionNameString = backend.namer.substitutionName(cls); | 3232 String substitutionNameString = backend.namer.substitutionName(cls); |
| 3226 HInstruction substitutionName = graph.addConstantString( | 3233 HInstruction substitutionName = graph.addConstantString( |
| 3227 new LiteralDartString(substitutionNameString), null, constantSystem); | 3234 new LiteralDartString(substitutionNameString), null, compiler); |
| 3228 HInstruction target = localsHandler.readThis(); | 3235 HInstruction target = localsHandler.readThis(); |
| 3229 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN, | 3236 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN, |
| 3230 <HInstruction>[target, substitutionName]); | 3237 <HInstruction>[target, substitutionName]); |
| 3231 add(substitution); | 3238 add(substitution); |
| 3232 pushInvokeStatic(null, | 3239 pushInvokeStatic(null, |
| 3233 backend.getGetRuntimeTypeArgument(), | 3240 backend.getGetRuntimeTypeArgument(), |
| 3234 [target, | 3241 [target, |
| 3235 substitution, | 3242 substitution, |
| 3236 graph.addConstantInt(index, constantSystem)], | 3243 graph.addConstantInt(index, compiler)], |
| 3237 HType.UNKNOWN); | 3244 HType.UNKNOWN); |
| 3238 return pop(); | 3245 return pop(); |
| 3239 } | 3246 } |
| 3240 | 3247 |
| 3241 /** | 3248 /** |
| 3242 * Helper to create an instruction that gets the value of a type variable. | 3249 * Helper to create an instruction that gets the value of a type variable. |
| 3243 */ | 3250 */ |
| 3244 HInstruction addTypeVariableReference(TypeVariableType type) { | 3251 HInstruction addTypeVariableReference(TypeVariableType type) { |
| 3245 Element member = currentElement; | 3252 Element member = currentElement; |
| 3246 bool isClosure = member.enclosingElement.isClosure(); | 3253 bool isClosure = member.enclosingElement.isClosure(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3274 * Documentation wanted -- johnniwinther | 3281 * Documentation wanted -- johnniwinther |
| 3275 * | 3282 * |
| 3276 * Invariant: [argument] must not be malformed in checked mode. | 3283 * Invariant: [argument] must not be malformed in checked mode. |
| 3277 */ | 3284 */ |
| 3278 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { | 3285 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| 3279 assert(invariant(currentNode, | 3286 assert(invariant(currentNode, |
| 3280 !compiler.enableTypeAssertions || !argument.isMalformed, | 3287 !compiler.enableTypeAssertions || !argument.isMalformed, |
| 3281 message: '$argument is malformed in checked mode')); | 3288 message: '$argument is malformed in checked mode')); |
| 3282 if (argument == compiler.types.dynamicType || argument.isMalformed) { | 3289 if (argument == compiler.types.dynamicType || argument.isMalformed) { |
| 3283 // Represent [dynamic] as [null]. | 3290 // Represent [dynamic] as [null]. |
| 3284 return graph.addConstantNull(constantSystem); | 3291 return graph.addConstantNull(compiler); |
| 3285 } | 3292 } |
| 3286 | 3293 |
| 3287 List<HInstruction> inputs = <HInstruction>[]; | 3294 List<HInstruction> inputs = <HInstruction>[]; |
| 3288 | 3295 |
| 3289 String template = rti.getTypeRepresentation(argument, (variable) { | 3296 String template = rti.getTypeRepresentation(argument, (variable) { |
| 3290 inputs.add(addTypeVariableReference(variable)); | 3297 inputs.add(addTypeVariableReference(variable)); |
| 3291 }); | 3298 }); |
| 3292 | 3299 |
| 3293 HInstruction result = createForeign(template, HType.STRING, inputs); | 3300 HInstruction result = createForeign(template, backend.stringType, inputs); |
| 3294 add(result); | 3301 add(result); |
| 3295 return result; | 3302 return result; |
| 3296 } | 3303 } |
| 3297 | 3304 |
| 3298 void handleListConstructor(InterfaceType type, | 3305 void handleListConstructor(InterfaceType type, |
| 3299 Node currentNode, | 3306 Node currentNode, |
| 3300 HInstruction newObject) { | 3307 HInstruction newObject) { |
| 3301 if (!backend.needsRti(type.element)) return; | 3308 if (!backend.needsRti(type.element)) return; |
| 3302 if (!type.isRaw) { | 3309 if (!type.isRaw) { |
| 3303 List<HInstruction> inputs = <HInstruction>[]; | 3310 List<HInstruction> inputs = <HInstruction>[]; |
| 3304 type.typeArguments.forEach((DartType argument) { | 3311 type.typeArguments.forEach((DartType argument) { |
| 3305 inputs.add(analyzeTypeArgument(argument, currentNode)); | 3312 inputs.add(analyzeTypeArgument(argument, currentNode)); |
| 3306 }); | 3313 }); |
| 3307 callSetRuntimeTypeInfo(type.element, inputs, newObject); | 3314 callSetRuntimeTypeInfo(type.element, inputs, newObject); |
| 3308 } | 3315 } |
| 3309 } | 3316 } |
| 3310 | 3317 |
| 3311 void callSetRuntimeTypeInfo(ClassElement element, | 3318 void callSetRuntimeTypeInfo(ClassElement element, |
| 3312 List<HInstruction> rtiInputs, | 3319 List<HInstruction> rtiInputs, |
| 3313 HInstruction newObject) { | 3320 HInstruction newObject) { |
| 3314 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { | 3321 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { |
| 3315 return; | 3322 return; |
| 3316 } | 3323 } |
| 3317 | 3324 |
| 3318 HInstruction typeInfo = new HLiteralList(rtiInputs); | 3325 HInstruction typeInfo = buildLiteralList(rtiInputs); |
| 3319 add(typeInfo); | 3326 add(typeInfo); |
| 3320 | 3327 |
| 3321 // Set the runtime type information on the object. | 3328 // Set the runtime type information on the object. |
| 3322 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); | 3329 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); |
| 3323 pushInvokeStatic( | 3330 pushInvokeStatic( |
| 3324 null, | 3331 null, |
| 3325 typeInfoSetterElement, | 3332 typeInfoSetterElement, |
| 3326 <HInstruction>[newObject, typeInfo], | 3333 <HInstruction>[newObject, typeInfo], |
| 3327 HType.UNKNOWN); | 3334 HType.UNKNOWN); |
| 3328 pop(); | 3335 pop(); |
| 3329 } | 3336 } |
| 3330 | 3337 |
| 3331 /** | 3338 /** |
| 3332 * Documentation wanted -- johnniwinther | 3339 * Documentation wanted -- johnniwinther |
| 3333 * | 3340 * |
| 3334 * Invariant: [type] must not be malformed in checked mode. | 3341 * Invariant: [type] must not be malformed in checked mode. |
| 3335 */ | 3342 */ |
| 3336 handleNewSend(NewExpression node, InterfaceType type) { | 3343 handleNewSend(NewExpression node, InterfaceType type) { |
| 3337 Send send = node.send; | 3344 Send send = node.send; |
| 3338 assert(invariant(send, | 3345 assert(invariant(send, |
| 3339 !compiler.enableTypeAssertions || !type.isMalformed, | 3346 !compiler.enableTypeAssertions || !type.isMalformed, |
| 3340 message: '$type is malformed in checked mode')); | 3347 message: '$type is malformed in checked mode')); |
| 3341 bool isListConstructor = false; | 3348 bool isListConstructor = false; |
| 3342 computeType(element) { | 3349 computeType(element) { |
| 3343 Element originalElement = elements[send]; | 3350 Element originalElement = elements[send]; |
| 3344 if (Elements.isFixedListConstructorCall( | 3351 if (Elements.isFixedListConstructorCall( |
| 3345 originalElement, send, compiler)) { | 3352 originalElement, send, compiler)) { |
| 3346 isListConstructor = true; | 3353 isListConstructor = true; |
| 3347 return HType.FIXED_ARRAY; | 3354 return backend.fixedArrayType; |
| 3348 } else if (Elements.isGrowableListConstructorCall( | 3355 } else if (Elements.isGrowableListConstructorCall( |
| 3349 originalElement, send, compiler)) { | 3356 originalElement, send, compiler)) { |
| 3350 isListConstructor = true; | 3357 isListConstructor = true; |
| 3351 return HType.EXTENDABLE_ARRAY; | 3358 return backend.extendableArrayType; |
| 3352 } else if (element.isGenerativeConstructor()) { | 3359 } else if (element.isGenerativeConstructor()) { |
| 3353 ClassElement cls = element.getEnclosingClass(); | 3360 ClassElement cls = element.getEnclosingClass(); |
| 3354 return new HType.nonNullExact(cls.thisType, compiler); | 3361 return new HType.nonNullExact(cls.thisType, compiler); |
| 3355 } else { | 3362 } else { |
| 3356 return new HType.inferredTypeForElement(originalElement, compiler); | 3363 return new HType.inferredTypeForElement(originalElement, compiler); |
| 3357 } | 3364 } |
| 3358 } | 3365 } |
| 3359 | 3366 |
| 3360 Element constructor = elements[send]; | 3367 Element constructor = elements[send]; |
| 3361 Selector selector = elements.getSelector(send); | 3368 Selector selector = elements.getSelector(send); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3416 } | 3423 } |
| 3417 if (backend.needsRti(cls)) { | 3424 if (backend.needsRti(cls)) { |
| 3418 Link<DartType> typeVariable = cls.typeVariables; | 3425 Link<DartType> typeVariable = cls.typeVariables; |
| 3419 type.typeArguments.forEach((DartType argument) { | 3426 type.typeArguments.forEach((DartType argument) { |
| 3420 inputs.add(analyzeTypeArgument(argument, send)); | 3427 inputs.add(analyzeTypeArgument(argument, send)); |
| 3421 typeVariable = typeVariable.tail; | 3428 typeVariable = typeVariable.tail; |
| 3422 }); | 3429 }); |
| 3423 // Also add null to non-provided type variables to call the | 3430 // Also add null to non-provided type variables to call the |
| 3424 // constructor with the right number of arguments. | 3431 // constructor with the right number of arguments. |
| 3425 while (!typeVariable.isEmpty) { | 3432 while (!typeVariable.isEmpty) { |
| 3426 inputs.add(graph.addConstantNull(constantSystem)); | 3433 inputs.add(graph.addConstantNull(compiler)); |
| 3427 typeVariable = typeVariable.tail; | 3434 typeVariable = typeVariable.tail; |
| 3428 } | 3435 } |
| 3429 } | 3436 } |
| 3430 | 3437 |
| 3431 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { | 3438 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { |
| 3432 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); | 3439 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
| 3433 } | 3440 } |
| 3434 HType elementType = computeType(constructor); | 3441 HType elementType = computeType(constructor); |
| 3435 pushInvokeStatic(node, constructor, inputs, elementType); | 3442 pushInvokeStatic(node, constructor, inputs, elementType); |
| 3436 HInstruction newInstance = stack.last; | 3443 HInstruction newInstance = stack.last; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3461 return; | 3468 return; |
| 3462 } | 3469 } |
| 3463 if (element.isErroneous()) { | 3470 if (element.isErroneous()) { |
| 3464 generateThrowNoSuchMethod(node, | 3471 generateThrowNoSuchMethod(node, |
| 3465 getTargetName(element), | 3472 getTargetName(element), |
| 3466 argumentNodes: node.arguments); | 3473 argumentNodes: node.arguments); |
| 3467 return; | 3474 return; |
| 3468 } | 3475 } |
| 3469 if (identical(element, compiler.assertMethod) | 3476 if (identical(element, compiler.assertMethod) |
| 3470 && !compiler.enableUserAssertions) { | 3477 && !compiler.enableUserAssertions) { |
| 3471 stack.add(graph.addConstantNull(constantSystem)); | 3478 stack.add(graph.addConstantNull(compiler)); |
| 3472 return; | 3479 return; |
| 3473 } | 3480 } |
| 3474 compiler.ensure(!element.isGenerativeConstructor()); | 3481 compiler.ensure(!element.isGenerativeConstructor()); |
| 3475 if (element.isFunction()) { | 3482 if (element.isFunction()) { |
| 3476 var inputs = <HInstruction>[]; | 3483 var inputs = <HInstruction>[]; |
| 3477 // TODO(5347): Try to avoid the need for calling [implementation] before | 3484 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3478 // calling [addStaticSendArgumentsToList]. | 3485 // calling [addStaticSendArgumentsToList]. |
| 3479 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3486 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 3480 element.implementation, | 3487 element.implementation, |
| 3481 inputs); | 3488 inputs); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3495 List<HInstruction> inputs = <HInstruction>[pop()]; | 3502 List<HInstruction> inputs = <HInstruction>[pop()]; |
| 3496 addDynamicSendArgumentsToList(node, inputs); | 3503 addDynamicSendArgumentsToList(node, inputs); |
| 3497 Selector closureSelector = new Selector.callClosureFrom(selector); | 3504 Selector closureSelector = new Selector.callClosureFrom(selector); |
| 3498 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); | 3505 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); |
| 3499 } | 3506 } |
| 3500 } | 3507 } |
| 3501 | 3508 |
| 3502 HConstant addConstantString(Node node, String string) { | 3509 HConstant addConstantString(Node node, String string) { |
| 3503 DartString dartString = new DartString.literal(string); | 3510 DartString dartString = new DartString.literal(string); |
| 3504 Constant constant = constantSystem.createString(dartString, node); | 3511 Constant constant = constantSystem.createString(dartString, node); |
| 3505 return graph.addConstant(constant); | 3512 return graph.addConstant(constant, compiler); |
| 3506 } | 3513 } |
| 3507 | 3514 |
| 3508 visitTypeReferenceSend(Send node) { | 3515 visitTypeReferenceSend(Send node) { |
| 3509 Element element = elements[node]; | 3516 Element element = elements[node]; |
| 3510 if (element.isClass() || element.isTypedef()) { | 3517 if (element.isClass() || element.isTypedef()) { |
| 3511 // TODO(karlklose): add type representation | 3518 // TODO(karlklose): add type representation |
| 3512 ConstantHandler handler = compiler.constantHandler; | 3519 ConstantHandler handler = compiler.constantHandler; |
| 3513 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3520 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3514 stack.add(graph.addConstant(constant)); | 3521 stack.add(graph.addConstant(constant, compiler)); |
| 3515 } else if (element.isTypeVariable()) { | 3522 } else if (element.isTypeVariable()) { |
| 3516 HInstruction value = | 3523 HInstruction value = |
| 3517 addTypeVariableReference(element.computeType(compiler)); | 3524 addTypeVariableReference(element.computeType(compiler)); |
| 3518 pushInvokeStatic(node, | 3525 pushInvokeStatic(node, |
| 3519 backend.getRuntimeTypeToString(), | 3526 backend.getRuntimeTypeToString(), |
| 3520 [value], | 3527 [value], |
| 3521 HType.STRING); | 3528 backend.stringType); |
| 3522 pushInvokeStatic(node, | 3529 pushInvokeStatic(node, |
| 3523 backend.getCreateRuntimeType(), | 3530 backend.getCreateRuntimeType(), |
| 3524 [pop()]); | 3531 [pop()]); |
| 3525 } else { | 3532 } else { |
| 3526 internalError('unexpected element kind $element', node: node); | 3533 internalError('unexpected element kind $element', node: node); |
| 3527 } | 3534 } |
| 3528 if (node.isCall) { | 3535 if (node.isCall) { |
| 3529 // This send is of the form 'e(...)', where e is resolved to a type | 3536 // This send is of the form 'e(...)', where e is resolved to a type |
| 3530 // reference. We create a regular closure call on the result of the type | 3537 // reference. We create a regular closure call on the result of the type |
| 3531 // reference instead of creating a NoSuchMethodError to avoid pulling it | 3538 // reference instead of creating a NoSuchMethodError to avoid pulling it |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3564 } | 3571 } |
| 3565 | 3572 |
| 3566 void generateThrowNoSuchMethod(Node diagnosticNode, | 3573 void generateThrowNoSuchMethod(Node diagnosticNode, |
| 3567 String methodName, | 3574 String methodName, |
| 3568 {Link<Node> argumentNodes, | 3575 {Link<Node> argumentNodes, |
| 3569 List<HInstruction> argumentValues, | 3576 List<HInstruction> argumentValues, |
| 3570 List<String> existingArguments}) { | 3577 List<String> existingArguments}) { |
| 3571 Element helper = backend.getThrowNoSuchMethod(); | 3578 Element helper = backend.getThrowNoSuchMethod(); |
| 3572 Constant receiverConstant = | 3579 Constant receiverConstant = |
| 3573 constantSystem.createString(new DartString.empty(), diagnosticNode); | 3580 constantSystem.createString(new DartString.empty(), diagnosticNode); |
| 3574 HInstruction receiver = graph.addConstant(receiverConstant); | 3581 HInstruction receiver = graph.addConstant(receiverConstant, compiler); |
| 3575 DartString dartString = new DartString.literal(methodName); | 3582 DartString dartString = new DartString.literal(methodName); |
| 3576 Constant nameConstant = | 3583 Constant nameConstant = |
| 3577 constantSystem.createString(dartString, diagnosticNode); | 3584 constantSystem.createString(dartString, diagnosticNode); |
| 3578 HInstruction name = graph.addConstant(nameConstant); | 3585 HInstruction name = graph.addConstant(nameConstant, compiler); |
| 3579 if (argumentValues == null) { | 3586 if (argumentValues == null) { |
| 3580 argumentValues = <HInstruction>[]; | 3587 argumentValues = <HInstruction>[]; |
| 3581 argumentNodes.forEach((argumentNode) { | 3588 argumentNodes.forEach((argumentNode) { |
| 3582 visit(argumentNode); | 3589 visit(argumentNode); |
| 3583 HInstruction value = pop(); | 3590 HInstruction value = pop(); |
| 3584 argumentValues.add(value); | 3591 argumentValues.add(value); |
| 3585 }); | 3592 }); |
| 3586 } | 3593 } |
| 3587 HInstruction arguments = new HLiteralList(argumentValues); | 3594 HInstruction arguments = buildLiteralList(argumentValues); |
| 3588 add(arguments); | 3595 add(arguments); |
| 3589 HInstruction existingNamesList; | 3596 HInstruction existingNamesList; |
| 3590 if (existingArguments != null) { | 3597 if (existingArguments != null) { |
| 3591 List<HInstruction> existingNames = <HInstruction>[]; | 3598 List<HInstruction> existingNames = <HInstruction>[]; |
| 3592 for (String name in existingArguments) { | 3599 for (String name in existingArguments) { |
| 3593 HInstruction nameConstant = | 3600 HInstruction nameConstant = |
| 3594 graph.addConstantString(new DartString.literal(name), | 3601 graph.addConstantString(new DartString.literal(name), |
| 3595 diagnosticNode, constantSystem); | 3602 diagnosticNode, compiler); |
| 3596 existingNames.add(nameConstant); | 3603 existingNames.add(nameConstant); |
| 3597 } | 3604 } |
| 3598 existingNamesList = new HLiteralList(existingNames); | 3605 existingNamesList = buildLiteralList(existingNames); |
| 3599 add(existingNamesList); | 3606 add(existingNamesList); |
| 3600 } else { | 3607 } else { |
| 3601 existingNamesList = graph.addConstantNull(constantSystem); | 3608 existingNamesList = graph.addConstantNull(compiler); |
| 3602 } | 3609 } |
| 3603 pushInvokeStatic(diagnosticNode, | 3610 pushInvokeStatic(diagnosticNode, |
| 3604 helper, | 3611 helper, |
| 3605 [receiver, name, arguments, existingNamesList]); | 3612 [receiver, name, arguments, existingNamesList]); |
| 3606 } | 3613 } |
| 3607 | 3614 |
| 3608 /** | 3615 /** |
| 3609 * Generate code to throw a [NoSuchMethodError] exception for calling a | 3616 * Generate code to throw a [NoSuchMethodError] exception for calling a |
| 3610 * method with a wrong number of arguments or mismatching named optional | 3617 * method with a wrong number of arguments or mismatching named optional |
| 3611 * arguments. | 3618 * arguments. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3646 getTargetName(error, 'constructor'), | 3653 getTargetName(error, 'constructor'), |
| 3647 argumentNodes: node.send.arguments); | 3654 argumentNodes: node.send.arguments); |
| 3648 } else { | 3655 } else { |
| 3649 Message message = error.messageKind.message(error.messageArguments); | 3656 Message message = error.messageKind.message(error.messageArguments); |
| 3650 generateRuntimeError(node.send, message.toString()); | 3657 generateRuntimeError(node.send, message.toString()); |
| 3651 } | 3658 } |
| 3652 } else if (node.isConst()) { | 3659 } else if (node.isConst()) { |
| 3653 // TODO(karlklose): add type representation | 3660 // TODO(karlklose): add type representation |
| 3654 ConstantHandler handler = compiler.constantHandler; | 3661 ConstantHandler handler = compiler.constantHandler; |
| 3655 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3662 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3656 stack.add(graph.addConstant(constant)); | 3663 stack.add(graph.addConstant(constant, compiler)); |
| 3657 if (isSymbolConstructor) { | 3664 if (isSymbolConstructor) { |
| 3658 ConstructedConstant symbol = constant; | 3665 ConstructedConstant symbol = constant; |
| 3659 StringConstant stringConstant = symbol.fields.single; | 3666 StringConstant stringConstant = symbol.fields.single; |
| 3660 String nameString = stringConstant.toDartString().slowToString(); | 3667 String nameString = stringConstant.toDartString().slowToString(); |
| 3661 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); | 3668 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); |
| 3662 } | 3669 } |
| 3663 } else { | 3670 } else { |
| 3664 DartType type = elements.getType(node); | 3671 DartType type = elements.getType(node); |
| 3665 if (compiler.enableTypeAssertions && type.isMalformed) { | 3672 if (compiler.enableTypeAssertions && type.isMalformed) { |
| 3666 String reasons = Types.fetchReasonsFromMalformedType(type); | 3673 String reasons = Types.fetchReasonsFromMalformedType(type); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3797 new HType.inferredReturnTypeForElement(element, compiler); | 3804 new HType.inferredReturnTypeForElement(element, compiler); |
| 3798 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 3805 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); |
| 3799 return instruction; | 3806 return instruction; |
| 3800 } | 3807 } |
| 3801 | 3808 |
| 3802 void handleComplexOperatorSend(SendSet node, | 3809 void handleComplexOperatorSend(SendSet node, |
| 3803 HInstruction receiver, | 3810 HInstruction receiver, |
| 3804 Link<Node> arguments) { | 3811 Link<Node> arguments) { |
| 3805 HInstruction rhs; | 3812 HInstruction rhs; |
| 3806 if (node.isPrefix || node.isPostfix) { | 3813 if (node.isPrefix || node.isPostfix) { |
| 3807 rhs = graph.addConstantInt(1, constantSystem); | 3814 rhs = graph.addConstantInt(1, compiler); |
| 3808 } else { | 3815 } else { |
| 3809 visit(arguments.head); | 3816 visit(arguments.head); |
| 3810 assert(arguments.tail.isEmpty); | 3817 assert(arguments.tail.isEmpty); |
| 3811 rhs = pop(); | 3818 rhs = pop(); |
| 3812 } | 3819 } |
| 3813 visitBinary(receiver, node.assignmentOperator, rhs, | 3820 visitBinary(receiver, node.assignmentOperator, rhs, |
| 3814 elements.getOperatorSelectorInComplexSendSet(node), node); | 3821 elements.getOperatorSelectorInComplexSendSet(node), node); |
| 3815 } | 3822 } |
| 3816 | 3823 |
| 3817 visitSendSet(SendSet node) { | 3824 visitSendSet(SendSet node) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 generateNonInstanceSetter(node, element, value); | 3955 generateNonInstanceSetter(node, element, value); |
| 3949 } | 3956 } |
| 3950 if (node.isPostfix) { | 3957 if (node.isPostfix) { |
| 3951 pop(); | 3958 pop(); |
| 3952 stack.add(getterInstruction); | 3959 stack.add(getterInstruction); |
| 3953 } | 3960 } |
| 3954 } | 3961 } |
| 3955 } | 3962 } |
| 3956 | 3963 |
| 3957 void visitLiteralInt(LiteralInt node) { | 3964 void visitLiteralInt(LiteralInt node) { |
| 3958 stack.add(graph.addConstantInt(node.value, constantSystem)); | 3965 stack.add(graph.addConstantInt(node.value, compiler)); |
| 3959 } | 3966 } |
| 3960 | 3967 |
| 3961 void visitLiteralDouble(LiteralDouble node) { | 3968 void visitLiteralDouble(LiteralDouble node) { |
| 3962 stack.add(graph.addConstantDouble(node.value, constantSystem)); | 3969 stack.add(graph.addConstantDouble(node.value, compiler)); |
| 3963 } | 3970 } |
| 3964 | 3971 |
| 3965 void visitLiteralBool(LiteralBool node) { | 3972 void visitLiteralBool(LiteralBool node) { |
| 3966 stack.add(graph.addConstantBool(node.value, constantSystem)); | 3973 stack.add(graph.addConstantBool(node.value, compiler)); |
| 3967 } | 3974 } |
| 3968 | 3975 |
| 3969 void visitLiteralString(LiteralString node) { | 3976 void visitLiteralString(LiteralString node) { |
| 3970 stack.add(graph.addConstantString(node.dartString, node, constantSystem)); | 3977 stack.add(graph.addConstantString(node.dartString, node, compiler)); |
| 3971 } | 3978 } |
| 3972 | 3979 |
| 3973 void visitStringJuxtaposition(StringJuxtaposition node) { | 3980 void visitStringJuxtaposition(StringJuxtaposition node) { |
| 3974 if (!node.isInterpolation) { | 3981 if (!node.isInterpolation) { |
| 3975 // This is a simple string with no interpolations. | 3982 // This is a simple string with no interpolations. |
| 3976 stack.add(graph.addConstantString(node.dartString, node, constantSystem)); | 3983 stack.add(graph.addConstantString(node.dartString, node, compiler)); |
| 3977 return; | 3984 return; |
| 3978 } | 3985 } |
| 3979 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 3986 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
| 3980 stringBuilder.visit(node); | 3987 stringBuilder.visit(node); |
| 3981 stack.add(stringBuilder.result); | 3988 stack.add(stringBuilder.result); |
| 3982 } | 3989 } |
| 3983 | 3990 |
| 3984 void visitLiteralNull(LiteralNull node) { | 3991 void visitLiteralNull(LiteralNull node) { |
| 3985 stack.add(graph.addConstantNull(constantSystem)); | 3992 stack.add(graph.addConstantNull(compiler)); |
| 3986 } | 3993 } |
| 3987 | 3994 |
| 3988 visitNodeList(NodeList node) { | 3995 visitNodeList(NodeList node) { |
| 3989 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3996 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 3990 if (isAborted()) { | 3997 if (isAborted()) { |
| 3991 compiler.reportWarning(link.head, 'dead code'); | 3998 compiler.reportWarning(link.head, 'dead code'); |
| 3992 } else { | 3999 } else { |
| 3993 visit(link.head); | 4000 visit(link.head); |
| 3994 } | 4001 } |
| 3995 } | 4002 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4019 if (!inTryStatement) return; | 4026 if (!inTryStatement) return; |
| 4020 HBasicBlock block = close(new HExitTry()); | 4027 HBasicBlock block = close(new HExitTry()); |
| 4021 HBasicBlock newBlock = graph.addNewBlock(); | 4028 HBasicBlock newBlock = graph.addNewBlock(); |
| 4022 block.addSuccessor(newBlock); | 4029 block.addSuccessor(newBlock); |
| 4023 open(newBlock); | 4030 open(newBlock); |
| 4024 } | 4031 } |
| 4025 | 4032 |
| 4026 visitRethrow(Rethrow node) { | 4033 visitRethrow(Rethrow node) { |
| 4027 HInstruction exception = rethrowableException; | 4034 HInstruction exception = rethrowableException; |
| 4028 if (exception == null) { | 4035 if (exception == null) { |
| 4029 exception = graph.addConstantNull(constantSystem); | 4036 exception = graph.addConstantNull(compiler); |
| 4030 compiler.internalError( | 4037 compiler.internalError( |
| 4031 'rethrowableException should not be null', node: node); | 4038 'rethrowableException should not be null', node: node); |
| 4032 } | 4039 } |
| 4033 handleInTryStatement(); | 4040 handleInTryStatement(); |
| 4034 closeAndGotoExit(new HThrow(exception, isRethrow: true)); | 4041 closeAndGotoExit(new HThrow(exception, isRethrow: true)); |
| 4035 } | 4042 } |
| 4036 | 4043 |
| 4037 visitReturn(Return node) { | 4044 visitReturn(Return node) { |
| 4038 if (identical(node.getBeginToken().stringValue, 'native')) { | 4045 if (identical(node.getBeginToken().stringValue, 'native')) { |
| 4039 native.handleSsaNative(this, node.expression); | 4046 native.handleSsaNative(this, node.expression); |
| 4040 return; | 4047 return; |
| 4041 } | 4048 } |
| 4042 HInstruction value; | 4049 HInstruction value; |
| 4043 if (node.isRedirectingFactoryBody) { | 4050 if (node.isRedirectingFactoryBody) { |
| 4044 // TODO(ahe): This is only for reflection, and it is not correct yet. | 4051 // TODO(ahe): This is only for reflection, and it is not correct yet. |
| 4045 value = graph.addConstantNull(constantSystem); | 4052 value = graph.addConstantNull(compiler); |
| 4046 } else if (node.expression == null) { | 4053 } else if (node.expression == null) { |
| 4047 value = graph.addConstantNull(constantSystem); | 4054 value = graph.addConstantNull(compiler); |
| 4048 } else { | 4055 } else { |
| 4049 visit(node.expression); | 4056 visit(node.expression); |
| 4050 value = pop(); | 4057 value = pop(); |
| 4051 value = potentiallyCheckType(value, returnType); | 4058 value = potentiallyCheckType(value, returnType); |
| 4052 } | 4059 } |
| 4053 | 4060 |
| 4054 handleInTryStatement(); | 4061 handleInTryStatement(); |
| 4055 | 4062 |
| 4056 if (!inliningStack.isEmpty) { | 4063 if (!inliningStack.isEmpty) { |
| 4057 localsHandler.updateLocal(returnElement, value); | 4064 localsHandler.updateLocal(returnElement, value); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4074 node: node); | 4081 node: node); |
| 4075 } | 4082 } |
| 4076 | 4083 |
| 4077 visitVariableDefinitions(VariableDefinitions node) { | 4084 visitVariableDefinitions(VariableDefinitions node) { |
| 4078 assert(isReachable); | 4085 assert(isReachable); |
| 4079 for (Link<Node> link = node.definitions.nodes; | 4086 for (Link<Node> link = node.definitions.nodes; |
| 4080 !link.isEmpty; | 4087 !link.isEmpty; |
| 4081 link = link.tail) { | 4088 link = link.tail) { |
| 4082 Node definition = link.head; | 4089 Node definition = link.head; |
| 4083 if (definition is Identifier) { | 4090 if (definition is Identifier) { |
| 4084 HInstruction initialValue = graph.addConstantNull(constantSystem); | 4091 HInstruction initialValue = graph.addConstantNull(compiler); |
| 4085 localsHandler.updateLocal(elements[definition], initialValue); | 4092 localsHandler.updateLocal(elements[definition], initialValue); |
| 4086 } else { | 4093 } else { |
| 4087 assert(definition is SendSet); | 4094 assert(definition is SendSet); |
| 4088 visitSendSet(definition); | 4095 visitSendSet(definition); |
| 4089 pop(); // Discard value. | 4096 pop(); // Discard value. |
| 4090 } | 4097 } |
| 4091 } | 4098 } |
| 4092 } | 4099 } |
| 4093 | 4100 |
| 4094 visitLiteralList(LiteralList node) { | 4101 visitLiteralList(LiteralList node) { |
| 4095 if (node.isConst()) { | 4102 if (node.isConst()) { |
| 4096 ConstantHandler handler = compiler.constantHandler; | 4103 ConstantHandler handler = compiler.constantHandler; |
| 4097 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 4104 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 4098 stack.add(graph.addConstant(constant)); | 4105 stack.add(graph.addConstant(constant, compiler)); |
| 4099 return; | 4106 return; |
| 4100 } | 4107 } |
| 4101 | 4108 |
| 4102 List<HInstruction> inputs = <HInstruction>[]; | 4109 List<HInstruction> inputs = <HInstruction>[]; |
| 4103 for (Link<Node> link = node.elements.nodes; | 4110 for (Link<Node> link = node.elements.nodes; |
| 4104 !link.isEmpty; | 4111 !link.isEmpty; |
| 4105 link = link.tail) { | 4112 link = link.tail) { |
| 4106 visit(link.head); | 4113 visit(link.head); |
| 4107 inputs.add(pop()); | 4114 inputs.add(pop()); |
| 4108 } | 4115 } |
| 4109 push(new HLiteralList(inputs)); | 4116 push(buildLiteralList(inputs)); |
| 4110 } | 4117 } |
| 4111 | 4118 |
| 4112 visitConditional(Conditional node) { | 4119 visitConditional(Conditional node) { |
| 4113 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); | 4120 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
| 4114 brancher.handleConditional(() => visit(node.condition), | 4121 brancher.handleConditional(() => visit(node.condition), |
| 4115 () => visit(node.thenExpression), | 4122 () => visit(node.thenExpression), |
| 4116 () => visit(node.elseExpression)); | 4123 () => visit(node.elseExpression)); |
| 4117 } | 4124 } |
| 4118 | 4125 |
| 4119 visitStringInterpolation(StringInterpolation node) { | 4126 visitStringInterpolation(StringInterpolation node) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4283 handler.labels()), | 4290 handler.labels()), |
| 4284 joinBlock); | 4291 joinBlock); |
| 4285 } | 4292 } |
| 4286 handler.close(); | 4293 handler.close(); |
| 4287 } | 4294 } |
| 4288 | 4295 |
| 4289 visitLiteralMap(LiteralMap node) { | 4296 visitLiteralMap(LiteralMap node) { |
| 4290 if (node.isConst()) { | 4297 if (node.isConst()) { |
| 4291 ConstantHandler handler = compiler.constantHandler; | 4298 ConstantHandler handler = compiler.constantHandler; |
| 4292 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 4299 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 4293 stack.add(graph.addConstant(constant)); | 4300 stack.add(graph.addConstant(constant, compiler)); |
| 4294 return; | 4301 return; |
| 4295 } | 4302 } |
| 4296 List<HInstruction> inputs = <HInstruction>[]; | 4303 List<HInstruction> inputs = <HInstruction>[]; |
| 4297 for (Link<Node> link = node.entries.nodes; | 4304 for (Link<Node> link = node.entries.nodes; |
| 4298 !link.isEmpty; | 4305 !link.isEmpty; |
| 4299 link = link.tail) { | 4306 link = link.tail) { |
| 4300 visit(link.head); | 4307 visit(link.head); |
| 4301 inputs.add(pop()); | 4308 inputs.add(pop()); |
| 4302 inputs.add(pop()); | 4309 inputs.add(pop()); |
| 4303 } | 4310 } |
| 4304 HLiteralList keyValuePairs = new HLiteralList(inputs); | 4311 HLiteralList keyValuePairs = buildLiteralList(inputs); |
| 4305 add(keyValuePairs); | 4312 add(keyValuePairs); |
| 4306 HType mapType = new HType.nonNullSubtype( | 4313 HType mapType = new HType.nonNullSubtype( |
| 4307 backend.mapLiteralClass.computeType(compiler), compiler); | 4314 backend.mapLiteralClass.computeType(compiler), compiler); |
| 4308 pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); | 4315 pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); |
| 4309 } | 4316 } |
| 4310 | 4317 |
| 4311 visitLiteralMapEntry(LiteralMapEntry node) { | 4318 visitLiteralMapEntry(LiteralMapEntry node) { |
| 4312 visit(node.value); | 4319 visit(node.value); |
| 4313 visit(node.key); | 4320 visit(node.key); |
| 4314 } | 4321 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4455 // l: while (true) { | 4462 // l: while (true) { |
| 4456 // switch (target) { | 4463 // switch (target) { |
| 4457 // case 1: s_1; break l; | 4464 // case 1: s_1; break l; |
| 4458 // case 2: s_2; target = i; continue l; | 4465 // case 2: s_2; target = i; continue l; |
| 4459 // ... | 4466 // ... |
| 4460 // case n: s_n; target = j; continue l; | 4467 // case n: s_n; target = j; continue l; |
| 4461 // } | 4468 // } |
| 4462 // } | 4469 // } |
| 4463 | 4470 |
| 4464 TargetElement switchTarget = elements[node]; | 4471 TargetElement switchTarget = elements[node]; |
| 4465 HInstruction initialValue = graph.addConstantNull(constantSystem); | 4472 HInstruction initialValue = graph.addConstantNull(compiler); |
| 4466 localsHandler.updateLocal(switchTarget, initialValue); | 4473 localsHandler.updateLocal(switchTarget, initialValue); |
| 4467 | 4474 |
| 4468 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); | 4475 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); |
| 4469 var switchCases = node.cases; | 4476 var switchCases = node.cases; |
| 4470 if (!hasDefault) { | 4477 if (!hasDefault) { |
| 4471 // Use [:null:] as the marker for a synthetic default clause. | 4478 // Use [:null:] as the marker for a synthetic default clause. |
| 4472 // The synthetic default is added because otherwise, there would be no | 4479 // The synthetic default is added because otherwise, there would be no |
| 4473 // good place to give a default value to the local. | 4480 // good place to give a default value to the local. |
| 4474 switchCases = node.cases.nodes.toList()..add(null); | 4481 switchCases = node.cases.nodes.toList()..add(null); |
| 4475 } | 4482 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4488 } | 4495 } |
| 4489 return constantList; | 4496 return constantList; |
| 4490 } | 4497 } |
| 4491 bool isDefaultCase(SwitchCase switchCase) { | 4498 bool isDefaultCase(SwitchCase switchCase) { |
| 4492 return switchCase == null || switchCase.isDefaultCase; | 4499 return switchCase == null || switchCase.isDefaultCase; |
| 4493 } | 4500 } |
| 4494 void buildSwitchCase(SwitchCase switchCase) { | 4501 void buildSwitchCase(SwitchCase switchCase) { |
| 4495 if (switchCase != null) { | 4502 if (switchCase != null) { |
| 4496 // Generate 'target = i; break;' for switch case i. | 4503 // Generate 'target = i; break;' for switch case i. |
| 4497 int index = caseIndex[switchCase]; | 4504 int index = caseIndex[switchCase]; |
| 4498 HInstruction value = graph.addConstantInt(index, constantSystem); | 4505 HInstruction value = graph.addConstantInt(index, compiler); |
| 4499 localsHandler.updateLocal(switchTarget, value); | 4506 localsHandler.updateLocal(switchTarget, value); |
| 4500 } else { | 4507 } else { |
| 4501 // Generate synthetic default case 'target = null; break;'. | 4508 // Generate synthetic default case 'target = null; break;'. |
| 4502 HInstruction value = graph.addConstantNull(constantSystem); | 4509 HInstruction value = graph.addConstantNull(compiler); |
| 4503 localsHandler.updateLocal(switchTarget, value); | 4510 localsHandler.updateLocal(switchTarget, value); |
| 4504 } | 4511 } |
| 4505 jumpTargets[switchTarget].generateBreak(); | 4512 jumpTargets[switchTarget].generateBreak(); |
| 4506 } | 4513 } |
| 4507 handleSwitch(node, | 4514 handleSwitch(node, |
| 4508 jumpHandler, | 4515 jumpHandler, |
| 4509 buildExpression, | 4516 buildExpression, |
| 4510 switchCases, | 4517 switchCases, |
| 4511 getConstants, | 4518 getConstants, |
| 4512 isDefaultCase, | 4519 isDefaultCase, |
| 4513 buildSwitchCase); | 4520 buildSwitchCase); |
| 4514 jumpHandler.close(); | 4521 jumpHandler.close(); |
| 4515 | 4522 |
| 4516 HInstruction buildCondition() => | 4523 HInstruction buildCondition() => |
| 4517 graph.addConstantBool(true, constantSystem); | 4524 graph.addConstantBool(true, compiler); |
| 4518 | 4525 |
| 4519 void buildSwitch() { | 4526 void buildSwitch() { |
| 4520 HInstruction buildExpression() { | 4527 HInstruction buildExpression() { |
| 4521 return localsHandler.readLocal(switchTarget); | 4528 return localsHandler.readLocal(switchTarget); |
| 4522 } | 4529 } |
| 4523 Iterable<Constant> getConstants(SwitchCase switchCase) { | 4530 Iterable<Constant> getConstants(SwitchCase switchCase) { |
| 4524 return <Constant>[constantSystem.createInt(caseIndex[switchCase])]; | 4531 return <Constant>[constantSystem.createInt(caseIndex[switchCase])]; |
| 4525 } | 4532 } |
| 4526 void buildSwitchCase(SwitchCase switchCase) { | 4533 void buildSwitchCase(SwitchCase switchCase) { |
| 4527 visit(switchCase.statements); | 4534 visit(switchCase.statements); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4602 bool hasDefault = false; | 4609 bool hasDefault = false; |
| 4603 Element getFallThroughErrorElement = backend.getFallThroughError(); | 4610 Element getFallThroughErrorElement = backend.getFallThroughError(); |
| 4604 HasNextIterator<Node> caseIterator = | 4611 HasNextIterator<Node> caseIterator = |
| 4605 new HasNextIterator<Node>(switchCases.iterator); | 4612 new HasNextIterator<Node>(switchCases.iterator); |
| 4606 while (caseIterator.hasNext) { | 4613 while (caseIterator.hasNext) { |
| 4607 SwitchCase switchCase = caseIterator.next(); | 4614 SwitchCase switchCase = caseIterator.next(); |
| 4608 List<Constant> caseConstants = <Constant>[]; | 4615 List<Constant> caseConstants = <Constant>[]; |
| 4609 HBasicBlock block = graph.addNewBlock(); | 4616 HBasicBlock block = graph.addNewBlock(); |
| 4610 for (Constant constant in getConstants(switchCase)) { | 4617 for (Constant constant in getConstants(switchCase)) { |
| 4611 caseConstants.add(constant); | 4618 caseConstants.add(constant); |
| 4612 HConstant hConstant = graph.addConstant(constant); | 4619 HConstant hConstant = graph.addConstant(constant, compiler); |
| 4613 switchInstruction.inputs.add(hConstant); | 4620 switchInstruction.inputs.add(hConstant); |
| 4614 hConstant.usedBy.add(switchInstruction); | 4621 hConstant.usedBy.add(switchInstruction); |
| 4615 expressionBlock.addSuccessor(block); | 4622 expressionBlock.addSuccessor(block); |
| 4616 } | 4623 } |
| 4617 matchExpressions.add(caseConstants); | 4624 matchExpressions.add(caseConstants); |
| 4618 | 4625 |
| 4619 if (isDefaultCase(switchCase)) { | 4626 if (isDefaultCase(switchCase)) { |
| 4620 // An HSwitch has n inputs and n+1 successors, the last being the | 4627 // An HSwitch has n inputs and n+1 successors, the last being the |
| 4621 // default case. | 4628 // default case. |
| 4622 expressionBlock.addSuccessor(block); | 4629 expressionBlock.addSuccessor(block); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4789 | 4796 |
| 4790 void pushCondition(CatchBlock catchBlock) { | 4797 void pushCondition(CatchBlock catchBlock) { |
| 4791 if (catchBlock.onKeyword != null) { | 4798 if (catchBlock.onKeyword != null) { |
| 4792 DartType type = elements.getType(catchBlock.type); | 4799 DartType type = elements.getType(catchBlock.type); |
| 4793 if (type == null) { | 4800 if (type == null) { |
| 4794 compiler.internalError('On with no type', node: catchBlock.type); | 4801 compiler.internalError('On with no type', node: catchBlock.type); |
| 4795 } | 4802 } |
| 4796 if (type.isMalformed) { | 4803 if (type.isMalformed) { |
| 4797 // TODO(johnniwinther): Handle malformed types in [HIs] instead. | 4804 // TODO(johnniwinther): Handle malformed types in [HIs] instead. |
| 4798 HInstruction condition = | 4805 HInstruction condition = |
| 4799 graph.addConstantBool(true, constantSystem); | 4806 graph.addConstantBool(true, compiler); |
| 4800 stack.add(condition); | 4807 stack.add(condition); |
| 4801 } else { | 4808 } else { |
| 4802 // TODO(karlkose): support type arguments here. | 4809 // TODO(karlkose): support type arguments here. |
| 4803 HInstruction condition = new HIs(type, | 4810 HInstruction condition = new HIs(type, |
| 4804 <HInstruction>[unwrappedException], | 4811 <HInstruction>[unwrappedException], |
| 4805 HIs.RAW_CHECK); | 4812 HIs.RAW_CHECK); |
| 4806 push(condition); | 4813 push(condition); |
| 4807 } | 4814 } |
| 4808 } else { | 4815 } else { |
| 4809 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 4816 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 4810 HInstruction condition = null; | 4817 HInstruction condition = null; |
| 4811 if (declaration.type == null) { | 4818 if (declaration.type == null) { |
| 4812 condition = graph.addConstantBool(true, constantSystem); | 4819 condition = graph.addConstantBool(true, compiler); |
| 4813 stack.add(condition); | 4820 stack.add(condition); |
| 4814 } else { | 4821 } else { |
| 4815 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 4822 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 4816 // "if" condition above and this "else" branch should be deleted as | 4823 // "if" condition above and this "else" branch should be deleted as |
| 4817 // type of declared variable won't matter for the catch | 4824 // type of declared variable won't matter for the catch |
| 4818 // condition. | 4825 // condition. |
| 4819 DartType type = elements.getType(declaration.type); | 4826 DartType type = elements.getType(declaration.type); |
| 4820 if (type == null) { | 4827 if (type == null) { |
| 4821 compiler.cancel('Catch with unresolved type', node: catchBlock); | 4828 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 4822 } | 4829 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4996 | 5003 |
| 4997 visitNode(Node node) { | 5004 visitNode(Node node) { |
| 4998 builder.compiler.internalError('unexpected node', node: node); | 5005 builder.compiler.internalError('unexpected node', node: node); |
| 4999 } | 5006 } |
| 5000 | 5007 |
| 5001 void visitExpression(Node node) { | 5008 void visitExpression(Node node) { |
| 5002 node.accept(builder); | 5009 node.accept(builder); |
| 5003 HInstruction expression = builder.pop(); | 5010 HInstruction expression = builder.pop(); |
| 5004 if (!expression.isConstantString()) { | 5011 if (!expression.isConstantString()) { |
| 5005 expression = new HStringify(expression, node); | 5012 expression = new HStringify(expression, node); |
| 5013 expression.instructionType = builder.backend.stringType; |
| 5006 builder.add(expression); | 5014 builder.add(expression); |
| 5007 } | 5015 } |
| 5008 result = (result == null) ? expression : concat(result, expression); | 5016 result = (result == null) ? expression : concat(result, expression); |
| 5009 } | 5017 } |
| 5010 | 5018 |
| 5011 void visitStringInterpolation(StringInterpolation node) { | 5019 void visitStringInterpolation(StringInterpolation node) { |
| 5012 node.visitChildren(this); | 5020 node.visitChildren(this); |
| 5013 } | 5021 } |
| 5014 | 5022 |
| 5015 void visitStringInterpolationPart(StringInterpolationPart node) { | 5023 void visitStringInterpolationPart(StringInterpolationPart node) { |
| 5016 visit(node.expression); | 5024 visit(node.expression); |
| 5017 visit(node.string); | 5025 visit(node.string); |
| 5018 } | 5026 } |
| 5019 | 5027 |
| 5020 void visitStringJuxtaposition(StringJuxtaposition node) { | 5028 void visitStringJuxtaposition(StringJuxtaposition node) { |
| 5021 node.visitChildren(this); | 5029 node.visitChildren(this); |
| 5022 } | 5030 } |
| 5023 | 5031 |
| 5024 void visitNodeList(NodeList node) { | 5032 void visitNodeList(NodeList node) { |
| 5025 node.visitChildren(this); | 5033 node.visitChildren(this); |
| 5026 } | 5034 } |
| 5027 | 5035 |
| 5028 HInstruction concat(HInstruction left, HInstruction right) { | 5036 HInstruction concat(HInstruction left, HInstruction right) { |
| 5029 HInstruction instruction = new HStringConcat(left, right, diagnosticNode); | 5037 HInstruction instruction = new HStringConcat(left, right, diagnosticNode); |
| 5038 instruction.instructionType = builder.backend.stringType; |
| 5030 builder.add(instruction); | 5039 builder.add(instruction); |
| 5031 return instruction; | 5040 return instruction; |
| 5032 } | 5041 } |
| 5033 } | 5042 } |
| 5034 | 5043 |
| 5035 /** | 5044 /** |
| 5036 * This class visits the method that is a candidate for inlining and | 5045 * This class visits the method that is a candidate for inlining and |
| 5037 * finds whether it is too difficult to inline. | 5046 * finds whether it is too difficult to inline. |
| 5038 */ | 5047 */ |
| 5039 class InlineWeeder extends Visitor { | 5048 class InlineWeeder extends Visitor { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5293 } | 5302 } |
| 5294 } | 5303 } |
| 5295 | 5304 |
| 5296 void visitThen() { | 5305 void visitThen() { |
| 5297 right(); | 5306 right(); |
| 5298 boolifiedRight = builder.popBoolified(); | 5307 boolifiedRight = builder.popBoolified(); |
| 5299 } | 5308 } |
| 5300 | 5309 |
| 5301 handleIf(visitCondition, visitThen, null); | 5310 handleIf(visitCondition, visitThen, null); |
| 5302 HConstant notIsAnd = | 5311 HConstant notIsAnd = |
| 5303 builder.graph.addConstantBool(!isAnd, builder.constantSystem); | 5312 builder.graph.addConstantBool(!isAnd, builder.compiler); |
| 5304 HPhi result = new HPhi.manyInputs(null, | 5313 HPhi result = new HPhi.manyInputs(null, |
| 5305 <HInstruction>[boolifiedRight, notIsAnd]); | 5314 <HInstruction>[boolifiedRight, notIsAnd]); |
| 5306 builder.current.addPhi(result); | 5315 builder.current.addPhi(result); |
| 5307 builder.stack.add(result); | 5316 builder.stack.add(result); |
| 5308 } | 5317 } |
| 5309 | 5318 |
| 5310 void handleLogicalAndOrWithLeftNode(Node left, | 5319 void handleLogicalAndOrWithLeftNode(Node left, |
| 5311 void visitRight(), | 5320 void visitRight(), |
| 5312 {bool isAnd}) { | 5321 {bool isAnd}) { |
| 5313 // This method is similar to [handleLogicalAndOr] but optimizes the case | 5322 // This method is similar to [handleLogicalAndOr] but optimizes the case |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5383 new HSubGraphBlockInformation(elseBranch.graph)); | 5392 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5384 | 5393 |
| 5385 HBasicBlock conditionStartBlock = conditionBranch.block; | 5394 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5386 conditionStartBlock.setBlockFlow(info, joinBlock); | 5395 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5387 SubGraph conditionGraph = conditionBranch.graph; | 5396 SubGraph conditionGraph = conditionBranch.graph; |
| 5388 HIf branch = conditionGraph.end.last; | 5397 HIf branch = conditionGraph.end.last; |
| 5389 assert(branch is HIf); | 5398 assert(branch is HIf); |
| 5390 branch.blockInformation = conditionStartBlock.blockFlow; | 5399 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5391 } | 5400 } |
| 5392 } | 5401 } |
| OLD | NEW |