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

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

Issue 2260223002: Add SSA instructions for reified type information (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: reformat Created 4 years, 4 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 2309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 // if there are field initializers. 2320 // if there are field initializers.
2321 add(new HFieldGet(null, newObject, backend.dynamicType, 2321 add(new HFieldGet(null, newObject, backend.dynamicType,
2322 isAssignable: false)); 2322 isAssignable: false));
2323 for (int i = 0; i < fields.length; i++) { 2323 for (int i = 0; i < fields.length; i++) {
2324 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); 2324 add(new HFieldSet(fields[i], newObject, constructorArguments[i]));
2325 } 2325 }
2326 } 2326 }
2327 removeInlinedInstantiation(type); 2327 removeInlinedInstantiation(type);
2328 // Create the runtime type information, if needed. 2328 // Create the runtime type information, if needed.
2329 if (backend.classNeedsRti(classElement)) { 2329 if (backend.classNeedsRti(classElement)) {
2330 // Read the values of the type arguments and create a list to set on the 2330 // Read the values of the type arguments and create a HTypeInfoExpression
2331 // newly create object. We can identify the case where the new list 2331 // to set on the newly create object. We can identify the case where the
2332 // would be of the form: 2332 // expression would be of the form:
2333 //
2333 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] 2334 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)]
2335 //
2334 // and k is the number of type arguments of this. If this is the case, 2336 // and k is the number of type arguments of this. If this is the case,
2335 // we can simply copy the list from this. 2337 // we can simply copy the list from this.
2336 2338
2337 // These locals are modified by [isIndexedTypeArgumentGet]. 2339 // These locals are modified by [isIndexedTypeArgumentGet].
2338 HThis source; // The source of the type arguments. 2340 HThis source; // The source of the type arguments.
2339 bool allIndexed = true; 2341 bool allIndexed = true;
2340 int expectedIndex = 0; 2342 int expectedIndex = 0;
2341 ClassElement contextClass; // The class of `this`. 2343 ClassElement contextClass; // The class of `this`.
2342 int remainingTypeVariables; // The number of 'remaining type variables' 2344 int remainingTypeVariables; // The number of 'remaining type variables'
2343 // of `this`. 2345 // of `this`.
2344 2346
2345 /// Helper to identify instructions that read a type variable without 2347 /// Helper to identify instructions that read a type variable without
2346 /// substitution (that is, directly use the index). These instructions 2348 /// substitution (that is, directly use the index). These are
2347 /// are of the form: 2349 /// HTypeInfoReadVariable instructions that require no substitution.
2348 /// HInvokeStatic(getTypeArgumentByIndex, this, index)
2349 /// 2350 ///
2350 /// Return `true` if [instruction] is of that form and the index is the 2351 /// Return `true` if [instruction] is of that form and the index is the
2351 /// next index in the sequence (held in [expectedIndex]). 2352 /// next index in the sequence (held in [expectedIndex]).
2353
2354 /// TODO: Move this to a simplifier optimization of HTypeInfoExpression.
2352 bool isIndexedTypeArgumentGet(HInstruction instruction) { 2355 bool isIndexedTypeArgumentGet(HInstruction instruction) {
2353 if (instruction is! HInvokeStatic) return false; 2356 if (instruction is HTypeInfoReadVariable) {
2354 HInvokeStatic invoke = instruction; 2357 HInstruction newSource = instruction.inputs[0];
2355 if (invoke.element != helpers.getTypeArgumentByIndex) { 2358 if (newSource is! HThis) {
2356 return false; 2359 return false;
2360 }
2361 if (source == null) {
2362 // This is the first match. Extract the context class for the type
2363 // variables and get the list of type variables to keep track of how
2364 // many arguments we need to process.
2365 source = newSource;
2366 contextClass = source.sourceElement.enclosingClass;
2367 if (needsSubstitutionForTypeVariableAccess(contextClass)) {
2368 return false;
2369 }
2370 remainingTypeVariables = contextClass.typeVariables.length;
2371 } else {
2372 assert(source == newSource);
2373 }
2374 // If there are no more type variables, then there are more type
2375 // arguments for the new object than the source has, and it can't be
2376 // a copy. Otherwise remove one argument.
2377 if (remainingTypeVariables == 0) return false;
2378 remainingTypeVariables--;
2379 // Check that the index is the one we expect.
2380 int index = instruction.variable.element.index;
2381 return index == expectedIndex++;
2357 } 2382 }
2358 HConstant index = invoke.inputs[1]; 2383 return false;
2359 HInstruction newSource = invoke.inputs[0];
2360 if (newSource is! HThis) {
2361 return false;
2362 }
2363 if (source == null) {
2364 // This is the first match. Extract the context class for the type
2365 // variables and get the list of type variables to keep track of how
2366 // many arguments we need to process.
2367 source = newSource;
2368 contextClass = source.sourceElement.enclosingClass;
2369 remainingTypeVariables = contextClass.typeVariables.length;
2370 } else {
2371 assert(source == newSource);
2372 }
2373 // If there are no more type variables, then there are more type
2374 // arguments for the new object than the source has, and it can't be
2375 // a copy. Otherwise remove one argument.
2376 if (remainingTypeVariables == 0) return false;
2377 remainingTypeVariables--;
2378 // Check that the index is the one we expect.
2379 IntConstantValue constant = index.constant;
2380 return constant.primitiveValue == expectedIndex++;
2381 } 2384 }
2382 2385
2383 List<HInstruction> typeArguments = <HInstruction>[]; 2386 List<HInstruction> typeArguments = <HInstruction>[];
2384 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 2387 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
2385 HInstruction argument = localsHandler 2388 HInstruction argument = localsHandler
2386 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); 2389 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
2387 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { 2390 if (allIndexed && !isIndexedTypeArgumentGet(argument)) {
2388 allIndexed = false; 2391 allIndexed = false;
2389 } 2392 }
2390 typeArguments.add(argument); 2393 typeArguments.add(argument);
2391 }); 2394 });
2392 2395
2393 if (source != null && allIndexed && remainingTypeVariables == 0) { 2396 if (source != null && allIndexed && remainingTypeVariables == 0) {
2394 copyRuntimeTypeInfo(source, newObject); 2397 HInstruction typeInfo =
2398 new HTypeInfoReadRaw(source, backend.dynamicType);
2399 add(typeInfo);
2400 newObject = callSetRuntimeTypeInfo(typeInfo, newObject);
2395 } else { 2401 } else {
2396 newObject = 2402 HInstruction typeInfo = new HTypeInfoExpression(
2397 callSetRuntimeTypeInfo(classElement, typeArguments, newObject); 2403 TypeInfoExpressionKind.INSTANCE,
2404 classElement.thisType,
2405 typeArguments,
2406 backend.dynamicType);
2407 add(typeInfo);
2408 newObject = callSetRuntimeTypeInfo(typeInfo, newObject);
2398 } 2409 }
2399 } 2410 }
2400 2411
2401 // Generate calls to the constructor bodies. 2412 // Generate calls to the constructor bodies.
2402 HInstruction interceptor = null; 2413 HInstruction interceptor = null;
2403 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { 2414 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) {
2404 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; 2415 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index];
2405 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); 2416 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst);
2406 if (body == null) continue; 2417 if (body == null) continue;
2407 2418
(...skipping 2295 matching lines...) Expand 10 before | Expand all | Expand 10 after
4703 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { 4714 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
4704 ClassWorld classWorld = compiler.world; 4715 ClassWorld classWorld = compiler.world;
4705 if (classWorld.isUsedAsMixin(cls)) return true; 4716 if (classWorld.isUsedAsMixin(cls)) return true;
4706 4717
4707 return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) { 4718 return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) {
4708 return !rti.isTrivialSubstitution(subclass, cls); 4719 return !rti.isTrivialSubstitution(subclass, cls);
4709 }); 4720 });
4710 } 4721 }
4711 4722
4712 /** 4723 /**
4713 * Generate code to extract the type arguments from the object, substitute 4724 * Generate code to extract the type argument from the object.
4714 * them as an instance of the type we are testing against (if necessary), and
4715 * extract the type argument by the index of the variable in the list of type
4716 * variables for that class.
4717 */ 4725 */
4718 HInstruction readTypeVariable(ClassElement cls, TypeVariableElement variable, 4726 HInstruction readTypeVariable(TypeVariableType variable,
4719 {SourceInformation sourceInformation}) { 4727 {SourceInformation sourceInformation}) {
4720 assert(sourceElement.isInstanceMember); 4728 assert(sourceElement.isInstanceMember);
4721 4729 assert(variable is! MethodTypeVariableType);
4722 HInstruction target = localsHandler.readThis(); 4730 HInstruction target = localsHandler.readThis();
4723 HConstant index = graph.addConstantInt(variable.index, compiler); 4731 push(new HTypeInfoReadVariable(variable, target, backend.dynamicType)
4724 4732 ..sourceInformation = sourceInformation);
4725 if (needsSubstitutionForTypeVariableAccess(cls)) {
4726 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to
4727 // string concatenation in the implementation), and may prevent
4728 // segmentation of '$'.
4729 js.Name substitutionName = backend.namer.runtimeTypeName(cls);
4730 HInstruction substitutionNameInstr =
4731 graph.addConstantStringFromName(substitutionName, compiler);
4732 pushInvokeStatic(null, helpers.getRuntimeTypeArgument,
4733 [target, substitutionNameInstr, index],
4734 typeMask: backend.dynamicType, sourceInformation: sourceInformation);
4735 } else {
4736 pushInvokeStatic(null, helpers.getTypeArgumentByIndex, [target, index],
4737 typeMask: backend.dynamicType, sourceInformation: sourceInformation);
4738 }
4739 return pop(); 4733 return pop();
4740 } 4734 }
4741 4735
4742 // TODO(karlklose): this is needed to avoid a bug where the resolved type is 4736 // TODO(karlklose): this is needed to avoid a bug where the resolved type is
4743 // not stored on a type annotation in the closure translator. Remove when 4737 // not stored on a type annotation in the closure translator. Remove when
4744 // fixed. 4738 // fixed.
4745 bool hasDirectLocal(Local local) { 4739 bool hasDirectLocal(Local local) {
4746 return !localsHandler.isAccessedDirectly(local) || 4740 return !localsHandler.isAccessedDirectly(local) ||
4747 localsHandler.directLocals[local] != null; 4741 localsHandler.directLocals[local] != null;
4748 } 4742 }
4749 4743
4750 /** 4744 /**
4751 * Helper to create an instruction that gets the value of a type variable. 4745 * Helper to create an instruction that gets the value of a type variable.
4752 */ 4746 */
4753 HInstruction addTypeVariableReference(TypeVariableType type, 4747 HInstruction addTypeVariableReference(TypeVariableType type,
4754 {SourceInformation sourceInformation}) { 4748 {SourceInformation sourceInformation}) {
4755 assert(assertTypeInContext(type)); 4749 assert(assertTypeInContext(type));
4750 if (type is MethodTypeVariableType) {
4751 return graph.addConstantNull(compiler);
4752 }
4756 Element member = sourceElement; 4753 Element member = sourceElement;
4757 bool isClosure = member.enclosingElement.isClosure; 4754 bool isClosure = member.enclosingElement.isClosure;
4758 if (isClosure) { 4755 if (isClosure) {
4759 ClosureClassElement closureClass = member.enclosingElement; 4756 ClosureClassElement closureClass = member.enclosingElement;
4760 member = closureClass.methodElement; 4757 member = closureClass.methodElement;
4761 member = member.outermostEnclosingMemberOrTopLevel; 4758 member = member.outermostEnclosingMemberOrTopLevel;
4762 } 4759 }
4763 bool isInConstructorContext = 4760 bool isInConstructorContext =
4764 member.isConstructor || member.isGenerativeConstructorBody; 4761 member.isConstructor || member.isGenerativeConstructorBody;
4765 Local typeVariableLocal = localsHandler.getTypeVariableAsLocal(type); 4762 Local typeVariableLocal = localsHandler.getTypeVariableAsLocal(type);
4766 if (isClosure) { 4763 if (isClosure) {
4767 if (member.isFactoryConstructor || 4764 if (member.isFactoryConstructor ||
4768 (isInConstructorContext && hasDirectLocal(typeVariableLocal))) { 4765 (isInConstructorContext && hasDirectLocal(typeVariableLocal))) {
4769 // The type variable is used from a closure in a factory constructor. 4766 // The type variable is used from a closure in a factory constructor.
4770 // The value of the type argument is stored as a local on the closure 4767 // The value of the type argument is stored as a local on the closure
4771 // itself. 4768 // itself.
4772 return localsHandler.readLocal(typeVariableLocal, 4769 return localsHandler.readLocal(typeVariableLocal,
4773 sourceInformation: sourceInformation); 4770 sourceInformation: sourceInformation);
4774 } else if (member.isFunction || 4771 } else if (member.isFunction ||
4775 member.isGetter || 4772 member.isGetter ||
4776 member.isSetter || 4773 member.isSetter ||
4777 isInConstructorContext) { 4774 isInConstructorContext) {
4778 // The type variable is stored on the "enclosing object" and needs to be 4775 // The type variable is stored on the "enclosing object" and needs to be
4779 // accessed using the this-reference in the closure. 4776 // accessed using the this-reference in the closure.
4780 return readTypeVariable(member.enclosingClass, type.element, 4777 return readTypeVariable(type, sourceInformation: sourceInformation);
4781 sourceInformation: sourceInformation);
4782 } else { 4778 } else {
4783 assert(member.isField); 4779 assert(member.isField);
4784 // The type variable is stored in a parameter of the method. 4780 // The type variable is stored in a parameter of the method.
4785 return localsHandler.readLocal(typeVariableLocal); 4781 return localsHandler.readLocal(typeVariableLocal);
4786 } 4782 }
4787 } else if (isInConstructorContext || 4783 } else if (isInConstructorContext ||
4788 // When [member] is a field, we can be either 4784 // When [member] is a field, we can be either
4789 // generating a checked setter or inlining its 4785 // generating a checked setter or inlining its
4790 // initializer in a constructor. An initializer is 4786 // initializer in a constructor. An initializer is
4791 // never built standalone, so in that case [target] is not 4787 // never built standalone, so in that case [target] is not
4792 // the [member] itself. 4788 // the [member] itself.
4793 (member.isField && member != target)) { 4789 (member.isField && member != target)) {
4794 // The type variable is stored in a parameter of the method. 4790 // The type variable is stored in a parameter of the method.
4795 return localsHandler.readLocal(typeVariableLocal, 4791 return localsHandler.readLocal(typeVariableLocal,
4796 sourceInformation: sourceInformation); 4792 sourceInformation: sourceInformation);
4797 } else if (member.isInstanceMember) { 4793 } else if (member.isInstanceMember) {
4798 // The type variable is stored on the object. 4794 // The type variable is stored on the object.
4799 return readTypeVariable(member.enclosingClass, type.element, 4795 return readTypeVariable(type, sourceInformation: sourceInformation);
4800 sourceInformation: sourceInformation);
4801 } else { 4796 } else {
4802 reporter.internalError( 4797 reporter.internalError(
4803 type.element, 'Unexpected type variable in static context.'); 4798 type.element, 'Unexpected type variable in static context.');
4804 return null; 4799 return null;
4805 } 4800 }
4806 } 4801 }
4807 4802
4808 HInstruction analyzeTypeArgument(DartType argument, 4803 HInstruction analyzeTypeArgument(DartType argument,
4809 {SourceInformation sourceInformation}) { 4804 {SourceInformation sourceInformation}) {
4810 assert(assertTypeInContext(argument)); 4805 assert(assertTypeInContext(argument));
4811 if (argument.treatAsDynamic) { 4806 if (argument.treatAsDynamic) {
4812 // Represent [dynamic] as [null]. 4807 // Represent [dynamic] as [null].
4813 return graph.addConstantNull(compiler); 4808 return graph.addConstantNull(compiler);
4814 } 4809 }
4815 4810
4816 if (argument.isTypeVariable) { 4811 if (argument.isTypeVariable) {
4817 return addTypeVariableReference(argument, 4812 return addTypeVariableReference(argument,
4818 sourceInformation: sourceInformation); 4813 sourceInformation: sourceInformation);
4819 } 4814 }
4820 4815
4821 List<HInstruction> inputs = <HInstruction>[]; 4816 List<HInstruction> inputs = <HInstruction>[];
4822 4817 argument.forEachTypeVariable((variable) {
4823 js.Expression template = 4818 if (variable is! MethodTypeVariableType) {
4824 rtiEncoder.getTypeRepresentationWithPlaceholders(argument, (variable) { 4819 inputs.add(analyzeTypeArgument(variable));
4825 inputs.add(addTypeVariableReference(variable)); 4820 }
4826 }); 4821 });
4827 4822 HInstruction result = new HTypeInfoExpression(
4828 js.Template code = new js.Template(null, template); 4823 TypeInfoExpressionKind.COMPLETE, argument, inputs, backend.dynamicType)
4829 HInstruction result = new HForeignCode(code, backend.stringType, inputs, 4824 ..sourceInformation = sourceInformation;
4830 nativeBehavior: native.NativeBehavior.PURE);
4831 add(result); 4825 add(result);
4832 return result; 4826 return result;
4833 } 4827 }
4834 4828
4835 HInstruction handleListConstructor( 4829 HInstruction handleListConstructor(
4836 InterfaceType type, ast.Node currentNode, HInstruction newObject) { 4830 InterfaceType type, ast.Node currentNode, HInstruction newObject) {
4837 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 4831 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
4838 return newObject; 4832 return newObject;
4839 } 4833 }
4840 List<HInstruction> inputs = <HInstruction>[]; 4834 List<HInstruction> inputs = <HInstruction>[];
4841 type = localsHandler.substInContext(type); 4835 type = localsHandler.substInContext(type);
4842 type.typeArguments.forEach((DartType argument) { 4836 type.typeArguments.forEach((DartType argument) {
4843 inputs.add(analyzeTypeArgument(argument)); 4837 inputs.add(analyzeTypeArgument(argument));
4844 }); 4838 });
4845 // TODO(15489): Register at codegen. 4839 // TODO(15489): Register at codegen.
4846 registry?.registerInstantiation(type); 4840 registry?.registerInstantiation(type);
4847 return callSetRuntimeTypeInfo(type.element, inputs, newObject); 4841 return callSetRuntimeTypeInfoWithTypeArguments(
4842 type.element, inputs, newObject);
4848 } 4843 }
4849 4844
4850 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { 4845 HInstruction callSetRuntimeTypeInfoWithTypeArguments(ClassElement element,
4851 Element copyHelper = helpers.copyTypeArguments;
4852 pushInvokeStatic(null, copyHelper, [source, target],
4853 sourceInformation: target.sourceInformation);
4854 pop();
4855 }
4856
4857 HInstruction callSetRuntimeTypeInfo(ClassElement element,
4858 List<HInstruction> rtiInputs, HInstruction newObject) { 4846 List<HInstruction> rtiInputs, HInstruction newObject) {
4859 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { 4847 if (!backend.classNeedsRti(element)) {
4860 return newObject; 4848 return newObject;
4861 } 4849 }
4862 4850
4863 HInstruction typeInfo = buildLiteralList(rtiInputs); 4851 HInstruction typeInfo = new HTypeInfoExpression(
4852 TypeInfoExpressionKind.INSTANCE,
4853 element.thisType,
4854 rtiInputs,
4855 backend.dynamicType);
4864 add(typeInfo); 4856 add(typeInfo);
4857 return callSetRuntimeTypeInfo(typeInfo, newObject);
4858 }
4865 4859
4860 HInstruction callSetRuntimeTypeInfo(
4861 HInstruction typeInfo, HInstruction newObject) {
4866 // Set the runtime type information on the object. 4862 // Set the runtime type information on the object.
4867 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; 4863 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo;
4868 pushInvokeStatic( 4864 pushInvokeStatic(
4869 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], 4865 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo],
4870 typeMask: backend.dynamicType, 4866 typeMask: backend.dynamicType,
4871 sourceInformation: newObject.sourceInformation); 4867 sourceInformation: newObject.sourceInformation);
4872 4868
4873 // The new object will now be referenced through the 4869 // The new object will now be referenced through the
4874 // `setRuntimeTypeInfo` call. We therefore set the type of that 4870 // `setRuntimeTypeInfo` call. We therefore set the type of that
4875 // instruction to be of the object's type. 4871 // instruction to be of the object's type.
4876 assert(invariant(CURRENT_ELEMENT_SPANNABLE, 4872 assert(invariant(CURRENT_ELEMENT_SPANNABLE,
4877 stack.last is HInvokeStatic || stack.last == newObject, 4873 stack.last is HInvokeStatic || stack.last == newObject,
4878 message: "Unexpected `stack.last`: Found ${stack.last}, " 4874 message: "Unexpected `stack.last`: Found ${stack.last}, "
4879 "expected ${newObject} or an HInvokeStatic. " 4875 "expected ${newObject} or an HInvokeStatic. "
4880 "State: element=$element, rtiInputs=$rtiInputs, stack=$stack.")); 4876 "State: typeInfo=$typeInfo, stack=$stack."));
4881 stack.last.instructionType = newObject.instructionType; 4877 stack.last.instructionType = newObject.instructionType;
4882 return pop(); 4878 return pop();
4883 } 4879 }
4884 4880
4885 void handleNewSend(ast.NewExpression node) { 4881 void handleNewSend(ast.NewExpression node) {
4886 ast.Send send = node.send; 4882 ast.Send send = node.send;
4887 generateIsDeferredLoadedCheckOfSend(send); 4883 generateIsDeferredLoadedCheckOfSend(send);
4888 4884
4889 bool isFixedList = false; 4885 bool isFixedList = false;
4890 bool isFixedListConstructorCall = 4886 bool isFixedListConstructorCall =
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
5096 pop(); 5092 pop();
5097 stack.add(checked); 5093 stack.add(checked);
5098 } 5094 }
5099 } 5095 }
5100 } 5096 }
5101 5097
5102 void potentiallyAddTypeArguments( 5098 void potentiallyAddTypeArguments(
5103 List<HInstruction> inputs, ClassElement cls, InterfaceType expectedType, 5099 List<HInstruction> inputs, ClassElement cls, InterfaceType expectedType,
5104 {SourceInformation sourceInformation}) { 5100 {SourceInformation sourceInformation}) {
5105 if (!backend.classNeedsRti(cls)) return; 5101 if (!backend.classNeedsRti(cls)) return;
5106 assert(expectedType.typeArguments.isEmpty || 5102 assert(cls.typeVariables.length == expectedType.typeArguments.length);
5107 cls.typeVariables.length == expectedType.typeArguments.length);
5108 expectedType.typeArguments.forEach((DartType argument) { 5103 expectedType.typeArguments.forEach((DartType argument) {
5109 inputs.add( 5104 inputs.add(
5110 analyzeTypeArgument(argument, sourceInformation: sourceInformation)); 5105 analyzeTypeArgument(argument, sourceInformation: sourceInformation));
5111 }); 5106 });
5112 } 5107 }
5113 5108
5114 /// In checked mode checks the [type] of [node] to be well-bounded. The method 5109 /// In checked mode checks the [type] of [node] to be well-bounded. The method
5115 /// returns [:true:] if an error can be statically determined. 5110 /// returns [:true:] if an error can be statically determined.
5116 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { 5111 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) {
5117 if (!compiler.options.enableTypeAssertions) return false; 5112 if (!compiler.options.enableTypeAssertions) return false;
(...skipping 1689 matching lines...) Expand 10 before | Expand all | Expand 10 after
6807 InterfaceType type = localsHandler.substInContext(elements.getType(node)); 6802 InterfaceType type = localsHandler.substInContext(elements.getType(node));
6808 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 6803 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
6809 return object; 6804 return object;
6810 } 6805 }
6811 List<HInstruction> arguments = <HInstruction>[]; 6806 List<HInstruction> arguments = <HInstruction>[];
6812 for (DartType argument in type.typeArguments) { 6807 for (DartType argument in type.typeArguments) {
6813 arguments.add(analyzeTypeArgument(argument)); 6808 arguments.add(analyzeTypeArgument(argument));
6814 } 6809 }
6815 // TODO(15489): Register at codegen. 6810 // TODO(15489): Register at codegen.
6816 registry?.registerInstantiation(type); 6811 registry?.registerInstantiation(type);
6817 return callSetRuntimeTypeInfo(type.element, arguments, object); 6812 return callSetRuntimeTypeInfoWithTypeArguments(
6813 type.element, arguments, object);
6818 } 6814 }
6819 6815
6820 visitLiteralList(ast.LiteralList node) { 6816 visitLiteralList(ast.LiteralList node) {
6821 HInstruction instruction; 6817 HInstruction instruction;
6822 6818
6823 if (node.isConst) { 6819 if (node.isConst) {
6824 instruction = addConstant(node); 6820 instruction = addConstant(node);
6825 } else { 6821 } else {
6826 List<HInstruction> inputs = <HInstruction>[]; 6822 List<HInstruction> inputs = <HInstruction>[];
6827 for (Link<ast.Node> link = node.elements.nodes; 6823 for (Link<ast.Node> link = node.elements.nodes;
(...skipping 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after
8659 const _LoopTypeVisitor(); 8655 const _LoopTypeVisitor();
8660 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; 8656 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
8661 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; 8657 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
8662 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; 8658 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
8663 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; 8659 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
8664 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8660 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8665 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8661 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8666 int visitSwitchStatement(ast.SwitchStatement node) => 8662 int visitSwitchStatement(ast.SwitchStatement node) =>
8667 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 8663 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
8668 } 8664 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend_impact.dart ('k') | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698