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'; |
11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
12 import '../common/names.dart' show Identifiers, Selectors; | 12 import '../common/names.dart' show Identifiers, Selectors; |
13 import '../common/tasks.dart' show CompilerTask; | 13 import '../common/tasks.dart' show CompilerTask; |
14 import '../compiler.dart' show Compiler; | 14 import '../compiler.dart' show Compiler; |
15 import '../constants/constant_system.dart'; | 15 import '../constants/constant_system.dart'; |
16 import '../constants/expressions.dart'; | 16 import '../constants/expressions.dart'; |
17 import '../constants/values.dart'; | 17 import '../constants/values.dart'; |
18 import '../common_elements.dart' show CommonElements; | 18 import '../common_elements.dart' show CommonElements; |
19 import '../elements/resolution_types.dart'; | 19 import '../elements/resolution_types.dart'; |
20 import '../diagnostics/messages.dart' show Message, MessageTemplate; | 20 import '../diagnostics/messages.dart' show Message, MessageTemplate; |
21 import '../dump_info.dart' show InfoReporter; | 21 import '../dump_info.dart' show InfoReporter; |
22 import '../elements/elements.dart'; | 22 import '../elements/elements.dart'; |
23 import '../elements/entities.dart'; | 23 import '../elements/entities.dart'; |
24 import '../elements/modelx.dart' show ConstructorBodyElementX; | 24 import '../elements/modelx.dart' show ConstructorBodyElementX; |
25 import '../io/source_information.dart'; | 25 import '../io/source_information.dart'; |
26 import '../js/js.dart' as js; | 26 import '../js/js.dart' as js; |
27 import '../js_backend/backend_helpers.dart' show BackendHelpers; | 27 import '../js_backend/backend.dart' show JavaScriptBackend; |
28 import '../js_backend/js_backend.dart'; | 28 import '../js_backend/js_backend.dart'; |
29 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; | 29 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; |
30 import '../native/native.dart' as native; | 30 import '../native/native.dart' as native; |
31 import '../resolution/operators.dart'; | 31 import '../resolution/operators.dart'; |
32 import '../resolution/semantic_visitor.dart'; | 32 import '../resolution/semantic_visitor.dart'; |
33 import '../resolution/tree_elements.dart' show TreeElements; | 33 import '../resolution/tree_elements.dart' show TreeElements; |
34 import '../tree/tree.dart' as ast; | 34 import '../tree/tree.dart' as ast; |
35 import '../types/types.dart'; | 35 import '../types/types.dart'; |
36 import '../universe/call_structure.dart' show CallStructure; | 36 import '../universe/call_structure.dart' show CallStructure; |
37 import '../universe/selector.dart' show Selector; | 37 import '../universe/selector.dart' show Selector; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 sourceElementStack.add(target); | 216 sourceElementStack.add(target); |
217 sourceInformationBuilder = | 217 sourceInformationBuilder = |
218 sourceInformationFactory.createBuilderForContext(resolvedAst); | 218 sourceInformationFactory.createBuilderForContext(resolvedAst); |
219 graph.sourceInformation = | 219 graph.sourceInformation = |
220 sourceInformationBuilder.buildVariableDeclaration(); | 220 sourceInformationBuilder.buildVariableDeclaration(); |
221 localsHandler = new LocalsHandler(this, target, null, compiler); | 221 localsHandler = new LocalsHandler(this, target, null, compiler); |
222 loopHandler = new SsaLoopHandler(this); | 222 loopHandler = new SsaLoopHandler(this); |
223 typeBuilder = new TypeBuilder(this); | 223 typeBuilder = new TypeBuilder(this); |
224 } | 224 } |
225 | 225 |
226 BackendHelpers get helpers => backend.helpers; | |
227 | |
228 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 226 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
229 | 227 |
230 DiagnosticReporter get reporter => compiler.reporter; | 228 DiagnosticReporter get reporter => compiler.reporter; |
231 | 229 |
232 CommonElements get commonElements => closedWorld.commonElements; | 230 CommonElements get commonElements => closedWorld.commonElements; |
233 | 231 |
234 Element get targetElement => target; | 232 Element get targetElement => target; |
235 | 233 |
236 /// Reference to resolved elements in [target]'s AST. | 234 /// Reference to resolved elements in [target]'s AST. |
237 TreeElements get elements => resolvedAst.elements; | 235 TreeElements get elements => resolvedAst.elements; |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 }, | 713 }, |
716 visitElse: null, | 714 visitElse: null, |
717 sourceInformation: sourceInformationBuilder.buildIf(function.body)); | 715 sourceInformation: sourceInformationBuilder.buildIf(function.body)); |
718 } | 716 } |
719 } | 717 } |
720 if (const bool.fromEnvironment('unreachable-throw')) { | 718 if (const bool.fromEnvironment('unreachable-throw')) { |
721 var emptyParameters = | 719 var emptyParameters = |
722 parameters.values.where((p) => p.instructionType.isEmpty); | 720 parameters.values.where((p) => p.instructionType.isEmpty); |
723 if (emptyParameters.length > 0) { | 721 if (emptyParameters.length > 0) { |
724 addComment('${emptyParameters} inferred as [empty]'); | 722 addComment('${emptyParameters} inferred as [empty]'); |
725 pushInvokeStatic(function.body, helpers.assertUnreachableMethod, []); | 723 pushInvokeStatic( |
| 724 function.body, commonElements.assertUnreachableMethod, []); |
726 pop(); | 725 pop(); |
727 return closeFunction(); | 726 return closeFunction(); |
728 } | 727 } |
729 } | 728 } |
730 function.body.accept(this); | 729 function.body.accept(this); |
731 return closeFunction(); | 730 return closeFunction(); |
732 } | 731 } |
733 | 732 |
734 /// Adds a JavaScript comment to the output. The comment will be omitted in | 733 /// Adds a JavaScript comment to the output. The comment will be omitted in |
735 /// minified mode. Each line in [text] is preceded with `//` and indented. | 734 /// minified mode. Each line in [text] is preceded with `//` and indented. |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 // Otherwise it is a lazy initializer which does not have parameters. | 1440 // Otherwise it is a lazy initializer which does not have parameters. |
1442 assert(element is VariableElement); | 1441 assert(element is VariableElement); |
1443 } | 1442 } |
1444 | 1443 |
1445 insertTraceCall(element); | 1444 insertTraceCall(element); |
1446 insertCoverageCall(element); | 1445 insertCoverageCall(element); |
1447 } | 1446 } |
1448 | 1447 |
1449 insertTraceCall(Element element) { | 1448 insertTraceCall(Element element) { |
1450 if (JavaScriptBackend.TRACE_METHOD == 'console') { | 1449 if (JavaScriptBackend.TRACE_METHOD == 'console') { |
1451 if (element == backend.helpers.traceHelper) return; | 1450 if (element == commonElements.traceHelper) return; |
1452 n(e) => e == null ? '' : e.name; | 1451 n(e) => e == null ? '' : e.name; |
1453 String name = "${n(element.library)}:${n(element.enclosingClass)}." | 1452 String name = "${n(element.library)}:${n(element.enclosingClass)}." |
1454 "${n(element)}"; | 1453 "${n(element)}"; |
1455 HConstant nameConstant = addConstantString(name); | 1454 HConstant nameConstant = addConstantString(name); |
1456 add(new HInvokeStatic(backend.helpers.traceHelper, | 1455 add(new HInvokeStatic(commonElements.traceHelper, |
1457 <HInstruction>[nameConstant], commonMasks.dynamicType)); | 1456 <HInstruction>[nameConstant], commonMasks.dynamicType)); |
1458 } | 1457 } |
1459 } | 1458 } |
1460 | 1459 |
1461 insertCoverageCall(Element element) { | 1460 insertCoverageCall(Element element) { |
1462 if (JavaScriptBackend.TRACE_METHOD == 'post') { | 1461 if (JavaScriptBackend.TRACE_METHOD == 'post') { |
1463 if (element == backend.helpers.traceHelper) return; | 1462 if (element == commonElements.traceHelper) return; |
1464 // TODO(sigmund): create a better uuid for elements. | 1463 // TODO(sigmund): create a better uuid for elements. |
1465 HConstant idConstant = | 1464 HConstant idConstant = |
1466 graph.addConstantInt(element.hashCode, closedWorld); | 1465 graph.addConstantInt(element.hashCode, closedWorld); |
1467 HConstant nameConstant = addConstantString(element.name); | 1466 HConstant nameConstant = addConstantString(element.name); |
1468 add(new HInvokeStatic(backend.helpers.traceHelper, | 1467 add(new HInvokeStatic(commonElements.traceHelper, |
1469 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType)); | 1468 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType)); |
1470 } | 1469 } |
1471 } | 1470 } |
1472 | 1471 |
1473 void assertIsSubtype(ast.Node node, ResolutionDartType subtype, | 1472 void assertIsSubtype(ast.Node node, ResolutionDartType subtype, |
1474 ResolutionDartType supertype, String message) { | 1473 ResolutionDartType supertype, String message) { |
1475 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument( | 1474 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument( |
1476 localsHandler.substInContext(subtype), sourceElement); | 1475 localsHandler.substInContext(subtype), sourceElement); |
1477 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument( | 1476 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument( |
1478 localsHandler.substInContext(supertype), sourceElement); | 1477 localsHandler.substInContext(supertype), sourceElement); |
1479 HInstruction messageInstruction = graph.addConstantString( | 1478 HInstruction messageInstruction = graph.addConstantString( |
1480 new ast.DartString.literal(message), closedWorld); | 1479 new ast.DartString.literal(message), closedWorld); |
1481 MethodElement element = helpers.assertIsSubtype; | 1480 MethodElement element = commonElements.assertIsSubtype; |
1482 var inputs = <HInstruction>[ | 1481 var inputs = <HInstruction>[ |
1483 subtypeInstruction, | 1482 subtypeInstruction, |
1484 supertypeInstruction, | 1483 supertypeInstruction, |
1485 messageInstruction | 1484 messageInstruction |
1486 ]; | 1485 ]; |
1487 HInstruction assertIsSubtype = | 1486 HInstruction assertIsSubtype = |
1488 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); | 1487 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); |
1489 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 1488 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
1490 add(assertIsSubtype); | 1489 add(assertIsSubtype); |
1491 } | 1490 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 | 1535 |
1537 visitAssert(ast.Assert node) { | 1536 visitAssert(ast.Assert node) { |
1538 if (!compiler.options.enableUserAssertions) return; | 1537 if (!compiler.options.enableUserAssertions) return; |
1539 | 1538 |
1540 if (!node.hasMessage) { | 1539 if (!node.hasMessage) { |
1541 // Generate: | 1540 // Generate: |
1542 // | 1541 // |
1543 // assertHelper(condition); | 1542 // assertHelper(condition); |
1544 // | 1543 // |
1545 visit(node.condition); | 1544 visit(node.condition); |
1546 pushInvokeStatic(node, helpers.assertHelper, [pop()]); | 1545 pushInvokeStatic(node, commonElements.assertHelper, [pop()]); |
1547 pop(); | 1546 pop(); |
1548 return; | 1547 return; |
1549 } | 1548 } |
1550 // Assert has message. Generate: | 1549 // Assert has message. Generate: |
1551 // | 1550 // |
1552 // if (assertTest(condition)) assertThrow(message); | 1551 // if (assertTest(condition)) assertThrow(message); |
1553 // | 1552 // |
1554 void buildCondition() { | 1553 void buildCondition() { |
1555 visit(node.condition); | 1554 visit(node.condition); |
1556 pushInvokeStatic(node, helpers.assertTest, [pop()]); | 1555 pushInvokeStatic(node, commonElements.assertTest, [pop()]); |
1557 } | 1556 } |
1558 | 1557 |
1559 void fail() { | 1558 void fail() { |
1560 visit(node.message); | 1559 visit(node.message); |
1561 pushInvokeStatic(node, helpers.assertThrow, [pop()]); | 1560 pushInvokeStatic(node, commonElements.assertThrow, [pop()]); |
1562 pop(); | 1561 pop(); |
1563 } | 1562 } |
1564 | 1563 |
1565 handleIf(node: node, visitCondition: buildCondition, visitThen: fail); | 1564 handleIf(node: node, visitCondition: buildCondition, visitThen: fail); |
1566 } | 1565 } |
1567 | 1566 |
1568 visitBlock(ast.Block node) { | 1567 visitBlock(ast.Block node) { |
1569 assert(!isAborted()); | 1568 assert(!isAborted()); |
1570 if (!isReachable) return; // This can only happen when inlining. | 1569 if (!isReachable) return; // This can only happen when inlining. |
1571 for (Link<ast.Node> link = node.statements.nodes; | 1570 for (Link<ast.Node> link = node.statements.nodes; |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2034 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. | 2033 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. |
2035 /// If [prefixElement] is [null] ndo nothing. | 2034 /// If [prefixElement] is [null] ndo nothing. |
2036 void generateIsDeferredLoadedCheckIfNeeded( | 2035 void generateIsDeferredLoadedCheckIfNeeded( |
2037 PrefixElement prefixElement, ast.Node location) { | 2036 PrefixElement prefixElement, ast.Node location) { |
2038 if (prefixElement == null) return; | 2037 if (prefixElement == null) return; |
2039 String loadId = | 2038 String loadId = |
2040 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); | 2039 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); |
2041 HInstruction loadIdConstant = addConstantString(loadId); | 2040 HInstruction loadIdConstant = addConstantString(loadId); |
2042 String uri = prefixElement.deferredImport.uri.toString(); | 2041 String uri = prefixElement.deferredImport.uri.toString(); |
2043 HInstruction uriConstant = addConstantString(uri); | 2042 HInstruction uriConstant = addConstantString(uri); |
2044 MethodElement helper = helpers.checkDeferredIsLoaded; | 2043 MethodElement helper = commonElements.checkDeferredIsLoaded; |
2045 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); | 2044 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); |
2046 pop(); | 2045 pop(); |
2047 } | 2046 } |
2048 | 2047 |
2049 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that | 2048 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
2050 /// resolves to a deferred library. | 2049 /// resolves to a deferred library. |
2051 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { | 2050 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { |
2052 generateIsDeferredLoadedCheckIfNeeded( | 2051 generateIsDeferredLoadedCheckIfNeeded( |
2053 compiler.deferredLoadTask.deferredPrefixElement(node, elements), node); | 2052 compiler.deferredLoadTask.deferredPrefixElement(node, elements), node); |
2054 } | 2053 } |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2400 generateTypeError(node, message); | 2399 generateTypeError(node, message); |
2401 HInstruction call = pop(); | 2400 HInstruction call = pop(); |
2402 return new HIs.compound(type, expression, call, commonMasks.boolType); | 2401 return new HIs.compound(type, expression, call, commonMasks.boolType); |
2403 } else if (type.isFunctionType) { | 2402 } else if (type.isFunctionType) { |
2404 HInstruction representation = | 2403 HInstruction representation = |
2405 typeBuilder.analyzeTypeArgument(type, sourceElement); | 2404 typeBuilder.analyzeTypeArgument(type, sourceElement); |
2406 List<HInstruction> inputs = <HInstruction>[ | 2405 List<HInstruction> inputs = <HInstruction>[ |
2407 expression, | 2406 expression, |
2408 representation, | 2407 representation, |
2409 ]; | 2408 ]; |
2410 pushInvokeStatic(node, helpers.functionTypeTest, inputs, | 2409 pushInvokeStatic(node, commonElements.functionTypeTest, inputs, |
2411 typeMask: commonMasks.boolType); | 2410 typeMask: commonMasks.boolType); |
2412 HInstruction call = pop(); | 2411 HInstruction call = pop(); |
2413 return new HIs.compound(type, expression, call, commonMasks.boolType); | 2412 return new HIs.compound(type, expression, call, commonMasks.boolType); |
2414 } else if (type.isTypeVariable) { | 2413 } else if (type.isTypeVariable) { |
2415 HInstruction runtimeType = | 2414 HInstruction runtimeType = |
2416 typeBuilder.addTypeVariableReference(type, sourceElement); | 2415 typeBuilder.addTypeVariableReference(type, sourceElement); |
2417 MethodElement helper = helpers.checkSubtypeOfRuntimeType; | 2416 MethodElement helper = commonElements.checkSubtypeOfRuntimeType; |
2418 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 2417 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
2419 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType); | 2418 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType); |
2420 HInstruction call = pop(); | 2419 HInstruction call = pop(); |
2421 return new HIs.variable(type, expression, call, commonMasks.boolType); | 2420 return new HIs.variable(type, expression, call, commonMasks.boolType); |
2422 } else if (RuntimeTypesSubstitutions.hasTypeArguments(type)) { | 2421 } else if (RuntimeTypesSubstitutions.hasTypeArguments(type)) { |
2423 ClassElement element = type.element; | 2422 ClassElement element = type.element; |
2424 MethodElement helper = helpers.checkSubtype; | 2423 MethodElement helper = commonElements.checkSubtype; |
2425 HInstruction representations = | 2424 HInstruction representations = |
2426 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); | 2425 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); |
2427 add(representations); | 2426 add(representations); |
2428 js.Name operator = backend.namer.operatorIs(element); | 2427 js.Name operator = backend.namer.operatorIs(element); |
2429 HInstruction isFieldName = addConstantStringFromName(operator); | 2428 HInstruction isFieldName = addConstantStringFromName(operator); |
2430 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) | 2429 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) |
2431 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 2430 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
2432 : graph.addConstantNull(closedWorld); | 2431 : graph.addConstantNull(closedWorld); |
2433 List<HInstruction> inputs = <HInstruction>[ | 2432 List<HInstruction> inputs = <HInstruction>[ |
2434 expression, | 2433 expression, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2678 // If the isolate library is not used, we just generate code | 2677 // If the isolate library is not used, we just generate code |
2679 // to fetch the static state. | 2678 // to fetch the static state. |
2680 String name = backend.namer.staticStateHolder; | 2679 String name = backend.namer.staticStateHolder; |
2681 push(new HForeignCode( | 2680 push(new HForeignCode( |
2682 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], | 2681 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], |
2683 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); | 2682 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); |
2684 } else { | 2683 } else { |
2685 // Call a helper method from the isolate library. The isolate | 2684 // Call a helper method from the isolate library. The isolate |
2686 // library uses its own isolate structure, that encapsulates | 2685 // library uses its own isolate structure, that encapsulates |
2687 // Leg's isolate. | 2686 // Leg's isolate. |
2688 MethodElement element = helpers.currentIsolate; | 2687 MethodElement element = commonElements.currentIsolate; |
2689 if (element == null) { | 2688 if (element == null) { |
2690 reporter.internalError(node, 'Isolate library and compiler mismatch.'); | 2689 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
2691 } | 2690 } |
2692 pushInvokeStatic(null, element, [], typeMask: commonMasks.dynamicType); | 2691 pushInvokeStatic(null, element, [], typeMask: commonMasks.dynamicType); |
2693 } | 2692 } |
2694 } | 2693 } |
2695 | 2694 |
2696 void handleForeignJsGetFlag(ast.Send node) { | 2695 void handleForeignJsGetFlag(ast.Send node) { |
2697 List<ast.Node> arguments = node.arguments.toList(); | 2696 List<ast.Node> arguments = node.arguments.toList(); |
2698 ast.Node argument; | 2697 ast.Node argument; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2746 default: | 2745 default: |
2747 for (int i = 1; i < arguments.length; i++) { | 2746 for (int i = 1; i < arguments.length; i++) { |
2748 reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC, | 2747 reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC, |
2749 {'text': 'Error: Extra argument to JS_GET_NAME.'}); | 2748 {'text': 'Error: Extra argument to JS_GET_NAME.'}); |
2750 } | 2749 } |
2751 return; | 2750 return; |
2752 } | 2751 } |
2753 Element element = elements[argument]; | 2752 Element element = elements[argument]; |
2754 if (element == null || | 2753 if (element == null || |
2755 element is! EnumConstantElement || | 2754 element is! EnumConstantElement || |
2756 element.enclosingClass != helpers.jsGetNameEnum) { | 2755 element.enclosingClass != commonElements.jsGetNameEnum) { |
2757 reporter.reportErrorMessage(argument, MessageKind.GENERIC, | 2756 reporter.reportErrorMessage(argument, MessageKind.GENERIC, |
2758 {'text': 'Error: Expected a JsGetName enum value.'}); | 2757 {'text': 'Error: Expected a JsGetName enum value.'}); |
2759 } | 2758 } |
2760 EnumConstantElement enumConstant = element; | 2759 EnumConstantElement enumConstant = element; |
2761 int index = enumConstant.index; | 2760 int index = enumConstant.index; |
2762 stack.add(addConstantStringFromName( | 2761 stack.add(addConstantStringFromName( |
2763 backend.namer.getNameForJsGetName(argument, JsGetName.values[index]))); | 2762 backend.namer.getNameForJsGetName(argument, JsGetName.values[index]))); |
2764 } | 2763 } |
2765 | 2764 |
2766 void handleForeignJsBuiltin(ast.Send node) { | 2765 void handleForeignJsBuiltin(ast.Send node) { |
2767 List<ast.Node> arguments = node.arguments.toList(); | 2766 List<ast.Node> arguments = node.arguments.toList(); |
2768 ast.Node argument; | 2767 ast.Node argument; |
2769 if (arguments.length < 2) { | 2768 if (arguments.length < 2) { |
2770 reporter.reportErrorMessage(node, MessageKind.GENERIC, | 2769 reporter.reportErrorMessage(node, MessageKind.GENERIC, |
2771 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'}); | 2770 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'}); |
2772 } | 2771 } |
2773 | 2772 |
2774 Element builtinElement = elements[arguments[1]]; | 2773 Element builtinElement = elements[arguments[1]]; |
2775 if (builtinElement == null || | 2774 if (builtinElement == null || |
2776 (builtinElement is! EnumConstantElement) || | 2775 (builtinElement is! EnumConstantElement) || |
2777 builtinElement.enclosingClass != helpers.jsBuiltinEnum) { | 2776 builtinElement.enclosingClass != commonElements.jsBuiltinEnum) { |
2778 reporter.reportErrorMessage(argument, MessageKind.GENERIC, | 2777 reporter.reportErrorMessage(argument, MessageKind.GENERIC, |
2779 {'text': 'Error: Expected a JsBuiltin enum value.'}); | 2778 {'text': 'Error: Expected a JsBuiltin enum value.'}); |
2780 } | 2779 } |
2781 EnumConstantElement enumConstant = builtinElement; | 2780 EnumConstantElement enumConstant = builtinElement; |
2782 int index = enumConstant.index; | 2781 int index = enumConstant.index; |
2783 | 2782 |
2784 js.Template template = | 2783 js.Template template = |
2785 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]); | 2784 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]); |
2786 | 2785 |
2787 List<HInstruction> compiledArguments = <HInstruction>[]; | 2786 List<HInstruction> compiledArguments = <HInstruction>[]; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2872 void handleForeignJsCallInIsolate(ast.Send node) { | 2871 void handleForeignJsCallInIsolate(ast.Send node) { |
2873 Link<ast.Node> link = node.arguments; | 2872 Link<ast.Node> link = node.arguments; |
2874 if (!backend.backendUsage.isIsolateInUse) { | 2873 if (!backend.backendUsage.isIsolateInUse) { |
2875 // If the isolate library is not used, we just invoke the | 2874 // If the isolate library is not used, we just invoke the |
2876 // closure. | 2875 // closure. |
2877 visit(link.tail.head); | 2876 visit(link.tail.head); |
2878 push(new HInvokeClosure(new Selector.callClosure(0), | 2877 push(new HInvokeClosure(new Selector.callClosure(0), |
2879 <HInstruction>[pop()], commonMasks.dynamicType)); | 2878 <HInstruction>[pop()], commonMasks.dynamicType)); |
2880 } else { | 2879 } else { |
2881 // Call a helper method from the isolate library. | 2880 // Call a helper method from the isolate library. |
2882 MethodElement element = helpers.callInIsolate; | 2881 MethodElement element = commonElements.callInIsolate; |
2883 if (element == null) { | 2882 if (element == null) { |
2884 reporter.internalError(node, 'Isolate library and compiler mismatch.'); | 2883 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
2885 } | 2884 } |
2886 List<HInstruction> inputs = <HInstruction>[]; | 2885 List<HInstruction> inputs = <HInstruction>[]; |
2887 addGenericSendArgumentsToList(link, inputs); | 2886 addGenericSendArgumentsToList(link, inputs); |
2888 pushInvokeStatic(node, element, inputs, | 2887 pushInvokeStatic(node, element, inputs, |
2889 typeMask: commonMasks.dynamicType); | 2888 typeMask: commonMasks.dynamicType); |
2890 } | 2889 } |
2891 } | 2890 } |
2892 | 2891 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2948 if (!node.arguments.isEmpty) { | 2947 if (!node.arguments.isEmpty) { |
2949 reporter.internalError(node.argumentsNode, 'Too many arguments.'); | 2948 reporter.internalError(node.argumentsNode, 'Too many arguments.'); |
2950 } | 2949 } |
2951 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder), | 2950 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder), |
2952 commonMasks.dynamicType, <HInstruction>[], | 2951 commonMasks.dynamicType, <HInstruction>[], |
2953 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); | 2952 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); |
2954 } | 2953 } |
2955 | 2954 |
2956 void handleForeignSend(ast.Send node, FunctionElement element) { | 2955 void handleForeignSend(ast.Send node, FunctionElement element) { |
2957 String name = element.name; | 2956 String name = element.name; |
2958 if (name == BackendHelpers.JS) { | 2957 if (name == JavaScriptBackend.JS) { |
2959 handleForeignJs(node); | 2958 handleForeignJs(node); |
2960 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { | 2959 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { |
2961 handleForeignJsCurrentIsolateContext(node); | 2960 handleForeignJsCurrentIsolateContext(node); |
2962 } else if (name == 'JS_CALL_IN_ISOLATE') { | 2961 } else if (name == 'JS_CALL_IN_ISOLATE') { |
2963 handleForeignJsCallInIsolate(node); | 2962 handleForeignJsCallInIsolate(node); |
2964 } else if (name == 'DART_CLOSURE_TO_JS') { | 2963 } else if (name == 'DART_CLOSURE_TO_JS') { |
2965 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); | 2964 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); |
2966 } else if (name == 'RAW_DART_FUNCTION_REF') { | 2965 } else if (name == 'RAW_DART_FUNCTION_REF') { |
2967 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); | 2966 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); |
2968 } else if (name == 'JS_SET_STATIC_STATE') { | 2967 } else if (name == 'JS_SET_STATIC_STATE') { |
2969 handleForeignJsSetStaticState(node); | 2968 handleForeignJsSetStaticState(node); |
2970 } else if (name == 'JS_GET_STATIC_STATE') { | 2969 } else if (name == 'JS_GET_STATIC_STATE') { |
2971 handleForeignJsGetStaticState(node); | 2970 handleForeignJsGetStaticState(node); |
2972 } else if (name == 'JS_GET_NAME') { | 2971 } else if (name == 'JS_GET_NAME') { |
2973 handleForeignJsGetName(node); | 2972 handleForeignJsGetName(node); |
2974 } else if (name == BackendHelpers.JS_EMBEDDED_GLOBAL) { | 2973 } else if (name == JavaScriptBackend.JS_EMBEDDED_GLOBAL) { |
2975 handleForeignJsEmbeddedGlobal(node); | 2974 handleForeignJsEmbeddedGlobal(node); |
2976 } else if (name == BackendHelpers.JS_BUILTIN) { | 2975 } else if (name == JavaScriptBackend.JS_BUILTIN) { |
2977 handleForeignJsBuiltin(node); | 2976 handleForeignJsBuiltin(node); |
2978 } else if (name == 'JS_GET_FLAG') { | 2977 } else if (name == 'JS_GET_FLAG') { |
2979 handleForeignJsGetFlag(node); | 2978 handleForeignJsGetFlag(node); |
2980 } else if (name == 'JS_EFFECT') { | 2979 } else if (name == 'JS_EFFECT') { |
2981 stack.add(graph.addConstantNull(closedWorld)); | 2980 stack.add(graph.addConstantNull(closedWorld)); |
2982 } else if (name == BackendHelpers.JS_INTERCEPTOR_CONSTANT) { | 2981 } else if (name == JavaScriptBackend.JS_INTERCEPTOR_CONSTANT) { |
2983 handleJsInterceptorConstant(node); | 2982 handleJsInterceptorConstant(node); |
2984 } else if (name == 'JS_STRING_CONCAT') { | 2983 } else if (name == 'JS_STRING_CONCAT') { |
2985 handleJsStringConcat(node); | 2984 handleJsStringConcat(node); |
2986 } else { | 2985 } else { |
2987 reporter.internalError(node, "Unknown foreign: ${element}"); | 2986 reporter.internalError(node, "Unknown foreign: ${element}"); |
2988 } | 2987 } |
2989 } | 2988 } |
2990 | 2989 |
2991 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, | 2990 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, |
2992 SourceInformation sourceInformation) { | 2991 SourceInformation sourceInformation) { |
2993 // Until now we only handle these as getters. | 2992 // Until now we only handle these as getters. |
2994 invariant(node, deferredLoader.isDeferredLoaderGetter); | 2993 invariant(node, deferredLoader.isDeferredLoaderGetter); |
2995 FunctionEntity loadFunction = helpers.loadLibraryWrapper; | 2994 FunctionEntity loadFunction = commonElements.loadLibraryWrapper; |
2996 PrefixElement prefixElement = deferredLoader.enclosingElement; | 2995 PrefixElement prefixElement = deferredLoader.enclosingElement; |
2997 String loadId = | 2996 String loadId = |
2998 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); | 2997 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); |
2999 var inputs = [ | 2998 var inputs = [ |
3000 graph.addConstantString(new ast.DartString.literal(loadId), closedWorld) | 2999 graph.addConstantString(new ast.DartString.literal(loadId), closedWorld) |
3001 ]; | 3000 ]; |
3002 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType, | 3001 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType, |
3003 targetCanThrow: false)..sourceInformation = sourceInformation); | 3002 targetCanThrow: false) |
| 3003 ..sourceInformation = sourceInformation); |
3004 } | 3004 } |
3005 | 3005 |
3006 generateSuperNoSuchMethodSend( | 3006 generateSuperNoSuchMethodSend( |
3007 ast.Send node, Selector selector, List<HInstruction> arguments) { | 3007 ast.Send node, Selector selector, List<HInstruction> arguments) { |
3008 String name = selector.name; | 3008 String name = selector.name; |
3009 | 3009 |
3010 ClassElement cls = currentNonClosureClass; | 3010 ClassElement cls = currentNonClosureClass; |
3011 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 3011 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
3012 if (!Selectors.noSuchMethod_.signatureApplies(element)) { | 3012 if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
3013 ClassElement objectClass = commonElements.objectClass; | 3013 ClassElement objectClass = commonElements.objectClass; |
3014 element = objectClass.lookupMember(Identifiers.noSuchMethod_); | 3014 element = objectClass.lookupMember(Identifiers.noSuchMethod_); |
3015 } | 3015 } |
3016 if (backend.backendUsage.isInvokeOnUsed && | 3016 if (backend.backendUsage.isInvokeOnUsed && |
3017 !element.enclosingClass.isObject) { | 3017 !element.enclosingClass.isObject) { |
3018 // Register the call as dynamic if [noSuchMethod] on the super | 3018 // Register the call as dynamic if [noSuchMethod] on the super |
3019 // class is _not_ the default implementation from [Object], in | 3019 // class is _not_ the default implementation from [Object], in |
3020 // case the [noSuchMethod] implementation calls | 3020 // case the [noSuchMethod] implementation calls |
3021 // [JSInvocationMirror._invokeOn]. | 3021 // [JSInvocationMirror._invokeOn]. |
3022 // TODO(johnniwinther): Register this more precisely. | 3022 // TODO(johnniwinther): Register this more precisely. |
3023 registry?.registerDynamicUse(new DynamicUse(selector, null)); | 3023 registry?.registerDynamicUse(new DynamicUse(selector, null)); |
3024 } | 3024 } |
3025 String publicName = name; | 3025 String publicName = name; |
3026 if (selector.isSetter) publicName += '='; | 3026 if (selector.isSetter) publicName += '='; |
3027 | 3027 |
3028 ConstantValue nameConstant = | 3028 ConstantValue nameConstant = |
3029 constantSystem.createString(new ast.DartString.literal(publicName)); | 3029 constantSystem.createString(new ast.DartString.literal(publicName)); |
3030 | 3030 |
3031 js.Name internalName = backend.namer.invocationName(selector); | 3031 js.Name internalName = backend.namer.invocationName(selector); |
3032 | 3032 |
3033 MethodElement createInvocationMirror = helpers.createInvocationMirror; | 3033 MethodElement createInvocationMirror = |
| 3034 commonElements.createInvocationMirror; |
3034 var argumentsInstruction = buildLiteralList(arguments); | 3035 var argumentsInstruction = buildLiteralList(arguments); |
3035 add(argumentsInstruction); | 3036 add(argumentsInstruction); |
3036 | 3037 |
3037 var argumentNames = new List<HInstruction>(); | 3038 var argumentNames = new List<HInstruction>(); |
3038 for (String argumentName in selector.namedArguments) { | 3039 for (String argumentName in selector.namedArguments) { |
3039 ConstantValue argumentNameConstant = | 3040 ConstantValue argumentNameConstant = |
3040 constantSystem.createString(new ast.DartString.literal(argumentName)); | 3041 constantSystem.createString(new ast.DartString.literal(argumentName)); |
3041 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); | 3042 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); |
3042 } | 3043 } |
3043 var argumentNamesInstruction = buildLiteralList(argumentNames); | 3044 var argumentNamesInstruction = buildLiteralList(argumentNames); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3252 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 3253 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
3253 }); | 3254 }); |
3254 // TODO(15489): Register at codegen. | 3255 // TODO(15489): Register at codegen. |
3255 registry?.registerInstantiation(type); | 3256 registry?.registerInstantiation(type); |
3256 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); | 3257 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); |
3257 } | 3258 } |
3258 | 3259 |
3259 HInstruction callSetRuntimeTypeInfo( | 3260 HInstruction callSetRuntimeTypeInfo( |
3260 HInstruction typeInfo, HInstruction newObject) { | 3261 HInstruction typeInfo, HInstruction newObject) { |
3261 // Set the runtime type information on the object. | 3262 // Set the runtime type information on the object. |
3262 MethodElement typeInfoSetterElement = helpers.setRuntimeTypeInfo; | 3263 MethodElement typeInfoSetterElement = commonElements.setRuntimeTypeInfo; |
3263 pushInvokeStatic( | 3264 pushInvokeStatic( |
3264 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], | 3265 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], |
3265 typeMask: commonMasks.dynamicType, | 3266 typeMask: commonMasks.dynamicType, |
3266 sourceInformation: newObject.sourceInformation); | 3267 sourceInformation: newObject.sourceInformation); |
3267 | 3268 |
3268 // The new object will now be referenced through the | 3269 // The new object will now be referenced through the |
3269 // `setRuntimeTypeInfo` call. We therefore set the type of that | 3270 // `setRuntimeTypeInfo` call. We therefore set the type of that |
3270 // instruction to be of the object's type. | 3271 // instruction to be of the object's type. |
3271 assert(invariant(CURRENT_ELEMENT_SPANNABLE, | 3272 assert(invariant(CURRENT_ELEMENT_SPANNABLE, |
3272 stack.last is HInvokeStatic || stack.last == newObject, | 3273 stack.last is HInvokeStatic || stack.last == newObject, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3326 } | 3327 } |
3327 } | 3328 } |
3328 | 3329 |
3329 CallStructure callStructure = elements.getSelector(send).callStructure; | 3330 CallStructure callStructure = elements.getSelector(send).callStructure; |
3330 ConstructorElement constructorDeclaration = constructor; | 3331 ConstructorElement constructorDeclaration = constructor; |
3331 ConstructorElement constructorImplementation = constructor.implementation; | 3332 ConstructorElement constructorImplementation = constructor.implementation; |
3332 constructor = constructorImplementation.effectiveTarget; | 3333 constructor = constructorImplementation.effectiveTarget; |
3333 | 3334 |
3334 final bool isSymbolConstructor = | 3335 final bool isSymbolConstructor = |
3335 closedWorld.commonElements.isSymbolConstructor(constructorDeclaration); | 3336 closedWorld.commonElements.isSymbolConstructor(constructorDeclaration); |
3336 final bool isJSArrayTypedConstructor = | 3337 final bool isJSArrayTypedConstructor = constructorDeclaration == |
3337 constructorDeclaration == helpers.jsArrayTypedConstructor; | 3338 closedWorld.commonElements.jsArrayTypedConstructor; |
3338 | 3339 |
3339 if (isSymbolConstructor) { | 3340 if (isSymbolConstructor) { |
3340 constructor = helpers.symbolValidatedConstructor; | 3341 constructor = commonElements.symbolValidatedConstructor; |
3341 assert(invariant(send, constructor != null, | 3342 assert(invariant(send, constructor != null, |
3342 message: 'Constructor Symbol.validated is missing')); | 3343 message: 'Constructor Symbol.validated is missing')); |
3343 callStructure = helpers.symbolValidatedConstructorSelector.callStructure; | 3344 callStructure = |
| 3345 commonElements.symbolValidatedConstructorSelector.callStructure; |
3344 assert(invariant(send, callStructure != null, | 3346 assert(invariant(send, callStructure != null, |
3345 message: 'Constructor Symbol.validated is missing')); | 3347 message: 'Constructor Symbol.validated is missing')); |
3346 } | 3348 } |
3347 | 3349 |
3348 bool isRedirected = constructorDeclaration.isRedirectingFactory; | 3350 bool isRedirected = constructorDeclaration.isRedirectingFactory; |
3349 if (!constructorDeclaration.isCyclicRedirection) { | 3351 if (!constructorDeclaration.isCyclicRedirection) { |
3350 // Insert a check for every deferred redirection on the path to the | 3352 // Insert a check for every deferred redirection on the path to the |
3351 // final target. | 3353 // final target. |
3352 ConstructorElement target = constructorDeclaration; | 3354 ConstructorElement target = constructorDeclaration; |
3353 while (target.isRedirectingFactory) { | 3355 while (target.isRedirectingFactory) { |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3760 ast.Send node, ResolutionTypeVariableType typeVariable) { | 3762 ast.Send node, ResolutionTypeVariableType typeVariable) { |
3761 // GENERIC_METHODS: This provides thin support for method type variables | 3763 // GENERIC_METHODS: This provides thin support for method type variables |
3762 // by treating them as malformed when evaluated as a literal. For full | 3764 // by treating them as malformed when evaluated as a literal. For full |
3763 // support of generic methods this must be revised. | 3765 // support of generic methods this must be revised. |
3764 if (typeVariable is MethodTypeVariableType) { | 3766 if (typeVariable is MethodTypeVariableType) { |
3765 generateTypeError(node, "Method type variables are not reified"); | 3767 generateTypeError(node, "Method type variables are not reified"); |
3766 } else { | 3768 } else { |
3767 ResolutionDartType type = localsHandler.substInContext(typeVariable); | 3769 ResolutionDartType type = localsHandler.substInContext(typeVariable); |
3768 HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement, | 3770 HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement, |
3769 sourceInformation: sourceInformationBuilder.buildGet(node)); | 3771 sourceInformation: sourceInformationBuilder.buildGet(node)); |
3770 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], | 3772 pushInvokeStatic(node, commonElements.runtimeTypeToString, [value], |
3771 typeMask: commonMasks.stringType); | 3773 typeMask: commonMasks.stringType); |
3772 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); | 3774 pushInvokeStatic(node, commonElements.createRuntimeType, [pop()]); |
3773 } | 3775 } |
3774 } | 3776 } |
3775 | 3777 |
3776 /// Generate a call to a type literal. | 3778 /// Generate a call to a type literal. |
3777 void generateTypeLiteralCall(ast.Send node) { | 3779 void generateTypeLiteralCall(ast.Send node) { |
3778 // This send is of the form 'e(...)', where e is resolved to a type | 3780 // This send is of the form 'e(...)', where e is resolved to a type |
3779 // reference. We create a regular closure call on the result of the type | 3781 // reference. We create a regular closure call on the result of the type |
3780 // reference instead of creating a NoSuchMethodError to avoid pulling it | 3782 // reference instead of creating a NoSuchMethodError to avoid pulling it |
3781 // in if it is not used (e.g., in a try/catch). | 3783 // in if it is not used (e.g., in a try/catch). |
3782 HInstruction target = pop(); | 3784 HInstruction target = pop(); |
(...skipping 20 matching lines...) Expand all Loading... |
3803 internalError(Spannable node, String reason) { | 3805 internalError(Spannable node, String reason) { |
3804 reporter.internalError(node, reason); | 3806 reporter.internalError(node, reason); |
3805 } | 3807 } |
3806 | 3808 |
3807 void generateError(ast.Node node, String message, Element helper) { | 3809 void generateError(ast.Node node, String message, Element helper) { |
3808 HInstruction errorMessage = addConstantString(message); | 3810 HInstruction errorMessage = addConstantString(message); |
3809 pushInvokeStatic(node, helper, [errorMessage]); | 3811 pushInvokeStatic(node, helper, [errorMessage]); |
3810 } | 3812 } |
3811 | 3813 |
3812 void generateRuntimeError(ast.Node node, String message) { | 3814 void generateRuntimeError(ast.Node node, String message) { |
3813 MethodElement helper = helpers.throwRuntimeError; | 3815 MethodElement helper = commonElements.throwRuntimeError; |
3814 generateError(node, message, helper); | 3816 generateError(node, message, helper); |
3815 } | 3817 } |
3816 | 3818 |
3817 void generateTypeError(ast.Node node, String message) { | 3819 void generateTypeError(ast.Node node, String message) { |
3818 MethodElement helper = helpers.throwTypeError; | 3820 MethodElement helper = commonElements.throwTypeError; |
3819 generateError(node, message, helper); | 3821 generateError(node, message, helper); |
3820 } | 3822 } |
3821 | 3823 |
3822 void generateAbstractClassInstantiationError(ast.Node node, String message) { | 3824 void generateAbstractClassInstantiationError(ast.Node node, String message) { |
3823 MethodElement helper = helpers.throwAbstractClassInstantiationError; | 3825 MethodElement helper = commonElements.throwAbstractClassInstantiationError; |
3824 generateError(node, message, helper); | 3826 generateError(node, message, helper); |
3825 } | 3827 } |
3826 | 3828 |
3827 void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName, | 3829 void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName, |
3828 {Link<ast.Node> argumentNodes, | 3830 {Link<ast.Node> argumentNodes, |
3829 List<HInstruction> argumentValues, | 3831 List<HInstruction> argumentValues, |
3830 List<String> existingArguments, | 3832 List<String> existingArguments, |
3831 SourceInformation sourceInformation}) { | 3833 SourceInformation sourceInformation}) { |
3832 MethodElement helper = helpers.throwNoSuchMethod; | 3834 MethodElement helper = commonElements.throwNoSuchMethod; |
3833 ConstantValue receiverConstant = | 3835 ConstantValue receiverConstant = |
3834 constantSystem.createString(new ast.DartString.empty()); | 3836 constantSystem.createString(new ast.DartString.empty()); |
3835 HInstruction receiver = graph.addConstant(receiverConstant, closedWorld); | 3837 HInstruction receiver = graph.addConstant(receiverConstant, closedWorld); |
3836 ast.DartString dartString = new ast.DartString.literal(methodName); | 3838 ast.DartString dartString = new ast.DartString.literal(methodName); |
3837 ConstantValue nameConstant = constantSystem.createString(dartString); | 3839 ConstantValue nameConstant = constantSystem.createString(dartString); |
3838 HInstruction name = graph.addConstant(nameConstant, closedWorld); | 3840 HInstruction name = graph.addConstant(nameConstant, closedWorld); |
3839 if (argumentValues == null) { | 3841 if (argumentValues == null) { |
3840 argumentValues = <HInstruction>[]; | 3842 argumentValues = <HInstruction>[]; |
3841 argumentNodes.forEach((argumentNode) { | 3843 argumentNodes.forEach((argumentNode) { |
3842 visit(argumentNode); | 3844 visit(argumentNode); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3937 List<HInstruction> arguments, | 3939 List<HInstruction> arguments, |
3938 {SourceInformation sourceInformation}) { | 3940 {SourceInformation sourceInformation}) { |
3939 // We prefer to not inline certain operations on indexables, | 3941 // We prefer to not inline certain operations on indexables, |
3940 // because the constant folder will handle them better and turn | 3942 // because the constant folder will handle them better and turn |
3941 // them into simpler instructions that allow further | 3943 // them into simpler instructions that allow further |
3942 // optimizations. | 3944 // optimizations. |
3943 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { | 3945 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { |
3944 bool isLength = selector.isGetter && selector.name == "length"; | 3946 bool isLength = selector.isGetter && selector.name == "length"; |
3945 if (isLength || selector.isIndex) { | 3947 if (isLength || selector.isIndex) { |
3946 return closedWorld.isSubtypeOf( | 3948 return closedWorld.isSubtypeOf( |
3947 element.enclosingClass, helpers.jsIndexableClass); | 3949 element.enclosingClass, commonElements.jsIndexableClass); |
3948 } else if (selector.isIndexSet) { | 3950 } else if (selector.isIndexSet) { |
3949 return closedWorld.isSubtypeOf( | 3951 return closedWorld.isSubtypeOf( |
3950 element.enclosingClass, helpers.jsMutableIndexableClass); | 3952 element.enclosingClass, commonElements.jsMutableIndexableClass); |
3951 } else { | 3953 } else { |
3952 return false; | 3954 return false; |
3953 } | 3955 } |
3954 } | 3956 } |
3955 | 3957 |
3956 bool isOptimizableOperation(Selector selector, Element element) { | 3958 bool isOptimizableOperation(Selector selector, Element element) { |
3957 ClassElement cls = element.enclosingClass; | 3959 ClassElement cls = element.enclosingClass; |
3958 if (isOptimizableOperationOnIndexable(selector, element)) return true; | 3960 if (isOptimizableOperationOnIndexable(selector, element)) return true; |
3959 if (!backend.interceptorData.interceptedClasses.contains(cls)) | 3961 if (!backend.interceptorData.interceptedClasses.contains(cls)) |
3960 return false; | 3962 return false; |
3961 if (selector.isOperator) return true; | 3963 if (selector.isOperator) return true; |
3962 if (selector.isSetter) return true; | 3964 if (selector.isSetter) return true; |
3963 if (selector.isIndex) return true; | 3965 if (selector.isIndex) return true; |
3964 if (selector.isIndexSet) return true; | 3966 if (selector.isIndexSet) return true; |
3965 if (element == helpers.jsArrayAdd || | 3967 if (element == commonElements.jsArrayAdd || |
3966 element == helpers.jsArrayRemoveLast || | 3968 element == commonElements.jsArrayRemoveLast || |
3967 element == helpers.jsStringSplit) { | 3969 element == commonElements.jsStringSplit) { |
3968 return true; | 3970 return true; |
3969 } | 3971 } |
3970 return false; | 3972 return false; |
3971 } | 3973 } |
3972 | 3974 |
3973 MemberElement element = closedWorld.locateSingleElement(selector, mask); | 3975 MemberElement element = closedWorld.locateSingleElement(selector, mask); |
3974 if (element != null && | 3976 if (element != null && |
3975 !element.isField && | 3977 !element.isField && |
3976 !(element.isGetter && selector.isCall) && | 3978 !(element.isGetter && selector.isCall) && |
3977 !(element.isFunction && selector.isGetter) && | 3979 !(element.isFunction && selector.isGetter) && |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4078 if (type is ResolutionInterfaceType && | 4080 if (type is ResolutionInterfaceType && |
4079 backend.nativeData.isNativeClass(type.element)) { | 4081 backend.nativeData.isNativeClass(type.element)) { |
4080 nativeBehavior.typesInstantiated.add(type); | 4082 nativeBehavior.typesInstantiated.add(type); |
4081 } | 4083 } |
4082 | 4084 |
4083 // It also includes any other JS interop type if we don't trust the | 4085 // It also includes any other JS interop type if we don't trust the |
4084 // annotation or if is declared too broad. | 4086 // annotation or if is declared too broad. |
4085 if (!compiler.options.trustJSInteropTypeAnnotations || | 4087 if (!compiler.options.trustJSInteropTypeAnnotations || |
4086 type.isObject || | 4088 type.isObject || |
4087 type.isDynamic) { | 4089 type.isDynamic) { |
4088 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; | 4090 ClassElement cls = commonElements.jsJavaScriptObjectClass; |
4089 nativeBehavior.typesInstantiated.add(cls.thisType); | 4091 nativeBehavior.typesInstantiated.add(cls.thisType); |
4090 } | 4092 } |
4091 | 4093 |
4092 String code; | 4094 String code; |
4093 if (element.isGetter) { | 4095 if (element.isGetter) { |
4094 code = "#"; | 4096 code = "#"; |
4095 } else if (element.isSetter) { | 4097 } else if (element.isSetter) { |
4096 code = "# = #"; | 4098 code = "# = #"; |
4097 } else { | 4099 } else { |
4098 var args = new List.filled(arguments.length, '#').join(','); | 4100 var args = new List.filled(arguments.length, '#').join(','); |
4099 code = element.isConstructor ? "new #($args)" : "#($args)"; | 4101 code = element.isConstructor ? "new #($args)" : "#($args)"; |
4100 } | 4102 } |
4101 js.Template codeTemplate = js.js.parseForeignJS(code); | 4103 js.Template codeTemplate = js.js.parseForeignJS(code); |
4102 nativeBehavior.codeTemplate = codeTemplate; | 4104 nativeBehavior.codeTemplate = codeTemplate; |
4103 | 4105 |
4104 return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs, | 4106 return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs, |
4105 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; | 4107 nativeBehavior: nativeBehavior) |
| 4108 ..sourceInformation = sourceInformation; |
4106 } | 4109 } |
4107 | 4110 |
4108 void pushInvokeStatic( | 4111 void pushInvokeStatic( |
4109 ast.Node location, MethodElement element, List<HInstruction> arguments, | 4112 ast.Node location, MethodElement element, List<HInstruction> arguments, |
4110 {TypeMask typeMask, | 4113 {TypeMask typeMask, |
4111 ResolutionInterfaceType instanceType, | 4114 ResolutionInterfaceType instanceType, |
4112 SourceInformation sourceInformation}) { | 4115 SourceInformation sourceInformation}) { |
4113 assert(element.isDeclaration); | 4116 assert(element.isDeclaration); |
4114 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4117 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
4115 if (tryInlineMethod(element, null, null, arguments, location, | 4118 if (tryInlineMethod(element, null, null, arguments, location, |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5323 } | 5326 } |
5324 return new JumpHandler(this, element); | 5327 return new JumpHandler(this, element); |
5325 } | 5328 } |
5326 | 5329 |
5327 visitAsyncForIn(ast.AsyncForIn node) { | 5330 visitAsyncForIn(ast.AsyncForIn node) { |
5328 // The async-for is implemented with a StreamIterator. | 5331 // The async-for is implemented with a StreamIterator. |
5329 HInstruction streamIterator; | 5332 HInstruction streamIterator; |
5330 | 5333 |
5331 visit(node.expression); | 5334 visit(node.expression); |
5332 HInstruction expression = pop(); | 5335 HInstruction expression = pop(); |
5333 ConstructorElement constructor = helpers.streamIteratorConstructor; | 5336 ConstructorElement constructor = commonElements.streamIteratorConstructor; |
5334 pushInvokeStatic( | 5337 pushInvokeStatic( |
5335 node, constructor, [expression, graph.addConstantNull(closedWorld)]); | 5338 node, constructor, [expression, graph.addConstantNull(closedWorld)]); |
5336 streamIterator = pop(); | 5339 streamIterator = pop(); |
5337 | 5340 |
5338 void buildInitializer() {} | 5341 void buildInitializer() {} |
5339 | 5342 |
5340 HInstruction buildCondition() { | 5343 HInstruction buildCondition() { |
5341 Selector selector = Selectors.moveNext; | 5344 Selector selector = Selectors.moveNext; |
5342 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); | 5345 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
5343 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 5346 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5391 | 5394 |
5392 // This scheme recognizes for-in on direct lists. It does not recognize all | 5395 // This scheme recognizes for-in on direct lists. It does not recognize all |
5393 // uses of ArrayIterator. They still occur when the receiver is an Iterable | 5396 // uses of ArrayIterator. They still occur when the receiver is an Iterable |
5394 // with a `get iterator` method that delegates to another Iterable and the | 5397 // with a `get iterator` method that delegates to another Iterable and the |
5395 // method is inlined. We would require full scalar replacement in that | 5398 // method is inlined. We would require full scalar replacement in that |
5396 // case. | 5399 // case. |
5397 | 5400 |
5398 TypeMask mask = elementInferenceResults.typeOfIterator(node); | 5401 TypeMask mask = elementInferenceResults.typeOfIterator(node); |
5399 | 5402 |
5400 if (mask != null && | 5403 if (mask != null && |
5401 mask.satisfies(helpers.jsIndexableClass, closedWorld) && | 5404 mask.satisfies(commonElements.jsIndexableClass, closedWorld) && |
5402 // String is indexable but not iterable. | 5405 // String is indexable but not iterable. |
5403 !mask.satisfies(helpers.jsStringClass, closedWorld)) { | 5406 !mask.satisfies(commonElements.jsStringClass, closedWorld)) { |
5404 return buildSyncForInIndexable(node, mask); | 5407 return buildSyncForInIndexable(node, mask); |
5405 } | 5408 } |
5406 buildSyncForInIterator(node); | 5409 buildSyncForInIterator(node); |
5407 } | 5410 } |
5408 | 5411 |
5409 buildSyncForInIterator(ast.SyncForIn node) { | 5412 buildSyncForInIterator(ast.SyncForIn node) { |
5410 // Generate a structure equivalent to: | 5413 // Generate a structure equivalent to: |
5411 // Iterator<E> $iter = <iterable>.iterator; | 5414 // Iterator<E> $iter = <iterable>.iterator; |
5412 // while ($iter.moveNext()) { | 5415 // while ($iter.moveNext()) { |
5413 // <declaredIdentifier> = $iter.current; | 5416 // <declaredIdentifier> = $iter.current; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5491 | 5494 |
5492 void buildConcurrentModificationErrorCheck() { | 5495 void buildConcurrentModificationErrorCheck() { |
5493 if (originalLength == null) return; | 5496 if (originalLength == null) return; |
5494 // The static call checkConcurrentModificationError() is expanded in | 5497 // The static call checkConcurrentModificationError() is expanded in |
5495 // codegen to: | 5498 // codegen to: |
5496 // | 5499 // |
5497 // array.length == _end || throwConcurrentModificationError(array) | 5500 // array.length == _end || throwConcurrentModificationError(array) |
5498 // | 5501 // |
5499 HInstruction length = buildGetLength(); | 5502 HInstruction length = buildGetLength(); |
5500 push(new HIdentity(length, originalLength, null, boolType)); | 5503 push(new HIdentity(length, originalLength, null, boolType)); |
5501 pushInvokeStatic( | 5504 pushInvokeStatic(node, commonElements.checkConcurrentModificationError, |
5502 node, helpers.checkConcurrentModificationError, [pop(), array]); | 5505 [pop(), array]); |
5503 pop(); | 5506 pop(); |
5504 } | 5507 } |
5505 | 5508 |
5506 void buildInitializer() { | 5509 void buildInitializer() { |
5507 visit(node.expression); | 5510 visit(node.expression); |
5508 array = pop(); | 5511 array = pop(); |
5509 isFixed = isFixedLength(array.instructionType, closedWorld); | 5512 isFixed = isFixedLength(array.instructionType, closedWorld); |
5510 localsHandler.updateLocal( | 5513 localsHandler.updateLocal( |
5511 indexVariable, graph.addConstantInt(0, closedWorld)); | 5514 indexVariable, graph.addConstantInt(0, closedWorld)); |
5512 originalLength = buildGetLength(); | 5515 originalLength = buildGetLength(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5620 link = link.tail) { | 5623 link = link.tail) { |
5621 visit(link.head); | 5624 visit(link.head); |
5622 listInputs.add(pop()); | 5625 listInputs.add(pop()); |
5623 listInputs.add(pop()); | 5626 listInputs.add(pop()); |
5624 } | 5627 } |
5625 | 5628 |
5626 ConstructorElement listConstructor; | 5629 ConstructorElement listConstructor; |
5627 List<HInstruction> inputs = <HInstruction>[]; | 5630 List<HInstruction> inputs = <HInstruction>[]; |
5628 | 5631 |
5629 if (listInputs.isEmpty) { | 5632 if (listInputs.isEmpty) { |
5630 listConstructor = helpers.mapLiteralConstructorEmpty; | 5633 listConstructor = commonElements.mapLiteralConstructorEmpty; |
5631 } else { | 5634 } else { |
5632 listConstructor = helpers.mapLiteralConstructor; | 5635 listConstructor = commonElements.mapLiteralConstructor; |
5633 HLiteralList keyValuePairs = buildLiteralList(listInputs); | 5636 HLiteralList keyValuePairs = buildLiteralList(listInputs); |
5634 add(keyValuePairs); | 5637 add(keyValuePairs); |
5635 inputs.add(keyValuePairs); | 5638 inputs.add(keyValuePairs); |
5636 } | 5639 } |
5637 | 5640 |
5638 assert(listConstructor.isFactoryConstructor); | 5641 assert(listConstructor.isFactoryConstructor); |
5639 | 5642 |
5640 ConstructorElement constructorElement = listConstructor; | 5643 ConstructorElement constructorElement = listConstructor; |
5641 listConstructor = constructorElement.effectiveTarget; | 5644 listConstructor = constructorElement.effectiveTarget; |
5642 | 5645 |
5643 ResolutionInterfaceType type = elements.getType(node); | 5646 ResolutionInterfaceType type = elements.getType(node); |
5644 ResolutionInterfaceType expectedType = | 5647 ResolutionInterfaceType expectedType = |
5645 constructorElement.computeEffectiveTargetType(type); | 5648 constructorElement.computeEffectiveTargetType(type); |
5646 expectedType = localsHandler.substInContext(expectedType); | 5649 expectedType = localsHandler.substInContext(expectedType); |
5647 | 5650 |
5648 ClassElement cls = listConstructor.enclosingClass; | 5651 ClassElement cls = listConstructor.enclosingClass; |
5649 | 5652 |
5650 MethodElement createFunction = listConstructor; | 5653 MethodElement createFunction = listConstructor; |
5651 if (backend.rtiNeed.classNeedsRti(cls)) { | 5654 if (backend.rtiNeed.classNeedsRti(cls)) { |
5652 List<HInstruction> typeInputs = <HInstruction>[]; | 5655 List<HInstruction> typeInputs = <HInstruction>[]; |
5653 expectedType.typeArguments.forEach((ResolutionDartType argument) { | 5656 expectedType.typeArguments.forEach((ResolutionDartType argument) { |
5654 typeInputs | 5657 typeInputs |
5655 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 5658 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
5656 }); | 5659 }); |
5657 | 5660 |
5658 // We lift this common call pattern into a helper function to save space | 5661 // We lift this common call pattern into a helper function to save space |
5659 // in the output. | 5662 // in the output. |
5660 if (typeInputs.every((HInstruction input) => input.isNull())) { | 5663 if (typeInputs.every((HInstruction input) => input.isNull())) { |
5661 if (listInputs.isEmpty) { | 5664 if (listInputs.isEmpty) { |
5662 createFunction = helpers.mapLiteralUntypedEmptyMaker; | 5665 createFunction = commonElements.mapLiteralUntypedEmptyMaker; |
5663 } else { | 5666 } else { |
5664 createFunction = helpers.mapLiteralUntypedMaker; | 5667 createFunction = commonElements.mapLiteralUntypedMaker; |
5665 } | 5668 } |
5666 } else { | 5669 } else { |
5667 inputs.addAll(typeInputs); | 5670 inputs.addAll(typeInputs); |
5668 } | 5671 } |
5669 } | 5672 } |
5670 | 5673 |
5671 // If rti is needed and the map literal has no type parameters, | 5674 // If rti is needed and the map literal has no type parameters, |
5672 // 'constructor' is a static function that forwards the call to the factory | 5675 // 'constructor' is a static function that forwards the call to the factory |
5673 // constructor without type parameters. | 5676 // constructor without type parameters. |
5674 assert(createFunction is ConstructorElement || | 5677 assert(createFunction is ConstructorElement || |
5675 createFunction is FunctionElement); | 5678 createFunction is FunctionElement); |
5676 | 5679 |
5677 // The instruction type will always be a subtype of the mapLiteralClass, but | 5680 // The instruction type will always be a subtype of the mapLiteralClass, but |
5678 // type inference might discover a more specific type, or find nothing (in | 5681 // type inference might discover a more specific type, or find nothing (in |
5679 // dart2js unit tests). | 5682 // dart2js unit tests). |
5680 TypeMask mapType = | 5683 TypeMask mapType = new TypeMask.nonNullSubtype( |
5681 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, closedWorld); | 5684 commonElements.mapLiteralClass, closedWorld); |
5682 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( | 5685 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( |
5683 createFunction, globalInferenceResults); | 5686 createFunction, globalInferenceResults); |
5684 TypeMask instructionType = | 5687 TypeMask instructionType = |
5685 mapType.intersection(returnTypeMask, closedWorld); | 5688 mapType.intersection(returnTypeMask, closedWorld); |
5686 | 5689 |
5687 addInlinedInstantiation(expectedType); | 5690 addInlinedInstantiation(expectedType); |
5688 pushInvokeStatic(node, createFunction, inputs, | 5691 pushInvokeStatic(node, createFunction, inputs, |
5689 typeMask: instructionType, instanceType: expectedType); | 5692 typeMask: instructionType, instanceType: expectedType); |
5690 removeInlinedInstantiation(expectedType); | 5693 removeInlinedInstantiation(expectedType); |
5691 } | 5694 } |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5978 // An HSwitch has n inputs and n+1 successors, the last being the | 5981 // An HSwitch has n inputs and n+1 successors, the last being the |
5979 // default case. | 5982 // default case. |
5980 expressionEnd.addSuccessor(block); | 5983 expressionEnd.addSuccessor(block); |
5981 hasDefault = true; | 5984 hasDefault = true; |
5982 } | 5985 } |
5983 open(block); | 5986 open(block); |
5984 localsHandler = new LocalsHandler.from(savedLocals); | 5987 localsHandler = new LocalsHandler.from(savedLocals); |
5985 buildSwitchCase(switchCase); | 5988 buildSwitchCase(switchCase); |
5986 if (!isAborted()) { | 5989 if (!isAborted()) { |
5987 if (caseIterator.hasNext && isReachable) { | 5990 if (caseIterator.hasNext && isReachable) { |
5988 pushInvokeStatic(switchCase, helpers.fallThroughError, []); | 5991 pushInvokeStatic(switchCase, commonElements.fallThroughError, []); |
5989 HInstruction error = pop(); | 5992 HInstruction error = pop(); |
5990 closeAndGotoExit(new HThrow(error, error.sourceInformation)); | 5993 closeAndGotoExit(new HThrow(error, error.sourceInformation)); |
5991 } else if (!isDefaultCase(switchCase)) { | 5994 } else if (!isDefaultCase(switchCase)) { |
5992 // If there is no default, we will add one later to avoid | 5995 // If there is no default, we will add one later to avoid |
5993 // the critical edge. So we generate a break statement to make | 5996 // the critical edge. So we generate a break statement to make |
5994 // sure the last case does not fall through to the default case. | 5997 // sure the last case does not fall through to the default case. |
5995 jumpHandler.generateBreak(); | 5998 jumpHandler.generateBreak(); |
5996 } | 5999 } |
5997 } | 6000 } |
5998 statements.add( | 6001 statements.add( |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6198 startCatchBlock = graph.addNewBlock(); | 6201 startCatchBlock = graph.addNewBlock(); |
6199 open(startCatchBlock); | 6202 open(startCatchBlock); |
6200 // Note that the name of this local is irrelevant. | 6203 // Note that the name of this local is irrelevant. |
6201 SyntheticLocal local = | 6204 SyntheticLocal local = |
6202 new SyntheticLocal('exception', localsHandler.executableContext); | 6205 new SyntheticLocal('exception', localsHandler.executableContext); |
6203 exception = new HLocalValue(local, commonMasks.nonNullType); | 6206 exception = new HLocalValue(local, commonMasks.nonNullType); |
6204 add(exception); | 6207 add(exception); |
6205 HInstruction oldRethrowableException = rethrowableException; | 6208 HInstruction oldRethrowableException = rethrowableException; |
6206 rethrowableException = exception; | 6209 rethrowableException = exception; |
6207 | 6210 |
6208 pushInvokeStatic(node, helpers.exceptionUnwrapper, [exception]); | 6211 pushInvokeStatic(node, commonElements.exceptionUnwrapper, [exception]); |
6209 HInvokeStatic unwrappedException = pop(); | 6212 HInvokeStatic unwrappedException = pop(); |
6210 tryInstruction.exception = exception; | 6213 tryInstruction.exception = exception; |
6211 Link<ast.Node> link = node.catchBlocks.nodes; | 6214 Link<ast.Node> link = node.catchBlocks.nodes; |
6212 | 6215 |
6213 void pushCondition(ast.CatchBlock catchBlock) { | 6216 void pushCondition(ast.CatchBlock catchBlock) { |
6214 if (catchBlock.onKeyword != null) { | 6217 if (catchBlock.onKeyword != null) { |
6215 ResolutionDartType type = elements.getType(catchBlock.type); | 6218 ResolutionDartType type = elements.getType(catchBlock.type); |
6216 if (type == null) { | 6219 if (type == null) { |
6217 reporter.internalError(catchBlock.type, 'On with no type.'); | 6220 reporter.internalError(catchBlock.type, 'On with no type.'); |
6218 } | 6221 } |
(...skipping 24 matching lines...) Expand all Loading... |
6243 void visitThen() { | 6246 void visitThen() { |
6244 ast.CatchBlock catchBlock = link.head; | 6247 ast.CatchBlock catchBlock = link.head; |
6245 link = link.tail; | 6248 link = link.tail; |
6246 if (catchBlock.exception != null) { | 6249 if (catchBlock.exception != null) { |
6247 LocalVariableElement exceptionVariable = | 6250 LocalVariableElement exceptionVariable = |
6248 elements[catchBlock.exception]; | 6251 elements[catchBlock.exception]; |
6249 localsHandler.updateLocal(exceptionVariable, unwrappedException); | 6252 localsHandler.updateLocal(exceptionVariable, unwrappedException); |
6250 } | 6253 } |
6251 ast.Node trace = catchBlock.trace; | 6254 ast.Node trace = catchBlock.trace; |
6252 if (trace != null) { | 6255 if (trace != null) { |
6253 pushInvokeStatic(trace, helpers.traceFromException, [exception]); | 6256 pushInvokeStatic( |
| 6257 trace, commonElements.traceFromException, [exception]); |
6254 HInstruction traceInstruction = pop(); | 6258 HInstruction traceInstruction = pop(); |
6255 LocalVariableElement traceVariable = elements[trace]; | 6259 LocalVariableElement traceVariable = elements[trace]; |
6256 localsHandler.updateLocal(traceVariable, traceInstruction); | 6260 localsHandler.updateLocal(traceVariable, traceInstruction); |
6257 } | 6261 } |
6258 visit(catchBlock); | 6262 visit(catchBlock); |
6259 } | 6263 } |
6260 | 6264 |
6261 void visitElse() { | 6265 void visitElse() { |
6262 if (link.isEmpty) { | 6266 if (link.isEmpty) { |
6263 closeAndGotoExit(new HThrow(exception, exception.sourceInformation, | 6267 closeAndGotoExit(new HThrow(exception, exception.sourceInformation, |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6760 this.oldReturnLocal, | 6764 this.oldReturnLocal, |
6761 this.oldReturnType, | 6765 this.oldReturnType, |
6762 this.oldResolvedAst, | 6766 this.oldResolvedAst, |
6763 this.oldStack, | 6767 this.oldStack, |
6764 this.oldLocalsHandler, | 6768 this.oldLocalsHandler, |
6765 this.inTryStatement, | 6769 this.inTryStatement, |
6766 this.allFunctionsCalledOnce, | 6770 this.allFunctionsCalledOnce, |
6767 this.oldElementInferenceResults) | 6771 this.oldElementInferenceResults) |
6768 : super(function); | 6772 : super(function); |
6769 } | 6773 } |
OLD | NEW |