| 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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 null; | 605 null; |
| 606 | 606 |
| 607 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { | 607 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { |
| 608 ConstantValue constantValue = | 608 ConstantValue constantValue = |
| 609 backend.constants.getConstantValue(parameter.constant); | 609 backend.constants.getConstantValue(parameter.constant); |
| 610 assert(invariant(parameter, constantValue != null, | 610 assert(invariant(parameter, constantValue != null, |
| 611 message: 'No constant computed for $parameter')); | 611 message: 'No constant computed for $parameter')); |
| 612 return graph.addConstant(constantValue, compiler); | 612 return graph.addConstant(constantValue, compiler); |
| 613 } | 613 } |
| 614 | 614 |
| 615 Element get currentNonClosureClass { | 615 ClassElement get currentNonClosureClass { |
| 616 ClassElement cls = sourceElement.enclosingClass; | 616 ClassElement cls = sourceElement.enclosingClass; |
| 617 if (cls != null && cls.isClosure) { | 617 if (cls != null && cls.isClosure) { |
| 618 var closureClass = cls; | 618 var closureClass = cls; |
| 619 return closureClass.methodElement.enclosingClass; | 619 return closureClass.methodElement.enclosingClass; |
| 620 } else { | 620 } else { |
| 621 return cls; | 621 return cls; |
| 622 } | 622 } |
| 623 } | 623 } |
| 624 | 624 |
| 625 /// A stack of [DartType]s that have been seen during inlining of factory | 625 /// A stack of [DartType]s that have been seen during inlining of factory |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 /// minified mode. Each line in [text] is preceded with `//` and indented. | 712 /// minified mode. Each line in [text] is preceded with `//` and indented. |
| 713 /// Use sparingly. In order for the comment to be retained it is modeled as | 713 /// Use sparingly. In order for the comment to be retained it is modeled as |
| 714 /// having side effects which will inhibit code motion. | 714 /// having side effects which will inhibit code motion. |
| 715 // TODO(sra): Figure out how to keep comment anchored without effects. | 715 // TODO(sra): Figure out how to keep comment anchored without effects. |
| 716 void addComment(String text) { | 716 void addComment(String text) { |
| 717 add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)), | 717 add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)), |
| 718 backend.dynamicType, <HInstruction>[], | 718 backend.dynamicType, <HInstruction>[], |
| 719 isStatement: true)); | 719 isStatement: true)); |
| 720 } | 720 } |
| 721 | 721 |
| 722 HGraph buildCheckedSetter(VariableElement field) { | 722 HGraph buildCheckedSetter(FieldElement field) { |
| 723 ResolvedAst resolvedAst = field.resolvedAst; | 723 ResolvedAst resolvedAst = field.resolvedAst; |
| 724 openFunction(field, resolvedAst.node); | 724 openFunction(field, resolvedAst.node); |
| 725 HInstruction thisInstruction = localsHandler.readThis(); | 725 HInstruction thisInstruction = localsHandler.readThis(); |
| 726 // Use dynamic type because the type computed by the inferrer is | 726 // Use dynamic type because the type computed by the inferrer is |
| 727 // narrowed to the type annotation. | 727 // narrowed to the type annotation. |
| 728 HInstruction parameter = new HParameterValue(field, backend.dynamicType); | 728 HInstruction parameter = new HParameterValue(field, backend.dynamicType); |
| 729 // Add the parameter as the last instruction of the entry block. | 729 // Add the parameter as the last instruction of the entry block. |
| 730 // If the method is intercepted, we want the actual receiver | 730 // If the method is intercepted, we want the actual receiver |
| 731 // to be the first parameter. | 731 // to be the first parameter. |
| 732 graph.entry.addBefore(graph.entry.last, parameter); | 732 graph.entry.addBefore(graph.entry.last, parameter); |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 } | 1223 } |
| 1224 }); | 1224 }); |
| 1225 | 1225 |
| 1226 // Analyze the constructor and all referenced constructors and collect | 1226 // Analyze the constructor and all referenced constructors and collect |
| 1227 // initializers and constructor bodies. | 1227 // initializers and constructor bodies. |
| 1228 List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst]; | 1228 List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst]; |
| 1229 buildInitializers(functionElement, constructorResolvedAsts, fieldValues); | 1229 buildInitializers(functionElement, constructorResolvedAsts, fieldValues); |
| 1230 | 1230 |
| 1231 // Call the JavaScript constructor with the fields as argument. | 1231 // Call the JavaScript constructor with the fields as argument. |
| 1232 List<HInstruction> constructorArguments = <HInstruction>[]; | 1232 List<HInstruction> constructorArguments = <HInstruction>[]; |
| 1233 List<Element> fields = <Element>[]; | 1233 List<FieldLike> fields = <FieldLike>[]; |
| 1234 | 1234 |
| 1235 classElement.forEachInstanceField( | 1235 classElement.forEachInstanceField( |
| 1236 (ClassElement enclosingClass, VariableElement member) { | 1236 (ClassElement enclosingClass, FieldElement member) { |
| 1237 HInstruction value = fieldValues[member]; | 1237 HInstruction value = fieldValues[member]; |
| 1238 if (value == null) { | 1238 if (value == null) { |
| 1239 // Uninitialized native fields are pre-initialized by the native | 1239 // Uninitialized native fields are pre-initialized by the native |
| 1240 // implementation. | 1240 // implementation. |
| 1241 assert(invariant( | 1241 assert(invariant( |
| 1242 member, isNativeUpgradeFactory || compiler.compilationFailed)); | 1242 member, isNativeUpgradeFactory || compiler.compilationFailed)); |
| 1243 } else { | 1243 } else { |
| 1244 fields.add(member); | 1244 fields.add(member); |
| 1245 DartType type = localsHandler.substInContext(member.type); | 1245 DartType type = localsHandler.substInContext(member.type); |
| 1246 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); | 1246 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 } | 1581 } |
| 1582 | 1582 |
| 1583 void assertIsSubtype( | 1583 void assertIsSubtype( |
| 1584 ast.Node node, DartType subtype, DartType supertype, String message) { | 1584 ast.Node node, DartType subtype, DartType supertype, String message) { |
| 1585 HInstruction subtypeInstruction = | 1585 HInstruction subtypeInstruction = |
| 1586 analyzeTypeArgument(localsHandler.substInContext(subtype)); | 1586 analyzeTypeArgument(localsHandler.substInContext(subtype)); |
| 1587 HInstruction supertypeInstruction = | 1587 HInstruction supertypeInstruction = |
| 1588 analyzeTypeArgument(localsHandler.substInContext(supertype)); | 1588 analyzeTypeArgument(localsHandler.substInContext(supertype)); |
| 1589 HInstruction messageInstruction = | 1589 HInstruction messageInstruction = |
| 1590 graph.addConstantString(new ast.DartString.literal(message), compiler); | 1590 graph.addConstantString(new ast.DartString.literal(message), compiler); |
| 1591 Element element = helpers.assertIsSubtype; | 1591 MethodElement element = helpers.assertIsSubtype; |
| 1592 var inputs = <HInstruction>[ | 1592 var inputs = <HInstruction>[ |
| 1593 subtypeInstruction, | 1593 subtypeInstruction, |
| 1594 supertypeInstruction, | 1594 supertypeInstruction, |
| 1595 messageInstruction | 1595 messageInstruction |
| 1596 ]; | 1596 ]; |
| 1597 HInstruction assertIsSubtype = | 1597 HInstruction assertIsSubtype = |
| 1598 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); | 1598 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); |
| 1599 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 1599 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
| 1600 add(assertIsSubtype); | 1600 add(assertIsSubtype); |
| 1601 } | 1601 } |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2216 SourceInformation sourceInformation = | 2216 SourceInformation sourceInformation = |
| 2217 sourceInformationBuilder.buildGet(node); | 2217 sourceInformationBuilder.buildGet(node); |
| 2218 if (constant != null) { | 2218 if (constant != null) { |
| 2219 if (!field.isAssignable) { | 2219 if (!field.isAssignable) { |
| 2220 // A static final or const. Get its constant value and inline it if | 2220 // A static final or const. Get its constant value and inline it if |
| 2221 // the value can be compiled eagerly. | 2221 // the value can be compiled eagerly. |
| 2222 generateStaticConstGet(node, field, constant, sourceInformation); | 2222 generateStaticConstGet(node, field, constant, sourceInformation); |
| 2223 } else { | 2223 } else { |
| 2224 // TODO(5346): Try to avoid the need for calling [declaration] before | 2224 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2225 // creating an [HStatic]. | 2225 // creating an [HStatic]. |
| 2226 HInstruction instruction = new HStatic(field.declaration, | 2226 HInstruction instruction = new HStatic( |
| 2227 TypeMaskFactory.inferredTypeForElement(field, compiler)) | 2227 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) |
| 2228 ..sourceInformation = sourceInformation; | 2228 ..sourceInformation = sourceInformation; |
| 2229 push(instruction); | 2229 push(instruction); |
| 2230 } | 2230 } |
| 2231 } else { | 2231 } else { |
| 2232 HInstruction instruction = new HLazyStatic( | 2232 HInstruction instruction = new HLazyStatic( |
| 2233 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) | 2233 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) |
| 2234 ..sourceInformation = sourceInformation; | 2234 ..sourceInformation = sourceInformation; |
| 2235 push(instruction); | 2235 push(instruction); |
| 2236 } | 2236 } |
| 2237 } | 2237 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2248 } | 2248 } |
| 2249 } | 2249 } |
| 2250 | 2250 |
| 2251 /// Generate a dynamic getter invocation. | 2251 /// Generate a dynamic getter invocation. |
| 2252 void generateDynamicGet(ast.Send node) { | 2252 void generateDynamicGet(ast.Send node) { |
| 2253 HInstruction receiver = generateInstanceSendReceiver(node); | 2253 HInstruction receiver = generateInstanceSendReceiver(node); |
| 2254 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), | 2254 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), |
| 2255 inferenceResults.typeOfSend(node, elements), receiver); | 2255 inferenceResults.typeOfSend(node, elements), receiver); |
| 2256 } | 2256 } |
| 2257 | 2257 |
| 2258 /// Generate a closurization of the static or top level [function]. | 2258 /// Generate a closurization of the static or top level [method]. |
| 2259 void generateStaticFunctionGet(ast.Send node, MethodElement function) { | 2259 void generateStaticFunctionGet(ast.Send node, MethodElement method) { |
| 2260 assert(method.isDeclaration); |
| 2260 // TODO(5346): Try to avoid the need for calling [declaration] before | 2261 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2261 // creating an [HStatic]. | 2262 // creating an [HStatic]. |
| 2262 SourceInformation sourceInformation = | 2263 SourceInformation sourceInformation = |
| 2263 sourceInformationBuilder.buildGet(node); | 2264 sourceInformationBuilder.buildGet(node); |
| 2264 push(new HStatic(function.declaration, backend.nonNullType) | 2265 push(new HStatic(method, backend.nonNullType) |
| 2265 ..sourceInformation = sourceInformation); | 2266 ..sourceInformation = sourceInformation); |
| 2266 } | 2267 } |
| 2267 | 2268 |
| 2268 /// Read a local variable, function or parameter. | 2269 /// Read a local variable, function or parameter. |
| 2269 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) { | 2270 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) { |
| 2270 stack.add( | 2271 stack.add( |
| 2271 localsHandler.readLocal(local, sourceInformation: sourceInformation)); | 2272 localsHandler.readLocal(local, sourceInformation: sourceInformation)); |
| 2272 } | 2273 } |
| 2273 | 2274 |
| 2274 void handleLocalGet(ast.Send node, LocalElement local) { | 2275 void handleLocalGet(ast.Send node, LocalElement local) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2397 location = send; | 2398 location = send; |
| 2398 } | 2399 } |
| 2399 assert(invariant( | 2400 assert(invariant( |
| 2400 location, send == null || !Elements.isInstanceSend(send, elements), | 2401 location, send == null || !Elements.isInstanceSend(send, elements), |
| 2401 message: "Unexpected non instance setter: $element.")); | 2402 message: "Unexpected non instance setter: $element.")); |
| 2402 if (Elements.isStaticOrTopLevelField(element)) { | 2403 if (Elements.isStaticOrTopLevelField(element)) { |
| 2403 if (element.isSetter) { | 2404 if (element.isSetter) { |
| 2404 pushInvokeStatic(location, element, <HInstruction>[value]); | 2405 pushInvokeStatic(location, element, <HInstruction>[value]); |
| 2405 pop(); | 2406 pop(); |
| 2406 } else { | 2407 } else { |
| 2407 VariableElement field = element; | 2408 FieldElement field = element; |
| 2408 value = potentiallyCheckOrTrustType(value, field.type); | 2409 value = potentiallyCheckOrTrustType(value, field.type); |
| 2409 addWithPosition(new HStaticStore(element, value), location); | 2410 addWithPosition(new HStaticStore(field, value), location); |
| 2410 } | 2411 } |
| 2411 stack.add(value); | 2412 stack.add(value); |
| 2412 } else if (Elements.isError(element)) { | 2413 } else if (Elements.isError(element)) { |
| 2413 generateNoSuchSetter(location, element, send == null ? null : value); | 2414 generateNoSuchSetter(location, element, send == null ? null : value); |
| 2414 } else if (Elements.isMalformed(element)) { | 2415 } else if (Elements.isMalformed(element)) { |
| 2415 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 2416 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 2416 stack.add(graph.addConstantNull(compiler)); | 2417 stack.add(graph.addConstantNull(compiler)); |
| 2417 } else { | 2418 } else { |
| 2418 stack.add(value); | 2419 stack.add(value); |
| 2419 LocalElement local = element; | 2420 LocalElement local = element; |
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3094 handleJsStringConcat(node); | 3095 handleJsStringConcat(node); |
| 3095 } else { | 3096 } else { |
| 3096 reporter.internalError(node, "Unknown foreign: ${element}"); | 3097 reporter.internalError(node, "Unknown foreign: ${element}"); |
| 3097 } | 3098 } |
| 3098 } | 3099 } |
| 3099 | 3100 |
| 3100 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, | 3101 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, |
| 3101 SourceInformation sourceInformation) { | 3102 SourceInformation sourceInformation) { |
| 3102 // Until now we only handle these as getters. | 3103 // Until now we only handle these as getters. |
| 3103 invariant(node, deferredLoader.isDeferredLoaderGetter); | 3104 invariant(node, deferredLoader.isDeferredLoaderGetter); |
| 3104 Element loadFunction = helpers.loadLibraryWrapper; | 3105 FunctionLike loadFunction = helpers.loadLibraryWrapper; |
| 3105 PrefixElement prefixElement = deferredLoader.enclosingElement; | 3106 PrefixElement prefixElement = deferredLoader.enclosingElement; |
| 3106 String loadId = | 3107 String loadId = |
| 3107 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); | 3108 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); |
| 3108 var inputs = [ | 3109 var inputs = [ |
| 3109 graph.addConstantString(new ast.DartString.literal(loadId), compiler) | 3110 graph.addConstantString(new ast.DartString.literal(loadId), compiler) |
| 3110 ]; | 3111 ]; |
| 3111 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, | 3112 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, |
| 3112 targetCanThrow: false)..sourceInformation = sourceInformation); | 3113 targetCanThrow: false)..sourceInformation = sourceInformation); |
| 3113 } | 3114 } |
| 3114 | 3115 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3163 argumentsInstruction, | 3164 argumentsInstruction, |
| 3164 argumentNamesInstruction | 3165 argumentNamesInstruction |
| 3165 ], | 3166 ], |
| 3166 typeMask: backend.dynamicType); | 3167 typeMask: backend.dynamicType); |
| 3167 | 3168 |
| 3168 var inputs = <HInstruction>[pop()]; | 3169 var inputs = <HInstruction>[pop()]; |
| 3169 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); | 3170 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); |
| 3170 } | 3171 } |
| 3171 | 3172 |
| 3172 /// Generate a call to a super method or constructor. | 3173 /// Generate a call to a super method or constructor. |
| 3173 void generateSuperInvoke(ast.Send node, FunctionElement function, | 3174 void generateSuperInvoke(ast.Send node, MethodElement method, |
| 3174 SourceInformation sourceInformation) { | 3175 SourceInformation sourceInformation) { |
| 3175 // TODO(5347): Try to avoid the need for calling [implementation] before | 3176 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3176 // calling [makeStaticArgumentList]. | 3177 // calling [makeStaticArgumentList]. |
| 3177 Selector selector = elements.getSelector(node); | 3178 Selector selector = elements.getSelector(node); |
| 3178 assert(invariant(node, selector.applies(function.implementation), | 3179 assert(invariant(node, selector.applies(method.implementation), |
| 3179 message: "$selector does not apply to ${function.implementation}")); | 3180 message: "$selector does not apply to ${method.implementation}")); |
| 3180 List<HInstruction> inputs = makeStaticArgumentList( | 3181 List<HInstruction> inputs = makeStaticArgumentList( |
| 3181 selector.callStructure, node.arguments, function.implementation); | 3182 selector.callStructure, node.arguments, method.implementation); |
| 3182 push(buildInvokeSuper(selector, function, inputs, sourceInformation)); | 3183 push(buildInvokeSuper(selector, method, inputs, sourceInformation)); |
| 3183 } | 3184 } |
| 3184 | 3185 |
| 3185 /// Access the value from the super [element]. | 3186 /// Access the value from the super [element]. |
| 3186 void handleSuperGet(ast.Send node, Element element) { | 3187 void handleSuperGet(ast.Send node, Element element) { |
| 3187 Selector selector = elements.getSelector(node); | 3188 Selector selector = elements.getSelector(node); |
| 3188 SourceInformation sourceInformation = | 3189 SourceInformation sourceInformation = |
| 3189 sourceInformationBuilder.buildGet(node); | 3190 sourceInformationBuilder.buildGet(node); |
| 3190 push(buildInvokeSuper( | 3191 push(buildInvokeSuper( |
| 3191 selector, element, const <HInstruction>[], sourceInformation)); | 3192 selector, element, const <HInstruction>[], sourceInformation)); |
| 3192 } | 3193 } |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3677 throwBehavior: native.NativeThrowBehavior.MAY)); | 3678 throwBehavior: native.NativeThrowBehavior.MAY)); |
| 3678 } | 3679 } |
| 3679 } else if (isGrowableListConstructorCall) { | 3680 } else if (isGrowableListConstructorCall) { |
| 3680 push(buildLiteralList(<HInstruction>[])); | 3681 push(buildLiteralList(<HInstruction>[])); |
| 3681 stack.last.instructionType = elementType; | 3682 stack.last.instructionType = elementType; |
| 3682 } else { | 3683 } else { |
| 3683 SourceInformation sourceInformation = | 3684 SourceInformation sourceInformation = |
| 3684 sourceInformationBuilder.buildNew(send); | 3685 sourceInformationBuilder.buildNew(send); |
| 3685 potentiallyAddTypeArguments(inputs, cls, expectedType); | 3686 potentiallyAddTypeArguments(inputs, cls, expectedType); |
| 3686 addInlinedInstantiation(expectedType); | 3687 addInlinedInstantiation(expectedType); |
| 3687 pushInvokeStatic(node, constructor, inputs, | 3688 pushInvokeStatic(node, constructor.declaration, inputs, |
| 3688 typeMask: elementType, | 3689 typeMask: elementType, |
| 3689 instanceType: expectedType, | 3690 instanceType: expectedType, |
| 3690 sourceInformation: sourceInformation); | 3691 sourceInformation: sourceInformation); |
| 3691 removeInlinedInstantiation(expectedType); | 3692 removeInlinedInstantiation(expectedType); |
| 3692 } | 3693 } |
| 3693 HInstruction newInstance = stack.last; | 3694 HInstruction newInstance = stack.last; |
| 3694 if (isFixedList) { | 3695 if (isFixedList) { |
| 3695 // Overwrite the element type, in case the allocation site has | 3696 // Overwrite the element type, in case the allocation site has |
| 3696 // been inlined. | 3697 // been inlined. |
| 3697 newInstance.instructionType = elementType; | 3698 newInstance.instructionType = elementType; |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4327 code = element.isConstructor ? "new #($args)" : "#($args)"; | 4328 code = element.isConstructor ? "new #($args)" : "#($args)"; |
| 4328 } | 4329 } |
| 4329 js.Template codeTemplate = js.js.parseForeignJS(code); | 4330 js.Template codeTemplate = js.js.parseForeignJS(code); |
| 4330 nativeBehavior.codeTemplate = codeTemplate; | 4331 nativeBehavior.codeTemplate = codeTemplate; |
| 4331 | 4332 |
| 4332 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, | 4333 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, |
| 4333 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; | 4334 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; |
| 4334 } | 4335 } |
| 4335 | 4336 |
| 4336 void pushInvokeStatic( | 4337 void pushInvokeStatic( |
| 4337 ast.Node location, Element element, List<HInstruction> arguments, | 4338 ast.Node location, MethodElement element, List<HInstruction> arguments, |
| 4338 {TypeMask typeMask, | 4339 {TypeMask typeMask, |
| 4339 InterfaceType instanceType, | 4340 InterfaceType instanceType, |
| 4340 SourceInformation sourceInformation}) { | 4341 SourceInformation sourceInformation}) { |
| 4342 assert(element.isDeclaration); |
| 4341 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4343 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
| 4342 if (tryInlineMethod(element, null, null, arguments, location, | 4344 if (tryInlineMethod(element, null, null, arguments, location, |
| 4343 instanceType: instanceType)) { | 4345 instanceType: instanceType)) { |
| 4344 return; | 4346 return; |
| 4345 } | 4347 } |
| 4346 | 4348 |
| 4347 if (typeMask == null) { | 4349 if (typeMask == null) { |
| 4348 typeMask = | 4350 typeMask = |
| 4349 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4351 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); |
| 4350 } | 4352 } |
| 4351 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element); | 4353 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element); |
| 4352 // TODO(5346): Try to avoid the need for calling [declaration] before | 4354 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 4353 var instruction; | 4355 var instruction; |
| 4354 if (backend.isJsInterop(element)) { | 4356 if (backend.isJsInterop(element)) { |
| 4355 instruction = | 4357 instruction = |
| 4356 invokeJsInteropFunction(element, arguments, sourceInformation); | 4358 invokeJsInteropFunction(element, arguments, sourceInformation); |
| 4357 } else { | 4359 } else { |
| 4358 // creating an [HInvokeStatic]. | 4360 // creating an [HInvokeStatic]. |
| 4359 instruction = new HInvokeStatic(element.declaration, arguments, typeMask, | 4361 instruction = new HInvokeStatic(element, arguments, typeMask, |
| 4360 targetCanThrow: targetCanThrow) | 4362 targetCanThrow: targetCanThrow) |
| 4361 ..sourceInformation = sourceInformation; | 4363 ..sourceInformation = sourceInformation; |
| 4362 if (currentInlinedInstantiations.isNotEmpty) { | 4364 if (currentInlinedInstantiations.isNotEmpty) { |
| 4363 instruction.instantiatedTypes = | 4365 instruction.instantiatedTypes = |
| 4364 new List<DartType>.from(currentInlinedInstantiations); | 4366 new List<DartType>.from(currentInlinedInstantiations); |
| 4365 } | 4367 } |
| 4366 instruction.sideEffects = | 4368 instruction.sideEffects = |
| 4367 compiler.closedWorld.getSideEffectsOfElement(element); | 4369 compiler.closedWorld.getSideEffectsOfElement(element); |
| 4368 } | 4370 } |
| 4369 if (location == null) { | 4371 if (location == null) { |
| 4370 push(instruction); | 4372 push(instruction); |
| 4371 } else { | 4373 } else { |
| 4372 pushWithPosition(instruction, location); | 4374 pushWithPosition(instruction, location); |
| 4373 } | 4375 } |
| 4374 } | 4376 } |
| 4375 | 4377 |
| 4376 HInstruction buildInvokeSuper( | 4378 HInstruction buildInvokeSuper( |
| 4377 Selector selector, Element element, List<HInstruction> arguments, | 4379 Selector selector, MemberElement element, List<HInstruction> arguments, |
| 4378 [SourceInformation sourceInformation]) { | 4380 [SourceInformation sourceInformation]) { |
| 4379 HInstruction receiver = localsHandler.readThis(); | 4381 HInstruction receiver = localsHandler.readThis(); |
| 4380 // TODO(5346): Try to avoid the need for calling [declaration] before | 4382 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 4381 // creating an [HStatic]. | 4383 // creating an [HStatic]. |
| 4382 List<HInstruction> inputs = <HInstruction>[]; | 4384 List<HInstruction> inputs = <HInstruction>[]; |
| 4383 if (backend.isInterceptedSelector(selector) && | 4385 if (backend.isInterceptedSelector(selector) && |
| 4384 // Fields don't need an interceptor; consider generating HFieldGet/Set | 4386 // Fields don't need an interceptor; consider generating HFieldGet/Set |
| 4385 // instead. | 4387 // instead. |
| 4386 element.kind != ElementKind.FIELD) { | 4388 element.kind != ElementKind.FIELD) { |
| 4387 inputs.add(invokeInterceptor(receiver)); | 4389 inputs.add(invokeInterceptor(receiver)); |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5323 ClassElement targetClass = targetConstructor.enclosingClass; | 5325 ClassElement targetClass = targetConstructor.enclosingClass; |
| 5324 if (backend.classNeedsRti(targetClass)) { | 5326 if (backend.classNeedsRti(targetClass)) { |
| 5325 ClassElement cls = redirectingConstructor.enclosingClass; | 5327 ClassElement cls = redirectingConstructor.enclosingClass; |
| 5326 InterfaceType targetType = | 5328 InterfaceType targetType = |
| 5327 redirectingConstructor.computeEffectiveTargetType(cls.thisType); | 5329 redirectingConstructor.computeEffectiveTargetType(cls.thisType); |
| 5328 targetType = localsHandler.substInContext(targetType); | 5330 targetType = localsHandler.substInContext(targetType); |
| 5329 targetType.typeArguments.forEach((DartType argument) { | 5331 targetType.typeArguments.forEach((DartType argument) { |
| 5330 inputs.add(analyzeTypeArgument(argument)); | 5332 inputs.add(analyzeTypeArgument(argument)); |
| 5331 }); | 5333 }); |
| 5332 } | 5334 } |
| 5333 pushInvokeStatic(node, targetConstructor, inputs); | 5335 pushInvokeStatic(node, targetConstructor.declaration, inputs); |
| 5334 HInstruction value = pop(); | 5336 HInstruction value = pop(); |
| 5335 emitReturn(value, node); | 5337 emitReturn(value, node); |
| 5336 } | 5338 } |
| 5337 | 5339 |
| 5338 /// Returns true if the [type] is a valid return type for an asynchronous | 5340 /// Returns true if the [type] is a valid return type for an asynchronous |
| 5339 /// function. | 5341 /// function. |
| 5340 /// | 5342 /// |
| 5341 /// Asynchronous functions return a `Future`, and a valid return is thus | 5343 /// Asynchronous functions return a `Future`, and a valid return is thus |
| 5342 /// either dynamic, Object, or Future. | 5344 /// either dynamic, Object, or Future. |
| 5343 /// | 5345 /// |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5712 Element loopVariable = elements.getForInVariable(node); | 5714 Element loopVariable = elements.getForInVariable(node); |
| 5713 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable); | 5715 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable); |
| 5714 TypeMask boolType = backend.boolType; | 5716 TypeMask boolType = backend.boolType; |
| 5715 | 5717 |
| 5716 // These variables are shared by initializer, condition, body and update. | 5718 // These variables are shared by initializer, condition, body and update. |
| 5717 HInstruction array; // Set in buildInitializer. | 5719 HInstruction array; // Set in buildInitializer. |
| 5718 bool isFixed; // Set in buildInitializer. | 5720 bool isFixed; // Set in buildInitializer. |
| 5719 HInstruction originalLength = null; // Set for growable lists. | 5721 HInstruction originalLength = null; // Set for growable lists. |
| 5720 | 5722 |
| 5721 HInstruction buildGetLength() { | 5723 HInstruction buildGetLength() { |
| 5722 Element lengthElement = helpers.jsIndexableLength; | 5724 MemberElement lengthElement = helpers.jsIndexableLength; |
| 5723 HFieldGet result = new HFieldGet( | 5725 HFieldGet result = new HFieldGet( |
| 5724 lengthElement, array, backend.positiveIntType, | 5726 lengthElement, array, backend.positiveIntType, |
| 5725 isAssignable: !isFixed); | 5727 isAssignable: !isFixed); |
| 5726 add(result); | 5728 add(result); |
| 5727 return result; | 5729 return result; |
| 5728 } | 5730 } |
| 5729 | 5731 |
| 5730 void buildConcurrentModificationErrorCheck() { | 5732 void buildConcurrentModificationErrorCheck() { |
| 5731 if (originalLength == null) return; | 5733 if (originalLength == null) return; |
| 5732 // The static call checkConcurrentModificationError() is expanded in | 5734 // The static call checkConcurrentModificationError() is expanded in |
| (...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7046 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7048 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 7047 unaliased.accept(this, builder); | 7049 unaliased.accept(this, builder); |
| 7048 } | 7050 } |
| 7049 | 7051 |
| 7050 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7052 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 7051 JavaScriptBackend backend = builder.compiler.backend; | 7053 JavaScriptBackend backend = builder.compiler.backend; |
| 7052 ClassElement cls = backend.helpers.DynamicRuntimeType; | 7054 ClassElement cls = backend.helpers.DynamicRuntimeType; |
| 7053 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); | 7055 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); |
| 7054 } | 7056 } |
| 7055 } | 7057 } |
| OLD | NEW |