Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 2675103003: Refactor BackendHelpers to be reusageable with KernelWorldBuilder (Closed)
Patch Set: Updated cf. comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/serialization/equivalence.dart ('k') | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698