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 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2128 instruction = | 2128 instruction = |
2129 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); | 2129 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); |
2130 } else { | 2130 } else { |
2131 instruction = graph.addConstant(value, compiler, | 2131 instruction = graph.addConstant(value, compiler, |
2132 sourceInformation: sourceInformation); | 2132 sourceInformation: sourceInformation); |
2133 } | 2133 } |
2134 stack.add(instruction); | 2134 stack.add(instruction); |
2135 // The inferrer may have found a better type than the constant | 2135 // The inferrer may have found a better type than the constant |
2136 // handler in the case of lists, because the constant handler | 2136 // handler in the case of lists, because the constant handler |
2137 // does not look at elements in the list. | 2137 // does not look at elements in the list. |
2138 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler); | 2138 TypeMask type = |
| 2139 TypeMaskFactory.inferredTypeForElement(field, globalInferenceResults); |
2139 if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) { | 2140 if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) { |
2140 // TODO(13429): The inferrer should know that an element | 2141 // TODO(13429): The inferrer should know that an element |
2141 // cannot be null. | 2142 // cannot be null. |
2142 instruction.instructionType = type.nonNullable(); | 2143 instruction.instructionType = type.nonNullable(); |
2143 } | 2144 } |
2144 } | 2145 } |
2145 | 2146 |
2146 @override | 2147 @override |
2147 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) { | 2148 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) { |
2148 generateIsDeferredLoadedCheckIfNeeded(prefix, node); | 2149 generateIsDeferredLoadedCheckIfNeeded(prefix, node); |
2149 } | 2150 } |
2150 | 2151 |
2151 /// Read a static or top level [field]. | 2152 /// Read a static or top level [field]. |
2152 void generateStaticFieldGet(ast.Send node, FieldElement field) { | 2153 void generateStaticFieldGet(ast.Send node, FieldElement field) { |
2153 ConstantExpression constant = field.constant; | 2154 ConstantExpression constant = field.constant; |
2154 SourceInformation sourceInformation = | 2155 SourceInformation sourceInformation = |
2155 sourceInformationBuilder.buildGet(node); | 2156 sourceInformationBuilder.buildGet(node); |
2156 if (constant != null) { | 2157 if (constant != null) { |
2157 if (!field.isAssignable) { | 2158 if (!field.isAssignable) { |
2158 // A static final or const. Get its constant value and inline it if | 2159 // A static final or const. Get its constant value and inline it if |
2159 // the value can be compiled eagerly. | 2160 // the value can be compiled eagerly. |
2160 generateStaticConstGet(node, field, constant, sourceInformation); | 2161 generateStaticConstGet(node, field, constant, sourceInformation); |
2161 } else { | 2162 } else { |
2162 // TODO(5346): Try to avoid the need for calling [declaration] before | 2163 // TODO(5346): Try to avoid the need for calling [declaration] before |
2163 // creating an [HStatic]. | 2164 // creating an [HStatic]. |
2164 HInstruction instruction = new HStatic( | 2165 HInstruction instruction = new HStatic( |
2165 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) | 2166 field, |
| 2167 TypeMaskFactory.inferredTypeForElement( |
| 2168 field, globalInferenceResults)) |
2166 ..sourceInformation = sourceInformation; | 2169 ..sourceInformation = sourceInformation; |
2167 push(instruction); | 2170 push(instruction); |
2168 } | 2171 } |
2169 } else { | 2172 } else { |
2170 HInstruction instruction = new HLazyStatic( | 2173 HInstruction instruction = new HLazyStatic(field, |
2171 field, TypeMaskFactory.inferredTypeForElement(field, compiler)) | 2174 TypeMaskFactory.inferredTypeForElement(field, globalInferenceResults)) |
2172 ..sourceInformation = sourceInformation; | 2175 ..sourceInformation = sourceInformation; |
2173 push(instruction); | 2176 push(instruction); |
2174 } | 2177 } |
2175 } | 2178 } |
2176 | 2179 |
2177 /// Generate a getter invocation of the static or top level [getter]. | 2180 /// Generate a getter invocation of the static or top level [getter]. |
2178 void generateStaticGetterGet(ast.Send node, MethodElement getter) { | 2181 void generateStaticGetterGet(ast.Send node, MethodElement getter) { |
2179 SourceInformation sourceInformation = | 2182 SourceInformation sourceInformation = |
2180 sourceInformationBuilder.buildGet(node); | 2183 sourceInformationBuilder.buildGet(node); |
2181 if (getter.isDeferredLoaderGetter) { | 2184 if (getter.isDeferredLoaderGetter) { |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2666 }); | 2669 }); |
2667 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | 2670 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. |
2668 return; | 2671 return; |
2669 } | 2672 } |
2670 | 2673 |
2671 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { | 2674 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { |
2672 reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE); | 2675 reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE); |
2673 } | 2676 } |
2674 | 2677 |
2675 TypeMask ssaType = | 2678 TypeMask ssaType = |
2676 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); | 2679 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
2677 | 2680 |
2678 SourceInformation sourceInformation = | 2681 SourceInformation sourceInformation = |
2679 sourceInformationBuilder.buildCall(node, node.argumentsNode); | 2682 sourceInformationBuilder.buildCall(node, node.argumentsNode); |
2680 if (nativeBehavior.codeTemplate.isExpression) { | 2683 if (nativeBehavior.codeTemplate.isExpression) { |
2681 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, | 2684 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, |
2682 effects: nativeBehavior.sideEffects, nativeBehavior: nativeBehavior) | 2685 effects: nativeBehavior.sideEffects, nativeBehavior: nativeBehavior) |
2683 ..sourceInformation = sourceInformation); | 2686 ..sourceInformation = sourceInformation); |
2684 } else { | 2687 } else { |
2685 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, | 2688 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, |
2686 isStatement: true, | 2689 isStatement: true, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 for (int i = 2; i < arguments.length; i++) { | 2822 for (int i = 2; i < arguments.length; i++) { |
2820 visit(arguments[i]); | 2823 visit(arguments[i]); |
2821 compiledArguments.add(pop()); | 2824 compiledArguments.add(pop()); |
2822 } | 2825 } |
2823 | 2826 |
2824 native.NativeBehavior nativeBehavior = elements.getNativeData(node); | 2827 native.NativeBehavior nativeBehavior = elements.getNativeData(node); |
2825 assert(invariant(node, nativeBehavior != null, | 2828 assert(invariant(node, nativeBehavior != null, |
2826 message: "No NativeBehavior for $node")); | 2829 message: "No NativeBehavior for $node")); |
2827 | 2830 |
2828 TypeMask ssaType = | 2831 TypeMask ssaType = |
2829 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); | 2832 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
2830 | 2833 |
2831 push(new HForeignCode(template, ssaType, compiledArguments, | 2834 push(new HForeignCode(template, ssaType, compiledArguments, |
2832 nativeBehavior: nativeBehavior)); | 2835 nativeBehavior: nativeBehavior)); |
2833 } | 2836 } |
2834 | 2837 |
2835 void handleForeignJsEmbeddedGlobal(ast.Send node) { | 2838 void handleForeignJsEmbeddedGlobal(ast.Send node) { |
2836 List<ast.Node> arguments = node.arguments.toList(); | 2839 List<ast.Node> arguments = node.arguments.toList(); |
2837 ast.Node globalNameNode; | 2840 ast.Node globalNameNode; |
2838 switch (arguments.length) { | 2841 switch (arguments.length) { |
2839 case 0: | 2842 case 0: |
(...skipping 24 matching lines...) Expand all Loading... |
2864 } | 2867 } |
2865 HConstant hConstant = globalNameHNode; | 2868 HConstant hConstant = globalNameHNode; |
2866 StringConstantValue constant = hConstant.constant; | 2869 StringConstantValue constant = hConstant.constant; |
2867 String globalName = constant.primitiveValue.slowToString(); | 2870 String globalName = constant.primitiveValue.slowToString(); |
2868 js.Template expr = js.js.expressionTemplateYielding( | 2871 js.Template expr = js.js.expressionTemplateYielding( |
2869 backend.emitter.generateEmbeddedGlobalAccess(globalName)); | 2872 backend.emitter.generateEmbeddedGlobalAccess(globalName)); |
2870 native.NativeBehavior nativeBehavior = elements.getNativeData(node); | 2873 native.NativeBehavior nativeBehavior = elements.getNativeData(node); |
2871 assert(invariant(node, nativeBehavior != null, | 2874 assert(invariant(node, nativeBehavior != null, |
2872 message: "No NativeBehavior for $node")); | 2875 message: "No NativeBehavior for $node")); |
2873 TypeMask ssaType = | 2876 TypeMask ssaType = |
2874 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); | 2877 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
2875 push(new HForeignCode(expr, ssaType, const [], | 2878 push(new HForeignCode(expr, ssaType, const [], |
2876 nativeBehavior: nativeBehavior)); | 2879 nativeBehavior: nativeBehavior)); |
2877 } | 2880 } |
2878 | 2881 |
2879 void handleJsInterceptorConstant(ast.Send node) { | 2882 void handleJsInterceptorConstant(ast.Send node) { |
2880 // Single argument must be a TypeConstant which is converted into a | 2883 // Single argument must be a TypeConstant which is converted into a |
2881 // InterceptorConstant. | 2884 // InterceptorConstant. |
2882 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) { | 2885 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) { |
2883 ast.Node argument = node.arguments.head; | 2886 ast.Node argument = node.arguments.head; |
2884 visit(argument); | 2887 visit(argument); |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3303 "State: typeInfo=$typeInfo, stack=$stack.")); | 3306 "State: typeInfo=$typeInfo, stack=$stack.")); |
3304 stack.last.instructionType = newObject.instructionType; | 3307 stack.last.instructionType = newObject.instructionType; |
3305 return pop(); | 3308 return pop(); |
3306 } | 3309 } |
3307 | 3310 |
3308 void handleNewSend(ast.NewExpression node) { | 3311 void handleNewSend(ast.NewExpression node) { |
3309 ast.Send send = node.send; | 3312 ast.Send send = node.send; |
3310 generateIsDeferredLoadedCheckOfSend(send); | 3313 generateIsDeferredLoadedCheckOfSend(send); |
3311 | 3314 |
3312 bool isFixedList = false; | 3315 bool isFixedList = false; |
3313 bool isFixedListConstructorCall = | 3316 bool isFixedListConstructorCall = Elements.isFixedListConstructorCall( |
3314 Elements.isFixedListConstructorCall(elements[send], send, compiler); | 3317 elements[send], send, closedWorld.commonElements); |
3315 bool isGrowableListConstructorCall = | 3318 bool isGrowableListConstructorCall = Elements.isGrowableListConstructorCall( |
3316 Elements.isGrowableListConstructorCall(elements[send], send, compiler); | 3319 elements[send], send, closedWorld.commonElements); |
3317 | 3320 |
3318 TypeMask computeType(element) { | 3321 TypeMask computeType(element) { |
3319 Element originalElement = elements[send]; | 3322 Element originalElement = elements[send]; |
3320 if (isFixedListConstructorCall || | 3323 if (isFixedListConstructorCall || |
3321 Elements.isFilledListConstructorCall( | 3324 Elements.isFilledListConstructorCall( |
3322 originalElement, send, compiler)) { | 3325 originalElement, send, closedWorld.commonElements)) { |
3323 isFixedList = true; | 3326 isFixedList = true; |
3324 TypeMask inferred = _inferredTypeOfNewList(send); | 3327 TypeMask inferred = _inferredTypeOfNewList(send); |
3325 return inferred.containsAll(closedWorld) | 3328 return inferred.containsAll(closedWorld) |
3326 ? commonMasks.fixedArrayType | 3329 ? commonMasks.fixedArrayType |
3327 : inferred; | 3330 : inferred; |
3328 } else if (isGrowableListConstructorCall) { | 3331 } else if (isGrowableListConstructorCall) { |
3329 TypeMask inferred = _inferredTypeOfNewList(send); | 3332 TypeMask inferred = _inferredTypeOfNewList(send); |
3330 return inferred.containsAll(closedWorld) | 3333 return inferred.containsAll(closedWorld) |
3331 ? commonMasks.extendableArrayType | 3334 ? commonMasks.extendableArrayType |
3332 : inferred; | 3335 : inferred; |
3333 } else if (Elements.isConstructorOfTypedArraySubclass( | 3336 } else if (Elements.isConstructorOfTypedArraySubclass( |
3334 originalElement, compiler)) { | 3337 originalElement, closedWorld)) { |
3335 isFixedList = true; | 3338 isFixedList = true; |
3336 TypeMask inferred = _inferredTypeOfNewList(send); | 3339 TypeMask inferred = _inferredTypeOfNewList(send); |
3337 ClassElement cls = element.enclosingClass; | 3340 ClassElement cls = element.enclosingClass; |
3338 assert(backend.isNative(cls.thisType.element)); | 3341 assert(backend.isNative(cls.thisType.element)); |
3339 return inferred.containsAll(closedWorld) | 3342 return inferred.containsAll(closedWorld) |
3340 ? new TypeMask.nonNullExact(cls.thisType.element, closedWorld) | 3343 ? new TypeMask.nonNullExact(cls.thisType.element, closedWorld) |
3341 : inferred; | 3344 : inferred; |
3342 } else if (element.isGenerativeConstructor) { | 3345 } else if (element.isGenerativeConstructor) { |
3343 ClassElement cls = element.enclosingClass; | 3346 ClassElement cls = element.enclosingClass; |
3344 if (cls.isAbstract) { | 3347 if (cls.isAbstract) { |
3345 // An error will be thrown. | 3348 // An error will be thrown. |
3346 return new TypeMask.nonNullEmpty(); | 3349 return new TypeMask.nonNullEmpty(); |
3347 } else { | 3350 } else { |
3348 return new TypeMask.nonNullExact(cls.thisType.element, closedWorld); | 3351 return new TypeMask.nonNullExact(cls.thisType.element, closedWorld); |
3349 } | 3352 } |
3350 } else { | 3353 } else { |
3351 return TypeMaskFactory.inferredReturnTypeForElement( | 3354 return TypeMaskFactory.inferredReturnTypeForElement( |
3352 originalElement, compiler); | 3355 originalElement, globalInferenceResults); |
3353 } | 3356 } |
3354 } | 3357 } |
3355 | 3358 |
3356 Element constructor = elements[send]; | 3359 Element constructor = elements[send]; |
3357 CallStructure callStructure = elements.getSelector(send).callStructure; | 3360 CallStructure callStructure = elements.getSelector(send).callStructure; |
3358 ConstructorElement constructorDeclaration = constructor; | 3361 ConstructorElement constructorDeclaration = constructor; |
3359 ConstructorElement constructorImplementation = constructor.implementation; | 3362 ConstructorElement constructorImplementation = constructor.implementation; |
3360 constructor = constructorImplementation.effectiveTarget; | 3363 constructor = constructorImplementation.effectiveTarget; |
3361 | 3364 |
3362 final bool isSymbolConstructor = | 3365 final bool isSymbolConstructor = |
3363 compiler.commonElements.isSymbolConstructor(constructorDeclaration); | 3366 closedWorld.commonElements.isSymbolConstructor(constructorDeclaration); |
3364 final bool isJSArrayTypedConstructor = | 3367 final bool isJSArrayTypedConstructor = |
3365 constructorDeclaration == helpers.jsArrayTypedConstructor; | 3368 constructorDeclaration == helpers.jsArrayTypedConstructor; |
3366 | 3369 |
3367 if (isSymbolConstructor) { | 3370 if (isSymbolConstructor) { |
3368 constructor = helpers.symbolValidatedConstructor; | 3371 constructor = helpers.symbolValidatedConstructor; |
3369 assert(invariant(send, constructor != null, | 3372 assert(invariant(send, constructor != null, |
3370 message: 'Constructor Symbol.validated is missing')); | 3373 message: 'Constructor Symbol.validated is missing')); |
3371 callStructure = helpers.symbolValidatedConstructorSelector.callStructure; | 3374 callStructure = helpers.symbolValidatedConstructorSelector.callStructure; |
3372 assert(invariant(send, callStructure != null, | 3375 assert(invariant(send, callStructure != null, |
3373 message: 'Constructor Symbol.validated is missing')); | 3376 message: 'Constructor Symbol.validated is missing')); |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4007 } | 4010 } |
4008 } | 4011 } |
4009 | 4012 |
4010 HInstruction receiver = arguments[0]; | 4013 HInstruction receiver = arguments[0]; |
4011 List<HInstruction> inputs = <HInstruction>[]; | 4014 List<HInstruction> inputs = <HInstruction>[]; |
4012 bool isIntercepted = backend.isInterceptedSelector(selector); | 4015 bool isIntercepted = backend.isInterceptedSelector(selector); |
4013 if (isIntercepted) { | 4016 if (isIntercepted) { |
4014 inputs.add(invokeInterceptor(receiver)); | 4017 inputs.add(invokeInterceptor(receiver)); |
4015 } | 4018 } |
4016 inputs.addAll(arguments); | 4019 inputs.addAll(arguments); |
4017 TypeMask type = | 4020 TypeMask type = TypeMaskFactory.inferredTypeForSelector( |
4018 TypeMaskFactory.inferredTypeForSelector(selector, mask, compiler); | 4021 selector, mask, globalInferenceResults); |
4019 if (selector.isGetter) { | 4022 if (selector.isGetter) { |
4020 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type) | 4023 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type) |
4021 ..sourceInformation = sourceInformation); | 4024 ..sourceInformation = sourceInformation); |
4022 } else if (selector.isSetter) { | 4025 } else if (selector.isSetter) { |
4023 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type) | 4026 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type) |
4024 ..sourceInformation = sourceInformation); | 4027 ..sourceInformation = sourceInformation); |
4025 } else { | 4028 } else { |
4026 push(new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted) | 4029 push(new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted) |
4027 ..sourceInformation = sourceInformation); | 4030 ..sourceInformation = sourceInformation); |
4028 } | 4031 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4134 InterfaceType instanceType, | 4137 InterfaceType instanceType, |
4135 SourceInformation sourceInformation}) { | 4138 SourceInformation sourceInformation}) { |
4136 assert(element.isDeclaration); | 4139 assert(element.isDeclaration); |
4137 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4140 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
4138 if (tryInlineMethod(element, null, null, arguments, location, | 4141 if (tryInlineMethod(element, null, null, arguments, location, |
4139 instanceType: instanceType)) { | 4142 instanceType: instanceType)) { |
4140 return; | 4143 return; |
4141 } | 4144 } |
4142 | 4145 |
4143 if (typeMask == null) { | 4146 if (typeMask == null) { |
4144 typeMask = | 4147 typeMask = TypeMaskFactory.inferredReturnTypeForElement( |
4145 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4148 element, globalInferenceResults); |
4146 } | 4149 } |
4147 bool targetCanThrow = !closedWorld.getCannotThrow(element); | 4150 bool targetCanThrow = !closedWorld.getCannotThrow(element); |
4148 // TODO(5346): Try to avoid the need for calling [declaration] before | 4151 // TODO(5346): Try to avoid the need for calling [declaration] before |
4149 var instruction; | 4152 var instruction; |
4150 if (backend.isJsInterop(element)) { | 4153 if (backend.isJsInterop(element)) { |
4151 instruction = | 4154 instruction = |
4152 invokeJsInteropFunction(element, arguments, sourceInformation); | 4155 invokeJsInteropFunction(element, arguments, sourceInformation); |
4153 } else { | 4156 } else { |
4154 // creating an [HInvokeStatic]. | 4157 // creating an [HInvokeStatic]. |
4155 instruction = new HInvokeStatic(element, arguments, typeMask, | 4158 instruction = new HInvokeStatic(element, arguments, typeMask, |
(...skipping 22 matching lines...) Expand all Loading... |
4178 if (backend.isInterceptedSelector(selector) && | 4181 if (backend.isInterceptedSelector(selector) && |
4179 // Fields don't need an interceptor; consider generating HFieldGet/Set | 4182 // Fields don't need an interceptor; consider generating HFieldGet/Set |
4180 // instead. | 4183 // instead. |
4181 element.kind != ElementKind.FIELD) { | 4184 element.kind != ElementKind.FIELD) { |
4182 inputs.add(invokeInterceptor(receiver)); | 4185 inputs.add(invokeInterceptor(receiver)); |
4183 } | 4186 } |
4184 inputs.add(receiver); | 4187 inputs.add(receiver); |
4185 inputs.addAll(arguments); | 4188 inputs.addAll(arguments); |
4186 TypeMask type; | 4189 TypeMask type; |
4187 if (!element.isGetter && selector.isGetter) { | 4190 if (!element.isGetter && selector.isGetter) { |
4188 type = TypeMaskFactory.inferredTypeForElement(element, compiler); | 4191 type = TypeMaskFactory.inferredTypeForElement( |
| 4192 element, globalInferenceResults); |
4189 } else { | 4193 } else { |
4190 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); | 4194 type = TypeMaskFactory.inferredReturnTypeForElement( |
| 4195 element, globalInferenceResults); |
4191 } | 4196 } |
4192 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, | 4197 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, |
4193 selector, inputs, type, sourceInformation, | 4198 selector, inputs, type, sourceInformation, |
4194 isSetter: selector.isSetter || selector.isIndexSet); | 4199 isSetter: selector.isSetter || selector.isIndexSet); |
4195 instruction.sideEffects = | 4200 instruction.sideEffects = |
4196 closedWorld.getSideEffectsOfSelector(selector, null); | 4201 closedWorld.getSideEffectsOfSelector(selector, null); |
4197 return instruction; | 4202 return instruction; |
4198 } | 4203 } |
4199 | 4204 |
4200 void handleComplexOperatorSend( | 4205 void handleComplexOperatorSend( |
(...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5548 // condition. It is not necessary on the first iteration since there is | 5553 // condition. It is not necessary on the first iteration since there is |
5549 // no code between calls to `get iterator` and `moveNext`, so the test is | 5554 // no code between calls to `get iterator` and `moveNext`, so the test is |
5550 // moved to the loop update. | 5555 // moved to the loop update. |
5551 | 5556 |
5552 // Find a type for the element. Use the element type of the indexer of the | 5557 // Find a type for the element. Use the element type of the indexer of the |
5553 // array, as this is stronger than the iterator's `get current` type, for | 5558 // array, as this is stronger than the iterator's `get current` type, for |
5554 // example, `get current` includes null. | 5559 // example, `get current` includes null. |
5555 // TODO(sra): The element type of a container type mask might be better. | 5560 // TODO(sra): The element type of a container type mask might be better. |
5556 Selector selector = new Selector.index(); | 5561 Selector selector = new Selector.index(); |
5557 TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 5562 TypeMask type = TypeMaskFactory.inferredTypeForSelector( |
5558 selector, arrayType, compiler); | 5563 selector, arrayType, globalInferenceResults); |
5559 | 5564 |
5560 HInstruction index = localsHandler.readLocal(indexVariable); | 5565 HInstruction index = localsHandler.readLocal(indexVariable); |
5561 HInstruction value = new HIndex(array, index, null, type); | 5566 HInstruction value = new HIndex(array, index, null, type); |
5562 add(value); | 5567 add(value); |
5563 | 5568 |
5564 buildAssignLoopVariable(node, value); | 5569 buildAssignLoopVariable(node, value); |
5565 visit(node.body); | 5570 visit(node.body); |
5566 } | 5571 } |
5567 | 5572 |
5568 void buildUpdate() { | 5573 void buildUpdate() { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5692 // If rti is needed and the map literal has no type parameters, | 5697 // If rti is needed and the map literal has no type parameters, |
5693 // 'constructor' is a static function that forwards the call to the factory | 5698 // 'constructor' is a static function that forwards the call to the factory |
5694 // constructor without type parameters. | 5699 // constructor without type parameters. |
5695 assert(constructor is ConstructorElement || constructor is FunctionElement); | 5700 assert(constructor is ConstructorElement || constructor is FunctionElement); |
5696 | 5701 |
5697 // The instruction type will always be a subtype of the mapLiteralClass, but | 5702 // The instruction type will always be a subtype of the mapLiteralClass, but |
5698 // type inference might discover a more specific type, or find nothing (in | 5703 // type inference might discover a more specific type, or find nothing (in |
5699 // dart2js unit tests). | 5704 // dart2js unit tests). |
5700 TypeMask mapType = | 5705 TypeMask mapType = |
5701 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, closedWorld); | 5706 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, closedWorld); |
5702 TypeMask returnTypeMask = | 5707 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( |
5703 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); | 5708 constructor, globalInferenceResults); |
5704 TypeMask instructionType = | 5709 TypeMask instructionType = |
5705 mapType.intersection(returnTypeMask, closedWorld); | 5710 mapType.intersection(returnTypeMask, closedWorld); |
5706 | 5711 |
5707 addInlinedInstantiation(expectedType); | 5712 addInlinedInstantiation(expectedType); |
5708 pushInvokeStatic(node, constructor, inputs, | 5713 pushInvokeStatic(node, constructor, inputs, |
5709 typeMask: instructionType, instanceType: expectedType); | 5714 typeMask: instructionType, instanceType: expectedType); |
5710 removeInlinedInstantiation(expectedType); | 5715 removeInlinedInstantiation(expectedType); |
5711 } | 5716 } |
5712 | 5717 |
5713 visitLiteralMapEntry(ast.LiteralMapEntry node) { | 5718 visitLiteralMapEntry(ast.LiteralMapEntry node) { |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6532 // fast-path code for most primitives. | 6537 // fast-path code for most primitives. |
6533 if (expression.canBePrimitive(builder.closedWorld)) { | 6538 if (expression.canBePrimitive(builder.closedWorld)) { |
6534 append(stringify(node, expression)); | 6539 append(stringify(node, expression)); |
6535 return; | 6540 return; |
6536 } | 6541 } |
6537 | 6542 |
6538 // If the `toString` method is guaranteed to return a string we can call it | 6543 // If the `toString` method is guaranteed to return a string we can call it |
6539 // directly. | 6544 // directly. |
6540 Selector selector = Selectors.toString_; | 6545 Selector selector = Selectors.toString_; |
6541 TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 6546 TypeMask type = TypeMaskFactory.inferredTypeForSelector( |
6542 selector, expression.instructionType, compiler); | 6547 selector, expression.instructionType, builder.globalInferenceResults); |
6543 if (type.containsOnlyString(builder.closedWorld)) { | 6548 if (type.containsOnlyString(builder.closedWorld)) { |
6544 builder.pushInvokeDynamic(node, selector, expression.instructionType, | 6549 builder.pushInvokeDynamic(node, selector, expression.instructionType, |
6545 <HInstruction>[expression]); | 6550 <HInstruction>[expression]); |
6546 append(builder.pop()); | 6551 append(builder.pop()); |
6547 return; | 6552 return; |
6548 } | 6553 } |
6549 | 6554 |
6550 append(stringify(node, expression)); | 6555 append(stringify(node, expression)); |
6551 } | 6556 } |
6552 | 6557 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6743 this.oldReturnLocal, | 6748 this.oldReturnLocal, |
6744 this.oldReturnType, | 6749 this.oldReturnType, |
6745 this.oldResolvedAst, | 6750 this.oldResolvedAst, |
6746 this.oldStack, | 6751 this.oldStack, |
6747 this.oldLocalsHandler, | 6752 this.oldLocalsHandler, |
6748 this.inTryStatement, | 6753 this.inTryStatement, |
6749 this.allFunctionsCalledOnce, | 6754 this.allFunctionsCalledOnce, |
6750 this.oldElementInferenceResults) | 6755 this.oldElementInferenceResults) |
6751 : super(function); | 6756 : super(function); |
6752 } | 6757 } |
OLD | NEW |