| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 | 8 |
| 9 import '../closure.dart'; | 9 import '../closure.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| 11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 12 import '../common/names.dart' show Identifiers, Selectors; | 12 import '../common/names.dart' show Identifiers, Selectors; |
| 13 import '../common/tasks.dart' show CompilerTask; | 13 import '../common/tasks.dart' show CompilerTask; |
| 14 import '../compiler.dart' show Compiler; | 14 import '../compiler.dart' show Compiler; |
| 15 import '../constants/constant_system.dart'; | 15 import '../constants/constant_system.dart'; |
| 16 import '../constants/expressions.dart'; | 16 import '../constants/expressions.dart'; |
| 17 import '../constants/values.dart'; | 17 import '../constants/values.dart'; |
| 18 import '../core_types.dart' show CoreClasses; | 18 import '../core_types.dart' show CoreClasses; |
| 19 import '../dart_types.dart'; | 19 import '../dart_types.dart'; |
| 20 import '../diagnostics/messages.dart' show Message, MessageTemplate; | 20 import '../diagnostics/messages.dart' show Message, MessageTemplate; |
| 21 import '../dump_info.dart' show InfoReporter; | 21 import '../dump_info.dart' show InfoReporter; |
| 22 import '../elements/elements.dart'; | 22 import '../elements/elements.dart'; |
| 23 import '../elements/entities.dart'; |
| 23 import '../elements/modelx.dart' show ConstructorBodyElementX; | 24 import '../elements/modelx.dart' show ConstructorBodyElementX; |
| 24 import '../io/source_information.dart'; | 25 import '../io/source_information.dart'; |
| 25 import '../js/js.dart' as js; | 26 import '../js/js.dart' as js; |
| 26 import '../js_backend/backend_helpers.dart' show BackendHelpers; | 27 import '../js_backend/backend_helpers.dart' show BackendHelpers; |
| 27 import '../js_backend/js_backend.dart'; | 28 import '../js_backend/js_backend.dart'; |
| 28 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; | 29 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; |
| 29 import '../native/native.dart' as native; | 30 import '../native/native.dart' as native; |
| 30 import '../resolution/operators.dart'; | 31 import '../resolution/operators.dart'; |
| 31 import '../resolution/semantic_visitor.dart'; | 32 import '../resolution/semantic_visitor.dart'; |
| 32 import '../resolution/tree_elements.dart' show TreeElements; | 33 import '../resolution/tree_elements.dart' show TreeElements; |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 null; | 606 null; |
| 606 | 607 |
| 607 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { | 608 HInstruction handleConstantForOptionalParameter(ParameterElement parameter) { |
| 608 ConstantValue constantValue = | 609 ConstantValue constantValue = |
| 609 backend.constants.getConstantValue(parameter.constant); | 610 backend.constants.getConstantValue(parameter.constant); |
| 610 assert(invariant(parameter, constantValue != null, | 611 assert(invariant(parameter, constantValue != null, |
| 611 message: 'No constant computed for $parameter')); | 612 message: 'No constant computed for $parameter')); |
| 612 return graph.addConstant(constantValue, compiler); | 613 return graph.addConstant(constantValue, compiler); |
| 613 } | 614 } |
| 614 | 615 |
| 615 Element get currentNonClosureClass { | 616 ClassElement get currentNonClosureClass { |
| 616 ClassElement cls = sourceElement.enclosingClass; | 617 ClassElement cls = sourceElement.enclosingClass; |
| 617 if (cls != null && cls.isClosure) { | 618 if (cls != null && cls.isClosure) { |
| 618 var closureClass = cls; | 619 var closureClass = cls; |
| 619 return closureClass.methodElement.enclosingClass; | 620 return closureClass.methodElement.enclosingClass; |
| 620 } else { | 621 } else { |
| 621 return cls; | 622 return cls; |
| 622 } | 623 } |
| 623 } | 624 } |
| 624 | 625 |
| 625 /// A stack of [DartType]s that have been seen during inlining of factory | 626 /// 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. | 713 /// 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 | 714 /// Use sparingly. In order for the comment to be retained it is modeled as |
| 714 /// having side effects which will inhibit code motion. | 715 /// having side effects which will inhibit code motion. |
| 715 // TODO(sra): Figure out how to keep comment anchored without effects. | 716 // TODO(sra): Figure out how to keep comment anchored without effects. |
| 716 void addComment(String text) { | 717 void addComment(String text) { |
| 717 add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)), | 718 add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)), |
| 718 backend.dynamicType, <HInstruction>[], | 719 backend.dynamicType, <HInstruction>[], |
| 719 isStatement: true)); | 720 isStatement: true)); |
| 720 } | 721 } |
| 721 | 722 |
| 722 HGraph buildCheckedSetter(VariableElement field) { | 723 HGraph buildCheckedSetter(FieldElement field) { |
| 723 ResolvedAst resolvedAst = field.resolvedAst; | 724 ResolvedAst resolvedAst = field.resolvedAst; |
| 724 openFunction(field, resolvedAst.node); | 725 openFunction(field, resolvedAst.node); |
| 725 HInstruction thisInstruction = localsHandler.readThis(); | 726 HInstruction thisInstruction = localsHandler.readThis(); |
| 726 // Use dynamic type because the type computed by the inferrer is | 727 // Use dynamic type because the type computed by the inferrer is |
| 727 // narrowed to the type annotation. | 728 // narrowed to the type annotation. |
| 728 HInstruction parameter = new HParameterValue(field, backend.dynamicType); | 729 HInstruction parameter = new HParameterValue(field, backend.dynamicType); |
| 729 // Add the parameter as the last instruction of the entry block. | 730 // Add the parameter as the last instruction of the entry block. |
| 730 // If the method is intercepted, we want the actual receiver | 731 // If the method is intercepted, we want the actual receiver |
| 731 // to be the first parameter. | 732 // to be the first parameter. |
| 732 graph.entry.addBefore(graph.entry.last, parameter); | 733 graph.entry.addBefore(graph.entry.last, parameter); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 752 // variable. So find the specific initialized variable we are referring to. | 753 // variable. So find the specific initialized variable we are referring to. |
| 753 ast.Node sourceInfoNode = initializer; | 754 ast.Node sourceInfoNode = initializer; |
| 754 for (var definition in node.definitions) { | 755 for (var definition in node.definitions) { |
| 755 if (definition is ast.SendSet && | 756 if (definition is ast.SendSet && |
| 756 definition.selector.asIdentifier().source == variable.name) { | 757 definition.selector.asIdentifier().source == variable.name) { |
| 757 sourceInfoNode = definition.assignmentOperator; | 758 sourceInfoNode = definition.assignmentOperator; |
| 758 break; | 759 break; |
| 759 } | 760 } |
| 760 } | 761 } |
| 761 | 762 |
| 762 closeAndGotoExit(new HReturn(value, sourceInformationBuilder.buildReturn( | 763 closeAndGotoExit(new HReturn( |
| 763 sourceInfoNode))); | 764 value, sourceInformationBuilder.buildReturn(sourceInfoNode))); |
| 764 return closeFunction(); | 765 return closeFunction(); |
| 765 } | 766 } |
| 766 | 767 |
| 767 /** | 768 /** |
| 768 * Returns the constructor body associated with the given constructor or | 769 * Returns the constructor body associated with the given constructor or |
| 769 * creates a new constructor body, if none can be found. | 770 * creates a new constructor body, if none can be found. |
| 770 * | 771 * |
| 771 * Returns [:null:] if the constructor does not have a body. | 772 * Returns [:null:] if the constructor does not have a body. |
| 772 */ | 773 */ |
| 773 ConstructorBodyElement getConstructorBody( | 774 ConstructorBodyElement getConstructorBody( |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1234 } | 1235 } |
| 1235 }); | 1236 }); |
| 1236 | 1237 |
| 1237 // Analyze the constructor and all referenced constructors and collect | 1238 // Analyze the constructor and all referenced constructors and collect |
| 1238 // initializers and constructor bodies. | 1239 // initializers and constructor bodies. |
| 1239 List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst]; | 1240 List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst]; |
| 1240 buildInitializers(functionElement, constructorResolvedAsts, fieldValues); | 1241 buildInitializers(functionElement, constructorResolvedAsts, fieldValues); |
| 1241 | 1242 |
| 1242 // Call the JavaScript constructor with the fields as argument. | 1243 // Call the JavaScript constructor with the fields as argument. |
| 1243 List<HInstruction> constructorArguments = <HInstruction>[]; | 1244 List<HInstruction> constructorArguments = <HInstruction>[]; |
| 1244 List<Element> fields = <Element>[]; | 1245 List<FieldEntity> fields = <FieldEntity>[]; |
| 1245 | 1246 |
| 1246 classElement.forEachInstanceField( | 1247 classElement.forEachInstanceField( |
| 1247 (ClassElement enclosingClass, VariableElement member) { | 1248 (ClassElement enclosingClass, FieldElement member) { |
| 1248 HInstruction value = fieldValues[member]; | 1249 HInstruction value = fieldValues[member]; |
| 1249 if (value == null) { | 1250 if (value == null) { |
| 1250 // Uninitialized native fields are pre-initialized by the native | 1251 // Uninitialized native fields are pre-initialized by the native |
| 1251 // implementation. | 1252 // implementation. |
| 1252 assert(invariant( | 1253 assert(invariant( |
| 1253 member, isNativeUpgradeFactory || compiler.compilationFailed)); | 1254 member, isNativeUpgradeFactory || compiler.compilationFailed)); |
| 1254 } else { | 1255 } else { |
| 1255 fields.add(member); | 1256 fields.add(member); |
| 1256 DartType type = localsHandler.substInContext(member.type); | 1257 DartType type = localsHandler.substInContext(member.type); |
| 1257 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); | 1258 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1592 } | 1593 } |
| 1593 | 1594 |
| 1594 void assertIsSubtype( | 1595 void assertIsSubtype( |
| 1595 ast.Node node, DartType subtype, DartType supertype, String message) { | 1596 ast.Node node, DartType subtype, DartType supertype, String message) { |
| 1596 HInstruction subtypeInstruction = | 1597 HInstruction subtypeInstruction = |
| 1597 analyzeTypeArgument(localsHandler.substInContext(subtype)); | 1598 analyzeTypeArgument(localsHandler.substInContext(subtype)); |
| 1598 HInstruction supertypeInstruction = | 1599 HInstruction supertypeInstruction = |
| 1599 analyzeTypeArgument(localsHandler.substInContext(supertype)); | 1600 analyzeTypeArgument(localsHandler.substInContext(supertype)); |
| 1600 HInstruction messageInstruction = | 1601 HInstruction messageInstruction = |
| 1601 graph.addConstantString(new ast.DartString.literal(message), compiler); | 1602 graph.addConstantString(new ast.DartString.literal(message), compiler); |
| 1602 Element element = helpers.assertIsSubtype; | 1603 MethodElement element = helpers.assertIsSubtype; |
| 1603 var inputs = <HInstruction>[ | 1604 var inputs = <HInstruction>[ |
| 1604 subtypeInstruction, | 1605 subtypeInstruction, |
| 1605 supertypeInstruction, | 1606 supertypeInstruction, |
| 1606 messageInstruction | 1607 messageInstruction |
| 1607 ]; | 1608 ]; |
| 1608 HInstruction assertIsSubtype = | 1609 HInstruction assertIsSubtype = |
| 1609 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); | 1610 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); |
| 1610 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 1611 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
| 1611 add(assertIsSubtype); | 1612 add(assertIsSubtype); |
| 1612 } | 1613 } |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 SourceInformation sourceInformation = | 2228 SourceInformation sourceInformation = |
| 2228 sourceInformationBuilder.buildGet(node); | 2229 sourceInformationBuilder.buildGet(node); |
| 2229 if (constant != null) { | 2230 if (constant != null) { |
| 2230 if (!field.isAssignable) { | 2231 if (!field.isAssignable) { |
| 2231 // A static final or const. Get its constant value and inline it if | 2232 // A static final or const. Get its constant value and inline it if |
| 2232 // the value can be compiled eagerly. | 2233 // the value can be compiled eagerly. |
| 2233 generateStaticConstGet(node, field, constant, sourceInformation); | 2234 generateStaticConstGet(node, field, constant, sourceInformation); |
| 2234 } else { | 2235 } else { |
| 2235 // TODO(5346): Try to avoid the need for calling [declaration] before | 2236 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2236 // creating an [HStatic]. | 2237 // creating an [HStatic]. |
| 2237 HInstruction instruction = new HStatic(field.declaration, | 2238 HInstruction instruction = new HStatic( |
| 2238 TypeMaskFactory.inferredTypeForElement(field, compiler)) | 2239 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) |
| 2239 ..sourceInformation = sourceInformation; | 2240 ..sourceInformation = sourceInformation; |
| 2240 push(instruction); | 2241 push(instruction); |
| 2241 } | 2242 } |
| 2242 } else { | 2243 } else { |
| 2243 HInstruction instruction = new HLazyStatic( | 2244 HInstruction instruction = new HLazyStatic( |
| 2244 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) | 2245 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) |
| 2245 ..sourceInformation = sourceInformation; | 2246 ..sourceInformation = sourceInformation; |
| 2246 push(instruction); | 2247 push(instruction); |
| 2247 } | 2248 } |
| 2248 } | 2249 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2259 } | 2260 } |
| 2260 } | 2261 } |
| 2261 | 2262 |
| 2262 /// Generate a dynamic getter invocation. | 2263 /// Generate a dynamic getter invocation. |
| 2263 void generateDynamicGet(ast.Send node) { | 2264 void generateDynamicGet(ast.Send node) { |
| 2264 HInstruction receiver = generateInstanceSendReceiver(node); | 2265 HInstruction receiver = generateInstanceSendReceiver(node); |
| 2265 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), | 2266 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), |
| 2266 inferenceResults.typeOfSend(node, elements), receiver); | 2267 inferenceResults.typeOfSend(node, elements), receiver); |
| 2267 } | 2268 } |
| 2268 | 2269 |
| 2269 /// Generate a closurization of the static or top level [function]. | 2270 /// Generate a closurization of the static or top level [method]. |
| 2270 void generateStaticFunctionGet(ast.Send node, MethodElement function) { | 2271 void generateStaticFunctionGet(ast.Send node, MethodElement method) { |
| 2272 assert(method.isDeclaration); |
| 2271 // TODO(5346): Try to avoid the need for calling [declaration] before | 2273 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2272 // creating an [HStatic]. | 2274 // creating an [HStatic]. |
| 2273 SourceInformation sourceInformation = | 2275 SourceInformation sourceInformation = |
| 2274 sourceInformationBuilder.buildGet(node); | 2276 sourceInformationBuilder.buildGet(node); |
| 2275 push(new HStatic(function.declaration, backend.nonNullType) | 2277 push(new HStatic(method, backend.nonNullType) |
| 2276 ..sourceInformation = sourceInformation); | 2278 ..sourceInformation = sourceInformation); |
| 2277 } | 2279 } |
| 2278 | 2280 |
| 2279 /// Read a local variable, function or parameter. | 2281 /// Read a local variable, function or parameter. |
| 2280 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) { | 2282 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) { |
| 2281 stack.add( | 2283 stack.add( |
| 2282 localsHandler.readLocal(local, sourceInformation: sourceInformation)); | 2284 localsHandler.readLocal(local, sourceInformation: sourceInformation)); |
| 2283 } | 2285 } |
| 2284 | 2286 |
| 2285 void handleLocalGet(ast.Send node, LocalElement local) { | 2287 void handleLocalGet(ast.Send node, LocalElement local) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 location = send; | 2410 location = send; |
| 2409 } | 2411 } |
| 2410 assert(invariant( | 2412 assert(invariant( |
| 2411 location, send == null || !Elements.isInstanceSend(send, elements), | 2413 location, send == null || !Elements.isInstanceSend(send, elements), |
| 2412 message: "Unexpected non instance setter: $element.")); | 2414 message: "Unexpected non instance setter: $element.")); |
| 2413 if (Elements.isStaticOrTopLevelField(element)) { | 2415 if (Elements.isStaticOrTopLevelField(element)) { |
| 2414 if (element.isSetter) { | 2416 if (element.isSetter) { |
| 2415 pushInvokeStatic(location, element, <HInstruction>[value]); | 2417 pushInvokeStatic(location, element, <HInstruction>[value]); |
| 2416 pop(); | 2418 pop(); |
| 2417 } else { | 2419 } else { |
| 2418 VariableElement field = element; | 2420 FieldElement field = element; |
| 2419 value = potentiallyCheckOrTrustType(value, field.type); | 2421 value = potentiallyCheckOrTrustType(value, field.type); |
| 2420 addWithPosition(new HStaticStore(element, value), location); | 2422 addWithPosition(new HStaticStore(field, value), location); |
| 2421 } | 2423 } |
| 2422 stack.add(value); | 2424 stack.add(value); |
| 2423 } else if (Elements.isError(element)) { | 2425 } else if (Elements.isError(element)) { |
| 2424 generateNoSuchSetter(location, element, send == null ? null : value); | 2426 generateNoSuchSetter(location, element, send == null ? null : value); |
| 2425 } else if (Elements.isMalformed(element)) { | 2427 } else if (Elements.isMalformed(element)) { |
| 2426 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 2428 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 2427 stack.add(graph.addConstantNull(compiler)); | 2429 stack.add(graph.addConstantNull(compiler)); |
| 2428 } else { | 2430 } else { |
| 2429 stack.add(value); | 2431 stack.add(value); |
| 2430 LocalElement local = element; | 2432 LocalElement local = element; |
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3105 handleJsStringConcat(node); | 3107 handleJsStringConcat(node); |
| 3106 } else { | 3108 } else { |
| 3107 reporter.internalError(node, "Unknown foreign: ${element}"); | 3109 reporter.internalError(node, "Unknown foreign: ${element}"); |
| 3108 } | 3110 } |
| 3109 } | 3111 } |
| 3110 | 3112 |
| 3111 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, | 3113 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader, |
| 3112 SourceInformation sourceInformation) { | 3114 SourceInformation sourceInformation) { |
| 3113 // Until now we only handle these as getters. | 3115 // Until now we only handle these as getters. |
| 3114 invariant(node, deferredLoader.isDeferredLoaderGetter); | 3116 invariant(node, deferredLoader.isDeferredLoaderGetter); |
| 3115 Element loadFunction = helpers.loadLibraryWrapper; | 3117 FunctionEntity loadFunction = helpers.loadLibraryWrapper; |
| 3116 PrefixElement prefixElement = deferredLoader.enclosingElement; | 3118 PrefixElement prefixElement = deferredLoader.enclosingElement; |
| 3117 String loadId = | 3119 String loadId = |
| 3118 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); | 3120 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); |
| 3119 var inputs = [ | 3121 var inputs = [ |
| 3120 graph.addConstantString(new ast.DartString.literal(loadId), compiler) | 3122 graph.addConstantString(new ast.DartString.literal(loadId), compiler) |
| 3121 ]; | 3123 ]; |
| 3122 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, | 3124 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, |
| 3123 targetCanThrow: false)..sourceInformation = sourceInformation); | 3125 targetCanThrow: false)..sourceInformation = sourceInformation); |
| 3124 } | 3126 } |
| 3125 | 3127 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3174 argumentsInstruction, | 3176 argumentsInstruction, |
| 3175 argumentNamesInstruction | 3177 argumentNamesInstruction |
| 3176 ], | 3178 ], |
| 3177 typeMask: backend.dynamicType); | 3179 typeMask: backend.dynamicType); |
| 3178 | 3180 |
| 3179 var inputs = <HInstruction>[pop()]; | 3181 var inputs = <HInstruction>[pop()]; |
| 3180 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); | 3182 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); |
| 3181 } | 3183 } |
| 3182 | 3184 |
| 3183 /// Generate a call to a super method or constructor. | 3185 /// Generate a call to a super method or constructor. |
| 3184 void generateSuperInvoke(ast.Send node, FunctionElement function, | 3186 void generateSuperInvoke(ast.Send node, MethodElement method, |
| 3185 SourceInformation sourceInformation) { | 3187 SourceInformation sourceInformation) { |
| 3186 // TODO(5347): Try to avoid the need for calling [implementation] before | 3188 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3187 // calling [makeStaticArgumentList]. | 3189 // calling [makeStaticArgumentList]. |
| 3188 Selector selector = elements.getSelector(node); | 3190 Selector selector = elements.getSelector(node); |
| 3189 assert(invariant(node, selector.applies(function.implementation), | 3191 assert(invariant(node, selector.applies(method.implementation), |
| 3190 message: "$selector does not apply to ${function.implementation}")); | 3192 message: "$selector does not apply to ${method.implementation}")); |
| 3191 List<HInstruction> inputs = makeStaticArgumentList( | 3193 List<HInstruction> inputs = makeStaticArgumentList( |
| 3192 selector.callStructure, node.arguments, function.implementation); | 3194 selector.callStructure, node.arguments, method.implementation); |
| 3193 push(buildInvokeSuper(selector, function, inputs, sourceInformation)); | 3195 push(buildInvokeSuper(selector, method, inputs, sourceInformation)); |
| 3194 } | 3196 } |
| 3195 | 3197 |
| 3196 /// Access the value from the super [element]. | 3198 /// Access the value from the super [element]. |
| 3197 void handleSuperGet(ast.Send node, Element element) { | 3199 void handleSuperGet(ast.Send node, Element element) { |
| 3198 Selector selector = elements.getSelector(node); | 3200 Selector selector = elements.getSelector(node); |
| 3199 SourceInformation sourceInformation = | 3201 SourceInformation sourceInformation = |
| 3200 sourceInformationBuilder.buildGet(node); | 3202 sourceInformationBuilder.buildGet(node); |
| 3201 push(buildInvokeSuper( | 3203 push(buildInvokeSuper( |
| 3202 selector, element, const <HInstruction>[], sourceInformation)); | 3204 selector, element, const <HInstruction>[], sourceInformation)); |
| 3203 } | 3205 } |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3688 throwBehavior: native.NativeThrowBehavior.MAY)); | 3690 throwBehavior: native.NativeThrowBehavior.MAY)); |
| 3689 } | 3691 } |
| 3690 } else if (isGrowableListConstructorCall) { | 3692 } else if (isGrowableListConstructorCall) { |
| 3691 push(buildLiteralList(<HInstruction>[])); | 3693 push(buildLiteralList(<HInstruction>[])); |
| 3692 stack.last.instructionType = elementType; | 3694 stack.last.instructionType = elementType; |
| 3693 } else { | 3695 } else { |
| 3694 SourceInformation sourceInformation = | 3696 SourceInformation sourceInformation = |
| 3695 sourceInformationBuilder.buildNew(send); | 3697 sourceInformationBuilder.buildNew(send); |
| 3696 potentiallyAddTypeArguments(inputs, cls, expectedType); | 3698 potentiallyAddTypeArguments(inputs, cls, expectedType); |
| 3697 addInlinedInstantiation(expectedType); | 3699 addInlinedInstantiation(expectedType); |
| 3698 pushInvokeStatic(node, constructor, inputs, | 3700 pushInvokeStatic(node, constructor.declaration, inputs, |
| 3699 typeMask: elementType, | 3701 typeMask: elementType, |
| 3700 instanceType: expectedType, | 3702 instanceType: expectedType, |
| 3701 sourceInformation: sourceInformation); | 3703 sourceInformation: sourceInformation); |
| 3702 removeInlinedInstantiation(expectedType); | 3704 removeInlinedInstantiation(expectedType); |
| 3703 } | 3705 } |
| 3704 HInstruction newInstance = stack.last; | 3706 HInstruction newInstance = stack.last; |
| 3705 if (isFixedList) { | 3707 if (isFixedList) { |
| 3706 // Overwrite the element type, in case the allocation site has | 3708 // Overwrite the element type, in case the allocation site has |
| 3707 // been inlined. | 3709 // been inlined. |
| 3708 newInstance.instructionType = elementType; | 3710 newInstance.instructionType = elementType; |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4338 code = element.isConstructor ? "new #($args)" : "#($args)"; | 4340 code = element.isConstructor ? "new #($args)" : "#($args)"; |
| 4339 } | 4341 } |
| 4340 js.Template codeTemplate = js.js.parseForeignJS(code); | 4342 js.Template codeTemplate = js.js.parseForeignJS(code); |
| 4341 nativeBehavior.codeTemplate = codeTemplate; | 4343 nativeBehavior.codeTemplate = codeTemplate; |
| 4342 | 4344 |
| 4343 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, | 4345 return new HForeignCode(codeTemplate, backend.dynamicType, inputs, |
| 4344 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; | 4346 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; |
| 4345 } | 4347 } |
| 4346 | 4348 |
| 4347 void pushInvokeStatic( | 4349 void pushInvokeStatic( |
| 4348 ast.Node location, Element element, List<HInstruction> arguments, | 4350 ast.Node location, MethodElement element, List<HInstruction> arguments, |
| 4349 {TypeMask typeMask, | 4351 {TypeMask typeMask, |
| 4350 InterfaceType instanceType, | 4352 InterfaceType instanceType, |
| 4351 SourceInformation sourceInformation}) { | 4353 SourceInformation sourceInformation}) { |
| 4354 assert(element.isDeclaration); |
| 4352 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4355 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
| 4353 if (tryInlineMethod(element, null, null, arguments, location, | 4356 if (tryInlineMethod(element, null, null, arguments, location, |
| 4354 instanceType: instanceType)) { | 4357 instanceType: instanceType)) { |
| 4355 return; | 4358 return; |
| 4356 } | 4359 } |
| 4357 | 4360 |
| 4358 if (typeMask == null) { | 4361 if (typeMask == null) { |
| 4359 typeMask = | 4362 typeMask = |
| 4360 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4363 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); |
| 4361 } | 4364 } |
| 4362 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element); | 4365 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element); |
| 4363 // TODO(5346): Try to avoid the need for calling [declaration] before | 4366 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 4364 var instruction; | 4367 var instruction; |
| 4365 if (backend.isJsInterop(element)) { | 4368 if (backend.isJsInterop(element)) { |
| 4366 instruction = | 4369 instruction = |
| 4367 invokeJsInteropFunction(element, arguments, sourceInformation); | 4370 invokeJsInteropFunction(element, arguments, sourceInformation); |
| 4368 } else { | 4371 } else { |
| 4369 // creating an [HInvokeStatic]. | 4372 // creating an [HInvokeStatic]. |
| 4370 instruction = new HInvokeStatic(element.declaration, arguments, typeMask, | 4373 instruction = new HInvokeStatic(element, arguments, typeMask, |
| 4371 targetCanThrow: targetCanThrow) | 4374 targetCanThrow: targetCanThrow) |
| 4372 ..sourceInformation = sourceInformation; | 4375 ..sourceInformation = sourceInformation; |
| 4373 if (currentInlinedInstantiations.isNotEmpty) { | 4376 if (currentInlinedInstantiations.isNotEmpty) { |
| 4374 instruction.instantiatedTypes = | 4377 instruction.instantiatedTypes = |
| 4375 new List<DartType>.from(currentInlinedInstantiations); | 4378 new List<DartType>.from(currentInlinedInstantiations); |
| 4376 } | 4379 } |
| 4377 instruction.sideEffects = | 4380 instruction.sideEffects = |
| 4378 compiler.closedWorld.getSideEffectsOfElement(element); | 4381 compiler.closedWorld.getSideEffectsOfElement(element); |
| 4379 } | 4382 } |
| 4380 if (location == null) { | 4383 if (location == null) { |
| 4381 push(instruction); | 4384 push(instruction); |
| 4382 } else { | 4385 } else { |
| 4383 pushWithPosition(instruction, location); | 4386 pushWithPosition(instruction, location); |
| 4384 } | 4387 } |
| 4385 } | 4388 } |
| 4386 | 4389 |
| 4387 HInstruction buildInvokeSuper( | 4390 HInstruction buildInvokeSuper( |
| 4388 Selector selector, Element element, List<HInstruction> arguments, | 4391 Selector selector, MemberElement element, List<HInstruction> arguments, |
| 4389 [SourceInformation sourceInformation]) { | 4392 [SourceInformation sourceInformation]) { |
| 4390 HInstruction receiver = localsHandler.readThis(); | 4393 HInstruction receiver = localsHandler.readThis(); |
| 4391 // TODO(5346): Try to avoid the need for calling [declaration] before | 4394 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 4392 // creating an [HStatic]. | 4395 // creating an [HStatic]. |
| 4393 List<HInstruction> inputs = <HInstruction>[]; | 4396 List<HInstruction> inputs = <HInstruction>[]; |
| 4394 if (backend.isInterceptedSelector(selector) && | 4397 if (backend.isInterceptedSelector(selector) && |
| 4395 // Fields don't need an interceptor; consider generating HFieldGet/Set | 4398 // Fields don't need an interceptor; consider generating HFieldGet/Set |
| 4396 // instead. | 4399 // instead. |
| 4397 element.kind != ElementKind.FIELD) { | 4400 element.kind != ElementKind.FIELD) { |
| 4398 inputs.add(invokeInterceptor(receiver)); | 4401 inputs.add(invokeInterceptor(receiver)); |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5334 ClassElement targetClass = targetConstructor.enclosingClass; | 5337 ClassElement targetClass = targetConstructor.enclosingClass; |
| 5335 if (backend.classNeedsRti(targetClass)) { | 5338 if (backend.classNeedsRti(targetClass)) { |
| 5336 ClassElement cls = redirectingConstructor.enclosingClass; | 5339 ClassElement cls = redirectingConstructor.enclosingClass; |
| 5337 InterfaceType targetType = | 5340 InterfaceType targetType = |
| 5338 redirectingConstructor.computeEffectiveTargetType(cls.thisType); | 5341 redirectingConstructor.computeEffectiveTargetType(cls.thisType); |
| 5339 targetType = localsHandler.substInContext(targetType); | 5342 targetType = localsHandler.substInContext(targetType); |
| 5340 targetType.typeArguments.forEach((DartType argument) { | 5343 targetType.typeArguments.forEach((DartType argument) { |
| 5341 inputs.add(analyzeTypeArgument(argument)); | 5344 inputs.add(analyzeTypeArgument(argument)); |
| 5342 }); | 5345 }); |
| 5343 } | 5346 } |
| 5344 pushInvokeStatic(node, targetConstructor, inputs); | 5347 pushInvokeStatic(node, targetConstructor.declaration, inputs); |
| 5345 HInstruction value = pop(); | 5348 HInstruction value = pop(); |
| 5346 emitReturn(value, node); | 5349 emitReturn(value, node); |
| 5347 } | 5350 } |
| 5348 | 5351 |
| 5349 /// Returns true if the [type] is a valid return type for an asynchronous | 5352 /// Returns true if the [type] is a valid return type for an asynchronous |
| 5350 /// function. | 5353 /// function. |
| 5351 /// | 5354 /// |
| 5352 /// Asynchronous functions return a `Future`, and a valid return is thus | 5355 /// Asynchronous functions return a `Future`, and a valid return is thus |
| 5353 /// either dynamic, Object, or Future. | 5356 /// either dynamic, Object, or Future. |
| 5354 /// | 5357 /// |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5723 Element loopVariable = elements.getForInVariable(node); | 5726 Element loopVariable = elements.getForInVariable(node); |
| 5724 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable); | 5727 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable); |
| 5725 TypeMask boolType = backend.boolType; | 5728 TypeMask boolType = backend.boolType; |
| 5726 | 5729 |
| 5727 // These variables are shared by initializer, condition, body and update. | 5730 // These variables are shared by initializer, condition, body and update. |
| 5728 HInstruction array; // Set in buildInitializer. | 5731 HInstruction array; // Set in buildInitializer. |
| 5729 bool isFixed; // Set in buildInitializer. | 5732 bool isFixed; // Set in buildInitializer. |
| 5730 HInstruction originalLength = null; // Set for growable lists. | 5733 HInstruction originalLength = null; // Set for growable lists. |
| 5731 | 5734 |
| 5732 HInstruction buildGetLength() { | 5735 HInstruction buildGetLength() { |
| 5733 Element lengthElement = helpers.jsIndexableLength; | 5736 MemberElement lengthElement = helpers.jsIndexableLength; |
| 5734 HFieldGet result = new HFieldGet( | 5737 HFieldGet result = new HFieldGet( |
| 5735 lengthElement, array, backend.positiveIntType, | 5738 lengthElement, array, backend.positiveIntType, |
| 5736 isAssignable: !isFixed); | 5739 isAssignable: !isFixed); |
| 5737 add(result); | 5740 add(result); |
| 5738 return result; | 5741 return result; |
| 5739 } | 5742 } |
| 5740 | 5743 |
| 5741 void buildConcurrentModificationErrorCheck() { | 5744 void buildConcurrentModificationErrorCheck() { |
| 5742 if (originalLength == null) return; | 5745 if (originalLength == null) return; |
| 5743 // The static call checkConcurrentModificationError() is expanded in | 5746 // The static call checkConcurrentModificationError() is expanded in |
| (...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7056 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7059 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 7057 unaliased.accept(this, builder); | 7060 unaliased.accept(this, builder); |
| 7058 } | 7061 } |
| 7059 | 7062 |
| 7060 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7063 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 7061 JavaScriptBackend backend = builder.compiler.backend; | 7064 JavaScriptBackend backend = builder.compiler.backend; |
| 7062 ClassElement cls = backend.helpers.DynamicRuntimeType; | 7065 ClassElement cls = backend.helpers.DynamicRuntimeType; |
| 7063 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); | 7066 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); |
| 7064 } | 7067 } |
| 7065 } | 7068 } |
| OLD | NEW |