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 |