| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 newLocalsHandler.updateLocal(typeVariable.element, argument); | 1177 newLocalsHandler.updateLocal(typeVariable.element, argument); |
| 1177 }); | 1178 }); |
| 1178 } | 1179 } |
| 1179 assert(argumentIndex == compiledArguments.length); | 1180 assert(argumentIndex == compiledArguments.length); |
| 1180 | 1181 |
| 1181 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 1182 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
| 1182 returnElement = new ElementX(const SourceString("result"), | 1183 returnElement = new ElementX(const SourceString("result"), |
| 1183 ElementKind.VARIABLE, | 1184 ElementKind.VARIABLE, |
| 1184 function); | 1185 function); |
| 1185 newLocalsHandler.updateLocal(returnElement, | 1186 newLocalsHandler.updateLocal(returnElement, |
| 1186 graph.addConstantNull(constantSystem)); | 1187 graph.addConstantNull(compiler)); |
| 1187 elements = compiler.enqueuer.resolution.getCachedElements(function); | 1188 elements = compiler.enqueuer.resolution.getCachedElements(function); |
| 1188 assert(elements != null); | 1189 assert(elements != null); |
| 1189 returnType = signature.returnType; | 1190 returnType = signature.returnType; |
| 1190 stack = <HInstruction>[]; | 1191 stack = <HInstruction>[]; |
| 1191 inliningStack.add(state); | 1192 inliningStack.add(state); |
| 1192 localsHandler = newLocalsHandler; | 1193 localsHandler = newLocalsHandler; |
| 1193 return state; | 1194 return state; |
| 1194 } | 1195 } |
| 1195 | 1196 |
| 1196 void leaveInlinedMethod(InliningState state) { | 1197 void leaveInlinedMethod(InliningState state) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 localsHandler.updateLocal(typeVariables.head.element, | 1337 localsHandler.updateLocal(typeVariables.head.element, |
| 1337 analyzeTypeArgument(argument, callNode)); | 1338 analyzeTypeArgument(argument, callNode)); |
| 1338 typeVariables = typeVariables.tail; | 1339 typeVariables = typeVariables.tail; |
| 1339 }); | 1340 }); |
| 1340 // If the supertype is a raw type, we need to set to null the | 1341 // If the supertype is a raw type, we need to set to null the |
| 1341 // type variables. | 1342 // type variables. |
| 1342 assert(typeVariables.isEmpty | 1343 assert(typeVariables.isEmpty |
| 1343 || superclass.typeVariables == typeVariables); | 1344 || superclass.typeVariables == typeVariables); |
| 1344 while (!typeVariables.isEmpty) { | 1345 while (!typeVariables.isEmpty) { |
| 1345 localsHandler.updateLocal(typeVariables.head.element, | 1346 localsHandler.updateLocal(typeVariables.head.element, |
| 1346 graph.addConstantNull(constantSystem)); | 1347 graph.addConstantNull(compiler)); |
| 1347 typeVariables = typeVariables.tail; | 1348 typeVariables = typeVariables.tail; |
| 1348 } | 1349 } |
| 1349 } | 1350 } |
| 1350 | 1351 |
| 1351 inlinedFrom(constructor, () { | 1352 inlinedFrom(constructor, () { |
| 1352 buildFieldInitializers(constructor.enclosingElement.implementation, | 1353 buildFieldInitializers(constructor.enclosingElement.implementation, |
| 1353 fieldValues); | 1354 fieldValues); |
| 1354 }); | 1355 }); |
| 1355 | 1356 |
| 1356 int index = 0; | 1357 int index = 0; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1483 Map<Element, HInstruction> fieldValues) { | 1484 Map<Element, HInstruction> fieldValues) { |
| 1484 assert(invariant(classElement, classElement.isImplementation)); | 1485 assert(invariant(classElement, classElement.isImplementation)); |
| 1485 classElement.forEachInstanceField( | 1486 classElement.forEachInstanceField( |
| 1486 (ClassElement enclosingClass, Element member) { | 1487 (ClassElement enclosingClass, Element member) { |
| 1487 compiler.withCurrentElement(member, () { | 1488 compiler.withCurrentElement(member, () { |
| 1488 TreeElements definitions = compiler.analyzeElement(member); | 1489 TreeElements definitions = compiler.analyzeElement(member); |
| 1489 Node node = member.parseNode(compiler); | 1490 Node node = member.parseNode(compiler); |
| 1490 SendSet assignment = node.asSendSet(); | 1491 SendSet assignment = node.asSendSet(); |
| 1491 HInstruction value; | 1492 HInstruction value; |
| 1492 if (assignment == null) { | 1493 if (assignment == null) { |
| 1493 value = graph.addConstantNull(constantSystem); | 1494 value = graph.addConstantNull(compiler); |
| 1494 } else { | 1495 } else { |
| 1495 Node right = assignment.arguments.head; | 1496 Node right = assignment.arguments.head; |
| 1496 TreeElements savedElements = elements; | 1497 TreeElements savedElements = elements; |
| 1497 elements = definitions; | 1498 elements = definitions; |
| 1498 // In case the field initializer uses closures, run the | 1499 // In case the field initializer uses closures, run the |
| 1499 // closure to class mapper. | 1500 // closure to class mapper. |
| 1500 compiler.closureToClassMapper.computeClosureToClassMapping( | 1501 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1501 member, node, elements); | 1502 member, node, elements); |
| 1502 inlinedFrom(member, () => right.accept(this)); | 1503 inlinedFrom(member, () => right.accept(this)); |
| 1503 elements = savedElements; | 1504 elements = savedElements; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 // | 1671 // |
| 1671 // foo([a = 42]) { | 1672 // foo([a = 42]) { |
| 1672 // var t1 = identical(a, sentinel); | 1673 // var t1 = identical(a, sentinel); |
| 1673 // if (t1) a = 42; | 1674 // if (t1) a = 42; |
| 1674 // if (!t1) print('parameter passed ' + a); | 1675 // if (!t1) print('parameter passed ' + a); |
| 1675 // } | 1676 // } |
| 1676 | 1677 |
| 1677 // Fetch the original default value of [element]; | 1678 // Fetch the original default value of [element]; |
| 1678 Constant constant = compileVariable(element); | 1679 Constant constant = compileVariable(element); |
| 1679 HConstant defaultValue = constant == null | 1680 HConstant defaultValue = constant == null |
| 1680 ? graph.addConstantNull(constantSystem) | 1681 ? graph.addConstantNull(compiler) |
| 1681 : graph.addConstant(constant); | 1682 : graph.addConstant(constant, compiler); |
| 1682 | 1683 |
| 1683 // Emit the equality check with the sentinel. | 1684 // Emit the equality check with the sentinel. |
| 1684 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL); | 1685 HConstant sentinel = |
| 1686 graph.addConstant(SentinelConstant.SENTINEL, compiler); |
| 1685 HInstruction operand = parameters[element]; | 1687 HInstruction operand = parameters[element]; |
| 1686 check = new HIdentity(sentinel, operand); | 1688 check = new HIdentity(sentinel, operand); |
| 1687 add(check); | 1689 add(check); |
| 1688 | 1690 |
| 1689 // If the check succeeds, we must update the parameter with the | 1691 // If the check succeeds, we must update the parameter with the |
| 1690 // default value. | 1692 // default value. |
| 1691 handleIf(element.parseNode(compiler), | 1693 handleIf(element.parseNode(compiler), |
| 1692 () => stack.add(check), | 1694 () => stack.add(check), |
| 1693 () => localsHandler.updateLocal(element, defaultValue), | 1695 () => localsHandler.updateLocal(element, defaultValue), |
| 1694 null); | 1696 null); |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 Node initializer = node.initializer; | 2238 Node initializer = node.initializer; |
| 2237 if (initializer != null) { | 2239 if (initializer != null) { |
| 2238 visit(initializer); | 2240 visit(initializer); |
| 2239 if (initializer.asExpression() != null) { | 2241 if (initializer.asExpression() != null) { |
| 2240 pop(); | 2242 pop(); |
| 2241 } | 2243 } |
| 2242 } | 2244 } |
| 2243 } | 2245 } |
| 2244 HInstruction buildCondition() { | 2246 HInstruction buildCondition() { |
| 2245 if (node.condition == null) { | 2247 if (node.condition == null) { |
| 2246 return graph.addConstantBool(true, constantSystem); | 2248 return graph.addConstantBool(true, compiler); |
| 2247 } | 2249 } |
| 2248 visit(node.condition); | 2250 visit(node.condition); |
| 2249 return popBoolified(); | 2251 return popBoolified(); |
| 2250 } | 2252 } |
| 2251 void buildUpdate() { | 2253 void buildUpdate() { |
| 2252 for (Expression expression in node.update) { | 2254 for (Expression expression in node.update) { |
| 2253 visit(expression); | 2255 visit(expression); |
| 2254 assert(!isAborted()); | 2256 assert(!isAborted()); |
| 2255 // The result of the update instruction isn't used, and can just | 2257 // The result of the update instruction isn't used, and can just |
| 2256 // be dropped. | 2258 // be dropped. |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2497 visit(node.receiver); | 2499 visit(node.receiver); |
| 2498 assert(!identical(op.token.kind, PLUS_TOKEN)); | 2500 assert(!identical(op.token.kind, PLUS_TOKEN)); |
| 2499 HInstruction operand = pop(); | 2501 HInstruction operand = pop(); |
| 2500 | 2502 |
| 2501 // See if we can constant-fold right away. This avoids rewrites later on. | 2503 // See if we can constant-fold right away. This avoids rewrites later on. |
| 2502 if (operand is HConstant) { | 2504 if (operand is HConstant) { |
| 2503 UnaryOperation operation = constantSystem.lookupUnary(op.source); | 2505 UnaryOperation operation = constantSystem.lookupUnary(op.source); |
| 2504 HConstant constant = operand; | 2506 HConstant constant = operand; |
| 2505 Constant folded = operation.fold(constant.constant); | 2507 Constant folded = operation.fold(constant.constant); |
| 2506 if (folded != null) { | 2508 if (folded != null) { |
| 2507 stack.add(graph.addConstant(folded)); | 2509 stack.add(graph.addConstant(folded, compiler)); |
| 2508 return; | 2510 return; |
| 2509 } | 2511 } |
| 2510 } | 2512 } |
| 2511 | 2513 |
| 2512 pushInvokeDynamic(node, elements.getSelector(node), [operand]); | 2514 pushInvokeDynamic(node, elements.getSelector(node), [operand]); |
| 2513 } | 2515 } |
| 2514 | 2516 |
| 2515 void visitBinary(HInstruction left, | 2517 void visitBinary(HInstruction left, |
| 2516 Operator op, | 2518 Operator op, |
| 2517 HInstruction right, | 2519 HInstruction right, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2565 | 2567 |
| 2566 void generateGetter(Send send, Element element) { | 2568 void generateGetter(Send send, Element element) { |
| 2567 if (Elements.isStaticOrTopLevelField(element)) { | 2569 if (Elements.isStaticOrTopLevelField(element)) { |
| 2568 Constant value; | 2570 Constant value; |
| 2569 if (element.isField() && !element.isAssignable()) { | 2571 if (element.isField() && !element.isAssignable()) { |
| 2570 // A static final or const. Get its constant value and inline it if | 2572 // A static final or const. Get its constant value and inline it if |
| 2571 // the value can be compiled eagerly. | 2573 // the value can be compiled eagerly. |
| 2572 value = compileVariable(element); | 2574 value = compileVariable(element); |
| 2573 } | 2575 } |
| 2574 if (value != null) { | 2576 if (value != null) { |
| 2575 stack.add(graph.addConstant(value)); | 2577 stack.add(graph.addConstant(value, compiler)); |
| 2576 } else if (element.isField() && isLazilyInitialized(element)) { | 2578 } else if (element.isField() && isLazilyInitialized(element)) { |
| 2577 HInstruction instruction = new HLazyStatic(element); | 2579 HInstruction instruction = new HLazyStatic(element); |
| 2578 instruction.instructionType = | 2580 instruction.instructionType = |
| 2579 new HType.inferredTypeForElement(element, compiler); | 2581 new HType.inferredTypeForElement(element, compiler); |
| 2580 push(instruction); | 2582 push(instruction); |
| 2581 } else { | 2583 } else { |
| 2582 if (element.isGetter()) { | 2584 if (element.isGetter()) { |
| 2583 pushInvokeStatic(send, element, <HInstruction>[]); | 2585 pushInvokeStatic(send, element, <HInstruction>[]); |
| 2584 } else { | 2586 } else { |
| 2585 // TODO(5346): Try to avoid the need for calling [declaration] before | 2587 // TODO(5346): Try to avoid the need for calling [declaration] before |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2682 HType type, | 2684 HType type, |
| 2683 List<HInstruction> inputs) { | 2685 List<HInstruction> inputs) { |
| 2684 return new HForeign(js.js.parseForeignJS(code), type, inputs); | 2686 return new HForeign(js.js.parseForeignJS(code), type, inputs); |
| 2685 } | 2687 } |
| 2686 | 2688 |
| 2687 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2689 HInstruction getRuntimeTypeInfo(HInstruction target) { |
| 2688 pushInvokeStatic(null, backend.getGetRuntimeTypeInfo(), [target]); | 2690 pushInvokeStatic(null, backend.getGetRuntimeTypeInfo(), [target]); |
| 2689 return pop(); | 2691 return pop(); |
| 2690 } | 2692 } |
| 2691 | 2693 |
| 2694 HLiteralList buildLiteralList(List<HInstruction> inputs) { |
| 2695 return new HLiteralList(inputs, backend.extendableArrayType); |
| 2696 } |
| 2697 |
| 2692 // TODO(karlklose): change construction of the representations to be GVN'able | 2698 // TODO(karlklose): change construction of the representations to be GVN'able |
| 2693 // (dartbug.com/7182). | 2699 // (dartbug.com/7182). |
| 2694 HInstruction buildTypeArgumentRepresentations(DartType type) { | 2700 HInstruction buildTypeArgumentRepresentations(DartType type) { |
| 2695 // Compute the representation of the type arguments, including access | 2701 // Compute the representation of the type arguments, including access |
| 2696 // to the runtime type information for type variables as instructions. | 2702 // to the runtime type information for type variables as instructions. |
| 2697 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2703 if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 2698 return new HLiteralList(<HInstruction>[addTypeVariableReference(type)]); | 2704 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); |
| 2699 } else { | 2705 } else { |
| 2700 assert(type.element.isClass()); | 2706 assert(type.element.isClass()); |
| 2701 InterfaceType interface = type; | 2707 InterfaceType interface = type; |
| 2702 List<HInstruction> inputs = <HInstruction>[]; | 2708 List<HInstruction> inputs = <HInstruction>[]; |
| 2703 bool first = true; | 2709 bool first = true; |
| 2704 List<String> templates = <String>[]; | 2710 List<String> templates = <String>[]; |
| 2705 for (DartType argument in interface.typeArguments) { | 2711 for (DartType argument in interface.typeArguments) { |
| 2706 templates.add(rti.getTypeRepresentation(argument, (variable) { | 2712 templates.add(rti.getTypeRepresentation(argument, (variable) { |
| 2707 HInstruction runtimeType = addTypeVariableReference(variable); | 2713 HInstruction runtimeType = addTypeVariableReference(variable); |
| 2708 inputs.add(runtimeType); | 2714 inputs.add(runtimeType); |
| 2709 })); | 2715 })); |
| 2710 } | 2716 } |
| 2711 String template = '[${templates.join(', ')}]'; | 2717 String template = '[${templates.join(', ')}]'; |
| 2712 HInstruction representation = | 2718 HInstruction representation = |
| 2713 createForeign(template, HType.READABLE_ARRAY, inputs); | 2719 createForeign(template, backend.readableArrayType, inputs); |
| 2714 return representation; | 2720 return representation; |
| 2715 } | 2721 } |
| 2716 } | 2722 } |
| 2717 | 2723 |
| 2718 visitOperatorSend(node) { | 2724 visitOperatorSend(node) { |
| 2719 Operator op = node.selector; | 2725 Operator op = node.selector; |
| 2720 if (const SourceString("[]") == op.source) { | 2726 if (const SourceString("[]") == op.source) { |
| 2721 visitDynamicSend(node); | 2727 visitDynamicSend(node); |
| 2722 } else if (const SourceString("&&") == op.source || | 2728 } else if (const SourceString("&&") == op.source || |
| 2723 const SourceString("||") == op.source) { | 2729 const SourceString("||") == op.source) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2782 ClassElement element = type.element; | 2788 ClassElement element = type.element; |
| 2783 Element helper = backend.getCheckSubtype(); | 2789 Element helper = backend.getCheckSubtype(); |
| 2784 HInstruction representations = | 2790 HInstruction representations = |
| 2785 buildTypeArgumentRepresentations(type); | 2791 buildTypeArgumentRepresentations(type); |
| 2786 add(representations); | 2792 add(representations); |
| 2787 String operator = | 2793 String operator = |
| 2788 backend.namer.operatorIs(backend.getImplementationClass(element)); | 2794 backend.namer.operatorIs(backend.getImplementationClass(element)); |
| 2789 HInstruction isFieldName = addConstantString(node, operator); | 2795 HInstruction isFieldName = addConstantString(node, operator); |
| 2790 HInstruction asFieldName = compiler.world.hasAnySubtype(element) | 2796 HInstruction asFieldName = compiler.world.hasAnySubtype(element) |
| 2791 ? addConstantString(node, backend.namer.substitutionName(element)) | 2797 ? addConstantString(node, backend.namer.substitutionName(element)) |
| 2792 : graph.addConstantNull(constantSystem); | 2798 : graph.addConstantNull(compiler); |
| 2793 List<HInstruction> inputs = <HInstruction>[expression, | 2799 List<HInstruction> inputs = <HInstruction>[expression, |
| 2794 isFieldName, | 2800 isFieldName, |
| 2795 representations, | 2801 representations, |
| 2796 asFieldName]; | 2802 asFieldName]; |
| 2797 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); | 2803 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); |
| 2798 HInstruction call = pop(); | 2804 HInstruction call = pop(); |
| 2799 return | 2805 return |
| 2800 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK); | 2806 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK); |
| 2801 } else { | 2807 } else { |
| 2802 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); | 2808 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2841 HInstruction handleConstantForOptionalParameter(Element parameter) { | 2847 HInstruction handleConstantForOptionalParameter(Element parameter) { |
| 2842 Constant constant; | 2848 Constant constant; |
| 2843 Element element = parameter.enclosingElement; | 2849 Element element = parameter.enclosingElement; |
| 2844 TreeElements calleeElements = | 2850 TreeElements calleeElements = |
| 2845 compiler.enqueuer.resolution.getCachedElements(element); | 2851 compiler.enqueuer.resolution.getCachedElements(element); |
| 2846 if (calleeElements.isParameterChecked(parameter)) { | 2852 if (calleeElements.isParameterChecked(parameter)) { |
| 2847 constant = SentinelConstant.SENTINEL; | 2853 constant = SentinelConstant.SENTINEL; |
| 2848 } else { | 2854 } else { |
| 2849 constant = compileConstant(parameter); | 2855 constant = compileConstant(parameter); |
| 2850 } | 2856 } |
| 2851 return graph.addConstant(constant); | 2857 return graph.addConstant(constant, compiler); |
| 2852 } | 2858 } |
| 2853 | 2859 |
| 2854 /** | 2860 /** |
| 2855 * Returns true if the arguments were compatible with the function signature. | 2861 * Returns true if the arguments were compatible with the function signature. |
| 2856 * | 2862 * |
| 2857 * Invariant: [element] must be an implementation element. | 2863 * Invariant: [element] must be an implementation element. |
| 2858 */ | 2864 */ |
| 2859 bool addStaticSendArgumentsToList(Selector selector, | 2865 bool addStaticSendArgumentsToList(Selector selector, |
| 2860 Link<Node> arguments, | 2866 Link<Node> arguments, |
| 2861 FunctionElement element, | 2867 FunctionElement element, |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3124 compiler.enqueuer.codegen.registerSelectorUse(selector); | 3130 compiler.enqueuer.codegen.registerSelectorUse(selector); |
| 3125 } | 3131 } |
| 3126 Constant nameConstant = constantSystem.createString( | 3132 Constant nameConstant = constantSystem.createString( |
| 3127 new DartString.literal(name.slowToString()), node); | 3133 new DartString.literal(name.slowToString()), node); |
| 3128 | 3134 |
| 3129 String internalName = backend.namer.invocationName(selector); | 3135 String internalName = backend.namer.invocationName(selector); |
| 3130 Constant internalNameConstant = | 3136 Constant internalNameConstant = |
| 3131 constantSystem.createString(new DartString.literal(internalName), node); | 3137 constantSystem.createString(new DartString.literal(internalName), node); |
| 3132 | 3138 |
| 3133 Element createInvocationMirror = backend.getCreateInvocationMirror(); | 3139 Element createInvocationMirror = backend.getCreateInvocationMirror(); |
| 3134 var argumentsInstruction = new HLiteralList(arguments); | 3140 var argumentsInstruction = buildLiteralList(arguments); |
| 3135 add(argumentsInstruction); | 3141 add(argumentsInstruction); |
| 3136 | 3142 |
| 3137 var argumentNames = new List<HInstruction>(); | 3143 var argumentNames = new List<HInstruction>(); |
| 3138 for (SourceString argumentName in selector.namedArguments) { | 3144 for (SourceString argumentName in selector.namedArguments) { |
| 3139 Constant argumentNameConstant = | 3145 Constant argumentNameConstant = |
| 3140 constantSystem.createString(new DartString.literal( | 3146 constantSystem.createString(new DartString.literal( |
| 3141 argumentName.slowToString()), node); | 3147 argumentName.slowToString()), node); |
| 3142 argumentNames.add(graph.addConstant(argumentNameConstant)); | 3148 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); |
| 3143 } | 3149 } |
| 3144 var argumentNamesInstruction = new HLiteralList(argumentNames); | 3150 var argumentNamesInstruction = buildLiteralList(argumentNames); |
| 3145 add(argumentNamesInstruction); | 3151 add(argumentNamesInstruction); |
| 3146 | 3152 |
| 3147 Constant kindConstant = | 3153 Constant kindConstant = |
| 3148 constantSystem.createInt(selector.invocationMirrorKind); | 3154 constantSystem.createInt(selector.invocationMirrorKind); |
| 3149 | 3155 |
| 3150 pushInvokeStatic(null, | 3156 pushInvokeStatic(null, |
| 3151 createInvocationMirror, | 3157 createInvocationMirror, |
| 3152 [graph.addConstant(nameConstant), | 3158 [graph.addConstant(nameConstant, compiler), |
| 3153 graph.addConstant(internalNameConstant), | 3159 graph.addConstant(internalNameConstant, compiler), |
| 3154 graph.addConstant(kindConstant), | 3160 graph.addConstant(kindConstant, compiler), |
| 3155 argumentsInstruction, | 3161 argumentsInstruction, |
| 3156 argumentNamesInstruction], | 3162 argumentNamesInstruction], |
| 3157 HType.UNKNOWN); | 3163 HType.UNKNOWN); |
| 3158 | 3164 |
| 3159 var inputs = <HInstruction>[pop()]; | 3165 var inputs = <HInstruction>[pop()]; |
| 3160 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); | 3166 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); |
| 3161 } | 3167 } |
| 3162 | 3168 |
| 3163 visitSend(Send node) { | 3169 visitSend(Send node) { |
| 3164 Element element = elements[node]; | 3170 Element element = elements[node]; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3207 * them as an instance of the type we are testing against (if necessary), and | 3213 * them as an instance of the type we are testing against (if necessary), and |
| 3208 * extract the type argument by the index of the variable in the list of type | 3214 * extract the type argument by the index of the variable in the list of type |
| 3209 * variables for that class. | 3215 * variables for that class. |
| 3210 */ | 3216 */ |
| 3211 HInstruction readTypeVariable(ClassElement cls, | 3217 HInstruction readTypeVariable(ClassElement cls, |
| 3212 TypeVariableElement variable) { | 3218 TypeVariableElement variable) { |
| 3213 assert(currentElement.isInstanceMember()); | 3219 assert(currentElement.isInstanceMember()); |
| 3214 int index = RuntimeTypes.getTypeVariableIndex(variable); | 3220 int index = RuntimeTypes.getTypeVariableIndex(variable); |
| 3215 String substitutionNameString = backend.namer.substitutionName(cls); | 3221 String substitutionNameString = backend.namer.substitutionName(cls); |
| 3216 HInstruction substitutionName = graph.addConstantString( | 3222 HInstruction substitutionName = graph.addConstantString( |
| 3217 new LiteralDartString(substitutionNameString), null, constantSystem); | 3223 new LiteralDartString(substitutionNameString), null, compiler); |
| 3218 HInstruction target = localsHandler.readThis(); | 3224 HInstruction target = localsHandler.readThis(); |
| 3219 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN, | 3225 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN, |
| 3220 <HInstruction>[target, substitutionName]); | 3226 <HInstruction>[target, substitutionName]); |
| 3221 add(substitution); | 3227 add(substitution); |
| 3222 pushInvokeStatic(null, | 3228 pushInvokeStatic(null, |
| 3223 backend.getGetRuntimeTypeArgument(), | 3229 backend.getGetRuntimeTypeArgument(), |
| 3224 [target, | 3230 [target, |
| 3225 substitution, | 3231 substitution, |
| 3226 graph.addConstantInt(index, constantSystem)], | 3232 graph.addConstantInt(index, compiler)], |
| 3227 HType.UNKNOWN); | 3233 HType.UNKNOWN); |
| 3228 return pop(); | 3234 return pop(); |
| 3229 } | 3235 } |
| 3230 | 3236 |
| 3231 /** | 3237 /** |
| 3232 * Helper to create an instruction that gets the value of a type variable. | 3238 * Helper to create an instruction that gets the value of a type variable. |
| 3233 */ | 3239 */ |
| 3234 HInstruction addTypeVariableReference(TypeVariableType type) { | 3240 HInstruction addTypeVariableReference(TypeVariableType type) { |
| 3235 Element member = currentElement; | 3241 Element member = currentElement; |
| 3236 bool isClosure = member.enclosingElement.isClosure(); | 3242 bool isClosure = member.enclosingElement.isClosure(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3264 * Documentation wanted -- johnniwinther | 3270 * Documentation wanted -- johnniwinther |
| 3265 * | 3271 * |
| 3266 * Invariant: [argument] must not be malformed in checked mode. | 3272 * Invariant: [argument] must not be malformed in checked mode. |
| 3267 */ | 3273 */ |
| 3268 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { | 3274 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| 3269 assert(invariant(currentNode, | 3275 assert(invariant(currentNode, |
| 3270 !compiler.enableTypeAssertions || !argument.isMalformed, | 3276 !compiler.enableTypeAssertions || !argument.isMalformed, |
| 3271 message: '$argument is malformed in checked mode')); | 3277 message: '$argument is malformed in checked mode')); |
| 3272 if (argument == compiler.types.dynamicType || argument.isMalformed) { | 3278 if (argument == compiler.types.dynamicType || argument.isMalformed) { |
| 3273 // Represent [dynamic] as [null]. | 3279 // Represent [dynamic] as [null]. |
| 3274 return graph.addConstantNull(constantSystem); | 3280 return graph.addConstantNull(compiler); |
| 3275 } | 3281 } |
| 3276 | 3282 |
| 3277 List<HInstruction> inputs = <HInstruction>[]; | 3283 List<HInstruction> inputs = <HInstruction>[]; |
| 3278 | 3284 |
| 3279 String template = rti.getTypeRepresentation(argument, (variable) { | 3285 String template = rti.getTypeRepresentation(argument, (variable) { |
| 3280 inputs.add(addTypeVariableReference(variable)); | 3286 inputs.add(addTypeVariableReference(variable)); |
| 3281 }); | 3287 }); |
| 3282 | 3288 |
| 3283 HInstruction result = createForeign(template, HType.STRING, inputs); | 3289 HInstruction result = createForeign(template, backend.stringType, inputs); |
| 3284 add(result); | 3290 add(result); |
| 3285 return result; | 3291 return result; |
| 3286 } | 3292 } |
| 3287 | 3293 |
| 3288 void handleListConstructor(InterfaceType type, | 3294 void handleListConstructor(InterfaceType type, |
| 3289 Node currentNode, | 3295 Node currentNode, |
| 3290 HInstruction newObject) { | 3296 HInstruction newObject) { |
| 3291 if (!backend.needsRti(type.element)) return; | 3297 if (!backend.needsRti(type.element)) return; |
| 3292 if (!type.isRaw) { | 3298 if (!type.isRaw) { |
| 3293 List<HInstruction> inputs = <HInstruction>[]; | 3299 List<HInstruction> inputs = <HInstruction>[]; |
| 3294 type.typeArguments.forEach((DartType argument) { | 3300 type.typeArguments.forEach((DartType argument) { |
| 3295 inputs.add(analyzeTypeArgument(argument, currentNode)); | 3301 inputs.add(analyzeTypeArgument(argument, currentNode)); |
| 3296 }); | 3302 }); |
| 3297 callSetRuntimeTypeInfo(type.element, inputs, newObject); | 3303 callSetRuntimeTypeInfo(type.element, inputs, newObject); |
| 3298 } | 3304 } |
| 3299 } | 3305 } |
| 3300 | 3306 |
| 3301 void callSetRuntimeTypeInfo(ClassElement element, | 3307 void callSetRuntimeTypeInfo(ClassElement element, |
| 3302 List<HInstruction> rtiInputs, | 3308 List<HInstruction> rtiInputs, |
| 3303 HInstruction newObject) { | 3309 HInstruction newObject) { |
| 3304 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { | 3310 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { |
| 3305 return; | 3311 return; |
| 3306 } | 3312 } |
| 3307 | 3313 |
| 3308 HInstruction typeInfo = new HLiteralList(rtiInputs); | 3314 HInstruction typeInfo = buildLiteralList(rtiInputs); |
| 3309 add(typeInfo); | 3315 add(typeInfo); |
| 3310 | 3316 |
| 3311 // Set the runtime type information on the object. | 3317 // Set the runtime type information on the object. |
| 3312 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); | 3318 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); |
| 3313 pushInvokeStatic( | 3319 pushInvokeStatic( |
| 3314 null, | 3320 null, |
| 3315 typeInfoSetterElement, | 3321 typeInfoSetterElement, |
| 3316 <HInstruction>[newObject, typeInfo], | 3322 <HInstruction>[newObject, typeInfo], |
| 3317 HType.UNKNOWN); | 3323 HType.UNKNOWN); |
| 3318 pop(); | 3324 pop(); |
| 3319 } | 3325 } |
| 3320 | 3326 |
| 3321 /** | 3327 /** |
| 3322 * Documentation wanted -- johnniwinther | 3328 * Documentation wanted -- johnniwinther |
| 3323 * | 3329 * |
| 3324 * Invariant: [type] must not be malformed in checked mode. | 3330 * Invariant: [type] must not be malformed in checked mode. |
| 3325 */ | 3331 */ |
| 3326 handleNewSend(NewExpression node, InterfaceType type) { | 3332 handleNewSend(NewExpression node, InterfaceType type) { |
| 3327 Send send = node.send; | 3333 Send send = node.send; |
| 3328 assert(invariant(send, | 3334 assert(invariant(send, |
| 3329 !compiler.enableTypeAssertions || !type.isMalformed, | 3335 !compiler.enableTypeAssertions || !type.isMalformed, |
| 3330 message: '$type is malformed in checked mode')); | 3336 message: '$type is malformed in checked mode')); |
| 3331 bool isListConstructor = false; | 3337 bool isListConstructor = false; |
| 3332 computeType(element) { | 3338 computeType(element) { |
| 3333 Element originalElement = elements[send]; | 3339 Element originalElement = elements[send]; |
| 3334 if (Elements.isFixedListConstructorCall( | 3340 if (Elements.isFixedListConstructorCall( |
| 3335 originalElement, send, compiler)) { | 3341 originalElement, send, compiler)) { |
| 3336 isListConstructor = true; | 3342 isListConstructor = true; |
| 3337 return HType.FIXED_ARRAY; | 3343 return backend.fixedArrayType; |
| 3338 } else if (Elements.isGrowableListConstructorCall( | 3344 } else if (Elements.isGrowableListConstructorCall( |
| 3339 originalElement, send, compiler)) { | 3345 originalElement, send, compiler)) { |
| 3340 isListConstructor = true; | 3346 isListConstructor = true; |
| 3341 return HType.EXTENDABLE_ARRAY; | 3347 return backend.extendableArrayType; |
| 3342 } else if (element.isGenerativeConstructor()) { | 3348 } else if (element.isGenerativeConstructor()) { |
| 3343 ClassElement cls = element.getEnclosingClass(); | 3349 ClassElement cls = element.getEnclosingClass(); |
| 3344 return new HType.nonNullExact(cls.thisType, compiler); | 3350 return new HType.nonNullExact(cls.thisType, compiler); |
| 3345 } else { | 3351 } else { |
| 3346 return new HType.inferredTypeForElement(originalElement, compiler); | 3352 return new HType.inferredTypeForElement(originalElement, compiler); |
| 3347 } | 3353 } |
| 3348 } | 3354 } |
| 3349 | 3355 |
| 3350 Element constructor = elements[send]; | 3356 Element constructor = elements[send]; |
| 3351 Selector selector = elements.getSelector(send); | 3357 Selector selector = elements.getSelector(send); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3406 } | 3412 } |
| 3407 if (backend.needsRti(cls)) { | 3413 if (backend.needsRti(cls)) { |
| 3408 Link<DartType> typeVariable = cls.typeVariables; | 3414 Link<DartType> typeVariable = cls.typeVariables; |
| 3409 type.typeArguments.forEach((DartType argument) { | 3415 type.typeArguments.forEach((DartType argument) { |
| 3410 inputs.add(analyzeTypeArgument(argument, send)); | 3416 inputs.add(analyzeTypeArgument(argument, send)); |
| 3411 typeVariable = typeVariable.tail; | 3417 typeVariable = typeVariable.tail; |
| 3412 }); | 3418 }); |
| 3413 // Also add null to non-provided type variables to call the | 3419 // Also add null to non-provided type variables to call the |
| 3414 // constructor with the right number of arguments. | 3420 // constructor with the right number of arguments. |
| 3415 while (!typeVariable.isEmpty) { | 3421 while (!typeVariable.isEmpty) { |
| 3416 inputs.add(graph.addConstantNull(constantSystem)); | 3422 inputs.add(graph.addConstantNull(compiler)); |
| 3417 typeVariable = typeVariable.tail; | 3423 typeVariable = typeVariable.tail; |
| 3418 } | 3424 } |
| 3419 } | 3425 } |
| 3420 | 3426 |
| 3421 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { | 3427 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { |
| 3422 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); | 3428 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
| 3423 } | 3429 } |
| 3424 HType elementType = computeType(constructor); | 3430 HType elementType = computeType(constructor); |
| 3425 pushInvokeStatic(node, constructor, inputs, elementType); | 3431 pushInvokeStatic(node, constructor, inputs, elementType); |
| 3426 HInstruction newInstance = stack.last; | 3432 HInstruction newInstance = stack.last; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3451 return; | 3457 return; |
| 3452 } | 3458 } |
| 3453 if (element.isErroneous()) { | 3459 if (element.isErroneous()) { |
| 3454 generateThrowNoSuchMethod(node, | 3460 generateThrowNoSuchMethod(node, |
| 3455 getTargetName(element), | 3461 getTargetName(element), |
| 3456 argumentNodes: node.arguments); | 3462 argumentNodes: node.arguments); |
| 3457 return; | 3463 return; |
| 3458 } | 3464 } |
| 3459 if (identical(element, compiler.assertMethod) | 3465 if (identical(element, compiler.assertMethod) |
| 3460 && !compiler.enableUserAssertions) { | 3466 && !compiler.enableUserAssertions) { |
| 3461 stack.add(graph.addConstantNull(constantSystem)); | 3467 stack.add(graph.addConstantNull(compiler)); |
| 3462 return; | 3468 return; |
| 3463 } | 3469 } |
| 3464 compiler.ensure(!element.isGenerativeConstructor()); | 3470 compiler.ensure(!element.isGenerativeConstructor()); |
| 3465 if (element.isFunction()) { | 3471 if (element.isFunction()) { |
| 3466 var inputs = <HInstruction>[]; | 3472 var inputs = <HInstruction>[]; |
| 3467 // TODO(5347): Try to avoid the need for calling [implementation] before | 3473 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3468 // calling [addStaticSendArgumentsToList]. | 3474 // calling [addStaticSendArgumentsToList]. |
| 3469 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3475 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 3470 element.implementation, | 3476 element.implementation, |
| 3471 inputs); | 3477 inputs); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3485 List<HInstruction> inputs = <HInstruction>[pop()]; | 3491 List<HInstruction> inputs = <HInstruction>[pop()]; |
| 3486 addDynamicSendArgumentsToList(node, inputs); | 3492 addDynamicSendArgumentsToList(node, inputs); |
| 3487 Selector closureSelector = new Selector.callClosureFrom(selector); | 3493 Selector closureSelector = new Selector.callClosureFrom(selector); |
| 3488 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); | 3494 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); |
| 3489 } | 3495 } |
| 3490 } | 3496 } |
| 3491 | 3497 |
| 3492 HConstant addConstantString(Node node, String string) { | 3498 HConstant addConstantString(Node node, String string) { |
| 3493 DartString dartString = new DartString.literal(string); | 3499 DartString dartString = new DartString.literal(string); |
| 3494 Constant constant = constantSystem.createString(dartString, node); | 3500 Constant constant = constantSystem.createString(dartString, node); |
| 3495 return graph.addConstant(constant); | 3501 return graph.addConstant(constant, compiler); |
| 3496 } | 3502 } |
| 3497 | 3503 |
| 3498 visitTypeReferenceSend(Send node) { | 3504 visitTypeReferenceSend(Send node) { |
| 3499 Element element = elements[node]; | 3505 Element element = elements[node]; |
| 3500 if (element.isClass() || element.isTypedef()) { | 3506 if (element.isClass() || element.isTypedef()) { |
| 3501 // TODO(karlklose): add type representation | 3507 // TODO(karlklose): add type representation |
| 3502 ConstantHandler handler = compiler.constantHandler; | 3508 ConstantHandler handler = compiler.constantHandler; |
| 3503 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3509 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3504 stack.add(graph.addConstant(constant)); | 3510 stack.add(graph.addConstant(constant, compiler)); |
| 3505 } else if (element.isTypeVariable()) { | 3511 } else if (element.isTypeVariable()) { |
| 3506 HInstruction value = | 3512 HInstruction value = |
| 3507 addTypeVariableReference(element.computeType(compiler)); | 3513 addTypeVariableReference(element.computeType(compiler)); |
| 3508 pushInvokeStatic(node, | 3514 pushInvokeStatic(node, |
| 3509 backend.getRuntimeTypeToString(), | 3515 backend.getRuntimeTypeToString(), |
| 3510 [value], | 3516 [value], |
| 3511 HType.STRING); | 3517 backend.stringType); |
| 3512 pushInvokeStatic(node, | 3518 pushInvokeStatic(node, |
| 3513 backend.getCreateRuntimeType(), | 3519 backend.getCreateRuntimeType(), |
| 3514 [pop()]); | 3520 [pop()]); |
| 3515 } else { | 3521 } else { |
| 3516 internalError('unexpected element kind $element', node: node); | 3522 internalError('unexpected element kind $element', node: node); |
| 3517 } | 3523 } |
| 3518 if (node.isCall) { | 3524 if (node.isCall) { |
| 3519 // This send is of the form 'e(...)', where e is resolved to a type | 3525 // This send is of the form 'e(...)', where e is resolved to a type |
| 3520 // reference. We create a regular closure call on the result of the type | 3526 // reference. We create a regular closure call on the result of the type |
| 3521 // reference instead of creating a NoSuchMethodError to avoid pulling it | 3527 // reference instead of creating a NoSuchMethodError to avoid pulling it |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3554 } | 3560 } |
| 3555 | 3561 |
| 3556 void generateThrowNoSuchMethod(Node diagnosticNode, | 3562 void generateThrowNoSuchMethod(Node diagnosticNode, |
| 3557 String methodName, | 3563 String methodName, |
| 3558 {Link<Node> argumentNodes, | 3564 {Link<Node> argumentNodes, |
| 3559 List<HInstruction> argumentValues, | 3565 List<HInstruction> argumentValues, |
| 3560 List<String> existingArguments}) { | 3566 List<String> existingArguments}) { |
| 3561 Element helper = backend.getThrowNoSuchMethod(); | 3567 Element helper = backend.getThrowNoSuchMethod(); |
| 3562 Constant receiverConstant = | 3568 Constant receiverConstant = |
| 3563 constantSystem.createString(new DartString.empty(), diagnosticNode); | 3569 constantSystem.createString(new DartString.empty(), diagnosticNode); |
| 3564 HInstruction receiver = graph.addConstant(receiverConstant); | 3570 HInstruction receiver = graph.addConstant(receiverConstant, compiler); |
| 3565 DartString dartString = new DartString.literal(methodName); | 3571 DartString dartString = new DartString.literal(methodName); |
| 3566 Constant nameConstant = | 3572 Constant nameConstant = |
| 3567 constantSystem.createString(dartString, diagnosticNode); | 3573 constantSystem.createString(dartString, diagnosticNode); |
| 3568 HInstruction name = graph.addConstant(nameConstant); | 3574 HInstruction name = graph.addConstant(nameConstant, compiler); |
| 3569 if (argumentValues == null) { | 3575 if (argumentValues == null) { |
| 3570 argumentValues = <HInstruction>[]; | 3576 argumentValues = <HInstruction>[]; |
| 3571 argumentNodes.forEach((argumentNode) { | 3577 argumentNodes.forEach((argumentNode) { |
| 3572 visit(argumentNode); | 3578 visit(argumentNode); |
| 3573 HInstruction value = pop(); | 3579 HInstruction value = pop(); |
| 3574 argumentValues.add(value); | 3580 argumentValues.add(value); |
| 3575 }); | 3581 }); |
| 3576 } | 3582 } |
| 3577 HInstruction arguments = new HLiteralList(argumentValues); | 3583 HInstruction arguments = buildLiteralList(argumentValues); |
| 3578 add(arguments); | 3584 add(arguments); |
| 3579 HInstruction existingNamesList; | 3585 HInstruction existingNamesList; |
| 3580 if (existingArguments != null) { | 3586 if (existingArguments != null) { |
| 3581 List<HInstruction> existingNames = <HInstruction>[]; | 3587 List<HInstruction> existingNames = <HInstruction>[]; |
| 3582 for (String name in existingArguments) { | 3588 for (String name in existingArguments) { |
| 3583 HInstruction nameConstant = | 3589 HInstruction nameConstant = |
| 3584 graph.addConstantString(new DartString.literal(name), | 3590 graph.addConstantString(new DartString.literal(name), |
| 3585 diagnosticNode, constantSystem); | 3591 diagnosticNode, compiler); |
| 3586 existingNames.add(nameConstant); | 3592 existingNames.add(nameConstant); |
| 3587 } | 3593 } |
| 3588 existingNamesList = new HLiteralList(existingNames); | 3594 existingNamesList = buildLiteralList(existingNames); |
| 3589 add(existingNamesList); | 3595 add(existingNamesList); |
| 3590 } else { | 3596 } else { |
| 3591 existingNamesList = graph.addConstantNull(constantSystem); | 3597 existingNamesList = graph.addConstantNull(compiler); |
| 3592 } | 3598 } |
| 3593 pushInvokeStatic(diagnosticNode, | 3599 pushInvokeStatic(diagnosticNode, |
| 3594 helper, | 3600 helper, |
| 3595 [receiver, name, arguments, existingNamesList]); | 3601 [receiver, name, arguments, existingNamesList]); |
| 3596 } | 3602 } |
| 3597 | 3603 |
| 3598 /** | 3604 /** |
| 3599 * Generate code to throw a [NoSuchMethodError] exception for calling a | 3605 * Generate code to throw a [NoSuchMethodError] exception for calling a |
| 3600 * method with a wrong number of arguments or mismatching named optional | 3606 * method with a wrong number of arguments or mismatching named optional |
| 3601 * arguments. | 3607 * arguments. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3636 getTargetName(error, 'constructor'), | 3642 getTargetName(error, 'constructor'), |
| 3637 argumentNodes: node.send.arguments); | 3643 argumentNodes: node.send.arguments); |
| 3638 } else { | 3644 } else { |
| 3639 Message message = error.messageKind.message(error.messageArguments); | 3645 Message message = error.messageKind.message(error.messageArguments); |
| 3640 generateRuntimeError(node.send, message.toString()); | 3646 generateRuntimeError(node.send, message.toString()); |
| 3641 } | 3647 } |
| 3642 } else if (node.isConst()) { | 3648 } else if (node.isConst()) { |
| 3643 // TODO(karlklose): add type representation | 3649 // TODO(karlklose): add type representation |
| 3644 ConstantHandler handler = compiler.constantHandler; | 3650 ConstantHandler handler = compiler.constantHandler; |
| 3645 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3651 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3646 stack.add(graph.addConstant(constant)); | 3652 stack.add(graph.addConstant(constant, compiler)); |
| 3647 if (isSymbolConstructor) { | 3653 if (isSymbolConstructor) { |
| 3648 ConstructedConstant symbol = constant; | 3654 ConstructedConstant symbol = constant; |
| 3649 StringConstant stringConstant = symbol.fields.single; | 3655 StringConstant stringConstant = symbol.fields.single; |
| 3650 String nameString = stringConstant.toDartString().slowToString(); | 3656 String nameString = stringConstant.toDartString().slowToString(); |
| 3651 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); | 3657 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); |
| 3652 } | 3658 } |
| 3653 } else { | 3659 } else { |
| 3654 DartType type = elements.getType(node); | 3660 DartType type = elements.getType(node); |
| 3655 if (compiler.enableTypeAssertions && type.isMalformed) { | 3661 if (compiler.enableTypeAssertions && type.isMalformed) { |
| 3656 String reasons = Types.fetchReasonsFromMalformedType(type); | 3662 String reasons = Types.fetchReasonsFromMalformedType(type); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3787 new HType.inferredReturnTypeForElement(element, compiler); | 3793 new HType.inferredReturnTypeForElement(element, compiler); |
| 3788 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 3794 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); |
| 3789 return instruction; | 3795 return instruction; |
| 3790 } | 3796 } |
| 3791 | 3797 |
| 3792 void handleComplexOperatorSend(SendSet node, | 3798 void handleComplexOperatorSend(SendSet node, |
| 3793 HInstruction receiver, | 3799 HInstruction receiver, |
| 3794 Link<Node> arguments) { | 3800 Link<Node> arguments) { |
| 3795 HInstruction rhs; | 3801 HInstruction rhs; |
| 3796 if (node.isPrefix || node.isPostfix) { | 3802 if (node.isPrefix || node.isPostfix) { |
| 3797 rhs = graph.addConstantInt(1, constantSystem); | 3803 rhs = graph.addConstantInt(1, compiler); |
| 3798 } else { | 3804 } else { |
| 3799 visit(arguments.head); | 3805 visit(arguments.head); |
| 3800 assert(arguments.tail.isEmpty); | 3806 assert(arguments.tail.isEmpty); |
| 3801 rhs = pop(); | 3807 rhs = pop(); |
| 3802 } | 3808 } |
| 3803 visitBinary(receiver, node.assignmentOperator, rhs, | 3809 visitBinary(receiver, node.assignmentOperator, rhs, |
| 3804 elements.getOperatorSelectorInComplexSendSet(node), node); | 3810 elements.getOperatorSelectorInComplexSendSet(node), node); |
| 3805 } | 3811 } |
| 3806 | 3812 |
| 3807 visitSendSet(SendSet node) { | 3813 visitSendSet(SendSet node) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3938 generateNonInstanceSetter(node, element, value); | 3944 generateNonInstanceSetter(node, element, value); |
| 3939 } | 3945 } |
| 3940 if (node.isPostfix) { | 3946 if (node.isPostfix) { |
| 3941 pop(); | 3947 pop(); |
| 3942 stack.add(getterInstruction); | 3948 stack.add(getterInstruction); |
| 3943 } | 3949 } |
| 3944 } | 3950 } |
| 3945 } | 3951 } |
| 3946 | 3952 |
| 3947 void visitLiteralInt(LiteralInt node) { | 3953 void visitLiteralInt(LiteralInt node) { |
| 3948 stack.add(graph.addConstantInt(node.value, constantSystem)); | 3954 stack.add(graph.addConstantInt(node.value, compiler)); |
| 3949 } | 3955 } |
| 3950 | 3956 |
| 3951 void visitLiteralDouble(LiteralDouble node) { | 3957 void visitLiteralDouble(LiteralDouble node) { |
| 3952 stack.add(graph.addConstantDouble(node.value, constantSystem)); | 3958 stack.add(graph.addConstantDouble(node.value, compiler)); |
| 3953 } | 3959 } |
| 3954 | 3960 |
| 3955 void visitLiteralBool(LiteralBool node) { | 3961 void visitLiteralBool(LiteralBool node) { |
| 3956 stack.add(graph.addConstantBool(node.value, constantSystem)); | 3962 stack.add(graph.addConstantBool(node.value, compiler)); |
| 3957 } | 3963 } |
| 3958 | 3964 |
| 3959 void visitLiteralString(LiteralString node) { | 3965 void visitLiteralString(LiteralString node) { |
| 3960 stack.add(graph.addConstantString(node.dartString, node, constantSystem)); | 3966 stack.add(graph.addConstantString(node.dartString, node, compiler)); |
| 3961 } | 3967 } |
| 3962 | 3968 |
| 3963 void visitStringJuxtaposition(StringJuxtaposition node) { | 3969 void visitStringJuxtaposition(StringJuxtaposition node) { |
| 3964 if (!node.isInterpolation) { | 3970 if (!node.isInterpolation) { |
| 3965 // This is a simple string with no interpolations. | 3971 // This is a simple string with no interpolations. |
| 3966 stack.add(graph.addConstantString(node.dartString, node, constantSystem)); | 3972 stack.add(graph.addConstantString(node.dartString, node, compiler)); |
| 3967 return; | 3973 return; |
| 3968 } | 3974 } |
| 3969 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 3975 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
| 3970 stringBuilder.visit(node); | 3976 stringBuilder.visit(node); |
| 3971 stack.add(stringBuilder.result); | 3977 stack.add(stringBuilder.result); |
| 3972 } | 3978 } |
| 3973 | 3979 |
| 3974 void visitLiteralNull(LiteralNull node) { | 3980 void visitLiteralNull(LiteralNull node) { |
| 3975 stack.add(graph.addConstantNull(constantSystem)); | 3981 stack.add(graph.addConstantNull(compiler)); |
| 3976 } | 3982 } |
| 3977 | 3983 |
| 3978 visitNodeList(NodeList node) { | 3984 visitNodeList(NodeList node) { |
| 3979 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3985 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 3980 if (isAborted()) { | 3986 if (isAborted()) { |
| 3981 compiler.reportWarning(link.head, 'dead code'); | 3987 compiler.reportWarning(link.head, 'dead code'); |
| 3982 } else { | 3988 } else { |
| 3983 visit(link.head); | 3989 visit(link.head); |
| 3984 } | 3990 } |
| 3985 } | 3991 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4009 if (!inTryStatement) return; | 4015 if (!inTryStatement) return; |
| 4010 HBasicBlock block = close(new HExitTry()); | 4016 HBasicBlock block = close(new HExitTry()); |
| 4011 HBasicBlock newBlock = graph.addNewBlock(); | 4017 HBasicBlock newBlock = graph.addNewBlock(); |
| 4012 block.addSuccessor(newBlock); | 4018 block.addSuccessor(newBlock); |
| 4013 open(newBlock); | 4019 open(newBlock); |
| 4014 } | 4020 } |
| 4015 | 4021 |
| 4016 visitRethrow(Rethrow node) { | 4022 visitRethrow(Rethrow node) { |
| 4017 HInstruction exception = rethrowableException; | 4023 HInstruction exception = rethrowableException; |
| 4018 if (exception == null) { | 4024 if (exception == null) { |
| 4019 exception = graph.addConstantNull(constantSystem); | 4025 exception = graph.addConstantNull(compiler); |
| 4020 compiler.internalError( | 4026 compiler.internalError( |
| 4021 'rethrowableException should not be null', node: node); | 4027 'rethrowableException should not be null', node: node); |
| 4022 } | 4028 } |
| 4023 handleInTryStatement(); | 4029 handleInTryStatement(); |
| 4024 closeAndGotoExit(new HThrow(exception, isRethrow: true)); | 4030 closeAndGotoExit(new HThrow(exception, isRethrow: true)); |
| 4025 } | 4031 } |
| 4026 | 4032 |
| 4027 visitReturn(Return node) { | 4033 visitReturn(Return node) { |
| 4028 if (identical(node.getBeginToken().stringValue, 'native')) { | 4034 if (identical(node.getBeginToken().stringValue, 'native')) { |
| 4029 native.handleSsaNative(this, node.expression); | 4035 native.handleSsaNative(this, node.expression); |
| 4030 return; | 4036 return; |
| 4031 } | 4037 } |
| 4032 HInstruction value; | 4038 HInstruction value; |
| 4033 if (node.isRedirectingFactoryBody) { | 4039 if (node.isRedirectingFactoryBody) { |
| 4034 // TODO(ahe): This is only for reflection, and it is not correct yet. | 4040 // TODO(ahe): This is only for reflection, and it is not correct yet. |
| 4035 value = graph.addConstantNull(constantSystem); | 4041 value = graph.addConstantNull(compiler); |
| 4036 } else if (node.expression == null) { | 4042 } else if (node.expression == null) { |
| 4037 value = graph.addConstantNull(constantSystem); | 4043 value = graph.addConstantNull(compiler); |
| 4038 } else { | 4044 } else { |
| 4039 visit(node.expression); | 4045 visit(node.expression); |
| 4040 value = pop(); | 4046 value = pop(); |
| 4041 value = potentiallyCheckType(value, returnType); | 4047 value = potentiallyCheckType(value, returnType); |
| 4042 } | 4048 } |
| 4043 | 4049 |
| 4044 handleInTryStatement(); | 4050 handleInTryStatement(); |
| 4045 | 4051 |
| 4046 if (!inliningStack.isEmpty) { | 4052 if (!inliningStack.isEmpty) { |
| 4047 localsHandler.updateLocal(returnElement, value); | 4053 localsHandler.updateLocal(returnElement, value); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4064 node: node); | 4070 node: node); |
| 4065 } | 4071 } |
| 4066 | 4072 |
| 4067 visitVariableDefinitions(VariableDefinitions node) { | 4073 visitVariableDefinitions(VariableDefinitions node) { |
| 4068 assert(isReachable); | 4074 assert(isReachable); |
| 4069 for (Link<Node> link = node.definitions.nodes; | 4075 for (Link<Node> link = node.definitions.nodes; |
| 4070 !link.isEmpty; | 4076 !link.isEmpty; |
| 4071 link = link.tail) { | 4077 link = link.tail) { |
| 4072 Node definition = link.head; | 4078 Node definition = link.head; |
| 4073 if (definition is Identifier) { | 4079 if (definition is Identifier) { |
| 4074 HInstruction initialValue = graph.addConstantNull(constantSystem); | 4080 HInstruction initialValue = graph.addConstantNull(compiler); |
| 4075 localsHandler.updateLocal(elements[definition], initialValue); | 4081 localsHandler.updateLocal(elements[definition], initialValue); |
| 4076 } else { | 4082 } else { |
| 4077 assert(definition is SendSet); | 4083 assert(definition is SendSet); |
| 4078 visitSendSet(definition); | 4084 visitSendSet(definition); |
| 4079 pop(); // Discard value. | 4085 pop(); // Discard value. |
| 4080 } | 4086 } |
| 4081 } | 4087 } |
| 4082 } | 4088 } |
| 4083 | 4089 |
| 4084 visitLiteralList(LiteralList node) { | 4090 visitLiteralList(LiteralList node) { |
| 4085 if (node.isConst()) { | 4091 if (node.isConst()) { |
| 4086 ConstantHandler handler = compiler.constantHandler; | 4092 ConstantHandler handler = compiler.constantHandler; |
| 4087 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 4093 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 4088 stack.add(graph.addConstant(constant)); | 4094 stack.add(graph.addConstant(constant, compiler)); |
| 4089 return; | 4095 return; |
| 4090 } | 4096 } |
| 4091 | 4097 |
| 4092 List<HInstruction> inputs = <HInstruction>[]; | 4098 List<HInstruction> inputs = <HInstruction>[]; |
| 4093 for (Link<Node> link = node.elements.nodes; | 4099 for (Link<Node> link = node.elements.nodes; |
| 4094 !link.isEmpty; | 4100 !link.isEmpty; |
| 4095 link = link.tail) { | 4101 link = link.tail) { |
| 4096 visit(link.head); | 4102 visit(link.head); |
| 4097 inputs.add(pop()); | 4103 inputs.add(pop()); |
| 4098 } | 4104 } |
| 4099 push(new HLiteralList(inputs)); | 4105 push(buildLiteralList(inputs)); |
| 4100 } | 4106 } |
| 4101 | 4107 |
| 4102 visitConditional(Conditional node) { | 4108 visitConditional(Conditional node) { |
| 4103 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); | 4109 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
| 4104 brancher.handleConditional(() => visit(node.condition), | 4110 brancher.handleConditional(() => visit(node.condition), |
| 4105 () => visit(node.thenExpression), | 4111 () => visit(node.thenExpression), |
| 4106 () => visit(node.elseExpression)); | 4112 () => visit(node.elseExpression)); |
| 4107 } | 4113 } |
| 4108 | 4114 |
| 4109 visitStringInterpolation(StringInterpolation node) { | 4115 visitStringInterpolation(StringInterpolation node) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4273 handler.labels()), | 4279 handler.labels()), |
| 4274 joinBlock); | 4280 joinBlock); |
| 4275 } | 4281 } |
| 4276 handler.close(); | 4282 handler.close(); |
| 4277 } | 4283 } |
| 4278 | 4284 |
| 4279 visitLiteralMap(LiteralMap node) { | 4285 visitLiteralMap(LiteralMap node) { |
| 4280 if (node.isConst()) { | 4286 if (node.isConst()) { |
| 4281 ConstantHandler handler = compiler.constantHandler; | 4287 ConstantHandler handler = compiler.constantHandler; |
| 4282 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 4288 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 4283 stack.add(graph.addConstant(constant)); | 4289 stack.add(graph.addConstant(constant, compiler)); |
| 4284 return; | 4290 return; |
| 4285 } | 4291 } |
| 4286 List<HInstruction> inputs = <HInstruction>[]; | 4292 List<HInstruction> inputs = <HInstruction>[]; |
| 4287 for (Link<Node> link = node.entries.nodes; | 4293 for (Link<Node> link = node.entries.nodes; |
| 4288 !link.isEmpty; | 4294 !link.isEmpty; |
| 4289 link = link.tail) { | 4295 link = link.tail) { |
| 4290 visit(link.head); | 4296 visit(link.head); |
| 4291 inputs.add(pop()); | 4297 inputs.add(pop()); |
| 4292 inputs.add(pop()); | 4298 inputs.add(pop()); |
| 4293 } | 4299 } |
| 4294 HLiteralList keyValuePairs = new HLiteralList(inputs); | 4300 HLiteralList keyValuePairs = buildLiteralList(inputs); |
| 4295 add(keyValuePairs); | 4301 add(keyValuePairs); |
| 4296 HType mapType = new HType.nonNullSubtype( | 4302 HType mapType = new HType.nonNullSubtype( |
| 4297 backend.mapLiteralClass.computeType(compiler), compiler); | 4303 backend.mapLiteralClass.computeType(compiler), compiler); |
| 4298 pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); | 4304 pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); |
| 4299 } | 4305 } |
| 4300 | 4306 |
| 4301 visitLiteralMapEntry(LiteralMapEntry node) { | 4307 visitLiteralMapEntry(LiteralMapEntry node) { |
| 4302 visit(node.value); | 4308 visit(node.value); |
| 4303 visit(node.key); | 4309 visit(node.key); |
| 4304 } | 4310 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4445 // l: while (true) { | 4451 // l: while (true) { |
| 4446 // switch (target) { | 4452 // switch (target) { |
| 4447 // case 1: s_1; break l; | 4453 // case 1: s_1; break l; |
| 4448 // case 2: s_2; target = i; continue l; | 4454 // case 2: s_2; target = i; continue l; |
| 4449 // ... | 4455 // ... |
| 4450 // case n: s_n; target = j; continue l; | 4456 // case n: s_n; target = j; continue l; |
| 4451 // } | 4457 // } |
| 4452 // } | 4458 // } |
| 4453 | 4459 |
| 4454 TargetElement switchTarget = elements[node]; | 4460 TargetElement switchTarget = elements[node]; |
| 4455 HInstruction initialValue = graph.addConstantNull(constantSystem); | 4461 HInstruction initialValue = graph.addConstantNull(compiler); |
| 4456 localsHandler.updateLocal(switchTarget, initialValue); | 4462 localsHandler.updateLocal(switchTarget, initialValue); |
| 4457 | 4463 |
| 4458 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); | 4464 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); |
| 4459 var switchCases = node.cases; | 4465 var switchCases = node.cases; |
| 4460 if (!hasDefault) { | 4466 if (!hasDefault) { |
| 4461 // Use [:null:] as the marker for a synthetic default clause. | 4467 // Use [:null:] as the marker for a synthetic default clause. |
| 4462 // The synthetic default is added because otherwise, there would be no | 4468 // The synthetic default is added because otherwise, there would be no |
| 4463 // good place to give a default value to the local. | 4469 // good place to give a default value to the local. |
| 4464 switchCases = node.cases.nodes.toList()..add(null); | 4470 switchCases = node.cases.nodes.toList()..add(null); |
| 4465 } | 4471 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4478 } | 4484 } |
| 4479 return constantList; | 4485 return constantList; |
| 4480 } | 4486 } |
| 4481 bool isDefaultCase(SwitchCase switchCase) { | 4487 bool isDefaultCase(SwitchCase switchCase) { |
| 4482 return switchCase == null || switchCase.isDefaultCase; | 4488 return switchCase == null || switchCase.isDefaultCase; |
| 4483 } | 4489 } |
| 4484 void buildSwitchCase(SwitchCase switchCase) { | 4490 void buildSwitchCase(SwitchCase switchCase) { |
| 4485 if (switchCase != null) { | 4491 if (switchCase != null) { |
| 4486 // Generate 'target = i; break;' for switch case i. | 4492 // Generate 'target = i; break;' for switch case i. |
| 4487 int index = caseIndex[switchCase]; | 4493 int index = caseIndex[switchCase]; |
| 4488 HInstruction value = graph.addConstantInt(index, constantSystem); | 4494 HInstruction value = graph.addConstantInt(index, compiler); |
| 4489 localsHandler.updateLocal(switchTarget, value); | 4495 localsHandler.updateLocal(switchTarget, value); |
| 4490 } else { | 4496 } else { |
| 4491 // Generate synthetic default case 'target = null; break;'. | 4497 // Generate synthetic default case 'target = null; break;'. |
| 4492 HInstruction value = graph.addConstantNull(constantSystem); | 4498 HInstruction value = graph.addConstantNull(compiler); |
| 4493 localsHandler.updateLocal(switchTarget, value); | 4499 localsHandler.updateLocal(switchTarget, value); |
| 4494 } | 4500 } |
| 4495 jumpTargets[switchTarget].generateBreak(); | 4501 jumpTargets[switchTarget].generateBreak(); |
| 4496 } | 4502 } |
| 4497 handleSwitch(node, | 4503 handleSwitch(node, |
| 4498 jumpHandler, | 4504 jumpHandler, |
| 4499 buildExpression, | 4505 buildExpression, |
| 4500 switchCases, | 4506 switchCases, |
| 4501 getConstants, | 4507 getConstants, |
| 4502 isDefaultCase, | 4508 isDefaultCase, |
| 4503 buildSwitchCase); | 4509 buildSwitchCase); |
| 4504 jumpHandler.close(); | 4510 jumpHandler.close(); |
| 4505 | 4511 |
| 4506 HInstruction buildCondition() => | 4512 HInstruction buildCondition() => |
| 4507 graph.addConstantBool(true, constantSystem); | 4513 graph.addConstantBool(true, compiler); |
| 4508 | 4514 |
| 4509 void buildSwitch() { | 4515 void buildSwitch() { |
| 4510 HInstruction buildExpression() { | 4516 HInstruction buildExpression() { |
| 4511 return localsHandler.readLocal(switchTarget); | 4517 return localsHandler.readLocal(switchTarget); |
| 4512 } | 4518 } |
| 4513 Iterable<Constant> getConstants(SwitchCase switchCase) { | 4519 Iterable<Constant> getConstants(SwitchCase switchCase) { |
| 4514 return <Constant>[constantSystem.createInt(caseIndex[switchCase])]; | 4520 return <Constant>[constantSystem.createInt(caseIndex[switchCase])]; |
| 4515 } | 4521 } |
| 4516 void buildSwitchCase(SwitchCase switchCase) { | 4522 void buildSwitchCase(SwitchCase switchCase) { |
| 4517 visit(switchCase.statements); | 4523 visit(switchCase.statements); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4592 bool hasDefault = false; | 4598 bool hasDefault = false; |
| 4593 Element getFallThroughErrorElement = backend.getFallThroughError(); | 4599 Element getFallThroughErrorElement = backend.getFallThroughError(); |
| 4594 HasNextIterator<Node> caseIterator = | 4600 HasNextIterator<Node> caseIterator = |
| 4595 new HasNextIterator<Node>(switchCases.iterator); | 4601 new HasNextIterator<Node>(switchCases.iterator); |
| 4596 while (caseIterator.hasNext) { | 4602 while (caseIterator.hasNext) { |
| 4597 SwitchCase switchCase = caseIterator.next(); | 4603 SwitchCase switchCase = caseIterator.next(); |
| 4598 List<Constant> caseConstants = <Constant>[]; | 4604 List<Constant> caseConstants = <Constant>[]; |
| 4599 HBasicBlock block = graph.addNewBlock(); | 4605 HBasicBlock block = graph.addNewBlock(); |
| 4600 for (Constant constant in getConstants(switchCase)) { | 4606 for (Constant constant in getConstants(switchCase)) { |
| 4601 caseConstants.add(constant); | 4607 caseConstants.add(constant); |
| 4602 HConstant hConstant = graph.addConstant(constant); | 4608 HConstant hConstant = graph.addConstant(constant, compiler); |
| 4603 switchInstruction.inputs.add(hConstant); | 4609 switchInstruction.inputs.add(hConstant); |
| 4604 hConstant.usedBy.add(switchInstruction); | 4610 hConstant.usedBy.add(switchInstruction); |
| 4605 expressionBlock.addSuccessor(block); | 4611 expressionBlock.addSuccessor(block); |
| 4606 } | 4612 } |
| 4607 matchExpressions.add(caseConstants); | 4613 matchExpressions.add(caseConstants); |
| 4608 | 4614 |
| 4609 if (isDefaultCase(switchCase)) { | 4615 if (isDefaultCase(switchCase)) { |
| 4610 // An HSwitch has n inputs and n+1 successors, the last being the | 4616 // An HSwitch has n inputs and n+1 successors, the last being the |
| 4611 // default case. | 4617 // default case. |
| 4612 expressionBlock.addSuccessor(block); | 4618 expressionBlock.addSuccessor(block); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4779 | 4785 |
| 4780 void pushCondition(CatchBlock catchBlock) { | 4786 void pushCondition(CatchBlock catchBlock) { |
| 4781 if (catchBlock.onKeyword != null) { | 4787 if (catchBlock.onKeyword != null) { |
| 4782 DartType type = elements.getType(catchBlock.type); | 4788 DartType type = elements.getType(catchBlock.type); |
| 4783 if (type == null) { | 4789 if (type == null) { |
| 4784 compiler.internalError('On with no type', node: catchBlock.type); | 4790 compiler.internalError('On with no type', node: catchBlock.type); |
| 4785 } | 4791 } |
| 4786 if (type.isMalformed) { | 4792 if (type.isMalformed) { |
| 4787 // TODO(johnniwinther): Handle malformed types in [HIs] instead. | 4793 // TODO(johnniwinther): Handle malformed types in [HIs] instead. |
| 4788 HInstruction condition = | 4794 HInstruction condition = |
| 4789 graph.addConstantBool(true, constantSystem); | 4795 graph.addConstantBool(true, compiler); |
| 4790 stack.add(condition); | 4796 stack.add(condition); |
| 4791 } else { | 4797 } else { |
| 4792 // TODO(karlkose): support type arguments here. | 4798 // TODO(karlkose): support type arguments here. |
| 4793 HInstruction condition = new HIs(type, | 4799 HInstruction condition = new HIs(type, |
| 4794 <HInstruction>[unwrappedException], | 4800 <HInstruction>[unwrappedException], |
| 4795 HIs.RAW_CHECK); | 4801 HIs.RAW_CHECK); |
| 4796 push(condition); | 4802 push(condition); |
| 4797 } | 4803 } |
| 4798 } else { | 4804 } else { |
| 4799 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 4805 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 4800 HInstruction condition = null; | 4806 HInstruction condition = null; |
| 4801 if (declaration.type == null) { | 4807 if (declaration.type == null) { |
| 4802 condition = graph.addConstantBool(true, constantSystem); | 4808 condition = graph.addConstantBool(true, compiler); |
| 4803 stack.add(condition); | 4809 stack.add(condition); |
| 4804 } else { | 4810 } else { |
| 4805 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 4811 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 4806 // "if" condition above and this "else" branch should be deleted as | 4812 // "if" condition above and this "else" branch should be deleted as |
| 4807 // type of declared variable won't matter for the catch | 4813 // type of declared variable won't matter for the catch |
| 4808 // condition. | 4814 // condition. |
| 4809 DartType type = elements.getType(declaration.type); | 4815 DartType type = elements.getType(declaration.type); |
| 4810 if (type == null) { | 4816 if (type == null) { |
| 4811 compiler.cancel('Catch with unresolved type', node: catchBlock); | 4817 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 4812 } | 4818 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4985 } | 4991 } |
| 4986 | 4992 |
| 4987 visitNode(Node node) { | 4993 visitNode(Node node) { |
| 4988 builder.compiler.internalError('unexpected node', node: node); | 4994 builder.compiler.internalError('unexpected node', node: node); |
| 4989 } | 4995 } |
| 4990 | 4996 |
| 4991 void visitExpression(Node node) { | 4997 void visitExpression(Node node) { |
| 4992 node.accept(builder); | 4998 node.accept(builder); |
| 4993 HInstruction expression = builder.pop(); | 4999 HInstruction expression = builder.pop(); |
| 4994 if (!expression.isConstantString()) { | 5000 if (!expression.isConstantString()) { |
| 4995 expression = new HStringify(expression, node); | 5001 expression = new HStringify(expression, node, builder.backend.stringType); |
| 4996 builder.add(expression); | 5002 builder.add(expression); |
| 4997 } | 5003 } |
| 4998 result = (result == null) ? expression : concat(result, expression); | 5004 result = (result == null) ? expression : concat(result, expression); |
| 4999 } | 5005 } |
| 5000 | 5006 |
| 5001 void visitStringInterpolation(StringInterpolation node) { | 5007 void visitStringInterpolation(StringInterpolation node) { |
| 5002 node.visitChildren(this); | 5008 node.visitChildren(this); |
| 5003 } | 5009 } |
| 5004 | 5010 |
| 5005 void visitStringInterpolationPart(StringInterpolationPart node) { | 5011 void visitStringInterpolationPart(StringInterpolationPart node) { |
| 5006 visit(node.expression); | 5012 visit(node.expression); |
| 5007 visit(node.string); | 5013 visit(node.string); |
| 5008 } | 5014 } |
| 5009 | 5015 |
| 5010 void visitStringJuxtaposition(StringJuxtaposition node) { | 5016 void visitStringJuxtaposition(StringJuxtaposition node) { |
| 5011 node.visitChildren(this); | 5017 node.visitChildren(this); |
| 5012 } | 5018 } |
| 5013 | 5019 |
| 5014 void visitNodeList(NodeList node) { | 5020 void visitNodeList(NodeList node) { |
| 5015 node.visitChildren(this); | 5021 node.visitChildren(this); |
| 5016 } | 5022 } |
| 5017 | 5023 |
| 5018 HInstruction concat(HInstruction left, HInstruction right) { | 5024 HInstruction concat(HInstruction left, HInstruction right) { |
| 5019 HInstruction instruction = new HStringConcat(left, right, diagnosticNode); | 5025 HInstruction instruction = new HStringConcat( |
| 5026 left, right, diagnosticNode, builder.backend.stringType); |
| 5020 builder.add(instruction); | 5027 builder.add(instruction); |
| 5021 return instruction; | 5028 return instruction; |
| 5022 } | 5029 } |
| 5023 } | 5030 } |
| 5024 | 5031 |
| 5025 /** | 5032 /** |
| 5026 * This class visits the method that is a candidate for inlining and | 5033 * This class visits the method that is a candidate for inlining and |
| 5027 * finds whether it is too difficult to inline. | 5034 * finds whether it is too difficult to inline. |
| 5028 */ | 5035 */ |
| 5029 class InlineWeeder extends Visitor { | 5036 class InlineWeeder extends Visitor { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5283 } | 5290 } |
| 5284 } | 5291 } |
| 5285 | 5292 |
| 5286 void visitThen() { | 5293 void visitThen() { |
| 5287 right(); | 5294 right(); |
| 5288 boolifiedRight = builder.popBoolified(); | 5295 boolifiedRight = builder.popBoolified(); |
| 5289 } | 5296 } |
| 5290 | 5297 |
| 5291 handleIf(visitCondition, visitThen, null); | 5298 handleIf(visitCondition, visitThen, null); |
| 5292 HConstant notIsAnd = | 5299 HConstant notIsAnd = |
| 5293 builder.graph.addConstantBool(!isAnd, builder.constantSystem); | 5300 builder.graph.addConstantBool(!isAnd, builder.compiler); |
| 5294 HPhi result = new HPhi.manyInputs(null, | 5301 HPhi result = new HPhi.manyInputs(null, |
| 5295 <HInstruction>[boolifiedRight, notIsAnd]); | 5302 <HInstruction>[boolifiedRight, notIsAnd]); |
| 5296 builder.current.addPhi(result); | 5303 builder.current.addPhi(result); |
| 5297 builder.stack.add(result); | 5304 builder.stack.add(result); |
| 5298 } | 5305 } |
| 5299 | 5306 |
| 5300 void handleLogicalAndOrWithLeftNode(Node left, | 5307 void handleLogicalAndOrWithLeftNode(Node left, |
| 5301 void visitRight(), | 5308 void visitRight(), |
| 5302 {bool isAnd}) { | 5309 {bool isAnd}) { |
| 5303 // This method is similar to [handleLogicalAndOr] but optimizes the case | 5310 // This method is similar to [handleLogicalAndOr] but optimizes the case |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5373 new HSubGraphBlockInformation(elseBranch.graph)); | 5380 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5374 | 5381 |
| 5375 HBasicBlock conditionStartBlock = conditionBranch.block; | 5382 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5376 conditionStartBlock.setBlockFlow(info, joinBlock); | 5383 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5377 SubGraph conditionGraph = conditionBranch.graph; | 5384 SubGraph conditionGraph = conditionBranch.graph; |
| 5378 HIf branch = conditionGraph.end.last; | 5385 HIf branch = conditionGraph.end.last; |
| 5379 assert(branch is HIf); | 5386 assert(branch is HIf); |
| 5380 branch.blockInformation = conditionStartBlock.blockFlow; | 5387 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5381 } | 5388 } |
| 5382 } | 5389 } |
| OLD | NEW |