| 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 2036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. | 2047 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. |
| 2048 /// If [prefixElement] is [null] ndo nothing. | 2048 /// If [prefixElement] is [null] ndo nothing. |
| 2049 void generateIsDeferredLoadedCheckIfNeeded( | 2049 void generateIsDeferredLoadedCheckIfNeeded( |
| 2050 PrefixElement prefixElement, ast.Node location) { | 2050 PrefixElement prefixElement, ast.Node location) { |
| 2051 if (prefixElement == null) return; | 2051 if (prefixElement == null) return; |
| 2052 String loadId = | 2052 String loadId = |
| 2053 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); | 2053 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); |
| 2054 HInstruction loadIdConstant = addConstantString(loadId); | 2054 HInstruction loadIdConstant = addConstantString(loadId); |
| 2055 String uri = prefixElement.deferredImport.uri.toString(); | 2055 String uri = prefixElement.deferredImport.uri.toString(); |
| 2056 HInstruction uriConstant = addConstantString(uri); | 2056 HInstruction uriConstant = addConstantString(uri); |
| 2057 Element helper = helpers.checkDeferredIsLoaded; | 2057 MethodElement helper = helpers.checkDeferredIsLoaded; |
| 2058 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); | 2058 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); |
| 2059 pop(); | 2059 pop(); |
| 2060 } | 2060 } |
| 2061 | 2061 |
| 2062 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that | 2062 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
| 2063 /// resolves to a deferred library. | 2063 /// resolves to a deferred library. |
| 2064 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { | 2064 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { |
| 2065 generateIsDeferredLoadedCheckIfNeeded( | 2065 generateIsDeferredLoadedCheckIfNeeded( |
| 2066 compiler.deferredLoadTask.deferredPrefixElement(node, elements), node); | 2066 compiler.deferredLoadTask.deferredPrefixElement(node, elements), node); |
| 2067 } | 2067 } |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2418 pushInvokeDynamic( | 2418 pushInvokeDynamic( |
| 2419 node, | 2419 node, |
| 2420 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), | 2420 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), |
| 2421 CallStructure.ONE_ARG), | 2421 CallStructure.ONE_ARG), |
| 2422 null, | 2422 null, |
| 2423 arguments); | 2423 arguments); |
| 2424 return new HIs.compound(type, expression, pop(), commonMasks.boolType); | 2424 return new HIs.compound(type, expression, pop(), commonMasks.boolType); |
| 2425 } else if (type.isTypeVariable) { | 2425 } else if (type.isTypeVariable) { |
| 2426 HInstruction runtimeType = | 2426 HInstruction runtimeType = |
| 2427 typeBuilder.addTypeVariableReference(type, sourceElement); | 2427 typeBuilder.addTypeVariableReference(type, sourceElement); |
| 2428 Element helper = helpers.checkSubtypeOfRuntimeType; | 2428 MethodElement helper = helpers.checkSubtypeOfRuntimeType; |
| 2429 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 2429 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
| 2430 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType); | 2430 pushInvokeStatic(null, helper, inputs, typeMask: commonMasks.boolType); |
| 2431 HInstruction call = pop(); | 2431 HInstruction call = pop(); |
| 2432 return new HIs.variable(type, expression, call, commonMasks.boolType); | 2432 return new HIs.variable(type, expression, call, commonMasks.boolType); |
| 2433 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2433 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 2434 ClassElement element = type.element; | 2434 ClassElement element = type.element; |
| 2435 Element helper = helpers.checkSubtype; | 2435 MethodElement helper = helpers.checkSubtype; |
| 2436 HInstruction representations = | 2436 HInstruction representations = |
| 2437 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); | 2437 typeBuilder.buildTypeArgumentRepresentations(type, sourceElement); |
| 2438 add(representations); | 2438 add(representations); |
| 2439 js.Name operator = backend.namer.operatorIs(element); | 2439 js.Name operator = backend.namer.operatorIs(element); |
| 2440 HInstruction isFieldName = addConstantStringFromName(operator); | 2440 HInstruction isFieldName = addConstantStringFromName(operator); |
| 2441 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) | 2441 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) |
| 2442 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 2442 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
| 2443 : graph.addConstantNull(closedWorld); | 2443 : graph.addConstantNull(closedWorld); |
| 2444 List<HInstruction> inputs = <HInstruction>[ | 2444 List<HInstruction> inputs = <HInstruction>[ |
| 2445 expression, | 2445 expression, |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2689 // If the isolate library is not used, we just generate code | 2689 // If the isolate library is not used, we just generate code |
| 2690 // to fetch the static state. | 2690 // to fetch the static state. |
| 2691 String name = backend.namer.staticStateHolder; | 2691 String name = backend.namer.staticStateHolder; |
| 2692 push(new HForeignCode( | 2692 push(new HForeignCode( |
| 2693 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], | 2693 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], |
| 2694 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); | 2694 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); |
| 2695 } else { | 2695 } else { |
| 2696 // Call a helper method from the isolate library. The isolate | 2696 // Call a helper method from the isolate library. The isolate |
| 2697 // library uses its own isolate structure, that encapsulates | 2697 // library uses its own isolate structure, that encapsulates |
| 2698 // Leg's isolate. | 2698 // Leg's isolate. |
| 2699 Element element = helpers.currentIsolate; | 2699 MethodElement element = helpers.currentIsolate; |
| 2700 if (element == null) { | 2700 if (element == null) { |
| 2701 reporter.internalError(node, 'Isolate library and compiler mismatch.'); | 2701 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
| 2702 } | 2702 } |
| 2703 pushInvokeStatic(null, element, [], typeMask: commonMasks.dynamicType); | 2703 pushInvokeStatic(null, element, [], typeMask: commonMasks.dynamicType); |
| 2704 } | 2704 } |
| 2705 } | 2705 } |
| 2706 | 2706 |
| 2707 void handleForeignJsGetFlag(ast.Send node) { | 2707 void handleForeignJsGetFlag(ast.Send node) { |
| 2708 List<ast.Node> arguments = node.arguments.toList(); | 2708 List<ast.Node> arguments = node.arguments.toList(); |
| 2709 ast.Node argument; | 2709 ast.Node argument; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2883 void handleForeignJsCallInIsolate(ast.Send node) { | 2883 void handleForeignJsCallInIsolate(ast.Send node) { |
| 2884 Link<ast.Node> link = node.arguments; | 2884 Link<ast.Node> link = node.arguments; |
| 2885 if (!backend.hasIsolateSupport) { | 2885 if (!backend.hasIsolateSupport) { |
| 2886 // If the isolate library is not used, we just invoke the | 2886 // If the isolate library is not used, we just invoke the |
| 2887 // closure. | 2887 // closure. |
| 2888 visit(link.tail.head); | 2888 visit(link.tail.head); |
| 2889 push(new HInvokeClosure(new Selector.callClosure(0), | 2889 push(new HInvokeClosure(new Selector.callClosure(0), |
| 2890 <HInstruction>[pop()], commonMasks.dynamicType)); | 2890 <HInstruction>[pop()], commonMasks.dynamicType)); |
| 2891 } else { | 2891 } else { |
| 2892 // Call a helper method from the isolate library. | 2892 // Call a helper method from the isolate library. |
| 2893 Element element = helpers.callInIsolate; | 2893 MethodElement element = helpers.callInIsolate; |
| 2894 if (element == null) { | 2894 if (element == null) { |
| 2895 reporter.internalError(node, 'Isolate library and compiler mismatch.'); | 2895 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
| 2896 } | 2896 } |
| 2897 List<HInstruction> inputs = <HInstruction>[]; | 2897 List<HInstruction> inputs = <HInstruction>[]; |
| 2898 addGenericSendArgumentsToList(link, inputs); | 2898 addGenericSendArgumentsToList(link, inputs); |
| 2899 pushInvokeStatic(node, element, inputs, | 2899 pushInvokeStatic(node, element, inputs, |
| 2900 typeMask: commonMasks.dynamicType); | 2900 typeMask: commonMasks.dynamicType); |
| 2901 } | 2901 } |
| 2902 } | 2902 } |
| 2903 | 2903 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3033 registry?.registerDynamicUse(new DynamicUse(selector, null)); | 3033 registry?.registerDynamicUse(new DynamicUse(selector, null)); |
| 3034 } | 3034 } |
| 3035 String publicName = name; | 3035 String publicName = name; |
| 3036 if (selector.isSetter) publicName += '='; | 3036 if (selector.isSetter) publicName += '='; |
| 3037 | 3037 |
| 3038 ConstantValue nameConstant = | 3038 ConstantValue nameConstant = |
| 3039 constantSystem.createString(new ast.DartString.literal(publicName)); | 3039 constantSystem.createString(new ast.DartString.literal(publicName)); |
| 3040 | 3040 |
| 3041 js.Name internalName = backend.namer.invocationName(selector); | 3041 js.Name internalName = backend.namer.invocationName(selector); |
| 3042 | 3042 |
| 3043 Element createInvocationMirror = helpers.createInvocationMirror; | 3043 MethodElement createInvocationMirror = helpers.createInvocationMirror; |
| 3044 var argumentsInstruction = buildLiteralList(arguments); | 3044 var argumentsInstruction = buildLiteralList(arguments); |
| 3045 add(argumentsInstruction); | 3045 add(argumentsInstruction); |
| 3046 | 3046 |
| 3047 var argumentNames = new List<HInstruction>(); | 3047 var argumentNames = new List<HInstruction>(); |
| 3048 for (String argumentName in selector.namedArguments) { | 3048 for (String argumentName in selector.namedArguments) { |
| 3049 ConstantValue argumentNameConstant = | 3049 ConstantValue argumentNameConstant = |
| 3050 constantSystem.createString(new ast.DartString.literal(argumentName)); | 3050 constantSystem.createString(new ast.DartString.literal(argumentName)); |
| 3051 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); | 3051 argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld)); |
| 3052 } | 3052 } |
| 3053 var argumentNamesInstruction = buildLiteralList(argumentNames); | 3053 var argumentNamesInstruction = buildLiteralList(argumentNames); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 3262 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
| 3263 }); | 3263 }); |
| 3264 // TODO(15489): Register at codegen. | 3264 // TODO(15489): Register at codegen. |
| 3265 registry?.registerInstantiation(type); | 3265 registry?.registerInstantiation(type); |
| 3266 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); | 3266 return callSetRuntimeTypeInfoWithTypeArguments(type, inputs, newObject); |
| 3267 } | 3267 } |
| 3268 | 3268 |
| 3269 HInstruction callSetRuntimeTypeInfo( | 3269 HInstruction callSetRuntimeTypeInfo( |
| 3270 HInstruction typeInfo, HInstruction newObject) { | 3270 HInstruction typeInfo, HInstruction newObject) { |
| 3271 // Set the runtime type information on the object. | 3271 // Set the runtime type information on the object. |
| 3272 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; | 3272 MethodElement typeInfoSetterElement = helpers.setRuntimeTypeInfo; |
| 3273 pushInvokeStatic( | 3273 pushInvokeStatic( |
| 3274 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], | 3274 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], |
| 3275 typeMask: commonMasks.dynamicType, | 3275 typeMask: commonMasks.dynamicType, |
| 3276 sourceInformation: newObject.sourceInformation); | 3276 sourceInformation: newObject.sourceInformation); |
| 3277 | 3277 |
| 3278 // The new object will now be referenced through the | 3278 // The new object will now be referenced through the |
| 3279 // `setRuntimeTypeInfo` call. We therefore set the type of that | 3279 // `setRuntimeTypeInfo` call. We therefore set the type of that |
| 3280 // instruction to be of the object's type. | 3280 // instruction to be of the object's type. |
| 3281 assert(invariant(CURRENT_ELEMENT_SPANNABLE, | 3281 assert(invariant(CURRENT_ELEMENT_SPANNABLE, |
| 3282 stack.last is HInvokeStatic || stack.last == newObject, | 3282 stack.last is HInvokeStatic || stack.last == newObject, |
| 3283 message: "Unexpected `stack.last`: Found ${stack.last}, " | 3283 message: "Unexpected `stack.last`: Found ${stack.last}, " |
| 3284 "expected ${newObject} or an HInvokeStatic. " | 3284 "expected ${newObject} or an HInvokeStatic. " |
| 3285 "State: typeInfo=$typeInfo, stack=$stack.")); | 3285 "State: typeInfo=$typeInfo, stack=$stack.")); |
| 3286 stack.last.instructionType = newObject.instructionType; | 3286 stack.last.instructionType = newObject.instructionType; |
| 3287 return pop(); | 3287 return pop(); |
| 3288 } | 3288 } |
| 3289 | 3289 |
| 3290 void handleNewSend(ast.NewExpression node) { | 3290 void handleNewSend(ast.NewExpression node) { |
| 3291 ast.Send send = node.send; | 3291 ast.Send send = node.send; |
| 3292 generateIsDeferredLoadedCheckOfSend(send); | 3292 generateIsDeferredLoadedCheckOfSend(send); |
| 3293 | 3293 |
| 3294 ConstructorElement constructor = elements[send]; |
| 3294 bool isFixedList = false; | 3295 bool isFixedList = false; |
| 3295 bool isFixedListConstructorCall = Elements.isFixedListConstructorCall( | 3296 bool isFixedListConstructorCall = Elements.isFixedListConstructorCall( |
| 3296 elements[send], send, closedWorld.commonElements); | 3297 constructor, send, closedWorld.commonElements); |
| 3297 bool isGrowableListConstructorCall = Elements.isGrowableListConstructorCall( | 3298 bool isGrowableListConstructorCall = Elements.isGrowableListConstructorCall( |
| 3298 elements[send], send, closedWorld.commonElements); | 3299 constructor, send, closedWorld.commonElements); |
| 3299 | 3300 |
| 3300 TypeMask computeType(element) { | 3301 TypeMask computeType(element) { |
| 3301 Element originalElement = elements[send]; | 3302 ConstructorElement originalElement = elements[send]; |
| 3302 if (isFixedListConstructorCall || | 3303 if (isFixedListConstructorCall || |
| 3303 Elements.isFilledListConstructorCall( | 3304 Elements.isFilledListConstructorCall( |
| 3304 originalElement, send, closedWorld.commonElements)) { | 3305 originalElement, send, closedWorld.commonElements)) { |
| 3305 isFixedList = true; | 3306 isFixedList = true; |
| 3306 TypeMask inferred = _inferredTypeOfNewList(send); | 3307 TypeMask inferred = _inferredTypeOfNewList(send); |
| 3307 return inferred.containsAll(closedWorld) | 3308 return inferred.containsAll(closedWorld) |
| 3308 ? commonMasks.fixedArrayType | 3309 ? commonMasks.fixedArrayType |
| 3309 : inferred; | 3310 : inferred; |
| 3310 } else if (isGrowableListConstructorCall) { | 3311 } else if (isGrowableListConstructorCall) { |
| 3311 TypeMask inferred = _inferredTypeOfNewList(send); | 3312 TypeMask inferred = _inferredTypeOfNewList(send); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3328 return new TypeMask.nonNullEmpty(); | 3329 return new TypeMask.nonNullEmpty(); |
| 3329 } else { | 3330 } else { |
| 3330 return new TypeMask.nonNullExact(cls.thisType.element, closedWorld); | 3331 return new TypeMask.nonNullExact(cls.thisType.element, closedWorld); |
| 3331 } | 3332 } |
| 3332 } else { | 3333 } else { |
| 3333 return TypeMaskFactory.inferredReturnTypeForElement( | 3334 return TypeMaskFactory.inferredReturnTypeForElement( |
| 3334 originalElement, globalInferenceResults); | 3335 originalElement, globalInferenceResults); |
| 3335 } | 3336 } |
| 3336 } | 3337 } |
| 3337 | 3338 |
| 3338 Element constructor = elements[send]; | |
| 3339 CallStructure callStructure = elements.getSelector(send).callStructure; | 3339 CallStructure callStructure = elements.getSelector(send).callStructure; |
| 3340 ConstructorElement constructorDeclaration = constructor; | 3340 ConstructorElement constructorDeclaration = constructor; |
| 3341 ConstructorElement constructorImplementation = constructor.implementation; | 3341 ConstructorElement constructorImplementation = constructor.implementation; |
| 3342 constructor = constructorImplementation.effectiveTarget; | 3342 constructor = constructorImplementation.effectiveTarget; |
| 3343 | 3343 |
| 3344 final bool isSymbolConstructor = | 3344 final bool isSymbolConstructor = |
| 3345 closedWorld.commonElements.isSymbolConstructor(constructorDeclaration); | 3345 closedWorld.commonElements.isSymbolConstructor(constructorDeclaration); |
| 3346 final bool isJSArrayTypedConstructor = | 3346 final bool isJSArrayTypedConstructor = |
| 3347 constructorDeclaration == helpers.jsArrayTypedConstructor; | 3347 constructorDeclaration == helpers.jsArrayTypedConstructor; |
| 3348 | 3348 |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3812 internalError(Spannable node, String reason) { | 3812 internalError(Spannable node, String reason) { |
| 3813 reporter.internalError(node, reason); | 3813 reporter.internalError(node, reason); |
| 3814 } | 3814 } |
| 3815 | 3815 |
| 3816 void generateError(ast.Node node, String message, Element helper) { | 3816 void generateError(ast.Node node, String message, Element helper) { |
| 3817 HInstruction errorMessage = addConstantString(message); | 3817 HInstruction errorMessage = addConstantString(message); |
| 3818 pushInvokeStatic(node, helper, [errorMessage]); | 3818 pushInvokeStatic(node, helper, [errorMessage]); |
| 3819 } | 3819 } |
| 3820 | 3820 |
| 3821 void generateRuntimeError(ast.Node node, String message) { | 3821 void generateRuntimeError(ast.Node node, String message) { |
| 3822 generateError(node, message, helpers.throwRuntimeError); | 3822 MethodElement helper = helpers.throwRuntimeError; |
| 3823 generateError(node, message, helper); |
| 3823 } | 3824 } |
| 3824 | 3825 |
| 3825 void generateTypeError(ast.Node node, String message) { | 3826 void generateTypeError(ast.Node node, String message) { |
| 3826 generateError(node, message, helpers.throwTypeError); | 3827 MethodElement helper = helpers.throwTypeError; |
| 3828 generateError(node, message, helper); |
| 3827 } | 3829 } |
| 3828 | 3830 |
| 3829 void generateAbstractClassInstantiationError(ast.Node node, String message) { | 3831 void generateAbstractClassInstantiationError(ast.Node node, String message) { |
| 3830 generateError(node, message, helpers.throwAbstractClassInstantiationError); | 3832 MethodElement helper = helpers.throwAbstractClassInstantiationError; |
| 3833 generateError(node, message, helper); |
| 3831 } | 3834 } |
| 3832 | 3835 |
| 3833 void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName, | 3836 void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName, |
| 3834 {Link<ast.Node> argumentNodes, | 3837 {Link<ast.Node> argumentNodes, |
| 3835 List<HInstruction> argumentValues, | 3838 List<HInstruction> argumentValues, |
| 3836 List<String> existingArguments, | 3839 List<String> existingArguments, |
| 3837 SourceInformation sourceInformation}) { | 3840 SourceInformation sourceInformation}) { |
| 3838 Element helper = helpers.throwNoSuchMethod; | 3841 MethodElement helper = helpers.throwNoSuchMethod; |
| 3839 ConstantValue receiverConstant = | 3842 ConstantValue receiverConstant = |
| 3840 constantSystem.createString(new ast.DartString.empty()); | 3843 constantSystem.createString(new ast.DartString.empty()); |
| 3841 HInstruction receiver = graph.addConstant(receiverConstant, closedWorld); | 3844 HInstruction receiver = graph.addConstant(receiverConstant, closedWorld); |
| 3842 ast.DartString dartString = new ast.DartString.literal(methodName); | 3845 ast.DartString dartString = new ast.DartString.literal(methodName); |
| 3843 ConstantValue nameConstant = constantSystem.createString(dartString); | 3846 ConstantValue nameConstant = constantSystem.createString(dartString); |
| 3844 HInstruction name = graph.addConstant(nameConstant, closedWorld); | 3847 HInstruction name = graph.addConstant(nameConstant, closedWorld); |
| 3845 if (argumentValues == null) { | 3848 if (argumentValues == null) { |
| 3846 argumentValues = <HInstruction>[]; | 3849 argumentValues = <HInstruction>[]; |
| 3847 argumentNodes.forEach((argumentNode) { | 3850 argumentNodes.forEach((argumentNode) { |
| 3848 visit(argumentNode); | 3851 visit(argumentNode); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4080 // includes js interop types). | 4083 // includes js interop types). |
| 4081 if (type.element != null && backend.isNative(type.element)) { | 4084 if (type.element != null && backend.isNative(type.element)) { |
| 4082 nativeBehavior.typesInstantiated.add(type); | 4085 nativeBehavior.typesInstantiated.add(type); |
| 4083 } | 4086 } |
| 4084 | 4087 |
| 4085 // It also includes any other JS interop type if we don't trust the | 4088 // It also includes any other JS interop type if we don't trust the |
| 4086 // annotation or if is declared too broad. | 4089 // annotation or if is declared too broad. |
| 4087 if (!compiler.options.trustJSInteropTypeAnnotations || | 4090 if (!compiler.options.trustJSInteropTypeAnnotations || |
| 4088 type.isObject || | 4091 type.isObject || |
| 4089 type.isDynamic) { | 4092 type.isDynamic) { |
| 4090 nativeBehavior.typesInstantiated | 4093 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; |
| 4091 .add(backend.helpers.jsJavaScriptObjectClass.thisType); | 4094 nativeBehavior.typesInstantiated.add(cls.thisType); |
| 4092 } | 4095 } |
| 4093 | 4096 |
| 4094 String code; | 4097 String code; |
| 4095 if (element.isGetter) { | 4098 if (element.isGetter) { |
| 4096 code = "#"; | 4099 code = "#"; |
| 4097 } else if (element.isSetter) { | 4100 } else if (element.isSetter) { |
| 4098 code = "# = #"; | 4101 code = "# = #"; |
| 4099 } else { | 4102 } else { |
| 4100 var args = new List.filled(arguments.length, '#').join(','); | 4103 var args = new List.filled(arguments.length, '#').join(','); |
| 4101 code = element.isConstructor ? "new #($args)" : "#($args)"; | 4104 code = element.isConstructor ? "new #($args)" : "#($args)"; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4159 // instead. | 4162 // instead. |
| 4160 element.kind != ElementKind.FIELD) { | 4163 element.kind != ElementKind.FIELD) { |
| 4161 inputs.add(invokeInterceptor(receiver)); | 4164 inputs.add(invokeInterceptor(receiver)); |
| 4162 } | 4165 } |
| 4163 inputs.add(receiver); | 4166 inputs.add(receiver); |
| 4164 inputs.addAll(arguments); | 4167 inputs.addAll(arguments); |
| 4165 TypeMask type; | 4168 TypeMask type; |
| 4166 if (!element.isGetter && selector.isGetter) { | 4169 if (!element.isGetter && selector.isGetter) { |
| 4167 type = TypeMaskFactory.inferredTypeForElement( | 4170 type = TypeMaskFactory.inferredTypeForElement( |
| 4168 element, globalInferenceResults); | 4171 element, globalInferenceResults); |
| 4169 } else { | 4172 } else if (element.isFunction) { |
| 4170 type = TypeMaskFactory.inferredReturnTypeForElement( | 4173 type = TypeMaskFactory.inferredReturnTypeForElement( |
| 4171 element, globalInferenceResults); | 4174 element, globalInferenceResults); |
| 4175 } else { |
| 4176 type = closedWorld.commonMasks.dynamicType; |
| 4172 } | 4177 } |
| 4173 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, | 4178 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, |
| 4174 selector, inputs, type, sourceInformation, | 4179 selector, inputs, type, sourceInformation, |
| 4175 isSetter: selector.isSetter || selector.isIndexSet); | 4180 isSetter: selector.isSetter || selector.isIndexSet); |
| 4176 instruction.sideEffects = | 4181 instruction.sideEffects = |
| 4177 closedWorld.getSideEffectsOfSelector(selector, null); | 4182 closedWorld.getSideEffectsOfSelector(selector, null); |
| 4178 return instruction; | 4183 return instruction; |
| 4179 } | 4184 } |
| 4180 | 4185 |
| 4181 void handleComplexOperatorSend( | 4186 void handleComplexOperatorSend( |
| (...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5323 } | 5328 } |
| 5324 return new JumpHandler(this, element); | 5329 return new JumpHandler(this, element); |
| 5325 } | 5330 } |
| 5326 | 5331 |
| 5327 visitAsyncForIn(ast.AsyncForIn node) { | 5332 visitAsyncForIn(ast.AsyncForIn node) { |
| 5328 // The async-for is implemented with a StreamIterator. | 5333 // The async-for is implemented with a StreamIterator. |
| 5329 HInstruction streamIterator; | 5334 HInstruction streamIterator; |
| 5330 | 5335 |
| 5331 visit(node.expression); | 5336 visit(node.expression); |
| 5332 HInstruction expression = pop(); | 5337 HInstruction expression = pop(); |
| 5333 pushInvokeStatic(node, helpers.streamIteratorConstructor, | 5338 ConstructorElement constructor = helpers.streamIteratorConstructor; |
| 5334 [expression, graph.addConstantNull(closedWorld)]); | 5339 pushInvokeStatic( |
| 5340 node, constructor, [expression, graph.addConstantNull(closedWorld)]); |
| 5335 streamIterator = pop(); | 5341 streamIterator = pop(); |
| 5336 | 5342 |
| 5337 void buildInitializer() {} | 5343 void buildInitializer() {} |
| 5338 | 5344 |
| 5339 HInstruction buildCondition() { | 5345 HInstruction buildCondition() { |
| 5340 Selector selector = Selectors.moveNext; | 5346 Selector selector = Selectors.moveNext; |
| 5341 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); | 5347 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
| 5342 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 5348 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
| 5343 HInstruction future = pop(); | 5349 HInstruction future = pop(); |
| 5344 push(new HAwait(future, | 5350 push(new HAwait(future, |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5617 } | 5623 } |
| 5618 List<HInstruction> listInputs = <HInstruction>[]; | 5624 List<HInstruction> listInputs = <HInstruction>[]; |
| 5619 for (Link<ast.Node> link = node.entries.nodes; | 5625 for (Link<ast.Node> link = node.entries.nodes; |
| 5620 !link.isEmpty; | 5626 !link.isEmpty; |
| 5621 link = link.tail) { | 5627 link = link.tail) { |
| 5622 visit(link.head); | 5628 visit(link.head); |
| 5623 listInputs.add(pop()); | 5629 listInputs.add(pop()); |
| 5624 listInputs.add(pop()); | 5630 listInputs.add(pop()); |
| 5625 } | 5631 } |
| 5626 | 5632 |
| 5627 Element constructor; | 5633 ConstructorElement listConstructor; |
| 5628 List<HInstruction> inputs = <HInstruction>[]; | 5634 List<HInstruction> inputs = <HInstruction>[]; |
| 5629 | 5635 |
| 5630 if (listInputs.isEmpty) { | 5636 if (listInputs.isEmpty) { |
| 5631 constructor = helpers.mapLiteralConstructorEmpty; | 5637 listConstructor = helpers.mapLiteralConstructorEmpty; |
| 5632 } else { | 5638 } else { |
| 5633 constructor = helpers.mapLiteralConstructor; | 5639 listConstructor = helpers.mapLiteralConstructor; |
| 5634 HLiteralList keyValuePairs = buildLiteralList(listInputs); | 5640 HLiteralList keyValuePairs = buildLiteralList(listInputs); |
| 5635 add(keyValuePairs); | 5641 add(keyValuePairs); |
| 5636 inputs.add(keyValuePairs); | 5642 inputs.add(keyValuePairs); |
| 5637 } | 5643 } |
| 5638 | 5644 |
| 5639 assert(constructor.isFactoryConstructor); | 5645 assert(listConstructor.isFactoryConstructor); |
| 5640 | 5646 |
| 5641 ConstructorElement functionElement = constructor; | 5647 ConstructorElement constructorElement = listConstructor; |
| 5642 constructor = functionElement.effectiveTarget; | 5648 listConstructor = constructorElement.effectiveTarget; |
| 5643 | 5649 |
| 5644 ResolutionInterfaceType type = elements.getType(node); | 5650 ResolutionInterfaceType type = elements.getType(node); |
| 5645 ResolutionInterfaceType expectedType = | 5651 ResolutionInterfaceType expectedType = |
| 5646 functionElement.computeEffectiveTargetType(type); | 5652 constructorElement.computeEffectiveTargetType(type); |
| 5647 expectedType = localsHandler.substInContext(expectedType); | 5653 expectedType = localsHandler.substInContext(expectedType); |
| 5648 | 5654 |
| 5649 ClassElement cls = constructor.enclosingClass; | 5655 ClassElement cls = listConstructor.enclosingClass; |
| 5650 | 5656 |
| 5657 MethodElement createFunction = listConstructor; |
| 5651 if (backend.classNeedsRti(cls)) { | 5658 if (backend.classNeedsRti(cls)) { |
| 5652 List<HInstruction> typeInputs = <HInstruction>[]; | 5659 List<HInstruction> typeInputs = <HInstruction>[]; |
| 5653 expectedType.typeArguments.forEach((ResolutionDartType argument) { | 5660 expectedType.typeArguments.forEach((ResolutionDartType argument) { |
| 5654 typeInputs | 5661 typeInputs |
| 5655 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); | 5662 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); |
| 5656 }); | 5663 }); |
| 5657 | 5664 |
| 5658 // We lift this common call pattern into a helper function to save space | 5665 // We lift this common call pattern into a helper function to save space |
| 5659 // in the output. | 5666 // in the output. |
| 5660 if (typeInputs.every((HInstruction input) => input.isNull())) { | 5667 if (typeInputs.every((HInstruction input) => input.isNull())) { |
| 5661 if (listInputs.isEmpty) { | 5668 if (listInputs.isEmpty) { |
| 5662 constructor = helpers.mapLiteralUntypedEmptyMaker; | 5669 createFunction = helpers.mapLiteralUntypedEmptyMaker; |
| 5663 } else { | 5670 } else { |
| 5664 constructor = helpers.mapLiteralUntypedMaker; | 5671 createFunction = helpers.mapLiteralUntypedMaker; |
| 5665 } | 5672 } |
| 5666 } else { | 5673 } else { |
| 5667 inputs.addAll(typeInputs); | 5674 inputs.addAll(typeInputs); |
| 5668 } | 5675 } |
| 5669 } | 5676 } |
| 5670 | 5677 |
| 5671 // If rti is needed and the map literal has no type parameters, | 5678 // If rti is needed and the map literal has no type parameters, |
| 5672 // 'constructor' is a static function that forwards the call to the factory | 5679 // 'constructor' is a static function that forwards the call to the factory |
| 5673 // constructor without type parameters. | 5680 // constructor without type parameters. |
| 5674 assert(constructor is ConstructorElement || constructor is FunctionElement); | 5681 assert(createFunction is ConstructorElement || |
| 5682 createFunction is FunctionElement); |
| 5675 | 5683 |
| 5676 // The instruction type will always be a subtype of the mapLiteralClass, but | 5684 // The instruction type will always be a subtype of the mapLiteralClass, but |
| 5677 // type inference might discover a more specific type, or find nothing (in | 5685 // type inference might discover a more specific type, or find nothing (in |
| 5678 // dart2js unit tests). | 5686 // dart2js unit tests). |
| 5679 TypeMask mapType = | 5687 TypeMask mapType = |
| 5680 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, closedWorld); | 5688 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, closedWorld); |
| 5681 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( | 5689 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( |
| 5682 constructor, globalInferenceResults); | 5690 createFunction, globalInferenceResults); |
| 5683 TypeMask instructionType = | 5691 TypeMask instructionType = |
| 5684 mapType.intersection(returnTypeMask, closedWorld); | 5692 mapType.intersection(returnTypeMask, closedWorld); |
| 5685 | 5693 |
| 5686 addInlinedInstantiation(expectedType); | 5694 addInlinedInstantiation(expectedType); |
| 5687 pushInvokeStatic(node, constructor, inputs, | 5695 pushInvokeStatic(node, createFunction, inputs, |
| 5688 typeMask: instructionType, instanceType: expectedType); | 5696 typeMask: instructionType, instanceType: expectedType); |
| 5689 removeInlinedInstantiation(expectedType); | 5697 removeInlinedInstantiation(expectedType); |
| 5690 } | 5698 } |
| 5691 | 5699 |
| 5692 visitLiteralMapEntry(ast.LiteralMapEntry node) { | 5700 visitLiteralMapEntry(ast.LiteralMapEntry node) { |
| 5693 visit(node.value); | 5701 visit(node.value); |
| 5694 visit(node.key); | 5702 visit(node.key); |
| 5695 } | 5703 } |
| 5696 | 5704 |
| 5697 visitNamedArgument(ast.NamedArgument node) { | 5705 visitNamedArgument(ast.NamedArgument node) { |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6722 this.oldReturnLocal, | 6730 this.oldReturnLocal, |
| 6723 this.oldReturnType, | 6731 this.oldReturnType, |
| 6724 this.oldResolvedAst, | 6732 this.oldResolvedAst, |
| 6725 this.oldStack, | 6733 this.oldStack, |
| 6726 this.oldLocalsHandler, | 6734 this.oldLocalsHandler, |
| 6727 this.inTryStatement, | 6735 this.inTryStatement, |
| 6728 this.allFunctionsCalledOnce, | 6736 this.allFunctionsCalledOnce, |
| 6729 this.oldElementInferenceResults) | 6737 this.oldElementInferenceResults) |
| 6730 : super(function); | 6738 : super(function); |
| 6731 } | 6739 } |
| OLD | NEW |