Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

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

Powered by Google App Engine
This is Rietveld 408576698