OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:collection'; | 5 import 'dart:collection'; |
6 | 6 |
7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
8 | 8 |
9 import '../closure.dart'; | 9 import '../closure.dart'; |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 * | 547 * |
548 * However, inlining can only be performed when the target function can be | 548 * However, inlining can only be performed when the target function can be |
549 * resolved statically. The defaults can therefore be included at this point. | 549 * resolved statically. The defaults can therefore be included at this point. |
550 * | 550 * |
551 * The [providedArguments] list contains first all positional arguments, then | 551 * The [providedArguments] list contains first all positional arguments, then |
552 * the provided named arguments (the named arguments that are defined in the | 552 * the provided named arguments (the named arguments that are defined in the |
553 * [selector]) in a specific order (see [addDynamicSendArgumentsToList]). | 553 * [selector]) in a specific order (see [addDynamicSendArgumentsToList]). |
554 */ | 554 */ |
555 List<HInstruction> completeDynamicSendArgumentsList(Selector selector, | 555 List<HInstruction> completeDynamicSendArgumentsList(Selector selector, |
556 FunctionElement function, List<HInstruction> providedArguments) { | 556 FunctionElement function, List<HInstruction> providedArguments) { |
557 assert(selector.applies(function, compiler.world)); | 557 assert(selector.applies(function, compiler.closedWorld)); |
558 FunctionSignature signature = function.functionSignature; | 558 FunctionSignature signature = function.functionSignature; |
559 List<HInstruction> compiledArguments = new List<HInstruction>( | 559 List<HInstruction> compiledArguments = new List<HInstruction>( |
560 signature.parameterCount + 1); // Plus one for receiver. | 560 signature.parameterCount + 1); // Plus one for receiver. |
561 | 561 |
562 compiledArguments[0] = providedArguments[0]; // Receiver. | 562 compiledArguments[0] = providedArguments[0]; // Receiver. |
563 int index = 1; | 563 int index = 1; |
564 for (; index <= signature.requiredParameterCount; index++) { | 564 for (; index <= signature.requiredParameterCount; index++) { |
565 compiledArguments[index] = providedArguments[index]; | 565 compiledArguments[index] = providedArguments[index]; |
566 } | 566 } |
567 if (!signature.optionalParametersAreNamed) { | 567 if (!signature.optionalParametersAreNamed) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 bool meetsHardConstraints() { | 641 bool meetsHardConstraints() { |
642 if (compiler.options.disableInlining) return false; | 642 if (compiler.options.disableInlining) return false; |
643 | 643 |
644 assert(invariant( | 644 assert(invariant( |
645 currentNode != null ? currentNode : element, | 645 currentNode != null ? currentNode : element, |
646 selector != null || | 646 selector != null || |
647 Elements.isStaticOrTopLevel(element) || | 647 Elements.isStaticOrTopLevel(element) || |
648 element.isGenerativeConstructorBody, | 648 element.isGenerativeConstructorBody, |
649 message: "Missing selector for inlining of $element.")); | 649 message: "Missing selector for inlining of $element.")); |
650 if (selector != null) { | 650 if (selector != null) { |
651 if (!selector.applies(function, compiler.world)) return false; | 651 if (!selector.applies(function, compiler.closedWorld)) return false; |
652 if (mask != null && !mask.canHit(function, selector, compiler.world)) { | 652 if (mask != null && |
| 653 !mask.canHit(function, selector, compiler.closedWorld)) { |
653 return false; | 654 return false; |
654 } | 655 } |
655 } | 656 } |
656 | 657 |
657 if (backend.isJsInterop(element)) return false; | 658 if (backend.isJsInterop(element)) return false; |
658 | 659 |
659 // Don't inline operator== methods if the parameter can be null. | 660 // Don't inline operator== methods if the parameter can be null. |
660 if (element.name == '==') { | 661 if (element.name == '==') { |
661 if (element.enclosingClass != coreClasses.objectClass && | 662 if (element.enclosingClass != coreClasses.objectClass && |
662 providedArguments[1].canBeNull()) { | 663 providedArguments[1].canBeNull()) { |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 return graph.addConstant(getConstantForNode(node), compiler); | 888 return graph.addConstant(getConstantForNode(node), compiler); |
888 } | 889 } |
889 | 890 |
890 /** | 891 /** |
891 * Documentation wanted -- johnniwinther | 892 * Documentation wanted -- johnniwinther |
892 * | 893 * |
893 * Invariant: [functionElement] must be an implementation element. | 894 * Invariant: [functionElement] must be an implementation element. |
894 */ | 895 */ |
895 HGraph buildMethod(FunctionElement functionElement) { | 896 HGraph buildMethod(FunctionElement functionElement) { |
896 assert(invariant(functionElement, functionElement.isImplementation)); | 897 assert(invariant(functionElement, functionElement.isImplementation)); |
897 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement); | 898 graph.calledInLoop = compiler.closedWorld.isCalledInLoop(functionElement); |
898 ast.FunctionExpression function = resolvedAst.node; | 899 ast.FunctionExpression function = resolvedAst.node; |
899 assert(function != null); | 900 assert(function != null); |
900 assert(elements.getFunctionDefinition(function) != null); | 901 assert(elements.getFunctionDefinition(function) != null); |
901 openFunction(functionElement, function); | 902 openFunction(functionElement, function); |
902 String name = functionElement.name; | 903 String name = functionElement.name; |
903 if (backend.isJsInterop(functionElement)) { | 904 if (backend.isJsInterop(functionElement)) { |
904 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), | 905 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), |
905 sourceInformationBuilder.buildGeneric(function))); | 906 sourceInformationBuilder.buildGeneric(function))); |
906 var value = pop(); | 907 var value = pop(); |
907 closeAndGotoExit(new HReturn( | 908 closeAndGotoExit(new HReturn( |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 assert(invariant( | 1476 assert(invariant( |
1476 member, isNativeUpgradeFactory || compiler.compilationFailed)); | 1477 member, isNativeUpgradeFactory || compiler.compilationFailed)); |
1477 } else { | 1478 } else { |
1478 fields.add(member); | 1479 fields.add(member); |
1479 DartType type = localsHandler.substInContext(member.type); | 1480 DartType type = localsHandler.substInContext(member.type); |
1480 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); | 1481 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); |
1481 } | 1482 } |
1482 }, includeSuperAndInjectedMembers: true); | 1483 }, includeSuperAndInjectedMembers: true); |
1483 | 1484 |
1484 InterfaceType type = classElement.thisType; | 1485 InterfaceType type = classElement.thisType; |
1485 TypeMask ssaType = | 1486 TypeMask ssaType = new TypeMask.nonNullExact( |
1486 new TypeMask.nonNullExact(classElement.declaration, compiler.world); | 1487 classElement.declaration, compiler.closedWorld); |
1487 List<DartType> instantiatedTypes; | 1488 List<DartType> instantiatedTypes; |
1488 addInlinedInstantiation(type); | 1489 addInlinedInstantiation(type); |
1489 if (!currentInlinedInstantiations.isEmpty) { | 1490 if (!currentInlinedInstantiations.isEmpty) { |
1490 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | 1491 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); |
1491 } | 1492 } |
1492 | 1493 |
1493 HInstruction newObject; | 1494 HInstruction newObject; |
1494 if (!isNativeUpgradeFactory) { | 1495 if (!isNativeUpgradeFactory) { |
1495 newObject = new HCreate( | 1496 newObject = new HCreate( |
1496 classElement, constructorArguments, ssaType, instantiatedTypes); | 1497 classElement, constructorArguments, ssaType, instantiatedTypes); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 }); | 1590 }); |
1590 } | 1591 } |
1591 | 1592 |
1592 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining. | 1593 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining. |
1593 tryInlineMethod(body, null, null, bodyCallInputs, function)) { | 1594 tryInlineMethod(body, null, null, bodyCallInputs, function)) { |
1594 pop(); | 1595 pop(); |
1595 } else { | 1596 } else { |
1596 HInvokeConstructorBody invoke = new HInvokeConstructorBody( | 1597 HInvokeConstructorBody invoke = new HInvokeConstructorBody( |
1597 body.declaration, bodyCallInputs, backend.nonNullType); | 1598 body.declaration, bodyCallInputs, backend.nonNullType); |
1598 invoke.sideEffects = | 1599 invoke.sideEffects = |
1599 compiler.world.getSideEffectsOfElement(constructor); | 1600 compiler.closedWorld.getSideEffectsOfElement(constructor); |
1600 add(invoke); | 1601 add(invoke); |
1601 } | 1602 } |
1602 } | 1603 } |
1603 if (inliningStack.isEmpty) { | 1604 if (inliningStack.isEmpty) { |
1604 closeAndGotoExit(new HReturn(newObject, | 1605 closeAndGotoExit(new HReturn(newObject, |
1605 sourceInformationBuilder.buildImplicitReturn(functionElement))); | 1606 sourceInformationBuilder.buildImplicitReturn(functionElement))); |
1606 return closeFunction(); | 1607 return closeFunction(); |
1607 } else { | 1608 } else { |
1608 localsHandler.updateLocal(returnLocal, newObject); | 1609 localsHandler.updateLocal(returnLocal, newObject); |
1609 return null; | 1610 return null; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 HInstruction buildTypeConversion( | 1732 HInstruction buildTypeConversion( |
1732 HInstruction original, DartType type, int kind) { | 1733 HInstruction original, DartType type, int kind) { |
1733 if (type == null) return original; | 1734 if (type == null) return original; |
1734 // GENERIC_METHODS: The following statement was added for parsing and | 1735 // GENERIC_METHODS: The following statement was added for parsing and |
1735 // ignoring method type variables; must be generalized for full support of | 1736 // ignoring method type variables; must be generalized for full support of |
1736 // generic methods. | 1737 // generic methods. |
1737 type = type.dynamifyMethodTypeVariableType; | 1738 type = type.dynamifyMethodTypeVariableType; |
1738 type = type.unaliased; | 1739 type = type.unaliased; |
1739 assert(assertTypeInContext(type, original)); | 1740 assert(assertTypeInContext(type, original)); |
1740 if (type.isInterfaceType && !type.treatAsRaw) { | 1741 if (type.isInterfaceType && !type.treatAsRaw) { |
1741 TypeMask subtype = new TypeMask.subtype(type.element, compiler.world); | 1742 TypeMask subtype = |
| 1743 new TypeMask.subtype(type.element, compiler.closedWorld); |
1742 HInstruction representations = buildTypeArgumentRepresentations(type); | 1744 HInstruction representations = buildTypeArgumentRepresentations(type); |
1743 add(representations); | 1745 add(representations); |
1744 return new HTypeConversion.withTypeRepresentation( | 1746 return new HTypeConversion.withTypeRepresentation( |
1745 type, kind, subtype, original, representations); | 1747 type, kind, subtype, original, representations); |
1746 } else if (type.isTypeVariable) { | 1748 } else if (type.isTypeVariable) { |
1747 TypeMask subtype = original.instructionType; | 1749 TypeMask subtype = original.instructionType; |
1748 HInstruction typeVariable = addTypeVariableReference(type); | 1750 HInstruction typeVariable = addTypeVariableReference(type); |
1749 return new HTypeConversion.withTypeRepresentation( | 1751 return new HTypeConversion.withTypeRepresentation( |
1750 type, kind, subtype, original, typeVariable); | 1752 type, kind, subtype, original, typeVariable); |
1751 } else if (type.isFunctionType) { | 1753 } else if (type.isFunctionType) { |
(...skipping 20 matching lines...) Expand all Loading... |
1772 HInstruction _trustType(HInstruction original, DartType type) { | 1774 HInstruction _trustType(HInstruction original, DartType type) { |
1773 assert(compiler.options.trustTypeAnnotations); | 1775 assert(compiler.options.trustTypeAnnotations); |
1774 assert(type != null); | 1776 assert(type != null); |
1775 type = localsHandler.substInContext(type); | 1777 type = localsHandler.substInContext(type); |
1776 type = type.unaliased; | 1778 type = type.unaliased; |
1777 if (type.isDynamic) return original; | 1779 if (type.isDynamic) return original; |
1778 if (!type.isInterfaceType) return original; | 1780 if (!type.isInterfaceType) return original; |
1779 if (type.isObject) return original; | 1781 if (type.isObject) return original; |
1780 // The type element is either a class or the void element. | 1782 // The type element is either a class or the void element. |
1781 Element element = type.element; | 1783 Element element = type.element; |
1782 TypeMask mask = new TypeMask.subtype(element, compiler.world); | 1784 TypeMask mask = new TypeMask.subtype(element, compiler.closedWorld); |
1783 return new HTypeKnown.pinned(mask, original); | 1785 return new HTypeKnown.pinned(mask, original); |
1784 } | 1786 } |
1785 | 1787 |
1786 HInstruction _checkType(HInstruction original, DartType type, int kind) { | 1788 HInstruction _checkType(HInstruction original, DartType type, int kind) { |
1787 assert(compiler.options.enableTypeAssertions); | 1789 assert(compiler.options.enableTypeAssertions); |
1788 assert(type != null); | 1790 assert(type != null); |
1789 type = localsHandler.substInContext(type); | 1791 type = localsHandler.substInContext(type); |
1790 HInstruction other = buildTypeConversion(original, type, kind); | 1792 HInstruction other = buildTypeConversion(original, type, kind); |
1791 registry?.registerTypeUse(new TypeUse.isCheck(type)); | 1793 registry?.registerTypeUse(new TypeUse.isCheck(type)); |
1792 return other; | 1794 return other; |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2417 | 2419 |
2418 List<HInstruction> capturedVariables = <HInstruction>[]; | 2420 List<HInstruction> capturedVariables = <HInstruction>[]; |
2419 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 2421 closureClassElement.closureFields.forEach((ClosureFieldElement field) { |
2420 Local capturedLocal = | 2422 Local capturedLocal = |
2421 nestedClosureData.getLocalVariableForClosureField(field); | 2423 nestedClosureData.getLocalVariableForClosureField(field); |
2422 assert(capturedLocal != null); | 2424 assert(capturedLocal != null); |
2423 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2425 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
2424 }); | 2426 }); |
2425 | 2427 |
2426 TypeMask type = | 2428 TypeMask type = |
2427 new TypeMask.nonNullExact(closureClassElement, compiler.world); | 2429 new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld); |
2428 push(new HCreate(closureClassElement, capturedVariables, type) | 2430 push(new HCreate(closureClassElement, capturedVariables, type) |
2429 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); | 2431 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); |
2430 | 2432 |
2431 Element methodElement = nestedClosureData.closureElement; | 2433 Element methodElement = nestedClosureData.closureElement; |
2432 registry?.registerInstantiatedClosure(methodElement); | 2434 registry?.registerInstantiatedClosure(methodElement); |
2433 } | 2435 } |
2434 | 2436 |
2435 visitFunctionDeclaration(ast.FunctionDeclaration node) { | 2437 visitFunctionDeclaration(ast.FunctionDeclaration node) { |
2436 assert(isReachable); | 2438 assert(isReachable); |
2437 visit(node.function); | 2439 visit(node.function); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2689 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); | 2691 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); |
2690 } else { | 2692 } else { |
2691 instruction = graph.addConstant(value, compiler, | 2693 instruction = graph.addConstant(value, compiler, |
2692 sourceInformation: sourceInformation); | 2694 sourceInformation: sourceInformation); |
2693 } | 2695 } |
2694 stack.add(instruction); | 2696 stack.add(instruction); |
2695 // The inferrer may have found a better type than the constant | 2697 // The inferrer may have found a better type than the constant |
2696 // handler in the case of lists, because the constant handler | 2698 // handler in the case of lists, because the constant handler |
2697 // does not look at elements in the list. | 2699 // does not look at elements in the list. |
2698 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler); | 2700 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler); |
2699 if (!type.containsAll(compiler.world) && !instruction.isConstantNull()) { | 2701 if (!type.containsAll(compiler.closedWorld) && |
| 2702 !instruction.isConstantNull()) { |
2700 // TODO(13429): The inferrer should know that an element | 2703 // TODO(13429): The inferrer should know that an element |
2701 // cannot be null. | 2704 // cannot be null. |
2702 instruction.instructionType = type.nonNullable(); | 2705 instruction.instructionType = type.nonNullable(); |
2703 } | 2706 } |
2704 } | 2707 } |
2705 | 2708 |
2706 @override | 2709 @override |
2707 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) { | 2710 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) { |
2708 generateIsDeferredLoadedCheckIfNeeded(prefix, node); | 2711 generateIsDeferredLoadedCheckIfNeeded(prefix, node); |
2709 } | 2712 } |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3035 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); | 3038 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); |
3036 HInstruction call = pop(); | 3039 HInstruction call = pop(); |
3037 return new HIs.variable(type, expression, call, backend.boolType); | 3040 return new HIs.variable(type, expression, call, backend.boolType); |
3038 } else if (RuntimeTypes.hasTypeArguments(type)) { | 3041 } else if (RuntimeTypes.hasTypeArguments(type)) { |
3039 ClassElement element = type.element; | 3042 ClassElement element = type.element; |
3040 Element helper = helpers.checkSubtype; | 3043 Element helper = helpers.checkSubtype; |
3041 HInstruction representations = buildTypeArgumentRepresentations(type); | 3044 HInstruction representations = buildTypeArgumentRepresentations(type); |
3042 add(representations); | 3045 add(representations); |
3043 js.Name operator = backend.namer.operatorIs(element); | 3046 js.Name operator = backend.namer.operatorIs(element); |
3044 HInstruction isFieldName = addConstantStringFromName(operator); | 3047 HInstruction isFieldName = addConstantStringFromName(operator); |
3045 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element) | 3048 HInstruction asFieldName = compiler.closedWorld |
| 3049 .hasAnyStrictSubtype(element) |
3046 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 3050 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
3047 : graph.addConstantNull(compiler); | 3051 : graph.addConstantNull(compiler); |
3048 List<HInstruction> inputs = <HInstruction>[ | 3052 List<HInstruction> inputs = <HInstruction>[ |
3049 expression, | 3053 expression, |
3050 isFieldName, | 3054 isFieldName, |
3051 representations, | 3055 representations, |
3052 asFieldName | 3056 asFieldName |
3053 ]; | 3057 ]; |
3054 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); | 3058 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); |
3055 HInstruction call = pop(); | 3059 HInstruction call = pop(); |
3056 return new HIs.compound(type, expression, call, backend.boolType); | 3060 return new HIs.compound(type, expression, call, backend.boolType); |
3057 } else { | 3061 } else { |
3058 if (backend.hasDirectCheckFor(type)) { | 3062 if (backend.hasDirectCheckFor(type)) { |
3059 return new HIs.direct(type, expression, backend.boolType); | 3063 return new HIs.direct(type, expression, backend.boolType); |
3060 } | 3064 } |
3061 // The interceptor is not always needed. It is removed by optimization | 3065 // The interceptor is not always needed. It is removed by optimization |
3062 // when the receiver type or tested type permit. | 3066 // when the receiver type or tested type permit. |
3063 return new HIs.raw( | 3067 return new HIs.raw( |
3064 type, expression, invokeInterceptor(expression), backend.boolType); | 3068 type, expression, invokeInterceptor(expression), backend.boolType); |
3065 } | 3069 } |
3066 } | 3070 } |
3067 | 3071 |
3068 HInstruction buildFunctionType(FunctionType type) { | 3072 HInstruction buildFunctionType(FunctionType type) { |
3069 type.accept(new TypeBuilder(compiler.world), this); | 3073 type.accept(new TypeBuilder(compiler.closedWorld), this); |
3070 return pop(); | 3074 return pop(); |
3071 } | 3075 } |
3072 | 3076 |
3073 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { | 3077 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { |
3074 CallStructure callStructure = elements.getSelector(node).callStructure; | 3078 CallStructure callStructure = elements.getSelector(node).callStructure; |
3075 if (callStructure.namedArgumentCount == 0) { | 3079 if (callStructure.namedArgumentCount == 0) { |
3076 addGenericSendArgumentsToList(node.arguments, list); | 3080 addGenericSendArgumentsToList(node.arguments, list); |
3077 } else { | 3081 } else { |
3078 // Visit positional arguments and add them to the list. | 3082 // Visit positional arguments and add them to the list. |
3079 Link<ast.Node> arguments = node.arguments; | 3083 Link<ast.Node> arguments = node.arguments; |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3676 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); | 3680 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); |
3677 } | 3681 } |
3678 | 3682 |
3679 /// Generate a call to a super method or constructor. | 3683 /// Generate a call to a super method or constructor. |
3680 void generateSuperInvoke(ast.Send node, FunctionElement function, | 3684 void generateSuperInvoke(ast.Send node, FunctionElement function, |
3681 SourceInformation sourceInformation) { | 3685 SourceInformation sourceInformation) { |
3682 // TODO(5347): Try to avoid the need for calling [implementation] before | 3686 // TODO(5347): Try to avoid the need for calling [implementation] before |
3683 // calling [makeStaticArgumentList]. | 3687 // calling [makeStaticArgumentList]. |
3684 Selector selector = elements.getSelector(node); | 3688 Selector selector = elements.getSelector(node); |
3685 assert(invariant( | 3689 assert(invariant( |
3686 node, selector.applies(function.implementation, compiler.world), | 3690 node, selector.applies(function.implementation, compiler.closedWorld), |
3687 message: "$selector does not apply to ${function.implementation}")); | 3691 message: "$selector does not apply to ${function.implementation}")); |
3688 List<HInstruction> inputs = makeStaticArgumentList( | 3692 List<HInstruction> inputs = makeStaticArgumentList( |
3689 selector.callStructure, node.arguments, function.implementation); | 3693 selector.callStructure, node.arguments, function.implementation); |
3690 push(buildInvokeSuper(selector, function, inputs, sourceInformation)); | 3694 push(buildInvokeSuper(selector, function, inputs, sourceInformation)); |
3691 } | 3695 } |
3692 | 3696 |
3693 /// Access the value from the super [element]. | 3697 /// Access the value from the super [element]. |
3694 void handleSuperGet(ast.Send node, Element element) { | 3698 void handleSuperGet(ast.Send node, Element element) { |
3695 Selector selector = elements.getSelector(node); | 3699 Selector selector = elements.getSelector(node); |
3696 SourceInformation sourceInformation = | 3700 SourceInformation sourceInformation = |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3841 } | 3845 } |
3842 | 3846 |
3843 void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) { | 3847 void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) { |
3844 Selector selector = elements.getSelector(node); | 3848 Selector selector = elements.getSelector(node); |
3845 List<HInstruction> inputs = <HInstruction>[]; | 3849 List<HInstruction> inputs = <HInstruction>[]; |
3846 addGenericSendArgumentsToList(arguments.nodes, inputs); | 3850 addGenericSendArgumentsToList(arguments.nodes, inputs); |
3847 generateSuperNoSuchMethodSend(node, selector, inputs); | 3851 generateSuperNoSuchMethodSend(node, selector, inputs); |
3848 } | 3852 } |
3849 | 3853 |
3850 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { | 3854 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { |
3851 ClassWorld classWorld = compiler.world; | 3855 ClassWorld classWorld = compiler.closedWorld; |
3852 if (classWorld.isUsedAsMixin(cls)) return true; | 3856 if (classWorld.isUsedAsMixin(cls)) return true; |
3853 | 3857 |
3854 return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) { | 3858 return compiler.closedWorld.anyStrictSubclassOf(cls, |
| 3859 (ClassElement subclass) { |
3855 return !rti.isTrivialSubstitution(subclass, cls); | 3860 return !rti.isTrivialSubstitution(subclass, cls); |
3856 }); | 3861 }); |
3857 } | 3862 } |
3858 | 3863 |
3859 /** | 3864 /** |
3860 * Generate code to extract the type argument from the object. | 3865 * Generate code to extract the type argument from the object. |
3861 */ | 3866 */ |
3862 HInstruction readTypeVariable(TypeVariableType variable, | 3867 HInstruction readTypeVariable(TypeVariableType variable, |
3863 {SourceInformation sourceInformation}) { | 3868 {SourceInformation sourceInformation}) { |
3864 assert(sourceElement.isInstanceMember); | 3869 assert(sourceElement.isInstanceMember); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4026 Elements.isGrowableListConstructorCall(elements[send], send, compiler); | 4031 Elements.isGrowableListConstructorCall(elements[send], send, compiler); |
4027 | 4032 |
4028 TypeMask computeType(element) { | 4033 TypeMask computeType(element) { |
4029 Element originalElement = elements[send]; | 4034 Element originalElement = elements[send]; |
4030 if (isFixedListConstructorCall || | 4035 if (isFixedListConstructorCall || |
4031 Elements.isFilledListConstructorCall( | 4036 Elements.isFilledListConstructorCall( |
4032 originalElement, send, compiler)) { | 4037 originalElement, send, compiler)) { |
4033 isFixedList = true; | 4038 isFixedList = true; |
4034 TypeMask inferred = | 4039 TypeMask inferred = |
4035 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); | 4040 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); |
4036 return inferred.containsAll(compiler.world) | 4041 return inferred.containsAll(compiler.closedWorld) |
4037 ? backend.fixedArrayType | 4042 ? backend.fixedArrayType |
4038 : inferred; | 4043 : inferred; |
4039 } else if (isGrowableListConstructorCall) { | 4044 } else if (isGrowableListConstructorCall) { |
4040 TypeMask inferred = | 4045 TypeMask inferred = |
4041 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); | 4046 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); |
4042 return inferred.containsAll(compiler.world) | 4047 return inferred.containsAll(compiler.closedWorld) |
4043 ? backend.extendableArrayType | 4048 ? backend.extendableArrayType |
4044 : inferred; | 4049 : inferred; |
4045 } else if (Elements.isConstructorOfTypedArraySubclass( | 4050 } else if (Elements.isConstructorOfTypedArraySubclass( |
4046 originalElement, compiler)) { | 4051 originalElement, compiler)) { |
4047 isFixedList = true; | 4052 isFixedList = true; |
4048 TypeMask inferred = | 4053 TypeMask inferred = |
4049 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); | 4054 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); |
4050 ClassElement cls = element.enclosingClass; | 4055 ClassElement cls = element.enclosingClass; |
4051 assert(backend.isNative(cls.thisType.element)); | 4056 assert(backend.isNative(cls.thisType.element)); |
4052 return inferred.containsAll(compiler.world) | 4057 return inferred.containsAll(compiler.closedWorld) |
4053 ? new TypeMask.nonNullExact(cls.thisType.element, compiler.world) | 4058 ? new TypeMask.nonNullExact( |
| 4059 cls.thisType.element, compiler.closedWorld) |
4054 : inferred; | 4060 : inferred; |
4055 } else if (element.isGenerativeConstructor) { | 4061 } else if (element.isGenerativeConstructor) { |
4056 ClassElement cls = element.enclosingClass; | 4062 ClassElement cls = element.enclosingClass; |
4057 if (cls.isAbstract) { | 4063 if (cls.isAbstract) { |
4058 // An error will be thrown. | 4064 // An error will be thrown. |
4059 return new TypeMask.nonNullEmpty(); | 4065 return new TypeMask.nonNullEmpty(); |
4060 } else { | 4066 } else { |
4061 return new TypeMask.nonNullExact( | 4067 return new TypeMask.nonNullExact( |
4062 cls.thisType.element, compiler.world); | 4068 cls.thisType.element, compiler.closedWorld); |
4063 } | 4069 } |
4064 } else { | 4070 } else { |
4065 return TypeMaskFactory.inferredReturnTypeForElement( | 4071 return TypeMaskFactory.inferredReturnTypeForElement( |
4066 originalElement, compiler); | 4072 originalElement, compiler); |
4067 } | 4073 } |
4068 } | 4074 } |
4069 | 4075 |
4070 Element constructor = elements[send]; | 4076 Element constructor = elements[send]; |
4071 CallStructure callStructure = elements.getSelector(send).callStructure; | 4077 CallStructure callStructure = elements.getSelector(send).callStructure; |
4072 ConstructorElement constructorDeclaration = constructor; | 4078 ConstructorElement constructorDeclaration = constructor; |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4676 void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask, | 4682 void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask, |
4677 List<HInstruction> arguments, | 4683 List<HInstruction> arguments, |
4678 {SourceInformation sourceInformation}) { | 4684 {SourceInformation sourceInformation}) { |
4679 // We prefer to not inline certain operations on indexables, | 4685 // We prefer to not inline certain operations on indexables, |
4680 // because the constant folder will handle them better and turn | 4686 // because the constant folder will handle them better and turn |
4681 // them into simpler instructions that allow further | 4687 // them into simpler instructions that allow further |
4682 // optimizations. | 4688 // optimizations. |
4683 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { | 4689 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { |
4684 bool isLength = selector.isGetter && selector.name == "length"; | 4690 bool isLength = selector.isGetter && selector.name == "length"; |
4685 if (isLength || selector.isIndex) { | 4691 if (isLength || selector.isIndex) { |
4686 return compiler.world.isSubtypeOf( | 4692 return compiler.closedWorld.isSubtypeOf( |
4687 element.enclosingClass.declaration, helpers.jsIndexableClass); | 4693 element.enclosingClass.declaration, helpers.jsIndexableClass); |
4688 } else if (selector.isIndexSet) { | 4694 } else if (selector.isIndexSet) { |
4689 return compiler.world.isSubtypeOf(element.enclosingClass.declaration, | 4695 return compiler.closedWorld.isSubtypeOf( |
| 4696 element.enclosingClass.declaration, |
4690 helpers.jsMutableIndexableClass); | 4697 helpers.jsMutableIndexableClass); |
4691 } else { | 4698 } else { |
4692 return false; | 4699 return false; |
4693 } | 4700 } |
4694 } | 4701 } |
4695 | 4702 |
4696 bool isOptimizableOperation(Selector selector, Element element) { | 4703 bool isOptimizableOperation(Selector selector, Element element) { |
4697 ClassElement cls = element.enclosingClass; | 4704 ClassElement cls = element.enclosingClass; |
4698 if (isOptimizableOperationOnIndexable(selector, element)) return true; | 4705 if (isOptimizableOperationOnIndexable(selector, element)) return true; |
4699 if (!backend.interceptedClasses.contains(cls)) return false; | 4706 if (!backend.interceptedClasses.contains(cls)) return false; |
4700 if (selector.isOperator) return true; | 4707 if (selector.isOperator) return true; |
4701 if (selector.isSetter) return true; | 4708 if (selector.isSetter) return true; |
4702 if (selector.isIndex) return true; | 4709 if (selector.isIndex) return true; |
4703 if (selector.isIndexSet) return true; | 4710 if (selector.isIndexSet) return true; |
4704 if (element == helpers.jsArrayAdd || | 4711 if (element == helpers.jsArrayAdd || |
4705 element == helpers.jsArrayRemoveLast || | 4712 element == helpers.jsArrayRemoveLast || |
4706 element == helpers.jsStringSplit) { | 4713 element == helpers.jsStringSplit) { |
4707 return true; | 4714 return true; |
4708 } | 4715 } |
4709 return false; | 4716 return false; |
4710 } | 4717 } |
4711 | 4718 |
4712 Element element = compiler.world.locateSingleElement(selector, mask); | 4719 Element element = compiler.closedWorld.locateSingleElement(selector, mask); |
4713 if (element != null && | 4720 if (element != null && |
4714 !element.isField && | 4721 !element.isField && |
4715 !(element.isGetter && selector.isCall) && | 4722 !(element.isGetter && selector.isCall) && |
4716 !(element.isFunction && selector.isGetter) && | 4723 !(element.isFunction && selector.isGetter) && |
4717 !isOptimizableOperation(selector, element)) { | 4724 !isOptimizableOperation(selector, element)) { |
4718 if (tryInlineMethod(element, selector, mask, arguments, node)) { | 4725 if (tryInlineMethod(element, selector, mask, arguments, node)) { |
4719 return; | 4726 return; |
4720 } | 4727 } |
4721 } | 4728 } |
4722 | 4729 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4849 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4856 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
4850 if (tryInlineMethod(element, null, null, arguments, location, | 4857 if (tryInlineMethod(element, null, null, arguments, location, |
4851 instanceType: instanceType)) { | 4858 instanceType: instanceType)) { |
4852 return; | 4859 return; |
4853 } | 4860 } |
4854 | 4861 |
4855 if (typeMask == null) { | 4862 if (typeMask == null) { |
4856 typeMask = | 4863 typeMask = |
4857 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4864 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); |
4858 } | 4865 } |
4859 bool targetCanThrow = !compiler.world.getCannotThrow(element); | 4866 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element); |
4860 // TODO(5346): Try to avoid the need for calling [declaration] before | 4867 // TODO(5346): Try to avoid the need for calling [declaration] before |
4861 var instruction; | 4868 var instruction; |
4862 if (backend.isJsInterop(element)) { | 4869 if (backend.isJsInterop(element)) { |
4863 instruction = | 4870 instruction = |
4864 invokeJsInteropFunction(element, arguments, sourceInformation); | 4871 invokeJsInteropFunction(element, arguments, sourceInformation); |
4865 } else { | 4872 } else { |
4866 // creating an [HInvokeStatic]. | 4873 // creating an [HInvokeStatic]. |
4867 instruction = new HInvokeStatic(element.declaration, arguments, typeMask, | 4874 instruction = new HInvokeStatic(element.declaration, arguments, typeMask, |
4868 targetCanThrow: targetCanThrow) | 4875 targetCanThrow: targetCanThrow) |
4869 ..sourceInformation = sourceInformation; | 4876 ..sourceInformation = sourceInformation; |
4870 if (currentInlinedInstantiations.isNotEmpty) { | 4877 if (currentInlinedInstantiations.isNotEmpty) { |
4871 instruction.instantiatedTypes = | 4878 instruction.instantiatedTypes = |
4872 new List<DartType>.from(currentInlinedInstantiations); | 4879 new List<DartType>.from(currentInlinedInstantiations); |
4873 } | 4880 } |
4874 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 4881 instruction.sideEffects = |
| 4882 compiler.closedWorld.getSideEffectsOfElement(element); |
4875 } | 4883 } |
4876 if (location == null) { | 4884 if (location == null) { |
4877 push(instruction); | 4885 push(instruction); |
4878 } else { | 4886 } else { |
4879 pushWithPosition(instruction, location); | 4887 pushWithPosition(instruction, location); |
4880 } | 4888 } |
4881 } | 4889 } |
4882 | 4890 |
4883 HInstruction buildInvokeSuper( | 4891 HInstruction buildInvokeSuper( |
4884 Selector selector, Element element, List<HInstruction> arguments, | 4892 Selector selector, Element element, List<HInstruction> arguments, |
(...skipping 13 matching lines...) Expand all Loading... |
4898 TypeMask type; | 4906 TypeMask type; |
4899 if (!element.isGetter && selector.isGetter) { | 4907 if (!element.isGetter && selector.isGetter) { |
4900 type = TypeMaskFactory.inferredTypeForElement(element, compiler); | 4908 type = TypeMaskFactory.inferredTypeForElement(element, compiler); |
4901 } else { | 4909 } else { |
4902 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4910 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); |
4903 } | 4911 } |
4904 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, | 4912 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, |
4905 selector, inputs, type, sourceInformation, | 4913 selector, inputs, type, sourceInformation, |
4906 isSetter: selector.isSetter || selector.isIndexSet); | 4914 isSetter: selector.isSetter || selector.isIndexSet); |
4907 instruction.sideEffects = | 4915 instruction.sideEffects = |
4908 compiler.world.getSideEffectsOfSelector(selector, null); | 4916 compiler.closedWorld.getSideEffectsOfSelector(selector, null); |
4909 return instruction; | 4917 return instruction; |
4910 } | 4918 } |
4911 | 4919 |
4912 void handleComplexOperatorSend( | 4920 void handleComplexOperatorSend( |
4913 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) { | 4921 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) { |
4914 HInstruction rhs; | 4922 HInstruction rhs; |
4915 if (node.isPrefix || node.isPostfix) { | 4923 if (node.isPrefix || node.isPostfix) { |
4916 rhs = graph.addConstantInt(1, compiler); | 4924 rhs = graph.addConstantInt(1, compiler); |
4917 } else { | 4925 } else { |
4918 visit(arguments.head); | 4926 visit(arguments.head); |
4919 assert(arguments.tail.isEmpty); | 4927 assert(arguments.tail.isEmpty); |
4920 rhs = pop(); | 4928 rhs = pop(); |
4921 } | 4929 } |
4922 visitBinarySend( | 4930 visitBinarySend( |
4923 receiver, | 4931 receiver, |
4924 rhs, | 4932 rhs, |
4925 elements.getOperatorSelectorInComplexSendSet(node), | 4933 elements.getOperatorSelectorInComplexSendSet(node), |
4926 elements.getOperatorTypeMaskInComplexSendSet(node), | 4934 elements.getOperatorTypeMaskInComplexSendSet(node), |
4927 node, | 4935 node, |
4928 sourceInformation: | 4936 sourceInformation: |
4929 sourceInformationBuilder.buildGeneric(node.assignmentOperator)); | 4937 sourceInformationBuilder.buildGeneric(node.assignmentOperator)); |
4930 } | 4938 } |
4931 | 4939 |
4932 void handleSuperSendSet(ast.SendSet node) { | 4940 void handleSuperSendSet(ast.SendSet node) { |
4933 Element element = elements[node]; | 4941 Element element = elements[node]; |
4934 List<HInstruction> setterInputs = <HInstruction>[]; | 4942 List<HInstruction> setterInputs = <HInstruction>[]; |
4935 void generateSuperSendSet() { | 4943 void generateSuperSendSet() { |
4936 Selector setterSelector = elements.getSelector(node); | 4944 Selector setterSelector = elements.getSelector(node); |
4937 if (Elements.isUnresolved(element) || | 4945 if (Elements.isUnresolved(element) || |
4938 !setterSelector.applies(element, compiler.world)) { | 4946 !setterSelector.applies(element, compiler.closedWorld)) { |
4939 generateSuperNoSuchMethodSend(node, setterSelector, setterInputs); | 4947 generateSuperNoSuchMethodSend(node, setterSelector, setterInputs); |
4940 pop(); | 4948 pop(); |
4941 } else { | 4949 } else { |
4942 add(buildInvokeSuper(setterSelector, element, setterInputs)); | 4950 add(buildInvokeSuper(setterSelector, element, setterInputs)); |
4943 } | 4951 } |
4944 } | 4952 } |
4945 | 4953 |
4946 if (identical(node.assignmentOperator.source, '=')) { | 4954 if (identical(node.assignmentOperator.source, '=')) { |
4947 addDynamicSendArgumentsToList(node, setterInputs); | 4955 addDynamicSendArgumentsToList(node, setterInputs); |
4948 generateSuperSendSet(); | 4956 generateSuperSendSet(); |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5901 visit(node.expression); | 5909 visit(node.expression); |
5902 HInstruction yielded = pop(); | 5910 HInstruction yielded = pop(); |
5903 add(new HYield(yielded, node.hasStar)); | 5911 add(new HYield(yielded, node.hasStar)); |
5904 } | 5912 } |
5905 | 5913 |
5906 visitAwait(ast.Await node) { | 5914 visitAwait(ast.Await node) { |
5907 visit(node.expression); | 5915 visit(node.expression); |
5908 HInstruction awaited = pop(); | 5916 HInstruction awaited = pop(); |
5909 // TODO(herhut): Improve this type. | 5917 // TODO(herhut): Improve this type. |
5910 push(new HAwait(awaited, | 5918 push(new HAwait(awaited, |
5911 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); | 5919 new TypeMask.subclass(coreClasses.objectClass, compiler.closedWorld))); |
5912 } | 5920 } |
5913 | 5921 |
5914 visitTypeAnnotation(ast.TypeAnnotation node) { | 5922 visitTypeAnnotation(ast.TypeAnnotation node) { |
5915 reporter.internalError(node, 'Visiting type annotation in SSA builder.'); | 5923 reporter.internalError(node, 'Visiting type annotation in SSA builder.'); |
5916 } | 5924 } |
5917 | 5925 |
5918 visitVariableDefinitions(ast.VariableDefinitions node) { | 5926 visitVariableDefinitions(ast.VariableDefinitions node) { |
5919 assert(isReachable); | 5927 assert(isReachable); |
5920 for (Link<ast.Node> link = node.definitions.nodes; | 5928 for (Link<ast.Node> link = node.definitions.nodes; |
5921 !link.isEmpty; | 5929 !link.isEmpty; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5962 visit(link.head); | 5970 visit(link.head); |
5963 inputs.add(pop()); | 5971 inputs.add(pop()); |
5964 } | 5972 } |
5965 instruction = buildLiteralList(inputs); | 5973 instruction = buildLiteralList(inputs); |
5966 add(instruction); | 5974 add(instruction); |
5967 instruction = setRtiIfNeeded(instruction, node); | 5975 instruction = setRtiIfNeeded(instruction, node); |
5968 } | 5976 } |
5969 | 5977 |
5970 TypeMask type = | 5978 TypeMask type = |
5971 TypeMaskFactory.inferredForNode(sourceElement, node, compiler); | 5979 TypeMaskFactory.inferredForNode(sourceElement, node, compiler); |
5972 if (!type.containsAll(compiler.world)) instruction.instructionType = type; | 5980 if (!type.containsAll(compiler.closedWorld)) |
| 5981 instruction.instructionType = type; |
5973 stack.add(instruction); | 5982 stack.add(instruction); |
5974 } | 5983 } |
5975 | 5984 |
5976 visitConditional(ast.Conditional node) { | 5985 visitConditional(ast.Conditional node) { |
5977 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 5986 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); |
5978 brancher.handleConditional(() => visit(node.condition), | 5987 brancher.handleConditional(() => visit(node.condition), |
5979 () => visit(node.thenExpression), () => visit(node.elseExpression)); | 5988 () => visit(node.thenExpression), () => visit(node.elseExpression)); |
5980 } | 5989 } |
5981 | 5990 |
5982 visitStringInterpolation(ast.StringInterpolation node) { | 5991 visitStringInterpolation(ast.StringInterpolation node) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6062 [expression, graph.addConstantNull(compiler)]); | 6071 [expression, graph.addConstantNull(compiler)]); |
6063 streamIterator = pop(); | 6072 streamIterator = pop(); |
6064 | 6073 |
6065 void buildInitializer() {} | 6074 void buildInitializer() {} |
6066 | 6075 |
6067 HInstruction buildCondition() { | 6076 HInstruction buildCondition() { |
6068 Selector selector = Selectors.moveNext; | 6077 Selector selector = Selectors.moveNext; |
6069 TypeMask mask = elements.getMoveNextTypeMask(node); | 6078 TypeMask mask = elements.getMoveNextTypeMask(node); |
6070 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 6079 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
6071 HInstruction future = pop(); | 6080 HInstruction future = pop(); |
6072 push(new HAwait(future, | 6081 push(new HAwait( |
6073 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); | 6082 future, |
| 6083 new TypeMask.subclass( |
| 6084 coreClasses.objectClass, compiler.closedWorld))); |
6074 return popBoolified(); | 6085 return popBoolified(); |
6075 } | 6086 } |
6076 | 6087 |
6077 void buildBody() { | 6088 void buildBody() { |
6078 Selector call = Selectors.current; | 6089 Selector call = Selectors.current; |
6079 TypeMask callMask = elements.getCurrentTypeMask(node); | 6090 TypeMask callMask = elements.getCurrentTypeMask(node); |
6080 pushInvokeDynamic(node, call, callMask, [streamIterator]); | 6091 pushInvokeDynamic(node, call, callMask, [streamIterator]); |
6081 | 6092 |
6082 ast.Node identifier = node.declaredIdentifier; | 6093 ast.Node identifier = node.declaredIdentifier; |
6083 Element variable = elements.getForInVariable(node); | 6094 Element variable = elements.getForInVariable(node); |
(...skipping 16 matching lines...) Expand all Loading... |
6100 } | 6111 } |
6101 | 6112 |
6102 void buildUpdate() {} | 6113 void buildUpdate() {} |
6103 ; | 6114 ; |
6104 | 6115 |
6105 buildProtectedByFinally(() { | 6116 buildProtectedByFinally(() { |
6106 handleLoop( | 6117 handleLoop( |
6107 node, buildInitializer, buildCondition, buildUpdate, buildBody); | 6118 node, buildInitializer, buildCondition, buildUpdate, buildBody); |
6108 }, () { | 6119 }, () { |
6109 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); | 6120 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); |
6110 push(new HAwait(pop(), | 6121 push(new HAwait( |
6111 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); | 6122 pop(), |
| 6123 new TypeMask.subclass( |
| 6124 coreClasses.objectClass, compiler.closedWorld))); |
6112 pop(); | 6125 pop(); |
6113 }); | 6126 }); |
6114 } | 6127 } |
6115 | 6128 |
6116 visitSyncForIn(ast.SyncForIn node) { | 6129 visitSyncForIn(ast.SyncForIn node) { |
6117 // The 'get iterator' selector for this node has the inferred receiver type. | 6130 // The 'get iterator' selector for this node has the inferred receiver type. |
6118 // If the receiver supports JavaScript indexing we generate an indexing loop | 6131 // If the receiver supports JavaScript indexing we generate an indexing loop |
6119 // instead of allocating an iterator object. | 6132 // instead of allocating an iterator object. |
6120 | 6133 |
6121 // This scheme recognizes for-in on direct lists. It does not recognize all | 6134 // This scheme recognizes for-in on direct lists. It does not recognize all |
6122 // uses of ArrayIterator. They still occur when the receiver is an Iterable | 6135 // uses of ArrayIterator. They still occur when the receiver is an Iterable |
6123 // with a `get iterator` method that delegate to another Iterable and the | 6136 // with a `get iterator` method that delegate to another Iterable and the |
6124 // method is inlined. We would require full scalar replacement in that | 6137 // method is inlined. We would require full scalar replacement in that |
6125 // case. | 6138 // case. |
6126 | 6139 |
6127 TypeMask mask = elements.getIteratorTypeMask(node); | 6140 TypeMask mask = elements.getIteratorTypeMask(node); |
6128 | 6141 |
6129 ClassWorld classWorld = compiler.world; | 6142 ClassWorld classWorld = compiler.closedWorld; |
6130 if (mask != null && | 6143 if (mask != null && |
6131 mask.satisfies(helpers.jsIndexableClass, classWorld) && | 6144 mask.satisfies(helpers.jsIndexableClass, classWorld) && |
6132 // String is indexable but not iterable. | 6145 // String is indexable but not iterable. |
6133 !mask.satisfies(helpers.jsStringClass, classWorld)) { | 6146 !mask.satisfies(helpers.jsStringClass, classWorld)) { |
6134 return buildSyncForInIndexable(node, mask); | 6147 return buildSyncForInIndexable(node, mask); |
6135 } | 6148 } |
6136 buildSyncForInIterator(node); | 6149 buildSyncForInIterator(node); |
6137 } | 6150 } |
6138 | 6151 |
6139 buildSyncForInIterator(ast.SyncForIn node) { | 6152 buildSyncForInIterator(ast.SyncForIn node) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6397 } | 6410 } |
6398 | 6411 |
6399 // If rti is needed and the map literal has no type parameters, | 6412 // If rti is needed and the map literal has no type parameters, |
6400 // 'constructor' is a static function that forwards the call to the factory | 6413 // 'constructor' is a static function that forwards the call to the factory |
6401 // constructor without type parameters. | 6414 // constructor without type parameters. |
6402 assert(constructor is ConstructorElement || constructor is FunctionElement); | 6415 assert(constructor is ConstructorElement || constructor is FunctionElement); |
6403 | 6416 |
6404 // The instruction type will always be a subtype of the mapLiteralClass, but | 6417 // The instruction type will always be a subtype of the mapLiteralClass, but |
6405 // type inference might discover a more specific type, or find nothing (in | 6418 // type inference might discover a more specific type, or find nothing (in |
6406 // dart2js unit tests). | 6419 // dart2js unit tests). |
6407 TypeMask mapType = | 6420 TypeMask mapType = new TypeMask.nonNullSubtype( |
6408 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, compiler.world); | 6421 helpers.mapLiteralClass, compiler.closedWorld); |
6409 TypeMask returnTypeMask = | 6422 TypeMask returnTypeMask = |
6410 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); | 6423 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); |
6411 TypeMask instructionType = | 6424 TypeMask instructionType = |
6412 mapType.intersection(returnTypeMask, compiler.world); | 6425 mapType.intersection(returnTypeMask, compiler.closedWorld); |
6413 | 6426 |
6414 addInlinedInstantiation(expectedType); | 6427 addInlinedInstantiation(expectedType); |
6415 pushInvokeStatic(node, constructor, inputs, | 6428 pushInvokeStatic(node, constructor, inputs, |
6416 typeMask: instructionType, instanceType: expectedType); | 6429 typeMask: instructionType, instanceType: expectedType); |
6417 removeInlinedInstantiation(expectedType); | 6430 removeInlinedInstantiation(expectedType); |
6418 } | 6431 } |
6419 | 6432 |
6420 visitLiteralMapEntry(ast.LiteralMapEntry node) { | 6433 visitLiteralMapEntry(ast.LiteralMapEntry node) { |
6421 visit(node.value); | 6434 visit(node.value); |
6422 visit(node.key); | 6435 visit(node.key); |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7230 if (expression.canBePrimitive(compiler)) { | 7243 if (expression.canBePrimitive(compiler)) { |
7231 append(stringify(node, expression)); | 7244 append(stringify(node, expression)); |
7232 return; | 7245 return; |
7233 } | 7246 } |
7234 | 7247 |
7235 // If the `toString` method is guaranteed to return a string we can call it | 7248 // If the `toString` method is guaranteed to return a string we can call it |
7236 // directly. | 7249 // directly. |
7237 Selector selector = Selectors.toString_; | 7250 Selector selector = Selectors.toString_; |
7238 TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 7251 TypeMask type = TypeMaskFactory.inferredTypeForSelector( |
7239 selector, expression.instructionType, compiler); | 7252 selector, expression.instructionType, compiler); |
7240 if (type.containsOnlyString(compiler.world)) { | 7253 if (type.containsOnlyString(compiler.closedWorld)) { |
7241 builder.pushInvokeDynamic(node, selector, expression.instructionType, | 7254 builder.pushInvokeDynamic(node, selector, expression.instructionType, |
7242 <HInstruction>[expression]); | 7255 <HInstruction>[expression]); |
7243 append(builder.pop()); | 7256 append(builder.pop()); |
7244 return; | 7257 return; |
7245 } | 7258 } |
7246 | 7259 |
7247 append(stringify(node, expression)); | 7260 append(stringify(node, expression)); |
7248 } | 7261 } |
7249 | 7262 |
7250 void visitStringInterpolation(ast.StringInterpolation node) { | 7263 void visitStringInterpolation(ast.StringInterpolation node) { |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7545 const _LoopTypeVisitor(); | 7558 const _LoopTypeVisitor(); |
7546 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 7559 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
7547 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 7560 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
7548 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 7561 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
7549 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 7562 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
7550 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 7563 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
7551 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 7564 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
7552 int visitSwitchStatement(ast.SwitchStatement node) => | 7565 int visitSwitchStatement(ast.SwitchStatement node) => |
7553 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 7566 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
7554 } | 7567 } |
OLD | NEW |