| 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 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 new HFieldGet(null, providedArguments[0], commonMasks.dynamicType, | 572 new HFieldGet(null, providedArguments[0], commonMasks.dynamicType, |
| 573 isAssignable: false), | 573 isAssignable: false), |
| 574 currentNode); | 574 currentNode); |
| 575 } | 575 } |
| 576 List<HInstruction> compiledArguments = completeSendArgumentsList( | 576 List<HInstruction> compiledArguments = completeSendArgumentsList( |
| 577 function, selector, providedArguments, currentNode); | 577 function, selector, providedArguments, currentNode); |
| 578 enterInlinedMethod(function, functionResolvedAst, compiledArguments, | 578 enterInlinedMethod(function, functionResolvedAst, compiledArguments, |
| 579 instanceType: instanceType); | 579 instanceType: instanceType); |
| 580 inlinedFrom(functionResolvedAst, () { | 580 inlinedFrom(functionResolvedAst, () { |
| 581 if (!isReachable) { | 581 if (!isReachable) { |
| 582 emitReturn(graph.addConstantNull(compiler), null); | 582 emitReturn(graph.addConstantNull(closedWorld), null); |
| 583 } else { | 583 } else { |
| 584 doInline(functionResolvedAst); | 584 doInline(functionResolvedAst); |
| 585 } | 585 } |
| 586 }); | 586 }); |
| 587 leaveInlinedMethod(); | 587 leaveInlinedMethod(); |
| 588 } | 588 } |
| 589 | 589 |
| 590 if (meetsHardConstraints() && heuristicSayGoodToGo()) { | 590 if (meetsHardConstraints() && heuristicSayGoodToGo()) { |
| 591 doInlining(); | 591 doInlining(); |
| 592 infoReporter?.reportInlined(element, | 592 infoReporter?.reportInlined(element, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 * from interop methods to match JavaScript semantics for omitted arguments. | 633 * from interop methods to match JavaScript semantics for omitted arguments. |
| 634 */ | 634 */ |
| 635 HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) => | 635 HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) => |
| 636 null; | 636 null; |
| 637 | 637 |
| 638 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { | 638 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { |
| 639 ConstantValue constantValue = | 639 ConstantValue constantValue = |
| 640 backend.constants.getConstantValue(parameter.constant); | 640 backend.constants.getConstantValue(parameter.constant); |
| 641 assert(invariant(parameter, constantValue != null, | 641 assert(invariant(parameter, constantValue != null, |
| 642 message: 'No constant computed for $parameter')); | 642 message: 'No constant computed for $parameter')); |
| 643 return graph.addConstant(constantValue, compiler); | 643 return graph.addConstant(constantValue, closedWorld); |
| 644 } | 644 } |
| 645 | 645 |
| 646 ClassElement get currentNonClosureClass { | 646 ClassElement get currentNonClosureClass { |
| 647 ClassElement cls = sourceElement.enclosingClass; | 647 ClassElement cls = sourceElement.enclosingClass; |
| 648 if (cls != null && cls.isClosure) { | 648 if (cls != null && cls.isClosure) { |
| 649 var closureClass = cls; | 649 var closureClass = cls; |
| 650 return closureClass.methodElement.enclosingClass; | 650 return closureClass.methodElement.enclosingClass; |
| 651 } else { | 651 } else { |
| 652 return cls; | 652 return cls; |
| 653 } | 653 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 670 | 670 |
| 671 ConstantValue getConstantForNode(ast.Node node) { | 671 ConstantValue getConstantForNode(ast.Node node) { |
| 672 ConstantValue constantValue = | 672 ConstantValue constantValue = |
| 673 backend.constants.getConstantValueForNode(node, elements); | 673 backend.constants.getConstantValueForNode(node, elements); |
| 674 assert(invariant(node, constantValue != null, | 674 assert(invariant(node, constantValue != null, |
| 675 message: 'No constant computed for $node')); | 675 message: 'No constant computed for $node')); |
| 676 return constantValue; | 676 return constantValue; |
| 677 } | 677 } |
| 678 | 678 |
| 679 HInstruction addConstant(ast.Node node) { | 679 HInstruction addConstant(ast.Node node) { |
| 680 return graph.addConstant(getConstantForNode(node), compiler); | 680 return graph.addConstant(getConstantForNode(node), closedWorld); |
| 681 } | 681 } |
| 682 | 682 |
| 683 /** | 683 /** |
| 684 * Documentation wanted -- johnniwinther | 684 * Documentation wanted -- johnniwinther |
| 685 * | 685 * |
| 686 * Invariant: [functionElement] must be an implementation element. | 686 * Invariant: [functionElement] must be an implementation element. |
| 687 */ | 687 */ |
| 688 HGraph buildMethod(FunctionElement functionElement) { | 688 HGraph buildMethod(FunctionElement functionElement) { |
| 689 assert(invariant(functionElement, functionElement.isImplementation)); | 689 assert(invariant(functionElement, functionElement.isImplementation)); |
| 690 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement); | 690 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 705 | 705 |
| 706 // If [functionElement] is `operator==` we explicitly add a null check at | 706 // If [functionElement] is `operator==` we explicitly add a null check at |
| 707 // the beginning of the method. This is to avoid having call sites do the | 707 // the beginning of the method. This is to avoid having call sites do the |
| 708 // null check. | 708 // null check. |
| 709 if (name == '==') { | 709 if (name == '==') { |
| 710 if (!backend.operatorEqHandlesNullArgument(functionElement)) { | 710 if (!backend.operatorEqHandlesNullArgument(functionElement)) { |
| 711 handleIf( | 711 handleIf( |
| 712 node: function, | 712 node: function, |
| 713 visitCondition: () { | 713 visitCondition: () { |
| 714 HParameterValue parameter = parameters.values.first; | 714 HParameterValue parameter = parameters.values.first; |
| 715 push(new HIdentity(parameter, graph.addConstantNull(compiler), | 715 push(new HIdentity(parameter, graph.addConstantNull(closedWorld), |
| 716 null, commonMasks.boolType)); | 716 null, commonMasks.boolType)); |
| 717 }, | 717 }, |
| 718 visitThen: () { | 718 visitThen: () { |
| 719 closeAndGotoExit(new HReturn( | 719 closeAndGotoExit(new HReturn( |
| 720 graph.addConstantBool(false, compiler), | 720 graph.addConstantBool(false, closedWorld), |
| 721 sourceInformationBuilder | 721 sourceInformationBuilder |
| 722 .buildImplicitReturn(functionElement))); | 722 .buildImplicitReturn(functionElement))); |
| 723 }, | 723 }, |
| 724 visitElse: null, | 724 visitElse: null, |
| 725 sourceInformation: sourceInformationBuilder.buildIf(function.body)); | 725 sourceInformation: sourceInformationBuilder.buildIf(function.body)); |
| 726 } | 726 } |
| 727 } | 727 } |
| 728 if (const bool.fromEnvironment('unreachable-throw')) { | 728 if (const bool.fromEnvironment('unreachable-throw')) { |
| 729 var emptyParameters = | 729 var emptyParameters = |
| 730 parameters.values.where((p) => p.instructionType.isEmpty); | 730 parameters.values.where((p) => p.instructionType.isEmpty); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 */ | 855 */ |
| 856 void setupStateForInlining( | 856 void setupStateForInlining( |
| 857 FunctionElement function, List<HInstruction> compiledArguments, | 857 FunctionElement function, List<HInstruction> compiledArguments, |
| 858 {InterfaceType instanceType}) { | 858 {InterfaceType instanceType}) { |
| 859 ResolvedAst resolvedAst = function.resolvedAst; | 859 ResolvedAst resolvedAst = function.resolvedAst; |
| 860 assert(resolvedAst != null); | 860 assert(resolvedAst != null); |
| 861 localsHandler = new LocalsHandler(this, function, instanceType, compiler); | 861 localsHandler = new LocalsHandler(this, function, instanceType, compiler); |
| 862 localsHandler.closureData = | 862 localsHandler.closureData = |
| 863 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 863 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); |
| 864 returnLocal = new SyntheticLocal("result", function); | 864 returnLocal = new SyntheticLocal("result", function); |
| 865 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler)); | 865 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld)); |
| 866 | 866 |
| 867 inTryStatement = false; // TODO(lry): why? Document. | 867 inTryStatement = false; // TODO(lry): why? Document. |
| 868 | 868 |
| 869 int argumentIndex = 0; | 869 int argumentIndex = 0; |
| 870 if (function.isInstanceMember) { | 870 if (function.isInstanceMember) { |
| 871 localsHandler.updateLocal(localsHandler.closureData.thisLocal, | 871 localsHandler.updateLocal(localsHandler.closureData.thisLocal, |
| 872 compiledArguments[argumentIndex++]); | 872 compiledArguments[argumentIndex++]); |
| 873 } | 873 } |
| 874 | 874 |
| 875 FunctionSignature signature = function.functionSignature; | 875 FunctionSignature signature = function.functionSignature; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 localsHandler.updateLocal( | 980 localsHandler.updateLocal( |
| 981 localsHandler.getTypeVariableAsLocal(typeVariable), | 981 localsHandler.getTypeVariableAsLocal(typeVariable), |
| 982 typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 982 typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
| 983 }); | 983 }); |
| 984 } else { | 984 } else { |
| 985 // If the supertype is a raw type, we need to set to null the | 985 // If the supertype is a raw type, we need to set to null the |
| 986 // type variables. | 986 // type variables. |
| 987 for (TypeVariableType variable in typeVariables) { | 987 for (TypeVariableType variable in typeVariables) { |
| 988 localsHandler.updateLocal( | 988 localsHandler.updateLocal( |
| 989 localsHandler.getTypeVariableAsLocal(variable), | 989 localsHandler.getTypeVariableAsLocal(variable), |
| 990 graph.addConstantNull(compiler)); | 990 graph.addConstantNull(closedWorld)); |
| 991 } | 991 } |
| 992 } | 992 } |
| 993 } | 993 } |
| 994 | 994 |
| 995 // For redirecting constructors, the fields will be initialized later | 995 // For redirecting constructors, the fields will be initialized later |
| 996 // by the effective target. | 996 // by the effective target. |
| 997 if (!callee.isRedirectingGenerative) { | 997 if (!callee.isRedirectingGenerative) { |
| 998 inlinedFrom(constructorResolvedAst, () { | 998 inlinedFrom(constructorResolvedAst, () { |
| 999 buildFieldInitializers( | 999 buildFieldInitializers( |
| 1000 callee.enclosingClass.implementation, fieldValues); | 1000 callee.enclosingClass.implementation, fieldValues); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 (ClassElement enclosingClass, FieldElement member) { | 1183 (ClassElement enclosingClass, FieldElement member) { |
| 1184 if (compiler.elementHasCompileTimeError(member)) return; | 1184 if (compiler.elementHasCompileTimeError(member)) return; |
| 1185 reporter.withCurrentElement(member, () { | 1185 reporter.withCurrentElement(member, () { |
| 1186 ResolvedAst fieldResolvedAst = member.resolvedAst; | 1186 ResolvedAst fieldResolvedAst = member.resolvedAst; |
| 1187 ast.Node node = fieldResolvedAst.node; | 1187 ast.Node node = fieldResolvedAst.node; |
| 1188 ast.Expression initializer = fieldResolvedAst.body; | 1188 ast.Expression initializer = fieldResolvedAst.body; |
| 1189 if (initializer == null) { | 1189 if (initializer == null) { |
| 1190 // Unassigned fields of native classes are not initialized to | 1190 // Unassigned fields of native classes are not initialized to |
| 1191 // prevent overwriting pre-initialized native properties. | 1191 // prevent overwriting pre-initialized native properties. |
| 1192 if (!backend.isNativeOrExtendsNative(classElement)) { | 1192 if (!backend.isNativeOrExtendsNative(classElement)) { |
| 1193 fieldValues[member] = graph.addConstantNull(compiler); | 1193 fieldValues[member] = graph.addConstantNull(closedWorld); |
| 1194 } | 1194 } |
| 1195 } else { | 1195 } else { |
| 1196 ast.Node right = initializer; | 1196 ast.Node right = initializer; |
| 1197 ResolvedAst savedResolvedAst = resolvedAst; | 1197 ResolvedAst savedResolvedAst = resolvedAst; |
| 1198 resolvedAst = fieldResolvedAst; | 1198 resolvedAst = fieldResolvedAst; |
| 1199 final oldElementInferenceResults = elementInferenceResults; | 1199 final oldElementInferenceResults = elementInferenceResults; |
| 1200 elementInferenceResults = inferenceResults.resultOf(member); | 1200 elementInferenceResults = inferenceResults.resultOf(member); |
| 1201 // In case the field initializer uses closures, run the | 1201 // In case the field initializer uses closures, run the |
| 1202 // closure to class mapper. | 1202 // closure to class mapper. |
| 1203 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 1203 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { | 1347 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { |
| 1348 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; | 1348 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; |
| 1349 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); | 1349 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); |
| 1350 if (body == null) continue; | 1350 if (body == null) continue; |
| 1351 | 1351 |
| 1352 List bodyCallInputs = <HInstruction>[]; | 1352 List bodyCallInputs = <HInstruction>[]; |
| 1353 if (isNativeUpgradeFactory) { | 1353 if (isNativeUpgradeFactory) { |
| 1354 if (interceptor == null) { | 1354 if (interceptor == null) { |
| 1355 ConstantValue constant = | 1355 ConstantValue constant = |
| 1356 new InterceptorConstantValue(classElement.thisType); | 1356 new InterceptorConstantValue(classElement.thisType); |
| 1357 interceptor = graph.addConstant(constant, compiler); | 1357 interceptor = graph.addConstant(constant, closedWorld); |
| 1358 } | 1358 } |
| 1359 bodyCallInputs.add(interceptor); | 1359 bodyCallInputs.add(interceptor); |
| 1360 } | 1360 } |
| 1361 bodyCallInputs.add(newObject); | 1361 bodyCallInputs.add(newObject); |
| 1362 ast.Node node = constructorResolvedAst.node; | 1362 ast.Node node = constructorResolvedAst.node; |
| 1363 ClosureClassMap parameterClosureData = compiler.closureToClassMapper | 1363 ClosureClassMap parameterClosureData = compiler.closureToClassMapper |
| 1364 .getClosureToClassMapping(constructorResolvedAst); | 1364 .getClosureToClassMapping(constructorResolvedAst); |
| 1365 | 1365 |
| 1366 FunctionSignature functionSignature = body.functionSignature; | 1366 FunctionSignature functionSignature = body.functionSignature; |
| 1367 // Provide the parameters to the generative constructor body. | 1367 // Provide the parameters to the generative constructor body. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 HConstant nameConstant = addConstantString(name); | 1504 HConstant nameConstant = addConstantString(name); |
| 1505 add(new HInvokeStatic(backend.helpers.traceHelper, | 1505 add(new HInvokeStatic(backend.helpers.traceHelper, |
| 1506 <HInstruction>[nameConstant], commonMasks.dynamicType)); | 1506 <HInstruction>[nameConstant], commonMasks.dynamicType)); |
| 1507 } | 1507 } |
| 1508 } | 1508 } |
| 1509 | 1509 |
| 1510 insertCoverageCall(Element element) { | 1510 insertCoverageCall(Element element) { |
| 1511 if (JavaScriptBackend.TRACE_METHOD == 'post') { | 1511 if (JavaScriptBackend.TRACE_METHOD == 'post') { |
| 1512 if (element == backend.helpers.traceHelper) return; | 1512 if (element == backend.helpers.traceHelper) return; |
| 1513 // TODO(sigmund): create a better uuid for elements. | 1513 // TODO(sigmund): create a better uuid for elements. |
| 1514 HConstant idConstant = graph.addConstantInt(element.hashCode, compiler); | 1514 HConstant idConstant = |
| 1515 graph.addConstantInt(element.hashCode, closedWorld); |
| 1515 HConstant nameConstant = addConstantString(element.name); | 1516 HConstant nameConstant = addConstantString(element.name); |
| 1516 add(new HInvokeStatic(backend.helpers.traceHelper, | 1517 add(new HInvokeStatic(backend.helpers.traceHelper, |
| 1517 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType)); | 1518 <HInstruction>[idConstant, nameConstant], commonMasks.dynamicType)); |
| 1518 } | 1519 } |
| 1519 } | 1520 } |
| 1520 | 1521 |
| 1521 void assertIsSubtype( | 1522 void assertIsSubtype( |
| 1522 ast.Node node, DartType subtype, DartType supertype, String message) { | 1523 ast.Node node, DartType subtype, DartType supertype, String message) { |
| 1523 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument( | 1524 HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument( |
| 1524 localsHandler.substInContext(subtype), sourceElement); | 1525 localsHandler.substInContext(subtype), sourceElement); |
| 1525 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument( | 1526 HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument( |
| 1526 localsHandler.substInContext(supertype), sourceElement); | 1527 localsHandler.substInContext(supertype), sourceElement); |
| 1527 HInstruction messageInstruction = | 1528 HInstruction messageInstruction = graph.addConstantString( |
| 1528 graph.addConstantString(new ast.DartString.literal(message), compiler); | 1529 new ast.DartString.literal(message), closedWorld); |
| 1529 MethodElement element = helpers.assertIsSubtype; | 1530 MethodElement element = helpers.assertIsSubtype; |
| 1530 var inputs = <HInstruction>[ | 1531 var inputs = <HInstruction>[ |
| 1531 subtypeInstruction, | 1532 subtypeInstruction, |
| 1532 supertypeInstruction, | 1533 supertypeInstruction, |
| 1533 messageInstruction | 1534 messageInstruction |
| 1534 ]; | 1535 ]; |
| 1535 HInstruction assertIsSubtype = | 1536 HInstruction assertIsSubtype = |
| 1536 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); | 1537 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); |
| 1537 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 1538 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
| 1538 add(assertIsSubtype); | 1539 add(assertIsSubtype); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 ast.Node initializer = node.initializer; | 1671 ast.Node initializer = node.initializer; |
| 1671 if (initializer == null) return; | 1672 if (initializer == null) return; |
| 1672 visit(initializer); | 1673 visit(initializer); |
| 1673 if (initializer.asExpression() != null) { | 1674 if (initializer.asExpression() != null) { |
| 1674 pop(); | 1675 pop(); |
| 1675 } | 1676 } |
| 1676 } | 1677 } |
| 1677 | 1678 |
| 1678 HInstruction buildCondition() { | 1679 HInstruction buildCondition() { |
| 1679 if (node.condition == null) { | 1680 if (node.condition == null) { |
| 1680 return graph.addConstantBool(true, compiler); | 1681 return graph.addConstantBool(true, closedWorld); |
| 1681 } | 1682 } |
| 1682 visit(node.condition); | 1683 visit(node.condition); |
| 1683 return popBoolified(); | 1684 return popBoolified(); |
| 1684 } | 1685 } |
| 1685 | 1686 |
| 1686 void buildUpdate() { | 1687 void buildUpdate() { |
| 1687 for (ast.Expression expression in node.update) { | 1688 for (ast.Expression expression in node.update) { |
| 1688 visit(expression); | 1689 visit(expression); |
| 1689 assert(!isAborted()); | 1690 assert(!isAborted()); |
| 1690 // The result of the update instruction isn't used, and can just | 1691 // The result of the update instruction isn't used, and can just |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1986 ast.Send node, UnaryOperator operator, ast.Node expression, _) { | 1987 ast.Send node, UnaryOperator operator, ast.Node expression, _) { |
| 1987 assert(node.argumentsNode is ast.Prefix); | 1988 assert(node.argumentsNode is ast.Prefix); |
| 1988 HInstruction operand = visitAndPop(expression); | 1989 HInstruction operand = visitAndPop(expression); |
| 1989 | 1990 |
| 1990 // See if we can constant-fold right away. This avoids rewrites later on. | 1991 // See if we can constant-fold right away. This avoids rewrites later on. |
| 1991 if (operand is HConstant) { | 1992 if (operand is HConstant) { |
| 1992 UnaryOperation operation = constantSystem.lookupUnary(operator); | 1993 UnaryOperation operation = constantSystem.lookupUnary(operator); |
| 1993 HConstant constant = operand; | 1994 HConstant constant = operand; |
| 1994 ConstantValue folded = operation.fold(constant.constant); | 1995 ConstantValue folded = operation.fold(constant.constant); |
| 1995 if (folded != null) { | 1996 if (folded != null) { |
| 1996 stack.add(graph.addConstant(folded, compiler)); | 1997 stack.add(graph.addConstant(folded, closedWorld)); |
| 1997 return; | 1998 return; |
| 1998 } | 1999 } |
| 1999 } | 2000 } |
| 2000 | 2001 |
| 2001 pushInvokeDynamic(node, elements.getSelector(node), | 2002 pushInvokeDynamic(node, elements.getSelector(node), |
| 2002 elementInferenceResults.typeOfSend(node), [operand], | 2003 elementInferenceResults.typeOfSend(node), [operand], |
| 2003 sourceInformation: sourceInformationBuilder.buildGeneric(node)); | 2004 sourceInformation: sourceInformationBuilder.buildGeneric(node)); |
| 2004 } | 2005 } |
| 2005 | 2006 |
| 2006 @override | 2007 @override |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 /// Generate read access of an unresolved static or top level entity. | 2108 /// Generate read access of an unresolved static or top level entity. |
| 2108 void generateStaticUnresolvedGet(ast.Send node, Element element) { | 2109 void generateStaticUnresolvedGet(ast.Send node, Element element) { |
| 2109 if (element is ErroneousElement) { | 2110 if (element is ErroneousElement) { |
| 2110 // An erroneous element indicates an unresolved static getter. | 2111 // An erroneous element indicates an unresolved static getter. |
| 2111 handleInvalidStaticGet(node, element); | 2112 handleInvalidStaticGet(node, element); |
| 2112 } else { | 2113 } else { |
| 2113 // This happens when [element] has parse errors. | 2114 // This happens when [element] has parse errors. |
| 2114 assert(invariant(node, element == null || element.isMalformed)); | 2115 assert(invariant(node, element == null || element.isMalformed)); |
| 2115 // TODO(ahe): Do something like the above, that is, emit a runtime | 2116 // TODO(ahe): Do something like the above, that is, emit a runtime |
| 2116 // error. | 2117 // error. |
| 2117 stack.add(graph.addConstantNull(compiler)); | 2118 stack.add(graph.addConstantNull(closedWorld)); |
| 2118 } | 2119 } |
| 2119 } | 2120 } |
| 2120 | 2121 |
| 2121 /// Read a static or top level [field] of constant value. | 2122 /// Read a static or top level [field] of constant value. |
| 2122 void generateStaticConstGet(ast.Send node, FieldElement field, | 2123 void generateStaticConstGet(ast.Send node, FieldElement field, |
| 2123 ConstantExpression constant, SourceInformation sourceInformation) { | 2124 ConstantExpression constant, SourceInformation sourceInformation) { |
| 2124 ConstantValue value = backend.constants.getConstantValue(constant); | 2125 ConstantValue value = backend.constants.getConstantValue(constant); |
| 2125 HConstant instruction; | 2126 HConstant instruction; |
| 2126 // Constants that are referred via a deferred prefix should be referred | 2127 // Constants that are referred via a deferred prefix should be referred |
| 2127 // by reference. | 2128 // by reference. |
| 2128 PrefixElement prefix = | 2129 PrefixElement prefix = |
| 2129 compiler.deferredLoadTask.deferredPrefixElement(node, elements); | 2130 compiler.deferredLoadTask.deferredPrefixElement(node, elements); |
| 2130 if (prefix != null) { | 2131 if (prefix != null) { |
| 2131 instruction = | 2132 instruction = graph.addDeferredConstant( |
| 2132 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); | 2133 value, prefix, sourceInformation, compiler, closedWorld); |
| 2133 } else { | 2134 } else { |
| 2134 instruction = graph.addConstant(value, compiler, | 2135 instruction = graph.addConstant(value, closedWorld, |
| 2135 sourceInformation: sourceInformation); | 2136 sourceInformation: sourceInformation); |
| 2136 } | 2137 } |
| 2137 stack.add(instruction); | 2138 stack.add(instruction); |
| 2138 // The inferrer may have found a better type than the constant | 2139 // The inferrer may have found a better type than the constant |
| 2139 // handler in the case of lists, because the constant handler | 2140 // handler in the case of lists, because the constant handler |
| 2140 // does not look at elements in the list. | 2141 // does not look at elements in the list. |
| 2141 TypeMask type = | 2142 TypeMask type = |
| 2142 TypeMaskFactory.inferredTypeForElement(field, globalInferenceResults); | 2143 TypeMaskFactory.inferredTypeForElement(field, globalInferenceResults); |
| 2143 if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) { | 2144 if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) { |
| 2144 // TODO(13429): The inferrer should know that an element | 2145 // TODO(13429): The inferrer should know that an element |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2351 } else { | 2352 } else { |
| 2352 FieldElement field = element; | 2353 FieldElement field = element; |
| 2353 value = typeBuilder.potentiallyCheckOrTrustType(value, field.type); | 2354 value = typeBuilder.potentiallyCheckOrTrustType(value, field.type); |
| 2354 addWithPosition(new HStaticStore(field, value), location); | 2355 addWithPosition(new HStaticStore(field, value), location); |
| 2355 } | 2356 } |
| 2356 stack.add(value); | 2357 stack.add(value); |
| 2357 } else if (Elements.isError(element)) { | 2358 } else if (Elements.isError(element)) { |
| 2358 generateNoSuchSetter(location, element, send == null ? null : value); | 2359 generateNoSuchSetter(location, element, send == null ? null : value); |
| 2359 } else if (Elements.isMalformed(element)) { | 2360 } else if (Elements.isMalformed(element)) { |
| 2360 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 2361 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 2361 stack.add(graph.addConstantNull(compiler)); | 2362 stack.add(graph.addConstantNull(closedWorld)); |
| 2362 } else { | 2363 } else { |
| 2363 stack.add(value); | 2364 stack.add(value); |
| 2364 LocalElement local = element; | 2365 LocalElement local = element; |
| 2365 // If the value does not already have a name, give it here. | 2366 // If the value does not already have a name, give it here. |
| 2366 if (value.sourceElement == null) { | 2367 if (value.sourceElement == null) { |
| 2367 value.sourceElement = local; | 2368 value.sourceElement = local; |
| 2368 } | 2369 } |
| 2369 HInstruction checkedOrTrusted = | 2370 HInstruction checkedOrTrusted = |
| 2370 typeBuilder.potentiallyCheckOrTrustType(value, local.type); | 2371 typeBuilder.potentiallyCheckOrTrustType(value, local.type); |
| 2371 if (!identical(checkedOrTrusted, value)) { | 2372 if (!identical(checkedOrTrusted, value)) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2461 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2462 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 2462 ClassElement element = type.element; | 2463 ClassElement element = type.element; |
| 2463 Element helper = helpers.checkSubtype; | 2464 Element helper = helpers.checkSubtype; |
| 2464 HInstruction representations = | 2465 HInstruction representations = |
| 2465 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); | 2466 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); |
| 2466 add(representations); | 2467 add(representations); |
| 2467 js.Name operator = backend.namer.operatorIs(element); | 2468 js.Name operator = backend.namer.operatorIs(element); |
| 2468 HInstruction isFieldName = addConstantStringFromName(operator); | 2469 HInstruction isFieldName = addConstantStringFromName(operator); |
| 2469 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) | 2470 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) |
| 2470 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 2471 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
| 2471 : graph.addConstantNull(compiler); | 2472 : graph.addConstantNull(closedWorld); |
| 2472 List<HInstruction> inputs = <HInstruction>[ | 2473 List<HInstruction> inputs = <HInstruction>[ |
| 2473 expression, | 2474 expression, |
| 2474 isFieldName, | 2475 isFieldName, |
| 2475 representations, | 2476 representations, |
| 2476 asFieldName | 2477 asFieldName |
| 2477 ]; | 2478 ]; |
| 2478 pushInvokeStatic(node, helper, inputs, typeMask: commonMasks.boolType); | 2479 pushInvokeStatic(node, helper, inputs, typeMask: commonMasks.boolType); |
| 2479 HInstruction call = pop(); | 2480 HInstruction call = pop(); |
| 2480 return new HIs.compound(type, expression, call, commonMasks.boolType); | 2481 return new HIs.compound(type, expression, call, commonMasks.boolType); |
| 2481 } else { | 2482 } else { |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2663 message: "No NativeBehavior for $node")); | 2664 message: "No NativeBehavior for $node")); |
| 2664 | 2665 |
| 2665 List<HInstruction> inputs = <HInstruction>[]; | 2666 List<HInstruction> inputs = <HInstruction>[]; |
| 2666 addGenericSendArgumentsToList(link.tail.tail, inputs); | 2667 addGenericSendArgumentsToList(link.tail.tail, inputs); |
| 2667 | 2668 |
| 2668 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { | 2669 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { |
| 2669 reporter.reportErrorMessage(node, MessageKind.GENERIC, { | 2670 reporter.reportErrorMessage(node, MessageKind.GENERIC, { |
| 2670 'text': 'Mismatch between number of placeholders' | 2671 'text': 'Mismatch between number of placeholders' |
| 2671 ' and number of arguments.' | 2672 ' and number of arguments.' |
| 2672 }); | 2673 }); |
| 2673 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | 2674 // Result expected on stack. |
| 2675 stack.add(graph.addConstantNull(closedWorld)); |
| 2674 return; | 2676 return; |
| 2675 } | 2677 } |
| 2676 | 2678 |
| 2677 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { | 2679 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { |
| 2678 reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE); | 2680 reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE); |
| 2679 } | 2681 } |
| 2680 | 2682 |
| 2681 TypeMask ssaType = | 2683 TypeMask ssaType = |
| 2682 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); | 2684 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
| 2683 | 2685 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2759 case 'MUST_RETAIN_METADATA': | 2761 case 'MUST_RETAIN_METADATA': |
| 2760 value = backend.mustRetainMetadata; | 2762 value = backend.mustRetainMetadata; |
| 2761 break; | 2763 break; |
| 2762 case 'USE_CONTENT_SECURITY_POLICY': | 2764 case 'USE_CONTENT_SECURITY_POLICY': |
| 2763 value = compiler.options.useContentSecurityPolicy; | 2765 value = compiler.options.useContentSecurityPolicy; |
| 2764 break; | 2766 break; |
| 2765 default: | 2767 default: |
| 2766 reporter.reportErrorMessage(node, MessageKind.GENERIC, | 2768 reporter.reportErrorMessage(node, MessageKind.GENERIC, |
| 2767 {'text': 'Error: Unknown internal flag "$name".'}); | 2769 {'text': 'Error: Unknown internal flag "$name".'}); |
| 2768 } | 2770 } |
| 2769 stack.add(graph.addConstantBool(value, compiler)); | 2771 stack.add(graph.addConstantBool(value, closedWorld)); |
| 2770 } | 2772 } |
| 2771 | 2773 |
| 2772 void handleForeignJsGetName(ast.Send node) { | 2774 void handleForeignJsGetName(ast.Send node) { |
| 2773 List<ast.Node> arguments = node.arguments.toList(); | 2775 List<ast.Node> arguments = node.arguments.toList(); |
| 2774 ast.Node argument; | 2776 ast.Node argument; |
| 2775 switch (arguments.length) { | 2777 switch (arguments.length) { |
| 2776 case 0: | 2778 case 0: |
| 2777 reporter.reportErrorMessage(node, MessageKind.GENERIC, | 2779 reporter.reportErrorMessage(node, MessageKind.GENERIC, |
| 2778 {'text': 'Error: Expected one argument to JS_GET_NAME.'}); | 2780 {'text': 'Error: Expected one argument to JS_GET_NAME.'}); |
| 2779 return; | 2781 return; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2887 // InterceptorConstant. | 2889 // InterceptorConstant. |
| 2888 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) { | 2890 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) { |
| 2889 ast.Node argument = node.arguments.head; | 2891 ast.Node argument = node.arguments.head; |
| 2890 visit(argument); | 2892 visit(argument); |
| 2891 HInstruction argumentInstruction = pop(); | 2893 HInstruction argumentInstruction = pop(); |
| 2892 if (argumentInstruction is HConstant) { | 2894 if (argumentInstruction is HConstant) { |
| 2893 ConstantValue argumentConstant = argumentInstruction.constant; | 2895 ConstantValue argumentConstant = argumentInstruction.constant; |
| 2894 if (argumentConstant is TypeConstantValue) { | 2896 if (argumentConstant is TypeConstantValue) { |
| 2895 ConstantValue constant = | 2897 ConstantValue constant = |
| 2896 new InterceptorConstantValue(argumentConstant.representedType); | 2898 new InterceptorConstantValue(argumentConstant.representedType); |
| 2897 HInstruction instruction = graph.addConstant(constant, compiler); | 2899 HInstruction instruction = graph.addConstant(constant, closedWorld); |
| 2898 stack.add(instruction); | 2900 stack.add(instruction); |
| 2899 return; | 2901 return; |
| 2900 } | 2902 } |
| 2901 } | 2903 } |
| 2902 } | 2904 } |
| 2903 reporter.reportErrorMessage( | 2905 reporter.reportErrorMessage( |
| 2904 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 2906 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 2905 stack.add(graph.addConstantNull(compiler)); | 2907 stack.add(graph.addConstantNull(closedWorld)); |
| 2906 } | 2908 } |
| 2907 | 2909 |
| 2908 void handleForeignJsCallInIsolate(ast.Send node) { | 2910 void handleForeignJsCallInIsolate(ast.Send node) { |
| 2909 Link<ast.Node> link = node.arguments; | 2911 Link<ast.Node> link = node.arguments; |
| 2910 if (!backend.hasIsolateSupport) { | 2912 if (!backend.hasIsolateSupport) { |
| 2911 // If the isolate library is not used, we just invoke the | 2913 // If the isolate library is not used, we just invoke the |
| 2912 // closure. | 2914 // closure. |
| 2913 visit(link.tail.head); | 2915 visit(link.tail.head); |
| 2914 push(new HInvokeClosure(new Selector.callClosure(0), | 2916 push(new HInvokeClosure(new Selector.callClosure(0), |
| 2915 <HInstruction>[pop()], commonMasks.dynamicType)); | 2917 <HInstruction>[pop()], commonMasks.dynamicType)); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3007 handleForeignJsGetStaticState(node); | 3009 handleForeignJsGetStaticState(node); |
| 3008 } else if (name == 'JS_GET_NAME') { | 3010 } else if (name == 'JS_GET_NAME') { |
| 3009 handleForeignJsGetName(node); | 3011 handleForeignJsGetName(node); |
| 3010 } else if (name == BackendHelpers.JS_EMBEDDED_GLOBAL) { | 3012 } else if (name == BackendHelpers.JS_EMBEDDED_GLOBAL) { |
| 3011 handleForeignJsEmbeddedGlobal(node); | 3013 handleForeignJsEmbeddedGlobal(node); |
| 3012 } else if (name == BackendHelpers.JS_BUILTIN) { | 3014 } else if (name == BackendHelpers.JS_BUILTIN) { |
| 3013 handleForeignJsBuiltin(node); | 3015 handleForeignJsBuiltin(node); |
| 3014 } else if (name == 'JS_GET_FLAG') { | 3016 } else if (name == 'JS_GET_FLAG') { |
| 3015 handleForeignJsGetFlag(node); | 3017 handleForeignJsGetFlag(node); |
| 3016 } else if (name == 'JS_EFFECT') { | 3018 } else if (name == 'JS_EFFECT') { |
| 3017 stack.add(graph.addConstantNull(compiler)); | 3019 stack.add(graph.addConstantNull(closedWorld)); |
| 3018 } else if (name == BackendHelpers.JS_INTERCEPTOR_CONSTANT) { | 3020 } else if (name == BackendHelpers.JS_INTERCEPTOR_CONSTANT) { |
| 3019 handleJsInterceptorConstant(node); | 3021 handleJsInterceptorConstant(node); |
| 3020 } else if (name == 'JS_STRING_CONCAT') { | 3022 } else if (name == 'JS_STRING_CONCAT') { |
| 3021 handleJsStringConcat(node); | 3023 handleJsStringConcat(node); |
| 3022 } else { | 3024 } else { |
| 3023 reporter.internalError(node, "Unknown foreign: ${element}"); | 3025 reporter.internalError(node, "Unknown foreign: ${element}"); |
| 3024 } | 3026 } |
| 3025 } | 3027 } |
| 3026 | 3028 |
| 3027 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, | 3029 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, |
| 3028 SourceInformation sourceInformation) { | 3030 SourceInformation sourceInformation) { |
| 3029 // Until now we only handle these as getters. | 3031 // Until now we only handle these as getters. |
| 3030 invariant(node, deferredLoader.isDeferredLoaderGetter); | 3032 invariant(node, deferredLoader.isDeferredLoaderGetter); |
| 3031 FunctionEntity loadFunction = helpers.loadLibraryWrapper; | 3033 FunctionEntity loadFunction = helpers.loadLibraryWrapper; |
| 3032 PrefixElement prefixElement = deferredLoader.enclosingElement; | 3034 PrefixElement prefixElement = deferredLoader.enclosingElement; |
| 3033 String loadId = | 3035 String loadId = |
| 3034 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); | 3036 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); |
| 3035 var inputs = [ | 3037 var inputs = [ |
| 3036 graph.addConstantString(new ast.DartString.literal(loadId), compiler) | 3038 graph.addConstantString(new ast.DartString.literal(loadId), closedWorld) |
| 3037 ]; | 3039 ]; |
| 3038 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType, | 3040 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType, |
| 3039 targetCanThrow: false)..sourceInformation = sourceInformation); | 3041 targetCanThrow: false)..sourceInformation = sourceInformation); |
| 3040 } | 3042 } |
| 3041 | 3043 |
| 3042 generateSuperNoSuchMethodSend( | 3044 generateSuperNoSuchMethodSend( |
| 3043 ast.Send node, Selector selector, List<HInstruction> arguments) { | 3045 ast.Send node, Selector selector, List<HInstruction> arguments) { |
| 3044 String name = selector.name; | 3046 String name = selector.name; |
| 3045 | 3047 |
| 3046 ClassElement cls = currentNonClosureClass; | 3048 ClassElement cls = currentNonClosureClass; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3065 js.Name internalName = backend.namer.invocationName(selector); | 3067 js.Name internalName = backend.namer.invocationName(selector); |
| 3066 | 3068 |
| 3067 Element createInvocationMirror = helpers.createInvocationMirror; | 3069 Element createInvocationMirror = helpers.createInvocationMirror; |
| 3068 var argumentsInstruction = buildLiteralList(arguments); | 3070 var argumentsInstruction = buildLiteralList(arguments); |
| 3069 add(argumentsInstruction); | 3071 add(argumentsInstruction); |
| 3070 | 3072 |
| 3071 var argumentNames = new List<HInstruction>(); | 3073 var argumentNames = new List<HInstruction>(); |
| 3072 for (String argumentName in selector.namedArguments) { | 3074 for (String argumentName in selector.namedArguments) { |
| 3073 ConstantValue argumentNameConstant = | 3075 ConstantValue argumentNameConstant = |
| 3074 constantSystem.createString(new ast.DartString.literal(argumentName)); | 3076 constantSystem.createString(new ast.DartString.literal(argumentName)); |
| 3075 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); | 3077 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); |
| 3076 } | 3078 } |
| 3077 var argumentNamesInstruction = buildLiteralList(argumentNames); | 3079 var argumentNamesInstruction = buildLiteralList(argumentNames); |
| 3078 add(argumentNamesInstruction); | 3080 add(argumentNamesInstruction); |
| 3079 | 3081 |
| 3080 ConstantValue kindConstant = | 3082 ConstantValue kindConstant = |
| 3081 constantSystem.createInt(selector.invocationMirrorKind); | 3083 constantSystem.createInt(selector.invocationMirrorKind); |
| 3082 | 3084 |
| 3083 pushInvokeStatic( | 3085 pushInvokeStatic( |
| 3084 null, | 3086 null, |
| 3085 createInvocationMirror, | 3087 createInvocationMirror, |
| 3086 [ | 3088 [ |
| 3087 graph.addConstant(nameConstant, compiler), | 3089 graph.addConstant(nameConstant, closedWorld), |
| 3088 graph.addConstantStringFromName(internalName, compiler), | 3090 graph.addConstantStringFromName(internalName, closedWorld), |
| 3089 graph.addConstant(kindConstant, compiler), | 3091 graph.addConstant(kindConstant, closedWorld), |
| 3090 argumentsInstruction, | 3092 argumentsInstruction, |
| 3091 argumentNamesInstruction | 3093 argumentNamesInstruction |
| 3092 ], | 3094 ], |
| 3093 typeMask: commonMasks.dynamicType); | 3095 typeMask: commonMasks.dynamicType); |
| 3094 | 3096 |
| 3095 var inputs = <HInstruction>[pop()]; | 3097 var inputs = <HInstruction>[pop()]; |
| 3096 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); | 3098 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); |
| 3097 } | 3099 } |
| 3098 | 3100 |
| 3099 /// Generate a call to a super method or constructor. | 3101 /// Generate a call to a super method or constructor. |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3392 target = target.immediateRedirectionTarget; | 3394 target = target.immediateRedirectionTarget; |
| 3393 } | 3395 } |
| 3394 } | 3396 } |
| 3395 InterfaceType type = elements.getType(node); | 3397 InterfaceType type = elements.getType(node); |
| 3396 InterfaceType expectedType = | 3398 InterfaceType expectedType = |
| 3397 constructorDeclaration.computeEffectiveTargetType(type); | 3399 constructorDeclaration.computeEffectiveTargetType(type); |
| 3398 expectedType = localsHandler.substInContext(expectedType); | 3400 expectedType = localsHandler.substInContext(expectedType); |
| 3399 | 3401 |
| 3400 if (compiler.elementHasCompileTimeError(constructor)) { | 3402 if (compiler.elementHasCompileTimeError(constructor)) { |
| 3401 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 3403 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 3402 stack.add(graph.addConstantNull(compiler)); | 3404 stack.add(graph.addConstantNull(closedWorld)); |
| 3403 return; | 3405 return; |
| 3404 } | 3406 } |
| 3405 | 3407 |
| 3406 if (checkTypeVariableBounds(node, type)) return; | 3408 if (checkTypeVariableBounds(node, type)) return; |
| 3407 | 3409 |
| 3408 // Abstract class instantiation error takes precedence over argument | 3410 // Abstract class instantiation error takes precedence over argument |
| 3409 // mismatch. | 3411 // mismatch. |
| 3410 ClassElement cls = constructor.enclosingClass; | 3412 ClassElement cls = constructor.enclosingClass; |
| 3411 if (cls.isAbstract && constructor.isGenerativeConstructor) { | 3413 if (cls.isAbstract && constructor.isGenerativeConstructor) { |
| 3412 // However, we need to ensure that all arguments are evaluated before we | 3414 // However, we need to ensure that all arguments are evaluated before we |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3427 .signatureApplies(constructorImplementation.functionSignature)) { | 3429 .signatureApplies(constructorImplementation.functionSignature)) { |
| 3428 generateWrongArgumentCountError(send, constructor, send.arguments); | 3430 generateWrongArgumentCountError(send, constructor, send.arguments); |
| 3429 return; | 3431 return; |
| 3430 } | 3432 } |
| 3431 | 3433 |
| 3432 List<HInstruction> inputs = <HInstruction>[]; | 3434 List<HInstruction> inputs = <HInstruction>[]; |
| 3433 if (constructor.isGenerativeConstructor && | 3435 if (constructor.isGenerativeConstructor && |
| 3434 backend.isNativeOrExtendsNative(constructor.enclosingClass) && | 3436 backend.isNativeOrExtendsNative(constructor.enclosingClass) && |
| 3435 !backend.isJsInterop(constructor)) { | 3437 !backend.isJsInterop(constructor)) { |
| 3436 // Native class generative constructors take a pre-constructed object. | 3438 // Native class generative constructors take a pre-constructed object. |
| 3437 inputs.add(graph.addConstantNull(compiler)); | 3439 inputs.add(graph.addConstantNull(closedWorld)); |
| 3438 } | 3440 } |
| 3439 inputs.addAll(makeStaticArgumentList( | 3441 inputs.addAll(makeStaticArgumentList( |
| 3440 callStructure, send.arguments, constructorImplementation)); | 3442 callStructure, send.arguments, constructorImplementation)); |
| 3441 | 3443 |
| 3442 TypeMask elementType = computeType(constructor); | 3444 TypeMask elementType = computeType(constructor); |
| 3443 if (isFixedListConstructorCall) { | 3445 if (isFixedListConstructorCall) { |
| 3444 if (!inputs[0].isNumber(closedWorld)) { | 3446 if (!inputs[0].isNumber(closedWorld)) { |
| 3445 HTypeConversion conversion = new HTypeConversion( | 3447 HTypeConversion conversion = new HTypeConversion( |
| 3446 null, | 3448 null, |
| 3447 HTypeConversion.ARGUMENT_TYPE_CHECK, | 3449 HTypeConversion.ARGUMENT_TYPE_CHECK, |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3717 | 3719 |
| 3718 @override | 3720 @override |
| 3719 void visitUnresolvedInvoke(ast.Send node, Element element, | 3721 void visitUnresolvedInvoke(ast.Send node, Element element, |
| 3720 ast.NodeList arguments, Selector selector, _) { | 3722 ast.NodeList arguments, Selector selector, _) { |
| 3721 if (element is ErroneousElement) { | 3723 if (element is ErroneousElement) { |
| 3722 // An erroneous element indicates that the function could not be | 3724 // An erroneous element indicates that the function could not be |
| 3723 // resolved (a warning has been issued). | 3725 // resolved (a warning has been issued). |
| 3724 handleInvalidStaticInvoke(node, element); | 3726 handleInvalidStaticInvoke(node, element); |
| 3725 } else { | 3727 } else { |
| 3726 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 3728 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 3727 stack.add(graph.addConstantNull(compiler)); | 3729 stack.add(graph.addConstantNull(closedWorld)); |
| 3728 } | 3730 } |
| 3729 return; | 3731 return; |
| 3730 } | 3732 } |
| 3731 | 3733 |
| 3732 HConstant addConstantString(String string) { | 3734 HConstant addConstantString(String string) { |
| 3733 ast.DartString dartString = new ast.DartString.literal(string); | 3735 ast.DartString dartString = new ast.DartString.literal(string); |
| 3734 return graph.addConstantString(dartString, compiler); | 3736 return graph.addConstantString(dartString, closedWorld); |
| 3735 } | 3737 } |
| 3736 | 3738 |
| 3737 HConstant addConstantStringFromName(js.Name name) { | 3739 HConstant addConstantStringFromName(js.Name name) { |
| 3738 return graph.addConstantStringFromName(name, compiler); | 3740 return graph.addConstantStringFromName(name, closedWorld); |
| 3739 } | 3741 } |
| 3740 | 3742 |
| 3741 visitClassTypeLiteralGet(ast.Send node, ConstantExpression constant, _) { | 3743 visitClassTypeLiteralGet(ast.Send node, ConstantExpression constant, _) { |
| 3742 generateConstantTypeLiteral(node); | 3744 generateConstantTypeLiteral(node); |
| 3743 } | 3745 } |
| 3744 | 3746 |
| 3745 visitClassTypeLiteralInvoke(ast.Send node, ConstantExpression constant, | 3747 visitClassTypeLiteralInvoke(ast.Send node, ConstantExpression constant, |
| 3746 ast.NodeList arguments, CallStructure callStructure, _) { | 3748 ast.NodeList arguments, CallStructure callStructure, _) { |
| 3747 generateConstantTypeLiteral(node); | 3749 generateConstantTypeLiteral(node); |
| 3748 generateTypeLiteralCall(node); | 3750 generateTypeLiteralCall(node); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3858 } | 3860 } |
| 3859 | 3861 |
| 3860 void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName, | 3862 void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName, |
| 3861 {Link<ast.Node> argumentNodes, | 3863 {Link<ast.Node> argumentNodes, |
| 3862 List<HInstruction> argumentValues, | 3864 List<HInstruction> argumentValues, |
| 3863 List<String> existingArguments, | 3865 List<String> existingArguments, |
| 3864 SourceInformation sourceInformation}) { | 3866 SourceInformation sourceInformation}) { |
| 3865 Element helper = helpers.throwNoSuchMethod; | 3867 Element helper = helpers.throwNoSuchMethod; |
| 3866 ConstantValue receiverConstant = | 3868 ConstantValue receiverConstant = |
| 3867 constantSystem.createString(new ast.DartString.empty()); | 3869 constantSystem.createString(new ast.DartString.empty()); |
| 3868 HInstruction receiver = graph.addConstant(receiverConstant, compiler); | 3870 HInstruction receiver = graph.addConstant(receiverConstant, closedWorld); |
| 3869 ast.DartString dartString = new ast.DartString.literal(methodName); | 3871 ast.DartString dartString = new ast.DartString.literal(methodName); |
| 3870 ConstantValue nameConstant = constantSystem.createString(dartString); | 3872 ConstantValue nameConstant = constantSystem.createString(dartString); |
| 3871 HInstruction name = graph.addConstant(nameConstant, compiler); | 3873 HInstruction name = graph.addConstant(nameConstant, closedWorld); |
| 3872 if (argumentValues == null) { | 3874 if (argumentValues == null) { |
| 3873 argumentValues = <HInstruction>[]; | 3875 argumentValues = <HInstruction>[]; |
| 3874 argumentNodes.forEach((argumentNode) { | 3876 argumentNodes.forEach((argumentNode) { |
| 3875 visit(argumentNode); | 3877 visit(argumentNode); |
| 3876 HInstruction value = pop(); | 3878 HInstruction value = pop(); |
| 3877 argumentValues.add(value); | 3879 argumentValues.add(value); |
| 3878 }); | 3880 }); |
| 3879 } | 3881 } |
| 3880 HInstruction arguments = buildLiteralList(argumentValues); | 3882 HInstruction arguments = buildLiteralList(argumentValues); |
| 3881 add(arguments); | 3883 add(arguments); |
| 3882 HInstruction existingNamesList; | 3884 HInstruction existingNamesList; |
| 3883 if (existingArguments != null) { | 3885 if (existingArguments != null) { |
| 3884 List<HInstruction> existingNames = <HInstruction>[]; | 3886 List<HInstruction> existingNames = <HInstruction>[]; |
| 3885 for (String name in existingArguments) { | 3887 for (String name in existingArguments) { |
| 3886 HInstruction nameConstant = | 3888 HInstruction nameConstant = graph.addConstantString( |
| 3887 graph.addConstantString(new ast.DartString.literal(name), compiler); | 3889 new ast.DartString.literal(name), closedWorld); |
| 3888 existingNames.add(nameConstant); | 3890 existingNames.add(nameConstant); |
| 3889 } | 3891 } |
| 3890 existingNamesList = buildLiteralList(existingNames); | 3892 existingNamesList = buildLiteralList(existingNames); |
| 3891 add(existingNamesList); | 3893 add(existingNamesList); |
| 3892 } else { | 3894 } else { |
| 3893 existingNamesList = graph.addConstantNull(compiler); | 3895 existingNamesList = graph.addConstantNull(closedWorld); |
| 3894 } | 3896 } |
| 3895 pushInvokeStatic( | 3897 pushInvokeStatic( |
| 3896 diagnosticNode, helper, [receiver, name, arguments, existingNamesList], | 3898 diagnosticNode, helper, [receiver, name, arguments, existingNamesList], |
| 3897 sourceInformation: sourceInformation); | 3899 sourceInformation: sourceInformation); |
| 3898 } | 3900 } |
| 3899 | 3901 |
| 3900 /** | 3902 /** |
| 3901 * Generate code to throw a [NoSuchMethodError] exception for calling a | 3903 * Generate code to throw a [NoSuchMethodError] exception for calling a |
| 3902 * method with a wrong number of arguments or mismatching named optional | 3904 * method with a wrong number of arguments or mismatching named optional |
| 3903 * arguments. | 3905 * arguments. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3934 generateThrowNoSuchMethod( | 3936 generateThrowNoSuchMethod( |
| 3935 node.send, noSuchMethodTargetSymbolString(error, 'constructor'), | 3937 node.send, noSuchMethodTargetSymbolString(error, 'constructor'), |
| 3936 argumentNodes: node.send.arguments); | 3938 argumentNodes: node.send.arguments); |
| 3937 } else { | 3939 } else { |
| 3938 MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind]; | 3940 MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind]; |
| 3939 Message message = template.message(error.messageArguments); | 3941 Message message = template.message(error.messageArguments); |
| 3940 generateRuntimeError(node.send, message.toString()); | 3942 generateRuntimeError(node.send, message.toString()); |
| 3941 } | 3943 } |
| 3942 } else if (Elements.isMalformed(element)) { | 3944 } else if (Elements.isMalformed(element)) { |
| 3943 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 3945 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 3944 stack.add(graph.addConstantNull(compiler)); | 3946 stack.add(graph.addConstantNull(closedWorld)); |
| 3945 } else if (node.isConst) { | 3947 } else if (node.isConst) { |
| 3946 stack.add(addConstant(node)); | 3948 stack.add(addConstant(node)); |
| 3947 if (isSymbolConstructor) { | 3949 if (isSymbolConstructor) { |
| 3948 ConstructedConstantValue symbol = getConstantForNode(node); | 3950 ConstructedConstantValue symbol = getConstantForNode(node); |
| 3949 StringConstantValue stringConstant = symbol.fields.values.single; | 3951 StringConstantValue stringConstant = symbol.fields.values.single; |
| 3950 String nameString = stringConstant.toDartString().slowToString(); | 3952 String nameString = stringConstant.toDartString().slowToString(); |
| 3951 registry?.registerConstSymbol(nameString); | 3953 registry?.registerConstSymbol(nameString); |
| 3952 } | 3954 } |
| 3953 } else { | 3955 } else { |
| 3954 handleNewSend(node); | 3956 handleNewSend(node); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4202 isSetter: selector.isSetter || selector.isIndexSet); | 4204 isSetter: selector.isSetter || selector.isIndexSet); |
| 4203 instruction.sideEffects = | 4205 instruction.sideEffects = |
| 4204 closedWorld.getSideEffectsOfSelector(selector, null); | 4206 closedWorld.getSideEffectsOfSelector(selector, null); |
| 4205 return instruction; | 4207 return instruction; |
| 4206 } | 4208 } |
| 4207 | 4209 |
| 4208 void handleComplexOperatorSend( | 4210 void handleComplexOperatorSend( |
| 4209 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) { | 4211 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) { |
| 4210 HInstruction rhs; | 4212 HInstruction rhs; |
| 4211 if (node.isPrefix || node.isPostfix) { | 4213 if (node.isPrefix || node.isPostfix) { |
| 4212 rhs = graph.addConstantInt(1, compiler); | 4214 rhs = graph.addConstantInt(1, closedWorld); |
| 4213 } else { | 4215 } else { |
| 4214 visit(arguments.head); | 4216 visit(arguments.head); |
| 4215 assert(arguments.tail.isEmpty); | 4217 assert(arguments.tail.isEmpty); |
| 4216 rhs = pop(); | 4218 rhs = pop(); |
| 4217 } | 4219 } |
| 4218 visitBinarySend( | 4220 visitBinarySend( |
| 4219 receiver, | 4221 receiver, |
| 4220 rhs, | 4222 rhs, |
| 4221 elements.getOperatorSelectorInComplexSendSet(node), | 4223 elements.getOperatorSelectorInComplexSendSet(node), |
| 4222 elementInferenceResults.typeOfOperator(node), | 4224 elementInferenceResults.typeOfOperator(node), |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4962 } | 4964 } |
| 4963 | 4965 |
| 4964 @override | 4966 @override |
| 4965 visitTypeVariableTypeLiteralSetIfNull( | 4967 visitTypeVariableTypeLiteralSetIfNull( |
| 4966 ast.Send node, TypeVariableElement element, ast.Node rhs, arg) { | 4968 ast.Send node, TypeVariableElement element, ast.Node rhs, arg) { |
| 4967 // The type variable is never `null`. | 4969 // The type variable is never `null`. |
| 4968 generateTypeVariableLiteral(node, element.type); | 4970 generateTypeVariableLiteral(node, element.type); |
| 4969 } | 4971 } |
| 4970 | 4972 |
| 4971 void visitLiteralInt(ast.LiteralInt node) { | 4973 void visitLiteralInt(ast.LiteralInt node) { |
| 4972 stack.add(graph.addConstantInt(node.value, compiler)); | 4974 stack.add(graph.addConstantInt(node.value, closedWorld)); |
| 4973 } | 4975 } |
| 4974 | 4976 |
| 4975 void visitLiteralDouble(ast.LiteralDouble node) { | 4977 void visitLiteralDouble(ast.LiteralDouble node) { |
| 4976 stack.add(graph.addConstantDouble(node.value, compiler)); | 4978 stack.add(graph.addConstantDouble(node.value, closedWorld)); |
| 4977 } | 4979 } |
| 4978 | 4980 |
| 4979 void visitLiteralBool(ast.LiteralBool node) { | 4981 void visitLiteralBool(ast.LiteralBool node) { |
| 4980 stack.add(graph.addConstantBool(node.value, compiler)); | 4982 stack.add(graph.addConstantBool(node.value, closedWorld)); |
| 4981 } | 4983 } |
| 4982 | 4984 |
| 4983 void visitLiteralString(ast.LiteralString node) { | 4985 void visitLiteralString(ast.LiteralString node) { |
| 4984 stack.add(graph.addConstantString(node.dartString, compiler)); | 4986 stack.add(graph.addConstantString(node.dartString, closedWorld)); |
| 4985 } | 4987 } |
| 4986 | 4988 |
| 4987 void visitLiteralSymbol(ast.LiteralSymbol node) { | 4989 void visitLiteralSymbol(ast.LiteralSymbol node) { |
| 4988 stack.add(addConstant(node)); | 4990 stack.add(addConstant(node)); |
| 4989 registry?.registerConstSymbol(node.slowNameString); | 4991 registry?.registerConstSymbol(node.slowNameString); |
| 4990 } | 4992 } |
| 4991 | 4993 |
| 4992 void visitStringJuxtaposition(ast.StringJuxtaposition node) { | 4994 void visitStringJuxtaposition(ast.StringJuxtaposition node) { |
| 4993 if (!node.isInterpolation) { | 4995 if (!node.isInterpolation) { |
| 4994 // This is a simple string with no interpolations. | 4996 // This is a simple string with no interpolations. |
| 4995 stack.add(graph.addConstantString(node.dartString, compiler)); | 4997 stack.add(graph.addConstantString(node.dartString, closedWorld)); |
| 4996 return; | 4998 return; |
| 4997 } | 4999 } |
| 4998 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 5000 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
| 4999 stringBuilder.visit(node); | 5001 stringBuilder.visit(node); |
| 5000 stack.add(stringBuilder.result); | 5002 stack.add(stringBuilder.result); |
| 5001 } | 5003 } |
| 5002 | 5004 |
| 5003 void visitLiteralNull(ast.LiteralNull node) { | 5005 void visitLiteralNull(ast.LiteralNull node) { |
| 5004 stack.add(graph.addConstantNull(compiler)); | 5006 stack.add(graph.addConstantNull(closedWorld)); |
| 5005 } | 5007 } |
| 5006 | 5008 |
| 5007 visitNodeList(ast.NodeList node) { | 5009 visitNodeList(ast.NodeList node) { |
| 5008 for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 5010 for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 5009 if (isAborted()) { | 5011 if (isAborted()) { |
| 5010 reporter.reportHintMessage( | 5012 reporter.reportHintMessage( |
| 5011 link.head, MessageKind.GENERIC, {'text': 'dead code'}); | 5013 link.head, MessageKind.GENERIC, {'text': 'dead code'}); |
| 5012 } else { | 5014 } else { |
| 5013 visit(link.head); | 5015 visit(link.head); |
| 5014 } | 5016 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5040 if (!inTryStatement) return; | 5042 if (!inTryStatement) return; |
| 5041 HBasicBlock block = close(new HExitTry()); | 5043 HBasicBlock block = close(new HExitTry()); |
| 5042 HBasicBlock newBlock = graph.addNewBlock(); | 5044 HBasicBlock newBlock = graph.addNewBlock(); |
| 5043 block.addSuccessor(newBlock); | 5045 block.addSuccessor(newBlock); |
| 5044 open(newBlock); | 5046 open(newBlock); |
| 5045 } | 5047 } |
| 5046 | 5048 |
| 5047 visitRethrow(ast.Rethrow node) { | 5049 visitRethrow(ast.Rethrow node) { |
| 5048 HInstruction exception = rethrowableException; | 5050 HInstruction exception = rethrowableException; |
| 5049 if (exception == null) { | 5051 if (exception == null) { |
| 5050 exception = graph.addConstantNull(compiler); | 5052 exception = graph.addConstantNull(closedWorld); |
| 5051 reporter.internalError(node, 'rethrowableException should not be null.'); | 5053 reporter.internalError(node, 'rethrowableException should not be null.'); |
| 5052 } | 5054 } |
| 5053 handleInTryStatement(); | 5055 handleInTryStatement(); |
| 5054 closeAndGotoExit(new HThrow( | 5056 closeAndGotoExit(new HThrow( |
| 5055 exception, sourceInformationBuilder.buildThrow(node), | 5057 exception, sourceInformationBuilder.buildThrow(node), |
| 5056 isRethrow: true)); | 5058 isRethrow: true)); |
| 5057 } | 5059 } |
| 5058 | 5060 |
| 5059 visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { | 5061 visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { |
| 5060 ConstructorElement targetConstructor = | 5062 ConstructorElement targetConstructor = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 5085 void loadPosition(int position, ParameterElement optionalParameter) { | 5087 void loadPosition(int position, ParameterElement optionalParameter) { |
| 5086 if (position < redirectingRequireds.length) { | 5088 if (position < redirectingRequireds.length) { |
| 5087 loadLocal(redirectingRequireds[position]); | 5089 loadLocal(redirectingRequireds[position]); |
| 5088 } else if (position < redirectingSignature.parameterCount && | 5090 } else if (position < redirectingSignature.parameterCount && |
| 5089 !redirectingSignature.optionalParametersAreNamed) { | 5091 !redirectingSignature.optionalParametersAreNamed) { |
| 5090 loadLocal(redirectingOptionals[position - redirectingRequireds.length]); | 5092 loadLocal(redirectingOptionals[position - redirectingRequireds.length]); |
| 5091 } else if (optionalParameter != null) { | 5093 } else if (optionalParameter != null) { |
| 5092 inputs.add(handleConstantForOptionalParameter(optionalParameter)); | 5094 inputs.add(handleConstantForOptionalParameter(optionalParameter)); |
| 5093 } else { | 5095 } else { |
| 5094 // Wrong. | 5096 // Wrong. |
| 5095 inputs.add(graph.addConstantNull(compiler)); | 5097 inputs.add(graph.addConstantNull(closedWorld)); |
| 5096 } | 5098 } |
| 5097 } | 5099 } |
| 5098 | 5100 |
| 5099 int position = 0; | 5101 int position = 0; |
| 5100 | 5102 |
| 5101 for (ParameterElement _ in targetRequireds) { | 5103 for (ParameterElement _ in targetRequireds) { |
| 5102 loadPosition(position++, null); | 5104 loadPosition(position++, null); |
| 5103 } | 5105 } |
| 5104 | 5106 |
| 5105 if (targetOptionals.isNotEmpty) { | 5107 if (targetOptionals.isNotEmpty) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5156 (type is InterfaceType && type.element == coreClasses.futureClass); | 5158 (type is InterfaceType && type.element == coreClasses.futureClass); |
| 5157 } | 5159 } |
| 5158 | 5160 |
| 5159 visitReturn(ast.Return node) { | 5161 visitReturn(ast.Return node) { |
| 5160 if (identical(node.beginToken.stringValue, 'native')) { | 5162 if (identical(node.beginToken.stringValue, 'native')) { |
| 5161 native.handleSsaNative(this, node.expression); | 5163 native.handleSsaNative(this, node.expression); |
| 5162 return; | 5164 return; |
| 5163 } | 5165 } |
| 5164 HInstruction value; | 5166 HInstruction value; |
| 5165 if (node.expression == null) { | 5167 if (node.expression == null) { |
| 5166 value = graph.addConstantNull(compiler); | 5168 value = graph.addConstantNull(closedWorld); |
| 5167 } else { | 5169 } else { |
| 5168 visit(node.expression); | 5170 visit(node.expression); |
| 5169 value = pop(); | 5171 value = pop(); |
| 5170 if (isBuildingAsyncFunction) { | 5172 if (isBuildingAsyncFunction) { |
| 5171 if (compiler.options.enableTypeAssertions && | 5173 if (compiler.options.enableTypeAssertions && |
| 5172 !isValidAsyncReturnType(returnType)) { | 5174 !isValidAsyncReturnType(returnType)) { |
| 5173 String message = "Async function returned a Future, " | 5175 String message = "Async function returned a Future, " |
| 5174 "was declared to return a $returnType."; | 5176 "was declared to return a $returnType."; |
| 5175 generateTypeError(node, message); | 5177 generateTypeError(node, message); |
| 5176 pop(); | 5178 pop(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5214 } | 5216 } |
| 5215 | 5217 |
| 5216 visitVariableDefinitions(ast.VariableDefinitions node) { | 5218 visitVariableDefinitions(ast.VariableDefinitions node) { |
| 5217 assert(isReachable); | 5219 assert(isReachable); |
| 5218 for (Link<ast.Node> link = node.definitions.nodes; | 5220 for (Link<ast.Node> link = node.definitions.nodes; |
| 5219 !link.isEmpty; | 5221 !link.isEmpty; |
| 5220 link = link.tail) { | 5222 link = link.tail) { |
| 5221 ast.Node definition = link.head; | 5223 ast.Node definition = link.head; |
| 5222 LocalElement local = elements[definition]; | 5224 LocalElement local = elements[definition]; |
| 5223 if (definition is ast.Identifier) { | 5225 if (definition is ast.Identifier) { |
| 5224 HInstruction initialValue = graph.addConstantNull(compiler); | 5226 HInstruction initialValue = graph.addConstantNull(closedWorld); |
| 5225 localsHandler.updateLocal(local, initialValue); | 5227 localsHandler.updateLocal(local, initialValue); |
| 5226 } else { | 5228 } else { |
| 5227 ast.SendSet node = definition; | 5229 ast.SendSet node = definition; |
| 5228 generateNonInstanceSetter( | 5230 generateNonInstanceSetter( |
| 5229 node, local, visitAndPop(node.arguments.first)); | 5231 node, local, visitAndPop(node.arguments.first)); |
| 5230 pop(); // Discard value. | 5232 pop(); // Discard value. |
| 5231 } | 5233 } |
| 5232 } | 5234 } |
| 5233 } | 5235 } |
| 5234 | 5236 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5353 return new JumpHandler(this, element); | 5355 return new JumpHandler(this, element); |
| 5354 } | 5356 } |
| 5355 | 5357 |
| 5356 visitAsyncForIn(ast.AsyncForIn node) { | 5358 visitAsyncForIn(ast.AsyncForIn node) { |
| 5357 // The async-for is implemented with a StreamIterator. | 5359 // The async-for is implemented with a StreamIterator. |
| 5358 HInstruction streamIterator; | 5360 HInstruction streamIterator; |
| 5359 | 5361 |
| 5360 visit(node.expression); | 5362 visit(node.expression); |
| 5361 HInstruction expression = pop(); | 5363 HInstruction expression = pop(); |
| 5362 pushInvokeStatic(node, helpers.streamIteratorConstructor, | 5364 pushInvokeStatic(node, helpers.streamIteratorConstructor, |
| 5363 [expression, graph.addConstantNull(compiler)]); | 5365 [expression, graph.addConstantNull(closedWorld)]); |
| 5364 streamIterator = pop(); | 5366 streamIterator = pop(); |
| 5365 | 5367 |
| 5366 void buildInitializer() {} | 5368 void buildInitializer() {} |
| 5367 | 5369 |
| 5368 HInstruction buildCondition() { | 5370 HInstruction buildCondition() { |
| 5369 Selector selector = Selectors.moveNext; | 5371 Selector selector = Selectors.moveNext; |
| 5370 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); | 5372 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
| 5371 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 5373 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
| 5372 HInstruction future = pop(); | 5374 HInstruction future = pop(); |
| 5373 push(new HAwait( | 5375 push(new HAwait( |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5531 pushInvokeStatic( | 5533 pushInvokeStatic( |
| 5532 node, helpers.checkConcurrentModificationError, [pop(), array]); | 5534 node, helpers.checkConcurrentModificationError, [pop(), array]); |
| 5533 pop(); | 5535 pop(); |
| 5534 } | 5536 } |
| 5535 | 5537 |
| 5536 void buildInitializer() { | 5538 void buildInitializer() { |
| 5537 visit(node.expression); | 5539 visit(node.expression); |
| 5538 array = pop(); | 5540 array = pop(); |
| 5539 isFixed = isFixedLength(array.instructionType, closedWorld); | 5541 isFixed = isFixedLength(array.instructionType, closedWorld); |
| 5540 localsHandler.updateLocal( | 5542 localsHandler.updateLocal( |
| 5541 indexVariable, graph.addConstantInt(0, compiler)); | 5543 indexVariable, graph.addConstantInt(0, closedWorld)); |
| 5542 originalLength = buildGetLength(); | 5544 originalLength = buildGetLength(); |
| 5543 } | 5545 } |
| 5544 | 5546 |
| 5545 HInstruction buildCondition() { | 5547 HInstruction buildCondition() { |
| 5546 HInstruction index = localsHandler.readLocal(indexVariable); | 5548 HInstruction index = localsHandler.readLocal(indexVariable); |
| 5547 HInstruction length = buildGetLength(); | 5549 HInstruction length = buildGetLength(); |
| 5548 HInstruction compare = new HLess(index, length, null, boolType); | 5550 HInstruction compare = new HLess(index, length, null, boolType); |
| 5549 add(compare); | 5551 add(compare); |
| 5550 return compare; | 5552 return compare; |
| 5551 } | 5553 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5575 | 5577 |
| 5576 void buildUpdate() { | 5578 void buildUpdate() { |
| 5577 // See buildBody as to why we check here. | 5579 // See buildBody as to why we check here. |
| 5578 buildConcurrentModificationErrorCheck(); | 5580 buildConcurrentModificationErrorCheck(); |
| 5579 | 5581 |
| 5580 // TODO(sra): It would be slightly shorter to generate `a[i++]` in the | 5582 // TODO(sra): It would be slightly shorter to generate `a[i++]` in the |
| 5581 // body (and that more closely follows what an inlined iterator would do) | 5583 // body (and that more closely follows what an inlined iterator would do) |
| 5582 // but the code is horrible as `i+1` is carried around the loop in an | 5584 // but the code is horrible as `i+1` is carried around the loop in an |
| 5583 // additional variable. | 5585 // additional variable. |
| 5584 HInstruction index = localsHandler.readLocal(indexVariable); | 5586 HInstruction index = localsHandler.readLocal(indexVariable); |
| 5585 HInstruction one = graph.addConstantInt(1, compiler); | 5587 HInstruction one = graph.addConstantInt(1, closedWorld); |
| 5586 HInstruction addInstruction = | 5588 HInstruction addInstruction = |
| 5587 new HAdd(index, one, null, commonMasks.positiveIntType); | 5589 new HAdd(index, one, null, commonMasks.positiveIntType); |
| 5588 add(addInstruction); | 5590 add(addInstruction); |
| 5589 localsHandler.updateLocal(indexVariable, addInstruction); | 5591 localsHandler.updateLocal(indexVariable, addInstruction); |
| 5590 } | 5592 } |
| 5591 | 5593 |
| 5592 loopHandler.handleLoop( | 5594 loopHandler.handleLoop( |
| 5593 node, buildInitializer, buildCondition, buildUpdate, buildBody); | 5595 node, buildInitializer, buildCondition, buildUpdate, buildBody); |
| 5594 } | 5596 } |
| 5595 | 5597 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5844 // l: while (true) { | 5846 // l: while (true) { |
| 5845 // switch (target) { | 5847 // switch (target) { |
| 5846 // case 1: s_1; break l; | 5848 // case 1: s_1; break l; |
| 5847 // case 2: s_2; target = i; continue l; | 5849 // case 2: s_2; target = i; continue l; |
| 5848 // ... | 5850 // ... |
| 5849 // case n: s_n; target = j; continue l; | 5851 // case n: s_n; target = j; continue l; |
| 5850 // } | 5852 // } |
| 5851 // } | 5853 // } |
| 5852 | 5854 |
| 5853 JumpTarget switchTarget = elements.getTargetDefinition(node); | 5855 JumpTarget switchTarget = elements.getTargetDefinition(node); |
| 5854 HInstruction initialValue = graph.addConstantNull(compiler); | 5856 HInstruction initialValue = graph.addConstantNull(closedWorld); |
| 5855 localsHandler.updateLocal(switchTarget, initialValue); | 5857 localsHandler.updateLocal(switchTarget, initialValue); |
| 5856 | 5858 |
| 5857 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); | 5859 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); |
| 5858 var switchCases = node.cases; | 5860 var switchCases = node.cases; |
| 5859 if (!hasDefault) { | 5861 if (!hasDefault) { |
| 5860 // Use [:null:] as the marker for a synthetic default clause. | 5862 // Use [:null:] as the marker for a synthetic default clause. |
| 5861 // The synthetic default is added because otherwise, there would be no | 5863 // The synthetic default is added because otherwise, there would be no |
| 5862 // good place to give a default value to the local. | 5864 // good place to give a default value to the local. |
| 5863 switchCases = node.cases.nodes.toList()..add(null); | 5865 switchCases = node.cases.nodes.toList()..add(null); |
| 5864 } | 5866 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5880 } | 5882 } |
| 5881 | 5883 |
| 5882 bool isDefaultCase(ast.SwitchCase switchCase) { | 5884 bool isDefaultCase(ast.SwitchCase switchCase) { |
| 5883 return switchCase == null || switchCase.isDefaultCase; | 5885 return switchCase == null || switchCase.isDefaultCase; |
| 5884 } | 5886 } |
| 5885 | 5887 |
| 5886 void buildSwitchCase(ast.SwitchCase switchCase) { | 5888 void buildSwitchCase(ast.SwitchCase switchCase) { |
| 5887 if (switchCase != null) { | 5889 if (switchCase != null) { |
| 5888 // Generate 'target = i; break;' for switch case i. | 5890 // Generate 'target = i; break;' for switch case i. |
| 5889 int index = caseIndex[switchCase]; | 5891 int index = caseIndex[switchCase]; |
| 5890 HInstruction value = graph.addConstantInt(index, compiler); | 5892 HInstruction value = graph.addConstantInt(index, closedWorld); |
| 5891 localsHandler.updateLocal(switchTarget, value); | 5893 localsHandler.updateLocal(switchTarget, value); |
| 5892 } else { | 5894 } else { |
| 5893 // Generate synthetic default case 'target = null; break;'. | 5895 // Generate synthetic default case 'target = null; break;'. |
| 5894 HInstruction value = graph.addConstantNull(compiler); | 5896 HInstruction value = graph.addConstantNull(closedWorld); |
| 5895 localsHandler.updateLocal(switchTarget, value); | 5897 localsHandler.updateLocal(switchTarget, value); |
| 5896 } | 5898 } |
| 5897 jumpTargets[switchTarget].generateBreak(); | 5899 jumpTargets[switchTarget].generateBreak(); |
| 5898 } | 5900 } |
| 5899 | 5901 |
| 5900 handleSwitch(node, jumpHandler, buildExpression, switchCases, getConstants, | 5902 handleSwitch(node, jumpHandler, buildExpression, switchCases, getConstants, |
| 5901 isDefaultCase, buildSwitchCase); | 5903 isDefaultCase, buildSwitchCase); |
| 5902 jumpHandler.close(); | 5904 jumpHandler.close(); |
| 5903 | 5905 |
| 5904 HInstruction buildCondition() => graph.addConstantBool(true, compiler); | 5906 HInstruction buildCondition() => graph.addConstantBool(true, closedWorld); |
| 5905 | 5907 |
| 5906 void buildSwitch() { | 5908 void buildSwitch() { |
| 5907 HInstruction buildExpression() { | 5909 HInstruction buildExpression() { |
| 5908 return localsHandler.readLocal(switchTarget); | 5910 return localsHandler.readLocal(switchTarget); |
| 5909 } | 5911 } |
| 5910 | 5912 |
| 5911 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) { | 5913 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) { |
| 5912 return <ConstantValue>[constantSystem.createInt(caseIndex[switchCase])]; | 5914 return <ConstantValue>[constantSystem.createInt(caseIndex[switchCase])]; |
| 5913 } | 5915 } |
| 5914 | 5916 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5989 LocalsHandler savedLocals = localsHandler; | 5991 LocalsHandler savedLocals = localsHandler; |
| 5990 | 5992 |
| 5991 List<HStatementInformation> statements = <HStatementInformation>[]; | 5993 List<HStatementInformation> statements = <HStatementInformation>[]; |
| 5992 bool hasDefault = false; | 5994 bool hasDefault = false; |
| 5993 HasNextIterator<ast.Node> caseIterator = | 5995 HasNextIterator<ast.Node> caseIterator = |
| 5994 new HasNextIterator<ast.Node>(switchCases.iterator); | 5996 new HasNextIterator<ast.Node>(switchCases.iterator); |
| 5995 while (caseIterator.hasNext) { | 5997 while (caseIterator.hasNext) { |
| 5996 ast.SwitchCase switchCase = caseIterator.next(); | 5998 ast.SwitchCase switchCase = caseIterator.next(); |
| 5997 HBasicBlock block = graph.addNewBlock(); | 5999 HBasicBlock block = graph.addNewBlock(); |
| 5998 for (ConstantValue constant in getConstants(switchCase)) { | 6000 for (ConstantValue constant in getConstants(switchCase)) { |
| 5999 HConstant hConstant = graph.addConstant(constant, compiler); | 6001 HConstant hConstant = graph.addConstant(constant, closedWorld); |
| 6000 switchInstruction.inputs.add(hConstant); | 6002 switchInstruction.inputs.add(hConstant); |
| 6001 hConstant.usedBy.add(switchInstruction); | 6003 hConstant.usedBy.add(switchInstruction); |
| 6002 expressionEnd.addSuccessor(block); | 6004 expressionEnd.addSuccessor(block); |
| 6003 } | 6005 } |
| 6004 | 6006 |
| 6005 if (isDefaultCase(switchCase)) { | 6007 if (isDefaultCase(switchCase)) { |
| 6006 // An HSwitch has n inputs and n+1 successors, the last being the | 6008 // An HSwitch has n inputs and n+1 successors, the last being the |
| 6007 // default case. | 6009 // default case. |
| 6008 expressionEnd.addSuccessor(block); | 6010 expressionEnd.addSuccessor(block); |
| 6009 hasDefault = true; | 6011 hasDefault = true; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6244 if (type == null) { | 6246 if (type == null) { |
| 6245 reporter.internalError(catchBlock.type, 'On with no type.'); | 6247 reporter.internalError(catchBlock.type, 'On with no type.'); |
| 6246 } | 6248 } |
| 6247 HInstruction condition = | 6249 HInstruction condition = |
| 6248 buildIsNode(catchBlock.type, type, unwrappedException); | 6250 buildIsNode(catchBlock.type, type, unwrappedException); |
| 6249 push(condition); | 6251 push(condition); |
| 6250 } else { | 6252 } else { |
| 6251 ast.VariableDefinitions declaration = catchBlock.formals.nodes.head; | 6253 ast.VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 6252 HInstruction condition = null; | 6254 HInstruction condition = null; |
| 6253 if (declaration.type == null) { | 6255 if (declaration.type == null) { |
| 6254 condition = graph.addConstantBool(true, compiler); | 6256 condition = graph.addConstantBool(true, closedWorld); |
| 6255 stack.add(condition); | 6257 stack.add(condition); |
| 6256 } else { | 6258 } else { |
| 6257 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 6259 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 6258 // "if" condition above and this "else" branch should be deleted as | 6260 // "if" condition above and this "else" branch should be deleted as |
| 6259 // type of declared variable won't matter for the catch | 6261 // type of declared variable won't matter for the catch |
| 6260 // condition. | 6262 // condition. |
| 6261 DartType type = elements.getType(declaration.type); | 6263 DartType type = elements.getType(declaration.type); |
| 6262 if (type == null) { | 6264 if (type == null) { |
| 6263 reporter.internalError(catchBlock, 'Catch with unresolved type.'); | 6265 reporter.internalError(catchBlock, 'Catch with unresolved type.'); |
| 6264 } | 6266 } |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6751 this.oldReturnLocal, | 6753 this.oldReturnLocal, |
| 6752 this.oldReturnType, | 6754 this.oldReturnType, |
| 6753 this.oldResolvedAst, | 6755 this.oldResolvedAst, |
| 6754 this.oldStack, | 6756 this.oldStack, |
| 6755 this.oldLocalsHandler, | 6757 this.oldLocalsHandler, |
| 6756 this.inTryStatement, | 6758 this.inTryStatement, |
| 6757 this.allFunctionsCalledOnce, | 6759 this.allFunctionsCalledOnce, |
| 6758 this.oldElementInferenceResults) | 6760 this.oldElementInferenceResults) |
| 6759 : super(function); | 6761 : super(function); |
| 6760 } | 6762 } |
| OLD | NEW |