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