Chromium Code Reviews| 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 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 } | 353 } |
| 354 | 354 |
| 355 /** | 355 /** |
| 356 * Returns an [HInstruction] for the given element. If the element is | 356 * Returns an [HInstruction] for the given element. If the element is |
| 357 * boxed or stored in a closure then the method generates code to retrieve | 357 * boxed or stored in a closure then the method generates code to retrieve |
| 358 * the value. | 358 * the value. |
| 359 */ | 359 */ |
| 360 HInstruction readLocal(Element element) { | 360 HInstruction readLocal(Element element) { |
| 361 if (isAccessedDirectly(element)) { | 361 if (isAccessedDirectly(element)) { |
| 362 if (directLocals[element] == null) { | 362 if (directLocals[element] == null) { |
| 363 builder.compiler.internalError("Cannot find value $element", | 363 if (element.isTypeVariable()) { |
| 364 element: element); | 364 builder.compiler.internalError( |
| 365 "Runtime type information not available for $element", | |
| 366 element: builder.compiler.currentElement); | |
| 367 } else { | |
| 368 builder.compiler.internalError( | |
| 369 "Cannot find value $element", | |
| 370 element: element); | |
| 371 } | |
| 365 } | 372 } |
| 366 return directLocals[element]; | 373 return directLocals[element]; |
| 367 } else if (isStoredInClosureField(element)) { | 374 } else if (isStoredInClosureField(element)) { |
| 368 Element redirect = redirectionMapping[element]; | 375 Element redirect = redirectionMapping[element]; |
| 369 HInstruction receiver = readLocal(closureData.closureElement); | 376 HInstruction receiver = readLocal(closureData.closureElement); |
| 370 HInstruction fieldGet = new HFieldGet(redirect, receiver); | 377 HInstruction fieldGet = new HFieldGet(redirect, receiver); |
| 371 fieldGet.instructionType = builder.getTypeOfCapturedVariable(element); | 378 fieldGet.instructionType = builder.getTypeOfCapturedVariable(element); |
| 372 builder.add(fieldGet); | 379 builder.add(fieldGet); |
| 373 return fieldGet; | 380 return fieldGet; |
| 374 } else if (isBoxed(element)) { | 381 } else if (isBoxed(element)) { |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1089 LocalsHandler newLocalsHandler = new LocalsHandler.from(localsHandler); | 1096 LocalsHandler newLocalsHandler = new LocalsHandler.from(localsHandler); |
| 1090 newLocalsHandler.closureData = | 1097 newLocalsHandler.closureData = |
| 1091 compiler.closureToClassMapper.computeClosureToClassMapping( | 1098 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1092 function, function.parseNode(compiler), elements); | 1099 function, function.parseNode(compiler), elements); |
| 1093 int argumentIndex = 0; | 1100 int argumentIndex = 0; |
| 1094 if (isInstanceMember) { | 1101 if (isInstanceMember) { |
| 1095 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, | 1102 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, |
| 1096 compiledArguments[argumentIndex++]); | 1103 compiledArguments[argumentIndex++]); |
| 1097 } | 1104 } |
| 1098 | 1105 |
| 1099 FunctionSignature signature = function.computeSignature(compiler); | |
| 1100 signature.orderedForEachParameter((Element parameter) { | |
| 1101 HInstruction argument = compiledArguments[argumentIndex++]; | |
| 1102 newLocalsHandler.updateLocal(parameter, argument); | |
| 1103 potentiallyCheckType(argument, parameter.computeType(compiler)); | |
| 1104 }); | |
| 1105 | |
| 1106 if (function.isConstructor()) { | 1106 if (function.isConstructor()) { |
| 1107 ClassElement enclosing = function.getEnclosingClass(); | 1107 ClassElement enclosing = function.getEnclosingClass(); |
| 1108 if (backend.needsRti(enclosing)) { | 1108 if (backend.needsRti(enclosing)) { |
| 1109 assert(currentNode is NewExpression); | 1109 assert(currentNode is NewExpression); |
| 1110 InterfaceType type = elements.getType(currentNode); | 1110 InterfaceType type = elements.getType(currentNode); |
| 1111 Link<DartType> typeVariable = enclosing.typeVariables; | 1111 Link<DartType> typeVariable = enclosing.typeVariables; |
| 1112 type.typeArguments.forEach((DartType argument) { | 1112 type.typeArguments.forEach((DartType argument) { |
| 1113 HInstruction instruction = | 1113 HInstruction instruction = |
| 1114 analyzeTypeArgument(argument, currentNode); | 1114 analyzeTypeArgument(argument, currentNode); |
| 1115 newLocalsHandler.updateLocal(typeVariable.head.element, instruction); | 1115 newLocalsHandler.updateLocal(typeVariable.head.element, instruction); |
| 1116 typeVariable = typeVariable.tail; | 1116 typeVariable = typeVariable.tail; |
| 1117 }); | 1117 }); |
| 1118 while (!typeVariable.isEmpty) { | 1118 while (!typeVariable.isEmpty) { |
| 1119 newLocalsHandler.updateLocal(typeVariable.head.element, | 1119 newLocalsHandler.updateLocal(typeVariable.head.element, |
| 1120 graph.addConstantNull(constantSystem)); | 1120 graph.addConstantNull(constantSystem)); |
| 1121 typeVariable = typeVariable.tail; | 1121 typeVariable = typeVariable.tail; |
| 1122 } | 1122 } |
| 1123 } | 1123 } |
| 1124 } | 1124 } |
| 1125 | 1125 |
| 1126 FunctionSignature signature = function.computeSignature(compiler); | |
|
ngeoffray
2013/05/13 09:10:59
Also add a similar comment to line 1675 here.
karlklose
2013/05/14 13:49:41
Done.
| |
| 1127 int index = 0; | |
| 1128 if (isInstanceMember) index++; | |
|
ngeoffray
2013/05/13 09:10:59
Why not using argumentIndex?
karlklose
2013/05/14 13:49:41
Done.
| |
| 1129 signature.orderedForEachParameter((Element parameter) { | |
| 1130 HInstruction argument = compiledArguments[index++]; | |
| 1131 newLocalsHandler.updateLocal(parameter, argument); | |
| 1132 potentiallyCheckType(argument, parameter.computeType(compiler)); | |
| 1133 }); | |
| 1134 | |
| 1126 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 1135 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
| 1127 returnElement = new ElementX(const SourceString("result"), | 1136 returnElement = new ElementX(const SourceString("result"), |
| 1128 ElementKind.VARIABLE, | 1137 ElementKind.VARIABLE, |
| 1129 function); | 1138 function); |
| 1130 newLocalsHandler.updateLocal(returnElement, | 1139 newLocalsHandler.updateLocal(returnElement, |
| 1131 graph.addConstantNull(constantSystem)); | 1140 graph.addConstantNull(constantSystem)); |
| 1132 elements = compiler.enqueuer.resolution.getCachedElements(function); | 1141 elements = compiler.enqueuer.resolution.getCachedElements(function); |
| 1133 assert(elements != null); | 1142 assert(elements != null); |
| 1134 returnType = signature.returnType; | 1143 returnType = signature.returnType; |
| 1135 stack = <HInstruction>[]; | 1144 stack = <HInstruction>[]; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1198 if (newElements == null) { | 1207 if (newElements == null) { |
| 1199 compiler.internalError("Element not resolved: $function"); | 1208 compiler.internalError("Element not resolved: $function"); |
| 1200 } | 1209 } |
| 1201 | 1210 |
| 1202 if (canBeInlined == null) { | 1211 if (canBeInlined == null) { |
| 1203 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); | 1212 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); |
| 1204 backend.canBeInlined[function] = canBeInlined; | 1213 backend.canBeInlined[function] = canBeInlined; |
| 1205 if (!canBeInlined) return false; | 1214 if (!canBeInlined) return false; |
| 1206 } | 1215 } |
| 1207 | 1216 |
| 1217 // TODO(karlklose): remove this and enable inlining of these methods. | |
|
ngeoffray
2013/05/13 09:10:59
Could you also explain why it does not work?
karlklose
2013/05/14 13:49:41
Done.
| |
| 1218 if (compiler.enableTypeAssertions && | |
| 1219 element.computeType(compiler).containsTypeVariables) { | |
| 1220 return false; | |
| 1221 } | |
| 1222 | |
| 1208 assert(canBeInlined); | 1223 assert(canBeInlined); |
| 1209 InliningState state = enterInlinedMethod( | 1224 InliningState state = enterInlinedMethod( |
| 1210 function, selector, argumentsNodes, providedArguments, currentNode); | 1225 function, selector, argumentsNodes, providedArguments, currentNode); |
| 1211 inlinedFrom(element, () { | 1226 inlinedFrom(element, () { |
| 1212 functionExpression.body.accept(this); | 1227 functionExpression.body.accept(this); |
| 1213 }); | 1228 }); |
| 1214 leaveInlinedMethod(state); | 1229 leaveInlinedMethod(state); |
| 1215 return true; | 1230 return true; |
| 1216 } | 1231 } |
| 1217 | 1232 |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1650 void openFunction(Element element, Expression node) { | 1665 void openFunction(Element element, Expression node) { |
| 1651 assert(invariant(element, element.isImplementation)); | 1666 assert(invariant(element, element.isImplementation)); |
| 1652 HBasicBlock block = graph.addNewBlock(); | 1667 HBasicBlock block = graph.addNewBlock(); |
| 1653 open(graph.entry); | 1668 open(graph.entry); |
| 1654 | 1669 |
| 1655 localsHandler.startFunction(element, node); | 1670 localsHandler.startFunction(element, node); |
| 1656 close(new HGoto()).addSuccessor(block); | 1671 close(new HGoto()).addSuccessor(block); |
| 1657 | 1672 |
| 1658 open(block); | 1673 open(block); |
| 1659 | 1674 |
| 1675 // Add the type parameters of the class as parameters of this method. This | |
| 1676 // must be done before adding the normal parameters, because their types | |
| 1677 // may contain references to type variables. | |
| 1678 var enclosing = element.enclosingElement; | |
| 1679 if ((element.isConstructor() || element.isGenerativeConstructorBody()) | |
| 1680 && backend.needsRti(enclosing)) { | |
| 1681 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { | |
| 1682 HParameterValue param = addParameter(typeVariable.element); | |
| 1683 localsHandler.directLocals[typeVariable.element] = param; | |
| 1684 }); | |
| 1685 } | |
| 1686 | |
| 1660 if (element is FunctionElement) { | 1687 if (element is FunctionElement) { |
| 1661 FunctionElement functionElement = element; | 1688 FunctionElement functionElement = element; |
| 1662 FunctionSignature signature = functionElement.computeSignature(compiler); | 1689 FunctionSignature signature = functionElement.computeSignature(compiler); |
| 1663 signature.orderedForEachParameter((Element parameterElement) { | 1690 signature.orderedForEachParameter((Element parameterElement) { |
| 1664 if (elements.isParameterChecked(parameterElement)) { | 1691 if (elements.isParameterChecked(parameterElement)) { |
| 1665 addParameterCheckInstruction(parameterElement); | 1692 addParameterCheckInstruction(parameterElement); |
| 1666 } | 1693 } |
| 1667 }); | 1694 }); |
| 1668 | 1695 |
| 1669 // Put the type checks in the first successor of the entry, | 1696 // Put the type checks in the first successor of the entry, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1686 localsHandler.directLocals[parameterElement], | 1713 localsHandler.directLocals[parameterElement], |
| 1687 parameterElement.computeType(compiler)); | 1714 parameterElement.computeType(compiler)); |
| 1688 localsHandler.directLocals[parameterElement] = newParameter; | 1715 localsHandler.directLocals[parameterElement] = newParameter; |
| 1689 }); | 1716 }); |
| 1690 | 1717 |
| 1691 returnType = signature.returnType; | 1718 returnType = signature.returnType; |
| 1692 } else { | 1719 } else { |
| 1693 // Otherwise it is a lazy initializer which does not have parameters. | 1720 // Otherwise it is a lazy initializer which does not have parameters. |
| 1694 assert(element is VariableElement); | 1721 assert(element is VariableElement); |
| 1695 } | 1722 } |
| 1723 } | |
| 1696 | 1724 |
| 1697 // Add the type parameters of the class as parameters of this | 1725 HInstruction buildTypeConversion(Compiler compiler, HInstruction original, |
| 1698 // method. | 1726 DartType type, int kind) { |
|
ngeoffray
2013/05/13 09:10:59
Please do not duplicate what's already in convertT
karlklose
2013/05/14 13:49:41
There are users in the optimizer, but they cannot
| |
| 1699 var enclosing = element.enclosingElement; | 1727 if (type == null) return original; |
| 1700 if ((element.isConstructor() || element.isGenerativeConstructorBody()) | 1728 if (identical(type.element, compiler.dynamicClass)) return original; |
| 1701 && backend.needsRti(enclosing)) { | 1729 if (identical(type.element, compiler.objectClass)) return original; |
| 1702 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { | 1730 if (type.isMalformed || (type.kind != TypeKind.INTERFACE && |
| 1703 HParameterValue param = addParameter(typeVariable.element); | 1731 type.kind != TypeKind.TYPE_VARIABLE)) { |
| 1704 localsHandler.directLocals[typeVariable.element] = param; | 1732 return new HTypeConversion(type, kind, HType.UNKNOWN, original); |
| 1705 }); | 1733 } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) { |
| 1734 // Boolean conversion checks work on non-nullable booleans. | |
| 1735 return new HTypeConversion(type, kind, HType.BOOLEAN, original); | |
| 1736 } | |
| 1737 if (type.kind == TypeKind.INTERFACE) { | |
| 1738 HType subtype = new HType.subtype(type, compiler); | |
| 1739 if (type.isRaw) { | |
| 1740 return new HTypeConversion(type, kind, subtype, original); | |
| 1741 } | |
| 1742 HInstruction representations = buildTypeArgumentRepresentations(type); | |
| 1743 add(representations); | |
| 1744 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | |
| 1745 original, representations); | |
| 1746 } else { | |
| 1747 HType subtype = original.instructionType; | |
| 1748 assert(type.kind == TypeKind.TYPE_VARIABLE); | |
|
ngeoffray
2013/05/13 09:10:59
Move that assert one up.
karlklose
2013/05/14 13:49:41
This assert is obsolete now.
| |
| 1749 HInstruction typeVariable = addTypeVariableReference(type); | |
| 1750 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | |
| 1751 original, typeVariable); | |
| 1706 } | 1752 } |
| 1707 } | 1753 } |
| 1708 | 1754 |
| 1709 HInstruction potentiallyCheckType( | 1755 HInstruction potentiallyCheckType(HInstruction original, DartType type, |
| 1710 HInstruction original, DartType type, | |
| 1711 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { | 1756 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
| 1712 if (!compiler.enableTypeAssertions) return original; | 1757 if (!compiler.enableTypeAssertions) return original; |
| 1713 HInstruction other = original.convertType(compiler, type, kind); | 1758 HInstruction other = |
| 1759 buildTypeConversion(compiler, original, type, kind); | |
| 1714 if (other != original) add(other); | 1760 if (other != original) add(other); |
| 1715 return other; | 1761 return other; |
| 1716 } | 1762 } |
| 1717 | 1763 |
| 1718 HGraph closeFunction() { | 1764 HGraph closeFunction() { |
| 1719 // TODO(kasperl): Make this goto an implicit return. | 1765 // TODO(kasperl): Make this goto an implicit return. |
| 1720 if (!isAborted()) closeAndGotoExit(new HGoto()); | 1766 if (!isAborted()) closeAndGotoExit(new HGoto()); |
| 1721 graph.finalize(); | 1767 graph.finalize(); |
| 1722 return graph; | 1768 return graph; |
| 1723 } | 1769 } |
| (...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2577 location = send; | 2623 location = send; |
| 2578 } | 2624 } |
| 2579 if (Elements.isStaticOrTopLevelField(element)) { | 2625 if (Elements.isStaticOrTopLevelField(element)) { |
| 2580 if (element.isSetter()) { | 2626 if (element.isSetter()) { |
| 2581 HStatic target = new HStatic(element); | 2627 HStatic target = new HStatic(element); |
| 2582 add(target); | 2628 add(target); |
| 2583 var instruction = buildInvokeStatic( | 2629 var instruction = buildInvokeStatic( |
| 2584 <HInstruction>[target, value], HType.UNKNOWN); | 2630 <HInstruction>[target, value], HType.UNKNOWN); |
| 2585 addWithPosition(instruction, location); | 2631 addWithPosition(instruction, location); |
| 2586 } else { | 2632 } else { |
| 2587 value = potentiallyCheckType(value, element.computeType(compiler)); | 2633 value = |
| 2634 potentiallyCheckType(value, element.computeType(compiler)); | |
| 2588 addWithPosition(new HStaticStore(element, value), location); | 2635 addWithPosition(new HStaticStore(element, value), location); |
| 2589 } | 2636 } |
| 2590 stack.add(value); | 2637 stack.add(value); |
| 2591 } else if (Elements.isErroneousElement(element)) { | 2638 } else if (Elements.isErroneousElement(element)) { |
| 2592 // An erroneous element indicates an unresolved static setter. | 2639 // An erroneous element indicates an unresolved static setter. |
| 2593 generateThrowNoSuchMethod( | 2640 generateThrowNoSuchMethod( |
| 2594 location, | 2641 location, |
| 2595 getTargetName(element, 'set'), | 2642 getTargetName(element, 'set'), |
| 2596 argumentNodes: (send == null ? const Link<Node>() : send.arguments)); | 2643 argumentNodes: (send == null ? const Link<Node>() : send.arguments)); |
| 2597 } else { | 2644 } else { |
| 2598 stack.add(value); | 2645 stack.add(value); |
| 2599 // If the value does not already have a name, give it here. | 2646 // If the value does not already have a name, give it here. |
| 2600 if (value.sourceElement == null) { | 2647 if (value.sourceElement == null) { |
| 2601 value.sourceElement = element; | 2648 value.sourceElement = element; |
| 2602 } | 2649 } |
| 2603 HInstruction checked = potentiallyCheckType( | 2650 HInstruction checked = |
| 2604 value, element.computeType(compiler)); | 2651 potentiallyCheckType(value, element.computeType(compiler)); |
| 2605 if (!identical(checked, value)) { | 2652 if (!identical(checked, value)) { |
| 2606 pop(); | 2653 pop(); |
| 2607 stack.add(checked); | 2654 stack.add(checked); |
| 2608 } | 2655 } |
| 2609 localsHandler.updateLocal(element, checked); | 2656 localsHandler.updateLocal(element, checked); |
| 2610 } | 2657 } |
| 2611 } | 2658 } |
| 2612 | 2659 |
| 2613 HInstruction invokeInterceptor(Set<ClassElement> intercepted, | 2660 HInstruction invokeInterceptor(Set<ClassElement> intercepted, |
| 2614 HInstruction receiver, | 2661 HInstruction receiver, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2764 isNot = true; | 2811 isNot = true; |
| 2765 } | 2812 } |
| 2766 DartType type = elements.getType(typeAnnotation); | 2813 DartType type = elements.getType(typeAnnotation); |
| 2767 if (type.isMalformed) { | 2814 if (type.isMalformed) { |
| 2768 String reasons = Types.fetchReasonsFromMalformedType(type); | 2815 String reasons = Types.fetchReasonsFromMalformedType(type); |
| 2769 if (compiler.enableTypeAssertions) { | 2816 if (compiler.enableTypeAssertions) { |
| 2770 generateMalformedSubtypeError(node, expression, type, reasons); | 2817 generateMalformedSubtypeError(node, expression, type, reasons); |
| 2771 } else { | 2818 } else { |
| 2772 generateRuntimeError(node, '$type is malformed: $reasons'); | 2819 generateRuntimeError(node, '$type is malformed: $reasons'); |
| 2773 } | 2820 } |
| 2774 return; | 2821 } else { |
|
ngeoffray
2013/05/13 09:10:59
You don't need this change anymore.
karlklose
2013/05/14 13:49:41
I know, but I think it reads better. In particular
| |
| 2822 HInstruction instruction = buildIsNode(node, type, expression); | |
| 2823 if (isNot) { | |
| 2824 add(instruction); | |
| 2825 instruction = new HNot(instruction); | |
| 2826 } | |
| 2827 push(instruction); | |
| 2775 } | 2828 } |
| 2829 } | |
| 2776 | 2830 |
| 2777 HInstruction instruction; | 2831 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { |
| 2778 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2832 if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 2779 HInstruction runtimeType = addTypeVariableReference(type); | 2833 HInstruction runtimeType = addTypeVariableReference(type); |
| 2780 Element helper = backend.getGetObjectIsSubtype(); | 2834 Element helper = backend.getObjectIsSubtype(); |
| 2781 HInstruction helperCall = new HStatic(helper); | 2835 HInstruction helperCall = new HStatic(helper); |
| 2782 add(helperCall); | 2836 add(helperCall); |
| 2783 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | 2837 List<HInstruction> inputs = <HInstruction>[helperCall, expression, |
| 2784 runtimeType]; | 2838 runtimeType]; |
| 2785 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); | 2839 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); |
| 2786 add(call); | 2840 add(call); |
| 2787 instruction = new HIs(type, <HInstruction>[expression, call], | 2841 return new HIs(type, <HInstruction>[expression, call], |
| 2788 HIs.VARIABLE_CHECK); | 2842 HIs.VARIABLE_CHECK); |
| 2789 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2843 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 2790 Element element = type.element; | 2844 Element element = type.element; |
| 2791 Element helper = backend.getCheckSubtype(); | 2845 Element helper = backend.getCheckSubtype(); |
| 2792 HInstruction helperCall = new HStatic(helper); | 2846 HInstruction helperCall = new HStatic(helper); |
| 2793 add(helperCall); | 2847 add(helperCall); |
| 2794 HInstruction representations = | 2848 HInstruction representations = |
| 2795 buildTypeArgumentRepresentations(type); | 2849 buildTypeArgumentRepresentations(type); |
| 2796 add(representations); | 2850 add(representations); |
| 2797 String operator = | 2851 String operator = |
| 2798 backend.namer.operatorIs(backend.getImplementationClass(element)); | 2852 backend.namer.operatorIs(backend.getImplementationClass(element)); |
| 2799 HInstruction isFieldName = addConstantString(node, operator); | 2853 HInstruction isFieldName = addConstantString(node, operator); |
| 2800 // TODO(karlklose): use [:null:] for [asField] if [element] does not | 2854 // TODO(karlklose): use [:null:] for [asField] if [element] does not |
| 2801 // have a subclass. | 2855 // have a subclass. |
| 2802 HInstruction asFieldName = | 2856 HInstruction asFieldName = |
| 2803 addConstantString(node, backend.namer.substitutionName(element)); | 2857 addConstantString(node, backend.namer.substitutionName(element)); |
| 2804 List<HInstruction> inputs = <HInstruction>[helperCall, | 2858 List<HInstruction> inputs = <HInstruction>[helperCall, |
| 2805 expression, | 2859 expression, |
| 2806 isFieldName, | 2860 isFieldName, |
| 2807 representations, | 2861 representations, |
| 2808 asFieldName]; | 2862 asFieldName]; |
| 2809 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); | 2863 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); |
| 2810 add(call); | 2864 add(call); |
| 2811 instruction = new HIs(type, <HInstruction>[expression, call], | 2865 return |
| 2812 HIs.COMPOUND_CHECK); | 2866 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK); |
| 2813 } else { | 2867 } else { |
| 2814 instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); | 2868 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); |
| 2815 } | 2869 } |
| 2816 if (isNot) { | |
| 2817 add(instruction); | |
| 2818 instruction = new HNot(instruction); | |
| 2819 } | |
| 2820 push(instruction); | |
| 2821 } | 2870 } |
| 2822 | 2871 |
| 2823 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { | 2872 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { |
| 2824 Selector selector = elements.getSelector(node); | 2873 Selector selector = elements.getSelector(node); |
| 2825 if (selector.namedArgumentCount == 0) { | 2874 if (selector.namedArgumentCount == 0) { |
| 2826 addGenericSendArgumentsToList(node.arguments, list); | 2875 addGenericSendArgumentsToList(node.arguments, list); |
| 2827 } else { | 2876 } else { |
| 2828 // Visit positional arguments and add them to the list. | 2877 // Visit positional arguments and add them to the list. |
| 2829 Link<Node> arguments = node.arguments; | 2878 Link<Node> arguments = node.arguments; |
| 2830 int positionalArgumentCount = selector.positionalArgumentCount; | 2879 int positionalArgumentCount = selector.positionalArgumentCount; |
| (...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4712 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 4761 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 4713 // "if" condition above and this "else" branch should be deleted as | 4762 // "if" condition above and this "else" branch should be deleted as |
| 4714 // type of declared variable won't matter for the catch | 4763 // type of declared variable won't matter for the catch |
| 4715 // condition. | 4764 // condition. |
| 4716 DartType type = elements.getType(declaration.type); | 4765 DartType type = elements.getType(declaration.type); |
| 4717 if (type == null) { | 4766 if (type == null) { |
| 4718 compiler.cancel('Catch with unresolved type', node: catchBlock); | 4767 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 4719 } | 4768 } |
| 4720 // TODO(karlkose): support type arguments here. | 4769 // TODO(karlkose): support type arguments here. |
| 4721 condition = new HIs(type, <HInstruction>[unwrappedException], | 4770 condition = new HIs(type, <HInstruction>[unwrappedException], |
| 4722 HIs.RAW_CHECK, nullOk: true); | 4771 HIs.RAW_CHECK); |
| 4723 push(condition); | 4772 push(condition); |
| 4724 } | 4773 } |
| 4725 } | 4774 } |
| 4726 } | 4775 } |
| 4727 | 4776 |
| 4728 void visitThen() { | 4777 void visitThen() { |
| 4729 CatchBlock catchBlock = link.head; | 4778 CatchBlock catchBlock = link.head; |
| 4730 link = link.tail; | 4779 link = link.tail; |
| 4731 | 4780 |
| 4732 if (compiler.enableTypeAssertions) { | 4781 if (compiler.enableTypeAssertions) { |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5280 new HSubGraphBlockInformation(elseBranch.graph)); | 5329 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5281 | 5330 |
| 5282 HBasicBlock conditionStartBlock = conditionBranch.block; | 5331 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5283 conditionStartBlock.setBlockFlow(info, joinBlock); | 5332 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5284 SubGraph conditionGraph = conditionBranch.graph; | 5333 SubGraph conditionGraph = conditionBranch.graph; |
| 5285 HIf branch = conditionGraph.end.last; | 5334 HIf branch = conditionGraph.end.last; |
| 5286 assert(branch is HIf); | 5335 assert(branch is HIf); |
| 5287 branch.blockInformation = conditionStartBlock.blockFlow; | 5336 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5288 } | 5337 } |
| 5289 } | 5338 } |
| OLD | NEW |