| 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 | 8 |
| 9 import '../closure.dart'; | 9 import '../closure.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 }, | 736 }, |
| 737 visitElse: null, | 737 visitElse: null, |
| 738 sourceInformation: sourceInformationBuilder.buildIf(function.body)); | 738 sourceInformation: sourceInformationBuilder.buildIf(function.body)); |
| 739 } | 739 } |
| 740 } | 740 } |
| 741 if (const bool.fromEnvironment('unreachable-throw')) { | 741 if (const bool.fromEnvironment('unreachable-throw')) { |
| 742 var emptyParameters = | 742 var emptyParameters = |
| 743 parameters.values.where((p) => p.instructionType.isEmpty); | 743 parameters.values.where((p) => p.instructionType.isEmpty); |
| 744 if (emptyParameters.length > 0) { | 744 if (emptyParameters.length > 0) { |
| 745 addComment('${emptyParameters} inferred as [empty]'); | 745 addComment('${emptyParameters} inferred as [empty]'); |
| 746 pushInvokeStatic(function.body, helpers.assertUnreachableMethod, []); | 746 pushInvokeStatic(helpers.assertUnreachableMethod, [], |
| 747 location: function.body); |
| 747 pop(); | 748 pop(); |
| 748 return closeFunction(); | 749 return closeFunction(); |
| 749 } | 750 } |
| 750 } | 751 } |
| 751 function.body.accept(this); | 752 function.body.accept(this); |
| 752 return closeFunction(); | 753 return closeFunction(); |
| 753 } | 754 } |
| 754 | 755 |
| 755 /// Adds a JavaScript comment to the output. The comment will be omitted in | 756 /// Adds a JavaScript comment to the output. The comment will be omitted in |
| 756 /// minified mode. Each line in [text] is preceded with `//` and indented. | 757 /// minified mode. Each line in [text] is preceded with `//` and indented. |
| (...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 | 1598 |
| 1598 visitAssert(ast.Assert node) { | 1599 visitAssert(ast.Assert node) { |
| 1599 if (!compiler.options.enableUserAssertions) return; | 1600 if (!compiler.options.enableUserAssertions) return; |
| 1600 | 1601 |
| 1601 if (!node.hasMessage) { | 1602 if (!node.hasMessage) { |
| 1602 // Generate: | 1603 // Generate: |
| 1603 // | 1604 // |
| 1604 // assertHelper(condition); | 1605 // assertHelper(condition); |
| 1605 // | 1606 // |
| 1606 visit(node.condition); | 1607 visit(node.condition); |
| 1607 pushInvokeStatic(node, helpers.assertHelper, [pop()]); | 1608 pushInvokeStatic(helpers.assertHelper, [pop()], location: node); |
| 1608 pop(); | 1609 pop(); |
| 1609 return; | 1610 return; |
| 1610 } | 1611 } |
| 1611 // Assert has message. Generate: | 1612 // Assert has message. Generate: |
| 1612 // | 1613 // |
| 1613 // if (assertTest(condition)) assertThrow(message); | 1614 // if (assertTest(condition)) assertThrow(message); |
| 1614 // | 1615 // |
| 1615 void buildCondition() { | 1616 void buildCondition() { |
| 1616 visit(node.condition); | 1617 visit(node.condition); |
| 1617 pushInvokeStatic(node, helpers.assertTest, [pop()]); | 1618 pushInvokeStatic(helpers.assertTest, [pop()], location: node); |
| 1618 } | 1619 } |
| 1619 | 1620 |
| 1620 void fail() { | 1621 void fail() { |
| 1621 visit(node.message); | 1622 visit(node.message); |
| 1622 pushInvokeStatic(node, helpers.assertThrow, [pop()]); | 1623 pushInvokeStatic(helpers.assertThrow, [pop()], location: node); |
| 1623 pop(); | 1624 pop(); |
| 1624 } | 1625 } |
| 1625 | 1626 |
| 1626 handleIf(node: node, visitCondition: buildCondition, visitThen: fail); | 1627 handleIf(node: node, visitCondition: buildCondition, visitThen: fail); |
| 1627 } | 1628 } |
| 1628 | 1629 |
| 1629 visitBlock(ast.Block node) { | 1630 visitBlock(ast.Block node) { |
| 1630 assert(!isAborted()); | 1631 assert(!isAborted()); |
| 1631 if (!isReachable) return; // This can only happen when inlining. | 1632 if (!isReachable) return; // This can only happen when inlining. |
| 1632 for (Link<ast.Node> link = node.statements.nodes; | 1633 for (Link<ast.Node> link = node.statements.nodes; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2090 /// If [prefixElement] is [null] ndo nothing. | 2091 /// If [prefixElement] is [null] ndo nothing. |
| 2091 void generateIsDeferredLoadedCheckIfNeeded( | 2092 void generateIsDeferredLoadedCheckIfNeeded( |
| 2092 PrefixElement prefixElement, ast.Node location) { | 2093 PrefixElement prefixElement, ast.Node location) { |
| 2093 if (prefixElement == null) return; | 2094 if (prefixElement == null) return; |
| 2094 String loadId = | 2095 String loadId = |
| 2095 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); | 2096 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); |
| 2096 HInstruction loadIdConstant = addConstantString(loadId); | 2097 HInstruction loadIdConstant = addConstantString(loadId); |
| 2097 String uri = prefixElement.deferredImport.uri.toString(); | 2098 String uri = prefixElement.deferredImport.uri.toString(); |
| 2098 HInstruction uriConstant = addConstantString(uri); | 2099 HInstruction uriConstant = addConstantString(uri); |
| 2099 Element helper = helpers.checkDeferredIsLoaded; | 2100 Element helper = helpers.checkDeferredIsLoaded; |
| 2100 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); | 2101 pushInvokeStatic(helper, [loadIdConstant, uriConstant], location: location); |
| 2101 pop(); | 2102 pop(); |
| 2102 } | 2103 } |
| 2103 | 2104 |
| 2104 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that | 2105 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
| 2105 /// resolves to a deferred library. | 2106 /// resolves to a deferred library. |
| 2106 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { | 2107 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { |
| 2107 generateIsDeferredLoadedCheckIfNeeded( | 2108 generateIsDeferredLoadedCheckIfNeeded( |
| 2108 compiler.deferredLoadTask.deferredPrefixElement(node, elements), node); | 2109 compiler.deferredLoadTask.deferredPrefixElement(node, elements), node); |
| 2109 } | 2110 } |
| 2110 | 2111 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2191 } | 2192 } |
| 2192 } | 2193 } |
| 2193 | 2194 |
| 2194 /// Generate a getter invocation of the static or top level [getter]. | 2195 /// Generate a getter invocation of the static or top level [getter]. |
| 2195 void generateStaticGetterGet(ast.Send node, MethodElement getter) { | 2196 void generateStaticGetterGet(ast.Send node, MethodElement getter) { |
| 2196 SourceInformation sourceInformation = | 2197 SourceInformation sourceInformation = |
| 2197 sourceInformationBuilder.buildGet(node); | 2198 sourceInformationBuilder.buildGet(node); |
| 2198 if (getter.isDeferredLoaderGetter) { | 2199 if (getter.isDeferredLoaderGetter) { |
| 2199 generateDeferredLoaderGet(node, getter, sourceInformation); | 2200 generateDeferredLoaderGet(node, getter, sourceInformation); |
| 2200 } else { | 2201 } else { |
| 2201 pushInvokeStatic(node, getter, <HInstruction>[], | 2202 pushInvokeStatic(getter, <HInstruction>[], |
| 2202 sourceInformation: sourceInformation); | 2203 sourceInformation: sourceInformation, location: node); |
| 2203 } | 2204 } |
| 2204 } | 2205 } |
| 2205 | 2206 |
| 2206 /// Generate a dynamic getter invocation. | 2207 /// Generate a dynamic getter invocation. |
| 2207 void generateDynamicGet(ast.Send node) { | 2208 void generateDynamicGet(ast.Send node) { |
| 2208 HInstruction receiver = generateInstanceSendReceiver(node); | 2209 HInstruction receiver = generateInstanceSendReceiver(node); |
| 2209 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), | 2210 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), |
| 2210 elementInferenceResults.typeOfSend(node), receiver); | 2211 elementInferenceResults.typeOfSend(node), receiver); |
| 2211 } | 2212 } |
| 2212 | 2213 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2350 {ast.Node location}) { | 2351 {ast.Node location}) { |
| 2351 if (location == null) { | 2352 if (location == null) { |
| 2352 assert(send != null); | 2353 assert(send != null); |
| 2353 location = send; | 2354 location = send; |
| 2354 } | 2355 } |
| 2355 assert(invariant( | 2356 assert(invariant( |
| 2356 location, send == null || !Elements.isInstanceSend(send, elements), | 2357 location, send == null || !Elements.isInstanceSend(send, elements), |
| 2357 message: "Unexpected non instance setter: $element.")); | 2358 message: "Unexpected non instance setter: $element.")); |
| 2358 if (Elements.isStaticOrTopLevelField(element)) { | 2359 if (Elements.isStaticOrTopLevelField(element)) { |
| 2359 if (element.isSetter) { | 2360 if (element.isSetter) { |
| 2360 pushInvokeStatic(location, element, <HInstruction>[value]); | 2361 pushInvokeStatic(element, <HInstruction>[value], location: location); |
| 2361 pop(); | 2362 pop(); |
| 2362 } else { | 2363 } else { |
| 2363 FieldElement field = element; | 2364 FieldElement field = element; |
| 2364 value = typeBuilder.potentiallyCheckOrTrustType(value, field.type); | 2365 value = typeBuilder.potentiallyCheckOrTrustType(value, field.type); |
| 2365 addWithPosition(new HStaticStore(field, value), location); | 2366 addWithPosition(new HStaticStore(field, value), location); |
| 2366 } | 2367 } |
| 2367 stack.add(value); | 2368 stack.add(value); |
| 2368 } else if (Elements.isError(element)) { | 2369 } else if (Elements.isError(element)) { |
| 2369 generateNoSuchSetter(location, element, send == null ? null : value); | 2370 generateNoSuchSetter(location, element, send == null ? null : value); |
| 2370 } else if (Elements.isMalformed(element)) { | 2371 } else if (Elements.isMalformed(element)) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2458 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), | 2459 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), |
| 2459 CallStructure.ONE_ARG), | 2460 CallStructure.ONE_ARG), |
| 2460 null, | 2461 null, |
| 2461 arguments); | 2462 arguments); |
| 2462 return new HIs.compound(type, expression, pop(), backend.boolType); | 2463 return new HIs.compound(type, expression, pop(), backend.boolType); |
| 2463 } else if (type.isTypeVariable) { | 2464 } else if (type.isTypeVariable) { |
| 2464 HInstruction runtimeType = | 2465 HInstruction runtimeType = |
| 2465 typeBuilder.addTypeVariableReference(type, sourceElement); | 2466 typeBuilder.addTypeVariableReference(type, sourceElement); |
| 2466 Element helper = helpers.checkSubtypeOfRuntimeType; | 2467 Element helper = helpers.checkSubtypeOfRuntimeType; |
| 2467 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 2468 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
| 2468 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); | 2469 pushInvokeStatic(helper, inputs, typeMask: backend.boolType); |
| 2469 HInstruction call = pop(); | 2470 HInstruction call = pop(); |
| 2470 return new HIs.variable(type, expression, call, backend.boolType); | 2471 return new HIs.variable(type, expression, call, backend.boolType); |
| 2471 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2472 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 2472 ClassElement element = type.element; | 2473 ClassElement element = type.element; |
| 2473 Element helper = helpers.checkSubtype; | 2474 Element helper = helpers.checkSubtype; |
| 2474 HInstruction representations = | 2475 HInstruction representations = |
| 2475 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); | 2476 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); |
| 2476 add(representations); | 2477 add(representations); |
| 2477 js.Name operator = backend.namer.operatorIs(element); | 2478 js.Name operator = backend.namer.operatorIs(element); |
| 2478 HInstruction isFieldName = addConstantStringFromName(operator); | 2479 HInstruction isFieldName = addConstantStringFromName(operator); |
| 2479 HInstruction asFieldName = compiler.closedWorld | 2480 HInstruction asFieldName = compiler.closedWorld |
| 2480 .hasAnyStrictSubtype(element) | 2481 .hasAnyStrictSubtype(element) |
| 2481 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 2482 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
| 2482 : graph.addConstantNull(compiler); | 2483 : graph.addConstantNull(compiler); |
| 2483 List<HInstruction> inputs = <HInstruction>[ | 2484 List<HInstruction> inputs = <HInstruction>[ |
| 2484 expression, | 2485 expression, |
| 2485 isFieldName, | 2486 isFieldName, |
| 2486 representations, | 2487 representations, |
| 2487 asFieldName | 2488 asFieldName |
| 2488 ]; | 2489 ]; |
| 2489 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); | 2490 pushInvokeStatic(helper, inputs, |
| 2491 typeMask: backend.boolType, location: node); |
| 2490 HInstruction call = pop(); | 2492 HInstruction call = pop(); |
| 2491 return new HIs.compound(type, expression, call, backend.boolType); | 2493 return new HIs.compound(type, expression, call, backend.boolType); |
| 2492 } else { | 2494 } else { |
| 2493 if (backend.hasDirectCheckFor(type)) { | 2495 if (backend.hasDirectCheckFor(type)) { |
| 2494 return new HIs.direct(type, expression, backend.boolType); | 2496 return new HIs.direct(type, expression, backend.boolType); |
| 2495 } | 2497 } |
| 2496 // The interceptor is not always needed. It is removed by optimization | 2498 // The interceptor is not always needed. It is removed by optimization |
| 2497 // when the receiver type or tested type permit. | 2499 // when the receiver type or tested type permit. |
| 2498 return new HIs.raw( | 2500 return new HIs.raw( |
| 2499 type, expression, invokeInterceptor(expression), backend.boolType); | 2501 type, expression, invokeInterceptor(expression), backend.boolType); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2730 js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[], | 2732 js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[], |
| 2731 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); | 2733 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); |
| 2732 } else { | 2734 } else { |
| 2733 // Call a helper method from the isolate library. The isolate | 2735 // Call a helper method from the isolate library. The isolate |
| 2734 // library uses its own isolate structure, that encapsulates | 2736 // library uses its own isolate structure, that encapsulates |
| 2735 // Leg's isolate. | 2737 // Leg's isolate. |
| 2736 Element element = helpers.currentIsolate; | 2738 Element element = helpers.currentIsolate; |
| 2737 if (element == null) { | 2739 if (element == null) { |
| 2738 reporter.internalError(node, 'Isolate library and compiler mismatch.'); | 2740 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
| 2739 } | 2741 } |
| 2740 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType); | 2742 pushInvokeStatic(element, [], typeMask: backend.dynamicType); |
| 2741 } | 2743 } |
| 2742 } | 2744 } |
| 2743 | 2745 |
| 2744 void handleForeignJsGetFlag(ast.Send node) { | 2746 void handleForeignJsGetFlag(ast.Send node) { |
| 2745 List<ast.Node> arguments = node.arguments.toList(); | 2747 List<ast.Node> arguments = node.arguments.toList(); |
| 2746 ast.Node argument; | 2748 ast.Node argument; |
| 2747 switch (arguments.length) { | 2749 switch (arguments.length) { |
| 2748 case 0: | 2750 case 0: |
| 2749 reporter.reportErrorMessage(node, MessageKind.GENERIC, | 2751 reporter.reportErrorMessage(node, MessageKind.GENERIC, |
| 2750 {'text': 'Error: Expected one argument to JS_GET_FLAG.'}); | 2752 {'text': 'Error: Expected one argument to JS_GET_FLAG.'}); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2925 push(new HInvokeClosure(new Selector.callClosure(0), | 2927 push(new HInvokeClosure(new Selector.callClosure(0), |
| 2926 <HInstruction>[pop()], backend.dynamicType)); | 2928 <HInstruction>[pop()], backend.dynamicType)); |
| 2927 } else { | 2929 } else { |
| 2928 // Call a helper method from the isolate library. | 2930 // Call a helper method from the isolate library. |
| 2929 Element element = helpers.callInIsolate; | 2931 Element element = helpers.callInIsolate; |
| 2930 if (element == null) { | 2932 if (element == null) { |
| 2931 reporter.internalError(node, 'Isolate library and compiler mismatch.'); | 2933 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
| 2932 } | 2934 } |
| 2933 List<HInstruction> inputs = <HInstruction>[]; | 2935 List<HInstruction> inputs = <HInstruction>[]; |
| 2934 addGenericSendArgumentsToList(link, inputs); | 2936 addGenericSendArgumentsToList(link, inputs); |
| 2935 pushInvokeStatic(node, element, inputs, typeMask: backend.dynamicType); | 2937 pushInvokeStatic(element, inputs, |
| 2938 typeMask: backend.dynamicType, location: node); |
| 2936 } | 2939 } |
| 2937 } | 2940 } |
| 2938 | 2941 |
| 2939 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) { | 2942 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) { |
| 2940 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 2943 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
| 2941 reporter.internalError( | 2944 reporter.internalError( |
| 2942 node.argumentsNode, '"$name" requires exactly one argument.'); | 2945 node.argumentsNode, '"$name" requires exactly one argument.'); |
| 2943 } | 2946 } |
| 2944 ast.Node closure = node.arguments.head; | 2947 ast.Node closure = node.arguments.head; |
| 2945 Element element = elements[closure]; | 2948 Element element = elements[closure]; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3084 constantSystem.createString(new ast.DartString.literal(argumentName)); | 3087 constantSystem.createString(new ast.DartString.literal(argumentName)); |
| 3085 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); | 3088 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); |
| 3086 } | 3089 } |
| 3087 var argumentNamesInstruction = buildLiteralList(argumentNames); | 3090 var argumentNamesInstruction = buildLiteralList(argumentNames); |
| 3088 add(argumentNamesInstruction); | 3091 add(argumentNamesInstruction); |
| 3089 | 3092 |
| 3090 ConstantValue kindConstant = | 3093 ConstantValue kindConstant = |
| 3091 constantSystem.createInt(selector.invocationMirrorKind); | 3094 constantSystem.createInt(selector.invocationMirrorKind); |
| 3092 | 3095 |
| 3093 pushInvokeStatic( | 3096 pushInvokeStatic( |
| 3094 null, | |
| 3095 createInvocationMirror, | 3097 createInvocationMirror, |
| 3096 [ | 3098 [ |
| 3097 graph.addConstant(nameConstant, compiler), | 3099 graph.addConstant(nameConstant, compiler), |
| 3098 graph.addConstantStringFromName(internalName, compiler), | 3100 graph.addConstantStringFromName(internalName, compiler), |
| 3099 graph.addConstant(kindConstant, compiler), | 3101 graph.addConstant(kindConstant, compiler), |
| 3100 argumentsInstruction, | 3102 argumentsInstruction, |
| 3101 argumentNamesInstruction | 3103 argumentNamesInstruction |
| 3102 ], | 3104 ], |
| 3103 typeMask: backend.dynamicType); | 3105 typeMask: backend.dynamicType); |
| 3104 | 3106 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3291 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 3293 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
| 3292 return newObject; | 3294 return newObject; |
| 3293 } | 3295 } |
| 3294 List<HInstruction> inputs = <HInstruction>[]; | 3296 List<HInstruction> inputs = <HInstruction>[]; |
| 3295 type = localsHandler.substInContext(type); | 3297 type = localsHandler.substInContext(type); |
| 3296 type.typeArguments.forEach((DartType argument) { | 3298 type.typeArguments.forEach((DartType argument) { |
| 3297 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 3299 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
| 3298 }); | 3300 }); |
| 3299 // TODO(15489): Register at codegen. | 3301 // TODO(15489): Register at codegen. |
| 3300 registry?.registerInstantiation(type); | 3302 registry?.registerInstantiation(type); |
| 3301 return callSetRuntimeTypeInfoWithTypeArguments( | 3303 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); |
| 3302 type.element, inputs, newObject); | |
| 3303 } | |
| 3304 | |
| 3305 HInstruction callSetRuntimeTypeInfoWithTypeArguments(ClassElement element, | |
| 3306 List<HInstruction> rtiInputs, HInstruction newObject) { | |
| 3307 if (!backend.classNeedsRti(element)) { | |
| 3308 return newObject; | |
| 3309 } | |
| 3310 | |
| 3311 HInstruction typeInfo = new HTypeInfoExpression( | |
| 3312 TypeInfoExpressionKind.INSTANCE, | |
| 3313 element.thisType, | |
| 3314 rtiInputs, | |
| 3315 backend.dynamicType); | |
| 3316 add(typeInfo); | |
| 3317 return callSetRuntimeTypeInfo(typeInfo, newObject); | |
| 3318 } | |
| 3319 | |
| 3320 HInstruction callSetRuntimeTypeInfo( | |
| 3321 HInstruction typeInfo, HInstruction newObject) { | |
| 3322 // Set the runtime type information on the object. | |
| 3323 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; | |
| 3324 pushInvokeStatic( | |
| 3325 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], | |
| 3326 typeMask: backend.dynamicType, | |
| 3327 sourceInformation: newObject.sourceInformation); | |
| 3328 | |
| 3329 // The new object will now be referenced through the | |
| 3330 // `setRuntimeTypeInfo` call. We therefore set the type of that | |
| 3331 // instruction to be of the object's type. | |
| 3332 assert(invariant(CURRENT_ELEMENT_SPANNABLE, | |
| 3333 stack.last is HInvokeStatic || stack.last == newObject, | |
| 3334 message: "Unexpected `stack.last`: Found ${stack.last}, " | |
| 3335 "expected ${newObject} or an HInvokeStatic. " | |
| 3336 "State: typeInfo=$typeInfo, stack=$stack.")); | |
| 3337 stack.last.instructionType = newObject.instructionType; | |
| 3338 return pop(); | |
| 3339 } | 3304 } |
| 3340 | 3305 |
| 3341 void handleNewSend(ast.NewExpression node) { | 3306 void handleNewSend(ast.NewExpression node) { |
| 3342 ast.Send send = node.send; | 3307 ast.Send send = node.send; |
| 3343 generateIsDeferredLoadedCheckOfSend(send); | 3308 generateIsDeferredLoadedCheckOfSend(send); |
| 3344 | 3309 |
| 3345 bool isFixedList = false; | 3310 bool isFixedList = false; |
| 3346 bool isFixedListConstructorCall = | 3311 bool isFixedListConstructorCall = |
| 3347 Elements.isFixedListConstructorCall(elements[send], send, compiler); | 3312 Elements.isFixedListConstructorCall(elements[send], send, compiler); |
| 3348 bool isGrowableListConstructorCall = | 3313 bool isGrowableListConstructorCall = |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3507 throwBehavior: native.NativeThrowBehavior.MAY)); | 3472 throwBehavior: native.NativeThrowBehavior.MAY)); |
| 3508 } | 3473 } |
| 3509 } else if (isGrowableListConstructorCall) { | 3474 } else if (isGrowableListConstructorCall) { |
| 3510 push(buildLiteralList(<HInstruction>[])); | 3475 push(buildLiteralList(<HInstruction>[])); |
| 3511 stack.last.instructionType = elementType; | 3476 stack.last.instructionType = elementType; |
| 3512 } else { | 3477 } else { |
| 3513 SourceInformation sourceInformation = | 3478 SourceInformation sourceInformation = |
| 3514 sourceInformationBuilder.buildNew(send); | 3479 sourceInformationBuilder.buildNew(send); |
| 3515 potentiallyAddTypeArguments(inputs, cls, expectedType); | 3480 potentiallyAddTypeArguments(inputs, cls, expectedType); |
| 3516 addInlinedInstantiation(expectedType); | 3481 addInlinedInstantiation(expectedType); |
| 3517 pushInvokeStatic(node, constructor.declaration, inputs, | 3482 pushInvokeStatic(constructor.declaration, inputs, |
| 3518 typeMask: elementType, | 3483 typeMask: elementType, |
| 3519 instanceType: expectedType, | 3484 instanceType: expectedType, |
| 3520 sourceInformation: sourceInformation); | 3485 sourceInformation: sourceInformation, |
| 3486 location: node); |
| 3521 removeInlinedInstantiation(expectedType); | 3487 removeInlinedInstantiation(expectedType); |
| 3522 } | 3488 } |
| 3523 HInstruction newInstance = stack.last; | 3489 HInstruction newInstance = stack.last; |
| 3524 if (isFixedList) { | 3490 if (isFixedList) { |
| 3525 // Overwrite the element type, in case the allocation site has | 3491 // Overwrite the element type, in case the allocation site has |
| 3526 // been inlined. | 3492 // been inlined. |
| 3527 newInstance.instructionType = elementType; | 3493 newInstance.instructionType = elementType; |
| 3528 graph.allocatedFixedLists?.add(newInstance); | 3494 graph.allocatedFixedLists?.add(newInstance); |
| 3529 } | 3495 } |
| 3530 | 3496 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3624 void generateStaticFunctionInvoke( | 3590 void generateStaticFunctionInvoke( |
| 3625 ast.Send node, FunctionElement function, CallStructure callStructure) { | 3591 ast.Send node, FunctionElement function, CallStructure callStructure) { |
| 3626 List<HInstruction> inputs = makeStaticArgumentList( | 3592 List<HInstruction> inputs = makeStaticArgumentList( |
| 3627 callStructure, node.arguments, function.implementation); | 3593 callStructure, node.arguments, function.implementation); |
| 3628 | 3594 |
| 3629 if (function == compiler.commonElements.identicalFunction) { | 3595 if (function == compiler.commonElements.identicalFunction) { |
| 3630 pushWithPosition( | 3596 pushWithPosition( |
| 3631 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); | 3597 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); |
| 3632 return; | 3598 return; |
| 3633 } else { | 3599 } else { |
| 3634 pushInvokeStatic(node, function, inputs, | 3600 pushInvokeStatic(function, inputs, |
| 3635 sourceInformation: | 3601 sourceInformation: |
| 3636 sourceInformationBuilder.buildCall(node, node.selector)); | 3602 sourceInformationBuilder.buildCall(node, node.selector), |
| 3603 location: node); |
| 3637 } | 3604 } |
| 3638 } | 3605 } |
| 3639 | 3606 |
| 3640 /// Generate an invocation to a static or top level function with the wrong | 3607 /// Generate an invocation to a static or top level function with the wrong |
| 3641 /// number of arguments. | 3608 /// number of arguments. |
| 3642 void generateStaticFunctionIncompatibleInvoke( | 3609 void generateStaticFunctionIncompatibleInvoke( |
| 3643 ast.Send node, Element element) { | 3610 ast.Send node, Element element) { |
| 3644 generateWrongArgumentCountError(node, element, node.arguments); | 3611 generateWrongArgumentCountError(node, element, node.arguments); |
| 3645 } | 3612 } |
| 3646 | 3613 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3825 ast.Send node, TypeVariableType typeVariable) { | 3792 ast.Send node, TypeVariableType typeVariable) { |
| 3826 // GENERIC_METHODS: This provides thin support for method type variables | 3793 // GENERIC_METHODS: This provides thin support for method type variables |
| 3827 // by treating them as malformed when evaluated as a literal. For full | 3794 // by treating them as malformed when evaluated as a literal. For full |
| 3828 // support of generic methods this must be revised. | 3795 // support of generic methods this must be revised. |
| 3829 if (typeVariable is MethodTypeVariableType) { | 3796 if (typeVariable is MethodTypeVariableType) { |
| 3830 generateTypeError(node, "Method type variables are not reified"); | 3797 generateTypeError(node, "Method type variables are not reified"); |
| 3831 } else { | 3798 } else { |
| 3832 DartType type = localsHandler.substInContext(typeVariable); | 3799 DartType type = localsHandler.substInContext(typeVariable); |
| 3833 HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement, | 3800 HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement, |
| 3834 sourceInformation: sourceInformationBuilder.buildGet(node)); | 3801 sourceInformation: sourceInformationBuilder.buildGet(node)); |
| 3835 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], | 3802 pushInvokeStatic(helpers.runtimeTypeToString, [value], |
| 3836 typeMask: backend.stringType); | 3803 typeMask: backend.stringType, location: node); |
| 3837 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); | 3804 pushInvokeStatic(helpers.createRuntimeType, [pop()], location: node); |
| 3838 } | 3805 } |
| 3839 } | 3806 } |
| 3840 | 3807 |
| 3841 /// Generate a call to a type literal. | 3808 /// Generate a call to a type literal. |
| 3842 void generateTypeLiteralCall(ast.Send node) { | 3809 void generateTypeLiteralCall(ast.Send node) { |
| 3843 // This send is of the form 'e(...)', where e is resolved to a type | 3810 // This send is of the form 'e(...)', where e is resolved to a type |
| 3844 // reference. We create a regular closure call on the result of the type | 3811 // reference. We create a regular closure call on the result of the type |
| 3845 // reference instead of creating a NoSuchMethodError to avoid pulling it | 3812 // reference instead of creating a NoSuchMethodError to avoid pulling it |
| 3846 // in if it is not used (e.g., in a try/catch). | 3813 // in if it is not used (e.g., in a try/catch). |
| 3847 HInstruction target = pop(); | 3814 HInstruction target = pop(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3864 internalError(node, "Unexpected visitGetterSend"); | 3831 internalError(node, "Unexpected visitGetterSend"); |
| 3865 } | 3832 } |
| 3866 | 3833 |
| 3867 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. | 3834 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. |
| 3868 internalError(Spannable node, String reason) { | 3835 internalError(Spannable node, String reason) { |
| 3869 reporter.internalError(node, reason); | 3836 reporter.internalError(node, reason); |
| 3870 } | 3837 } |
| 3871 | 3838 |
| 3872 void generateError(ast.Node node, String message, Element helper) { | 3839 void generateError(ast.Node node, String message, Element helper) { |
| 3873 HInstruction errorMessage = addConstantString(message); | 3840 HInstruction errorMessage = addConstantString(message); |
| 3874 pushInvokeStatic(node, helper, [errorMessage]); | 3841 pushInvokeStatic(helper, [errorMessage], location: node); |
| 3875 } | 3842 } |
| 3876 | 3843 |
| 3877 void generateRuntimeError(ast.Node node, String message) { | 3844 void generateRuntimeError(ast.Node node, String message) { |
| 3878 generateError(node, message, helpers.throwRuntimeError); | 3845 generateError(node, message, helpers.throwRuntimeError); |
| 3879 } | 3846 } |
| 3880 | 3847 |
| 3881 void generateTypeError(ast.Node node, String message) { | 3848 void generateTypeError(ast.Node node, String message) { |
| 3882 generateError(node, message, helpers.throwTypeError); | 3849 generateError(node, message, helpers.throwTypeError); |
| 3883 } | 3850 } |
| 3884 | 3851 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3914 for (String name in existingArguments) { | 3881 for (String name in existingArguments) { |
| 3915 HInstruction nameConstant = | 3882 HInstruction nameConstant = |
| 3916 graph.addConstantString(new ast.DartString.literal(name), compiler); | 3883 graph.addConstantString(new ast.DartString.literal(name), compiler); |
| 3917 existingNames.add(nameConstant); | 3884 existingNames.add(nameConstant); |
| 3918 } | 3885 } |
| 3919 existingNamesList = buildLiteralList(existingNames); | 3886 existingNamesList = buildLiteralList(existingNames); |
| 3920 add(existingNamesList); | 3887 add(existingNamesList); |
| 3921 } else { | 3888 } else { |
| 3922 existingNamesList = graph.addConstantNull(compiler); | 3889 existingNamesList = graph.addConstantNull(compiler); |
| 3923 } | 3890 } |
| 3924 pushInvokeStatic( | 3891 pushInvokeStatic(helper, [receiver, name, arguments, existingNamesList], |
| 3925 diagnosticNode, helper, [receiver, name, arguments, existingNamesList], | 3892 sourceInformation: sourceInformation, location: diagnosticNode); |
| 3926 sourceInformation: sourceInformation); | |
| 3927 } | 3893 } |
| 3928 | 3894 |
| 3929 /** | 3895 /** |
| 3930 * Generate code to throw a [NoSuchMethodError] exception for calling a | 3896 * Generate code to throw a [NoSuchMethodError] exception for calling a |
| 3931 * method with a wrong number of arguments or mismatching named optional | 3897 * method with a wrong number of arguments or mismatching named optional |
| 3932 * arguments. | 3898 * arguments. |
| 3933 */ | 3899 */ |
| 3934 void generateWrongArgumentCountError(ast.Node diagnosticNode, | 3900 void generateWrongArgumentCountError(ast.Node diagnosticNode, |
| 3935 FunctionElement function, Link<ast.Node> argumentNodes) { | 3901 FunctionElement function, Link<ast.Node> argumentNodes) { |
| 3936 List<String> existingArguments = <String>[]; | 3902 List<String> existingArguments = <String>[]; |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4157 var args = new List.filled(arguments.length, '#').join(','); | 4123 var args = new List.filled(arguments.length, '#').join(','); |
| 4158 code = element.isConstructor ? "new #($args)" : "#($args)"; | 4124 code = element.isConstructor ? "new #($args)" : "#($args)"; |
| 4159 } | 4125 } |
| 4160 js.Template codeTemplate = js.js.parseForeignJS(code); | 4126 js.Template codeTemplate = js.js.parseForeignJS(code); |
| 4161 nativeBehavior.codeTemplate = codeTemplate; | 4127 nativeBehavior.codeTemplate = codeTemplate; |
| 4162 | 4128 |
| 4163 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, | 4129 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, |
| 4164 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; | 4130 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; |
| 4165 } | 4131 } |
| 4166 | 4132 |
| 4167 void pushInvokeStatic( | 4133 void pushInvokeStatic(MethodElement element, List<HInstruction> arguments, |
| 4168 ast.Node location, MethodElement element, List<HInstruction> arguments, | |
| 4169 {TypeMask typeMask, | 4134 {TypeMask typeMask, |
| 4170 InterfaceType instanceType, | 4135 InterfaceType instanceType, |
| 4171 SourceInformation sourceInformation}) { | 4136 SourceInformation sourceInformation, |
| 4137 ast.Node location}) { |
| 4172 assert(element.isDeclaration); | 4138 assert(element.isDeclaration); |
| 4173 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4139 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
| 4174 if (tryInlineMethod(element, null, null, arguments, location, | 4140 if (tryInlineMethod(element, null, null, arguments, location, |
| 4175 instanceType: instanceType)) { | 4141 instanceType: instanceType)) { |
| 4176 return; | 4142 return; |
| 4177 } | 4143 } |
| 4178 | 4144 |
| 4179 if (typeMask == null) { | 4145 if (typeMask == null) { |
| 4180 typeMask = | 4146 typeMask = |
| 4181 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4147 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); |
| (...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5152 ClassElement targetClass = targetConstructor.enclosingClass; | 5118 ClassElement targetClass = targetConstructor.enclosingClass; |
| 5153 if (backend.classNeedsRti(targetClass)) { | 5119 if (backend.classNeedsRti(targetClass)) { |
| 5154 ClassElement cls = redirectingConstructor.enclosingClass; | 5120 ClassElement cls = redirectingConstructor.enclosingClass; |
| 5155 InterfaceType targetType = | 5121 InterfaceType targetType = |
| 5156 redirectingConstructor.computeEffectiveTargetType(cls.thisType); | 5122 redirectingConstructor.computeEffectiveTargetType(cls.thisType); |
| 5157 targetType = localsHandler.substInContext(targetType); | 5123 targetType = localsHandler.substInContext(targetType); |
| 5158 targetType.typeArguments.forEach((DartType argument) { | 5124 targetType.typeArguments.forEach((DartType argument) { |
| 5159 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 5125 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
| 5160 }); | 5126 }); |
| 5161 } | 5127 } |
| 5162 pushInvokeStatic(node, targetConstructor.declaration, inputs); | 5128 pushInvokeStatic(targetConstructor.declaration, inputs, location: node); |
| 5163 HInstruction value = pop(); | 5129 HInstruction value = pop(); |
| 5164 emitReturn(value, node); | 5130 emitReturn(value, node); |
| 5165 } | 5131 } |
| 5166 | 5132 |
| 5167 /// Returns true if the [type] is a valid return type for an asynchronous | 5133 /// Returns true if the [type] is a valid return type for an asynchronous |
| 5168 /// function. | 5134 /// function. |
| 5169 /// | 5135 /// |
| 5170 /// Asynchronous functions return a `Future`, and a valid return is thus | 5136 /// Asynchronous functions return a `Future`, and a valid return is thus |
| 5171 /// either dynamic, Object, or Future. | 5137 /// either dynamic, Object, or Future. |
| 5172 /// | 5138 /// |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5266 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 5232 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
| 5267 return object; | 5233 return object; |
| 5268 } | 5234 } |
| 5269 List<HInstruction> arguments = <HInstruction>[]; | 5235 List<HInstruction> arguments = <HInstruction>[]; |
| 5270 for (DartType argument in type.typeArguments) { | 5236 for (DartType argument in type.typeArguments) { |
| 5271 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 5237 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
| 5272 } | 5238 } |
| 5273 // TODO(15489): Register at codegen. | 5239 // TODO(15489): Register at codegen. |
| 5274 registry?.registerInstantiation(type); | 5240 registry?.registerInstantiation(type); |
| 5275 return callSetRuntimeTypeInfoWithTypeArguments( | 5241 return callSetRuntimeTypeInfoWithTypeArguments( |
| 5276 type.element, arguments, object); | 5242 // TODO(efortuna): this was type.element.thisType. Is this equivalent? |
| 5243 type, |
| 5244 arguments, |
| 5245 object); |
| 5277 } | 5246 } |
| 5278 | 5247 |
| 5279 visitLiteralList(ast.LiteralList node) { | 5248 visitLiteralList(ast.LiteralList node) { |
| 5280 HInstruction instruction; | 5249 HInstruction instruction; |
| 5281 | 5250 |
| 5282 if (node.isConst) { | 5251 if (node.isConst) { |
| 5283 instruction = addConstant(node); | 5252 instruction = addConstant(node); |
| 5284 } else { | 5253 } else { |
| 5285 List<HInstruction> inputs = <HInstruction>[]; | 5254 List<HInstruction> inputs = <HInstruction>[]; |
| 5286 for (Link<ast.Node> link = node.elements.nodes; | 5255 for (Link<ast.Node> link = node.elements.nodes; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5383 } | 5352 } |
| 5384 return new JumpHandler(this, element); | 5353 return new JumpHandler(this, element); |
| 5385 } | 5354 } |
| 5386 | 5355 |
| 5387 visitAsyncForIn(ast.AsyncForIn node) { | 5356 visitAsyncForIn(ast.AsyncForIn node) { |
| 5388 // The async-for is implemented with a StreamIterator. | 5357 // The async-for is implemented with a StreamIterator. |
| 5389 HInstruction streamIterator; | 5358 HInstruction streamIterator; |
| 5390 | 5359 |
| 5391 visit(node.expression); | 5360 visit(node.expression); |
| 5392 HInstruction expression = pop(); | 5361 HInstruction expression = pop(); |
| 5393 pushInvokeStatic(node, helpers.streamIteratorConstructor, | 5362 pushInvokeStatic(helpers.streamIteratorConstructor, |
| 5394 [expression, graph.addConstantNull(compiler)]); | 5363 [expression, graph.addConstantNull(compiler)], |
| 5364 location: node); |
| 5395 streamIterator = pop(); | 5365 streamIterator = pop(); |
| 5396 | 5366 |
| 5397 void buildInitializer() {} | 5367 void buildInitializer() {} |
| 5398 | 5368 |
| 5399 HInstruction buildCondition() { | 5369 HInstruction buildCondition() { |
| 5400 Selector selector = Selectors.moveNext; | 5370 Selector selector = Selectors.moveNext; |
| 5401 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); | 5371 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
| 5402 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 5372 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
| 5403 HInstruction future = pop(); | 5373 HInstruction future = pop(); |
| 5404 push(new HAwait( | 5374 push(new HAwait( |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5557 | 5527 |
| 5558 void buildConcurrentModificationErrorCheck() { | 5528 void buildConcurrentModificationErrorCheck() { |
| 5559 if (originalLength == null) return; | 5529 if (originalLength == null) return; |
| 5560 // The static call checkConcurrentModificationError() is expanded in | 5530 // The static call checkConcurrentModificationError() is expanded in |
| 5561 // codegen to: | 5531 // codegen to: |
| 5562 // | 5532 // |
| 5563 // array.length == _end || throwConcurrentModificationError(array) | 5533 // array.length == _end || throwConcurrentModificationError(array) |
| 5564 // | 5534 // |
| 5565 HInstruction length = buildGetLength(); | 5535 HInstruction length = buildGetLength(); |
| 5566 push(new HIdentity(length, originalLength, null, boolType)); | 5536 push(new HIdentity(length, originalLength, null, boolType)); |
| 5567 pushInvokeStatic( | 5537 pushInvokeStatic(helpers.checkConcurrentModificationError, [pop(), array], |
| 5568 node, helpers.checkConcurrentModificationError, [pop(), array]); | 5538 location: node); |
| 5569 pop(); | 5539 pop(); |
| 5570 } | 5540 } |
| 5571 | 5541 |
| 5572 void buildInitializer() { | 5542 void buildInitializer() { |
| 5573 visit(node.expression); | 5543 visit(node.expression); |
| 5574 array = pop(); | 5544 array = pop(); |
| 5575 isFixed = isFixedLength(array.instructionType, compiler); | 5545 isFixed = isFixedLength(array.instructionType, compiler); |
| 5576 localsHandler.updateLocal( | 5546 localsHandler.updateLocal( |
| 5577 indexVariable, graph.addConstantInt(0, compiler)); | 5547 indexVariable, graph.addConstantInt(0, compiler)); |
| 5578 originalLength = buildGetLength(); | 5548 originalLength = buildGetLength(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5742 // type inference might discover a more specific type, or find nothing (in | 5712 // type inference might discover a more specific type, or find nothing (in |
| 5743 // dart2js unit tests). | 5713 // dart2js unit tests). |
| 5744 TypeMask mapType = new TypeMask.nonNullSubtype( | 5714 TypeMask mapType = new TypeMask.nonNullSubtype( |
| 5745 helpers.mapLiteralClass, compiler.closedWorld); | 5715 helpers.mapLiteralClass, compiler.closedWorld); |
| 5746 TypeMask returnTypeMask = | 5716 TypeMask returnTypeMask = |
| 5747 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); | 5717 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); |
| 5748 TypeMask instructionType = | 5718 TypeMask instructionType = |
| 5749 mapType.intersection(returnTypeMask, compiler.closedWorld); | 5719 mapType.intersection(returnTypeMask, compiler.closedWorld); |
| 5750 | 5720 |
| 5751 addInlinedInstantiation(expectedType); | 5721 addInlinedInstantiation(expectedType); |
| 5752 pushInvokeStatic(node, constructor, inputs, | 5722 pushInvokeStatic(constructor, inputs, |
| 5753 typeMask: instructionType, instanceType: expectedType); | 5723 typeMask: instructionType, instanceType: expectedType, location: node); |
| 5754 removeInlinedInstantiation(expectedType); | 5724 removeInlinedInstantiation(expectedType); |
| 5755 } | 5725 } |
| 5756 | 5726 |
| 5757 visitLiteralMapEntry(ast.LiteralMapEntry node) { | 5727 visitLiteralMapEntry(ast.LiteralMapEntry node) { |
| 5758 visit(node.value); | 5728 visit(node.value); |
| 5759 visit(node.key); | 5729 visit(node.key); |
| 5760 } | 5730 } |
| 5761 | 5731 |
| 5762 visitNamedArgument(ast.NamedArgument node) { | 5732 visitNamedArgument(ast.NamedArgument node) { |
| 5763 visit(node.expression); | 5733 visit(node.expression); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6042 // An HSwitch has n inputs and n+1 successors, the last being the | 6012 // An HSwitch has n inputs and n+1 successors, the last being the |
| 6043 // default case. | 6013 // default case. |
| 6044 expressionEnd.addSuccessor(block); | 6014 expressionEnd.addSuccessor(block); |
| 6045 hasDefault = true; | 6015 hasDefault = true; |
| 6046 } | 6016 } |
| 6047 open(block); | 6017 open(block); |
| 6048 localsHandler = new LocalsHandler.from(savedLocals); | 6018 localsHandler = new LocalsHandler.from(savedLocals); |
| 6049 buildSwitchCase(switchCase); | 6019 buildSwitchCase(switchCase); |
| 6050 if (!isAborted()) { | 6020 if (!isAborted()) { |
| 6051 if (caseIterator.hasNext && isReachable) { | 6021 if (caseIterator.hasNext && isReachable) { |
| 6052 pushInvokeStatic(switchCase, helpers.fallThroughError, []); | 6022 pushInvokeStatic(helpers.fallThroughError, [], location: switchCase); |
| 6053 HInstruction error = pop(); | 6023 HInstruction error = pop(); |
| 6054 closeAndGotoExit(new HThrow(error, error.sourceInformation)); | 6024 closeAndGotoExit(new HThrow(error, error.sourceInformation)); |
| 6055 } else if (!isDefaultCase(switchCase)) { | 6025 } else if (!isDefaultCase(switchCase)) { |
| 6056 // If there is no default, we will add one later to avoid | 6026 // If there is no default, we will add one later to avoid |
| 6057 // the critical edge. So we generate a break statement to make | 6027 // the critical edge. So we generate a break statement to make |
| 6058 // sure the last case does not fall through to the default case. | 6028 // sure the last case does not fall through to the default case. |
| 6059 jumpHandler.generateBreak(); | 6029 jumpHandler.generateBreak(); |
| 6060 } | 6030 } |
| 6061 } | 6031 } |
| 6062 statements.add( | 6032 statements.add( |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6262 startCatchBlock = graph.addNewBlock(); | 6232 startCatchBlock = graph.addNewBlock(); |
| 6263 open(startCatchBlock); | 6233 open(startCatchBlock); |
| 6264 // Note that the name of this local is irrelevant. | 6234 // Note that the name of this local is irrelevant. |
| 6265 SyntheticLocal local = | 6235 SyntheticLocal local = |
| 6266 new SyntheticLocal('exception', localsHandler.executableContext); | 6236 new SyntheticLocal('exception', localsHandler.executableContext); |
| 6267 exception = new HLocalValue(local, backend.nonNullType); | 6237 exception = new HLocalValue(local, backend.nonNullType); |
| 6268 add(exception); | 6238 add(exception); |
| 6269 HInstruction oldRethrowableException = rethrowableException; | 6239 HInstruction oldRethrowableException = rethrowableException; |
| 6270 rethrowableException = exception; | 6240 rethrowableException = exception; |
| 6271 | 6241 |
| 6272 pushInvokeStatic(node, helpers.exceptionUnwrapper, [exception]); | 6242 pushInvokeStatic(helpers.exceptionUnwrapper, [exception], location: node); |
| 6273 HInvokeStatic unwrappedException = pop(); | 6243 HInvokeStatic unwrappedException = pop(); |
| 6274 tryInstruction.exception = exception; | 6244 tryInstruction.exception = exception; |
| 6275 Link<ast.Node> link = node.catchBlocks.nodes; | 6245 Link<ast.Node> link = node.catchBlocks.nodes; |
| 6276 | 6246 |
| 6277 void pushCondition(ast.CatchBlock catchBlock) { | 6247 void pushCondition(ast.CatchBlock catchBlock) { |
| 6278 if (catchBlock.onKeyword != null) { | 6248 if (catchBlock.onKeyword != null) { |
| 6279 DartType type = elements.getType(catchBlock.type); | 6249 DartType type = elements.getType(catchBlock.type); |
| 6280 if (type == null) { | 6250 if (type == null) { |
| 6281 reporter.internalError(catchBlock.type, 'On with no type.'); | 6251 reporter.internalError(catchBlock.type, 'On with no type.'); |
| 6282 } | 6252 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 6307 void visitThen() { | 6277 void visitThen() { |
| 6308 ast.CatchBlock catchBlock = link.head; | 6278 ast.CatchBlock catchBlock = link.head; |
| 6309 link = link.tail; | 6279 link = link.tail; |
| 6310 if (catchBlock.exception != null) { | 6280 if (catchBlock.exception != null) { |
| 6311 LocalVariableElement exceptionVariable = | 6281 LocalVariableElement exceptionVariable = |
| 6312 elements[catchBlock.exception]; | 6282 elements[catchBlock.exception]; |
| 6313 localsHandler.updateLocal(exceptionVariable, unwrappedException); | 6283 localsHandler.updateLocal(exceptionVariable, unwrappedException); |
| 6314 } | 6284 } |
| 6315 ast.Node trace = catchBlock.trace; | 6285 ast.Node trace = catchBlock.trace; |
| 6316 if (trace != null) { | 6286 if (trace != null) { |
| 6317 pushInvokeStatic(trace, helpers.traceFromException, [exception]); | 6287 pushInvokeStatic(helpers.traceFromException, [exception], |
| 6288 location: trace); |
| 6318 HInstruction traceInstruction = pop(); | 6289 HInstruction traceInstruction = pop(); |
| 6319 LocalVariableElement traceVariable = elements[trace]; | 6290 LocalVariableElement traceVariable = elements[trace]; |
| 6320 localsHandler.updateLocal(traceVariable, traceInstruction); | 6291 localsHandler.updateLocal(traceVariable, traceInstruction); |
| 6321 } | 6292 } |
| 6322 visit(catchBlock); | 6293 visit(catchBlock); |
| 6323 } | 6294 } |
| 6324 | 6295 |
| 6325 void visitElse() { | 6296 void visitElse() { |
| 6326 if (link.isEmpty) { | 6297 if (link.isEmpty) { |
| 6327 closeAndGotoExit(new HThrow(exception, exception.sourceInformation, | 6298 closeAndGotoExit(new HThrow(exception, exception.sourceInformation, |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6787 this.oldReturnLocal, | 6758 this.oldReturnLocal, |
| 6788 this.oldReturnType, | 6759 this.oldReturnType, |
| 6789 this.oldResolvedAst, | 6760 this.oldResolvedAst, |
| 6790 this.oldStack, | 6761 this.oldStack, |
| 6791 this.oldLocalsHandler, | 6762 this.oldLocalsHandler, |
| 6792 this.inTryStatement, | 6763 this.inTryStatement, |
| 6793 this.allFunctionsCalledOnce, | 6764 this.allFunctionsCalledOnce, |
| 6794 this.oldElementInferenceResults) | 6765 this.oldElementInferenceResults) |
| 6795 : super(function); | 6766 : super(function); |
| 6796 } | 6767 } |
| OLD | NEW |