| 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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 } | 354 } |
| 355 | 355 |
| 356 /** | 356 /** |
| 357 * Returns an [HInstruction] for the given element. If the element is | 357 * Returns an [HInstruction] for the given element. If the element is |
| 358 * boxed or stored in a closure then the method generates code to retrieve | 358 * boxed or stored in a closure then the method generates code to retrieve |
| 359 * the value. | 359 * the value. |
| 360 */ | 360 */ |
| 361 HInstruction readLocal(Element element) { | 361 HInstruction readLocal(Element element) { |
| 362 if (isAccessedDirectly(element)) { | 362 if (isAccessedDirectly(element)) { |
| 363 if (directLocals[element] == null) { | 363 if (directLocals[element] == null) { |
| 364 if (element.isTypeVariable()) { | 364 builder.compiler.internalError("Cannot find value $element", |
| 365 builder.compiler.internalError( | 365 element: element); |
| 366 "Runtime type information not available for $element", | |
| 367 element: builder.compiler.currentElement); | |
| 368 } else { | |
| 369 builder.compiler.internalError( | |
| 370 "Cannot find value $element", | |
| 371 element: element); | |
| 372 } | |
| 373 } | 366 } |
| 374 return directLocals[element]; | 367 return directLocals[element]; |
| 375 } else if (isStoredInClosureField(element)) { | 368 } else if (isStoredInClosureField(element)) { |
| 376 Element redirect = redirectionMapping[element]; | 369 Element redirect = redirectionMapping[element]; |
| 377 HInstruction receiver = readLocal(closureData.closureElement); | 370 HInstruction receiver = readLocal(closureData.closureElement); |
| 378 HInstruction fieldGet = new HFieldGet(redirect, receiver); | 371 HInstruction fieldGet = new HFieldGet(redirect, receiver); |
| 379 fieldGet.instructionType = builder.getTypeOfCapturedVariable(element); | 372 fieldGet.instructionType = builder.getTypeOfCapturedVariable(element); |
| 380 builder.add(fieldGet); | 373 builder.add(fieldGet); |
| 381 return fieldGet; | 374 return fieldGet; |
| 382 } else if (isBoxed(element)) { | 375 } else if (isBoxed(element)) { |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 LocalsHandler newLocalsHandler = new LocalsHandler.from(localsHandler); | 1174 LocalsHandler newLocalsHandler = new LocalsHandler.from(localsHandler); |
| 1182 newLocalsHandler.closureData = | 1175 newLocalsHandler.closureData = |
| 1183 compiler.closureToClassMapper.computeClosureToClassMapping( | 1176 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1184 function, function.parseNode(compiler), elements); | 1177 function, function.parseNode(compiler), elements); |
| 1185 int argumentIndex = 0; | 1178 int argumentIndex = 0; |
| 1186 if (isInstanceMember) { | 1179 if (isInstanceMember) { |
| 1187 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, | 1180 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, |
| 1188 compiledArguments[argumentIndex++]); | 1181 compiledArguments[argumentIndex++]); |
| 1189 } | 1182 } |
| 1190 | 1183 |
| 1184 FunctionSignature signature = function.computeSignature(compiler); |
| 1185 signature.orderedForEachParameter((Element parameter) { |
| 1186 HInstruction argument = compiledArguments[argumentIndex++]; |
| 1187 newLocalsHandler.updateLocal(parameter, argument); |
| 1188 potentiallyCheckType(argument, parameter.computeType(compiler)); |
| 1189 }); |
| 1190 |
| 1191 if (function.isConstructor()) { | 1191 if (function.isConstructor()) { |
| 1192 ClassElement enclosing = function.getEnclosingClass(); | 1192 ClassElement enclosing = function.getEnclosingClass(); |
| 1193 if (backend.needsRti(enclosing)) { | 1193 if (backend.needsRti(enclosing)) { |
| 1194 assert(currentNode is NewExpression); | 1194 assert(currentNode is NewExpression); |
| 1195 InterfaceType type = elements.getType(currentNode); | 1195 InterfaceType type = elements.getType(currentNode); |
| 1196 Link<DartType> typeVariable = enclosing.typeVariables; | 1196 Link<DartType> typeVariable = enclosing.typeVariables; |
| 1197 type.typeArguments.forEach((DartType argument) { | 1197 type.typeArguments.forEach((DartType argument) { |
| 1198 HInstruction instruction = | 1198 HInstruction instruction = |
| 1199 analyzeTypeArgument(argument, currentNode); | 1199 analyzeTypeArgument(argument, currentNode); |
| 1200 newLocalsHandler.updateLocal(typeVariable.head.element, instruction); | 1200 newLocalsHandler.updateLocal(typeVariable.head.element, instruction); |
| 1201 typeVariable = typeVariable.tail; | 1201 typeVariable = typeVariable.tail; |
| 1202 }); | 1202 }); |
| 1203 while (!typeVariable.isEmpty) { | 1203 while (!typeVariable.isEmpty) { |
| 1204 newLocalsHandler.updateLocal(typeVariable.head.element, | 1204 newLocalsHandler.updateLocal(typeVariable.head.element, |
| 1205 graph.addConstantNull(constantSystem)); | 1205 graph.addConstantNull(constantSystem)); |
| 1206 typeVariable = typeVariable.tail; | 1206 typeVariable = typeVariable.tail; |
| 1207 } | 1207 } |
| 1208 } | 1208 } |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 // Check the type of the arguments. This must be done after setting up the | |
| 1212 // type variables in the [localsHandler] because the checked types may | |
| 1213 // contain type variables. | |
| 1214 FunctionSignature signature = function.computeSignature(compiler); | |
| 1215 signature.orderedForEachParameter((Element parameter) { | |
| 1216 HInstruction argument = compiledArguments[argumentIndex++]; | |
| 1217 newLocalsHandler.updateLocal(parameter, argument); | |
| 1218 potentiallyCheckType(argument, parameter.computeType(compiler)); | |
| 1219 }); | |
| 1220 | |
| 1221 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 1211 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
| 1222 returnElement = new ElementX(const SourceString("result"), | 1212 returnElement = new ElementX(const SourceString("result"), |
| 1223 ElementKind.VARIABLE, | 1213 ElementKind.VARIABLE, |
| 1224 function); | 1214 function); |
| 1225 newLocalsHandler.updateLocal(returnElement, | 1215 newLocalsHandler.updateLocal(returnElement, |
| 1226 graph.addConstantNull(constantSystem)); | 1216 graph.addConstantNull(constantSystem)); |
| 1227 elements = compiler.enqueuer.resolution.getCachedElements(function); | 1217 elements = compiler.enqueuer.resolution.getCachedElements(function); |
| 1228 assert(elements != null); | 1218 assert(elements != null); |
| 1229 returnType = signature.returnType; | 1219 returnType = signature.returnType; |
| 1230 stack = <HInstruction>[]; | 1220 stack = <HInstruction>[]; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 if (newElements == null) { | 1292 if (newElements == null) { |
| 1303 compiler.internalError("Element not resolved: $function"); | 1293 compiler.internalError("Element not resolved: $function"); |
| 1304 } | 1294 } |
| 1305 | 1295 |
| 1306 if (canBeInlined == null) { | 1296 if (canBeInlined == null) { |
| 1307 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); | 1297 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); |
| 1308 backend.canBeInlined[function] = canBeInlined; | 1298 backend.canBeInlined[function] = canBeInlined; |
| 1309 if (!canBeInlined) return false; | 1299 if (!canBeInlined) return false; |
| 1310 } | 1300 } |
| 1311 | 1301 |
| 1312 // We cannot inline methods with type variables in the signature in checked | |
| 1313 // mode, because we currently do not have access to the type variables | |
| 1314 // through the locals. | |
| 1315 // TODO(karlklose): remove this and enable inlining of these methods. | |
| 1316 if (compiler.enableTypeAssertions && | |
| 1317 element.computeType(compiler).containsTypeVariables) { | |
| 1318 return false; | |
| 1319 } | |
| 1320 | |
| 1321 assert(canBeInlined); | 1302 assert(canBeInlined); |
| 1322 InliningState state = enterInlinedMethod( | 1303 InliningState state = enterInlinedMethod( |
| 1323 function, selector, argumentsNodes, providedArguments, currentNode); | 1304 function, selector, argumentsNodes, providedArguments, currentNode); |
| 1324 // Add an explicit null check on the receiver. We use [element] | 1305 // Add an explicit null check on the receiver. We use [element] |
| 1325 // to get the same name in the NoSuchMethodError message as if we had | 1306 // to get the same name in the NoSuchMethodError message as if we had |
| 1326 // called it. | 1307 // called it. |
| 1327 if (element.isInstanceMember() | 1308 if (element.isInstanceMember() |
| 1328 && (selector.mask == null || selector.mask.isNullable)) { | 1309 && (selector.mask == null || selector.mask.isNullable)) { |
| 1329 addWithPosition( | 1310 addWithPosition( |
| 1330 new HFieldGet(element, providedArguments[0]), currentNode); | 1311 new HFieldGet(element, providedArguments[0]), currentNode); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1773 void openFunction(Element element, Expression node) { | 1754 void openFunction(Element element, Expression node) { |
| 1774 assert(invariant(element, element.isImplementation)); | 1755 assert(invariant(element, element.isImplementation)); |
| 1775 HBasicBlock block = graph.addNewBlock(); | 1756 HBasicBlock block = graph.addNewBlock(); |
| 1776 open(graph.entry); | 1757 open(graph.entry); |
| 1777 | 1758 |
| 1778 localsHandler.startFunction(element, node); | 1759 localsHandler.startFunction(element, node); |
| 1779 close(new HGoto()).addSuccessor(block); | 1760 close(new HGoto()).addSuccessor(block); |
| 1780 | 1761 |
| 1781 open(block); | 1762 open(block); |
| 1782 | 1763 |
| 1783 // Add the type parameters of the class as parameters of this method. This | |
| 1784 // must be done before adding the normal parameters, because their types | |
| 1785 // may contain references to type variables. | |
| 1786 var enclosing = element.enclosingElement; | |
| 1787 if ((element.isConstructor() || element.isGenerativeConstructorBody()) | |
| 1788 && backend.needsRti(enclosing)) { | |
| 1789 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { | |
| 1790 HParameterValue param = addParameter(typeVariable.element); | |
| 1791 localsHandler.directLocals[typeVariable.element] = param; | |
| 1792 }); | |
| 1793 } | |
| 1794 | |
| 1795 if (element is FunctionElement) { | 1764 if (element is FunctionElement) { |
| 1796 FunctionElement functionElement = element; | 1765 FunctionElement functionElement = element; |
| 1797 FunctionSignature signature = functionElement.computeSignature(compiler); | 1766 FunctionSignature signature = functionElement.computeSignature(compiler); |
| 1798 signature.orderedForEachParameter((Element parameterElement) { | 1767 signature.orderedForEachParameter((Element parameterElement) { |
| 1799 if (elements.isParameterChecked(parameterElement)) { | 1768 if (elements.isParameterChecked(parameterElement)) { |
| 1800 addParameterCheckInstruction(parameterElement); | 1769 addParameterCheckInstruction(parameterElement); |
| 1801 } | 1770 } |
| 1802 }); | 1771 }); |
| 1803 | 1772 |
| 1804 // Put the type checks in the first successor of the entry, | 1773 // Put the type checks in the first successor of the entry, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1821 localsHandler.directLocals[parameterElement], | 1790 localsHandler.directLocals[parameterElement], |
| 1822 parameterElement.computeType(compiler)); | 1791 parameterElement.computeType(compiler)); |
| 1823 localsHandler.directLocals[parameterElement] = newParameter; | 1792 localsHandler.directLocals[parameterElement] = newParameter; |
| 1824 }); | 1793 }); |
| 1825 | 1794 |
| 1826 returnType = signature.returnType; | 1795 returnType = signature.returnType; |
| 1827 } else { | 1796 } else { |
| 1828 // Otherwise it is a lazy initializer which does not have parameters. | 1797 // Otherwise it is a lazy initializer which does not have parameters. |
| 1829 assert(element is VariableElement); | 1798 assert(element is VariableElement); |
| 1830 } | 1799 } |
| 1831 } | |
| 1832 | 1800 |
| 1833 HInstruction buildTypeConversion(Compiler compiler, HInstruction original, | 1801 // Add the type parameters of the class as parameters of this |
| 1834 DartType type, int kind) { | 1802 // method. |
| 1835 if (type == null) return original; | 1803 var enclosing = element.enclosingElement; |
| 1836 if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) { | 1804 if ((element.isConstructor() || element.isGenerativeConstructorBody()) |
| 1837 HType subtype = new HType.subtype(type, compiler); | 1805 && backend.needsRti(enclosing)) { |
| 1838 if (type.isRaw) { | 1806 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1839 return new HTypeConversion(type, kind, subtype, original); | 1807 HParameterValue param = addParameter(typeVariable.element); |
| 1840 } | 1808 localsHandler.directLocals[typeVariable.element] = param; |
| 1841 HInstruction representations = buildTypeArgumentRepresentations(type); | 1809 }); |
| 1842 add(representations); | |
| 1843 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | |
| 1844 original, representations); | |
| 1845 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | |
| 1846 HType subtype = original.instructionType; | |
| 1847 HInstruction typeVariable = addTypeVariableReference(type); | |
| 1848 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | |
| 1849 original, typeVariable); | |
| 1850 } else { | |
| 1851 return original.convertType(compiler, type, kind); | |
| 1852 } | 1810 } |
| 1853 } | 1811 } |
| 1854 | 1812 |
| 1855 HInstruction potentiallyCheckType(HInstruction original, DartType type, | 1813 HInstruction potentiallyCheckType( |
| 1814 HInstruction original, DartType type, |
| 1856 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { | 1815 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
| 1857 if (!compiler.enableTypeAssertions) return original; | 1816 if (!compiler.enableTypeAssertions) return original; |
| 1858 HInstruction other = | 1817 HInstruction other = original.convertType(compiler, type, kind); |
| 1859 buildTypeConversion(compiler, original, type, kind); | |
| 1860 if (other != original) add(other); | 1818 if (other != original) add(other); |
| 1861 return other; | 1819 return other; |
| 1862 } | 1820 } |
| 1863 | 1821 |
| 1864 HGraph closeFunction() { | 1822 HGraph closeFunction() { |
| 1865 // TODO(kasperl): Make this goto an implicit return. | 1823 // TODO(kasperl): Make this goto an implicit return. |
| 1866 if (!isAborted()) closeAndGotoExit(new HGoto()); | 1824 if (!isAborted()) closeAndGotoExit(new HGoto()); |
| 1867 graph.finalize(); | 1825 graph.finalize(); |
| 1868 return graph; | 1826 return graph; |
| 1869 } | 1827 } |
| (...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2705 assert(send == null || !Elements.isInstanceSend(send, elements)); | 2663 assert(send == null || !Elements.isInstanceSend(send, elements)); |
| 2706 if (location == null) { | 2664 if (location == null) { |
| 2707 assert(send != null); | 2665 assert(send != null); |
| 2708 location = send; | 2666 location = send; |
| 2709 } | 2667 } |
| 2710 if (Elements.isStaticOrTopLevelField(element)) { | 2668 if (Elements.isStaticOrTopLevelField(element)) { |
| 2711 if (element.isSetter()) { | 2669 if (element.isSetter()) { |
| 2712 pushInvokeStatic(location, element, <HInstruction>[value]); | 2670 pushInvokeStatic(location, element, <HInstruction>[value]); |
| 2713 pop(); | 2671 pop(); |
| 2714 } else { | 2672 } else { |
| 2715 value = | 2673 value = potentiallyCheckType(value, element.computeType(compiler)); |
| 2716 potentiallyCheckType(value, element.computeType(compiler)); | |
| 2717 addWithPosition(new HStaticStore(element, value), location); | 2674 addWithPosition(new HStaticStore(element, value), location); |
| 2718 } | 2675 } |
| 2719 stack.add(value); | 2676 stack.add(value); |
| 2720 } else if (Elements.isErroneousElement(element)) { | 2677 } else if (Elements.isErroneousElement(element)) { |
| 2721 // An erroneous element indicates an unresolved static setter. | 2678 // An erroneous element indicates an unresolved static setter. |
| 2722 generateThrowNoSuchMethod( | 2679 generateThrowNoSuchMethod( |
| 2723 location, | 2680 location, |
| 2724 getTargetName(element, 'set'), | 2681 getTargetName(element, 'set'), |
| 2725 argumentNodes: (send == null ? const Link<Node>() : send.arguments)); | 2682 argumentNodes: (send == null ? const Link<Node>() : send.arguments)); |
| 2726 } else { | 2683 } else { |
| 2727 stack.add(value); | 2684 stack.add(value); |
| 2728 // If the value does not already have a name, give it here. | 2685 // If the value does not already have a name, give it here. |
| 2729 if (value.sourceElement == null) { | 2686 if (value.sourceElement == null) { |
| 2730 value.sourceElement = element; | 2687 value.sourceElement = element; |
| 2731 } | 2688 } |
| 2732 HInstruction checked = | 2689 HInstruction checked = potentiallyCheckType( |
| 2733 potentiallyCheckType(value, element.computeType(compiler)); | 2690 value, element.computeType(compiler)); |
| 2734 if (!identical(checked, value)) { | 2691 if (!identical(checked, value)) { |
| 2735 pop(); | 2692 pop(); |
| 2736 stack.add(checked); | 2693 stack.add(checked); |
| 2737 } | 2694 } |
| 2738 localsHandler.updateLocal(element, checked); | 2695 localsHandler.updateLocal(element, checked); |
| 2739 } | 2696 } |
| 2740 } | 2697 } |
| 2741 | 2698 |
| 2742 HInstruction invokeInterceptor(Set<ClassElement> intercepted, | 2699 HInstruction invokeInterceptor(Set<ClassElement> intercepted, |
| 2743 HInstruction receiver) { | 2700 HInstruction receiver) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2828 isNot = true; | 2785 isNot = true; |
| 2829 } | 2786 } |
| 2830 DartType type = elements.getType(typeAnnotation); | 2787 DartType type = elements.getType(typeAnnotation); |
| 2831 if (type.isMalformed) { | 2788 if (type.isMalformed) { |
| 2832 String reasons = Types.fetchReasonsFromMalformedType(type); | 2789 String reasons = Types.fetchReasonsFromMalformedType(type); |
| 2833 if (compiler.enableTypeAssertions) { | 2790 if (compiler.enableTypeAssertions) { |
| 2834 generateMalformedSubtypeError(node, expression, type, reasons); | 2791 generateMalformedSubtypeError(node, expression, type, reasons); |
| 2835 } else { | 2792 } else { |
| 2836 generateRuntimeError(node, '$type is malformed: $reasons'); | 2793 generateRuntimeError(node, '$type is malformed: $reasons'); |
| 2837 } | 2794 } |
| 2838 } else { | 2795 return; |
| 2839 HInstruction instruction = buildIsNode(node, type, expression); | |
| 2840 if (isNot) { | |
| 2841 add(instruction); | |
| 2842 instruction = new HNot(instruction); | |
| 2843 } | |
| 2844 push(instruction); | |
| 2845 } | 2796 } |
| 2846 } | |
| 2847 | 2797 |
| 2848 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { | 2798 HInstruction instruction; |
| 2849 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2799 if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 2850 HInstruction runtimeType = addTypeVariableReference(type); | 2800 HInstruction runtimeType = addTypeVariableReference(type); |
| 2851 Element helper = backend.getCheckSubtypeOfRuntimeType(); | 2801 Element helper = backend.getGetObjectIsSubtype(); |
| 2852 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 2802 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
| 2853 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); | 2803 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); |
| 2854 HInstruction call = pop(); | 2804 HInstruction call = pop(); |
| 2855 return new HIs(type, <HInstruction>[expression, call], | 2805 instruction = new HIs(type, <HInstruction>[expression, call], |
| 2856 HIs.VARIABLE_CHECK); | 2806 HIs.VARIABLE_CHECK); |
| 2857 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2807 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 2858 Element element = type.element; | 2808 Element element = type.element; |
| 2859 Element helper = backend.getCheckSubtype(); | 2809 Element helper = backend.getCheckSubtype(); |
| 2860 HInstruction representations = | 2810 HInstruction representations = |
| 2861 buildTypeArgumentRepresentations(type); | 2811 buildTypeArgumentRepresentations(type); |
| 2862 add(representations); | 2812 add(representations); |
| 2863 String operator = | 2813 String operator = |
| 2864 backend.namer.operatorIs(backend.getImplementationClass(element)); | 2814 backend.namer.operatorIs(backend.getImplementationClass(element)); |
| 2865 HInstruction isFieldName = addConstantString(node, operator); | 2815 HInstruction isFieldName = addConstantString(node, operator); |
| 2866 // TODO(karlklose): use [:null:] for [asField] if [element] does not | 2816 // TODO(karlklose): use [:null:] for [asField] if [element] does not |
| 2867 // have a subclass. | 2817 // have a subclass. |
| 2868 HInstruction asFieldName = | 2818 HInstruction asFieldName = |
| 2869 addConstantString(node, backend.namer.substitutionName(element)); | 2819 addConstantString(node, backend.namer.substitutionName(element)); |
| 2870 List<HInstruction> inputs = <HInstruction>[expression, | 2820 List<HInstruction> inputs = <HInstruction>[expression, |
| 2871 isFieldName, | 2821 isFieldName, |
| 2872 representations, | 2822 representations, |
| 2873 asFieldName]; | 2823 asFieldName]; |
| 2874 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); | 2824 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); |
| 2875 HInstruction call = pop(); | 2825 HInstruction call = pop(); |
| 2876 return | 2826 instruction = new HIs(type, <HInstruction>[expression, call], |
| 2877 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK); | 2827 HIs.COMPOUND_CHECK); |
| 2878 } else { | 2828 } else { |
| 2879 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); | 2829 instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); |
| 2880 } | 2830 } |
| 2831 if (isNot) { |
| 2832 add(instruction); |
| 2833 instruction = new HNot(instruction); |
| 2834 } |
| 2835 push(instruction); |
| 2881 } | 2836 } |
| 2882 | 2837 |
| 2883 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { | 2838 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { |
| 2884 Selector selector = elements.getSelector(node); | 2839 Selector selector = elements.getSelector(node); |
| 2885 if (selector.namedArgumentCount == 0) { | 2840 if (selector.namedArgumentCount == 0) { |
| 2886 addGenericSendArgumentsToList(node.arguments, list); | 2841 addGenericSendArgumentsToList(node.arguments, list); |
| 2887 } else { | 2842 } else { |
| 2888 // Visit positional arguments and add them to the list. | 2843 // Visit positional arguments and add them to the list. |
| 2889 Link<Node> arguments = node.arguments; | 2844 Link<Node> arguments = node.arguments; |
| 2890 int positionalArgumentCount = selector.positionalArgumentCount; | 2845 int positionalArgumentCount = selector.positionalArgumentCount; |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3285 graph.addConstantInt(index, constantSystem)], | 3240 graph.addConstantInt(index, constantSystem)], |
| 3286 HType.UNKNOWN); | 3241 HType.UNKNOWN); |
| 3287 return pop(); | 3242 return pop(); |
| 3288 } | 3243 } |
| 3289 | 3244 |
| 3290 /** | 3245 /** |
| 3291 * Helper to create an instruction that gets the value of a type variable. | 3246 * Helper to create an instruction that gets the value of a type variable. |
| 3292 */ | 3247 */ |
| 3293 HInstruction addTypeVariableReference(TypeVariableType type) { | 3248 HInstruction addTypeVariableReference(TypeVariableType type) { |
| 3294 Element member = currentElement; | 3249 Element member = currentElement; |
| 3295 bool isClosure = member.enclosingElement.isClosure(); | 3250 if (member.enclosingElement.isClosure()) { |
| 3296 if (isClosure) { | |
| 3297 ClosureClassElement closureClass = member.enclosingElement; | 3251 ClosureClassElement closureClass = member.enclosingElement; |
| 3298 member = closureClass.methodElement; | 3252 member = closureClass.methodElement; |
| 3299 member = member.getOutermostEnclosingMemberOrTopLevel(); | 3253 member = member.getOutermostEnclosingMemberOrTopLevel(); |
| 3300 } | 3254 } |
| 3301 if (isClosure && member.isFactoryConstructor()) { | 3255 if (member.isConstructor() |
| 3302 // The type variable is used from a closure in a factory constructor. The | 3256 || member.isGenerativeConstructorBody() |
| 3303 // value of the type argument is stored as a local on the closure itself. | 3257 || member.isField()) { |
| 3304 return localsHandler.readLocal(type.element); | |
| 3305 } else if (member.isConstructor() || | |
| 3306 member.isGenerativeConstructorBody() || | |
| 3307 member.isField()) { | |
| 3308 // The type variable is stored in a parameter of the method. | 3258 // The type variable is stored in a parameter of the method. |
| 3309 return localsHandler.readLocal(type.element); | 3259 return localsHandler.readLocal(type.element); |
| 3310 } else if (member.isInstanceMember()) { | 3260 } else if (member.isInstanceMember()) { |
| 3311 // The type variable is stored on the object. | 3261 // The type variable is stored on the object. |
| 3312 return readTypeVariable(member.getEnclosingClass(), | 3262 return readTypeVariable(member.getEnclosingClass(), |
| 3313 type.element); | 3263 type.element); |
| 3314 } else { | 3264 } else { |
| 3315 // TODO(ngeoffray): Match the VM behavior and throw an | 3265 // TODO(ngeoffray): Match the VM behavior and throw an |
| 3316 // exception at runtime. | 3266 // exception at runtime. |
| 3317 compiler.cancel('Unimplemented unresolved type variable', | 3267 compiler.cancel('Unimplemented unresolved type variable', |
| (...skipping 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4858 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 4808 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 4859 // "if" condition above and this "else" branch should be deleted as | 4809 // "if" condition above and this "else" branch should be deleted as |
| 4860 // type of declared variable won't matter for the catch | 4810 // type of declared variable won't matter for the catch |
| 4861 // condition. | 4811 // condition. |
| 4862 DartType type = elements.getType(declaration.type); | 4812 DartType type = elements.getType(declaration.type); |
| 4863 if (type == null) { | 4813 if (type == null) { |
| 4864 compiler.cancel('Catch with unresolved type', node: catchBlock); | 4814 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 4865 } | 4815 } |
| 4866 // TODO(karlkose): support type arguments here. | 4816 // TODO(karlkose): support type arguments here. |
| 4867 condition = new HIs(type, <HInstruction>[unwrappedException], | 4817 condition = new HIs(type, <HInstruction>[unwrappedException], |
| 4868 HIs.RAW_CHECK); | 4818 HIs.RAW_CHECK, nullOk: true); |
| 4869 push(condition); | 4819 push(condition); |
| 4870 } | 4820 } |
| 4871 } | 4821 } |
| 4872 } | 4822 } |
| 4873 | 4823 |
| 4874 void visitThen() { | 4824 void visitThen() { |
| 4875 CatchBlock catchBlock = link.head; | 4825 CatchBlock catchBlock = link.head; |
| 4876 link = link.tail; | 4826 link = link.tail; |
| 4877 | 4827 |
| 4878 if (compiler.enableTypeAssertions) { | 4828 if (compiler.enableTypeAssertions) { |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5425 new HSubGraphBlockInformation(elseBranch.graph)); | 5375 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5426 | 5376 |
| 5427 HBasicBlock conditionStartBlock = conditionBranch.block; | 5377 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5428 conditionStartBlock.setBlockFlow(info, joinBlock); | 5378 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5429 SubGraph conditionGraph = conditionBranch.graph; | 5379 SubGraph conditionGraph = conditionBranch.graph; |
| 5430 HIf branch = conditionGraph.end.last; | 5380 HIf branch = conditionGraph.end.last; |
| 5431 assert(branch is HIf); | 5381 assert(branch is HIf); |
| 5432 branch.blockInformation = conditionStartBlock.blockFlow; | 5382 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5433 } | 5383 } |
| 5434 } | 5384 } |
| OLD | NEW |