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

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

Powered by Google App Engine
This is Rietveld 408576698