| 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 |