| Index: pkg/compiler/lib/src/ssa/builder.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
|
| index 90a5c04c737d5c900ff4a304bd44eb1f9c4a9cb4..96af76e61510e5a5eed8a14abb2f9d1bc92dc5c9 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder.dart
|
| @@ -36,7 +36,7 @@ import '../types/types.dart';
|
| import '../universe/call_structure.dart' show CallStructure;
|
| import '../universe/selector.dart' show Selector;
|
| import '../universe/side_effects.dart' show SideEffects;
|
| -import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
|
| +import '../universe/use.dart' show DynamicUse, StaticUse;
|
| import '../util/util.dart';
|
| import '../world.dart' show ClosedWorld;
|
|
|
| @@ -47,6 +47,7 @@ import 'loop_handler.dart';
|
| import 'nodes.dart';
|
| import 'optimize.dart';
|
| import 'ssa_branch_builder.dart';
|
| +import 'type_builder.dart';
|
| import 'types.dart';
|
|
|
| class SsaBuilderTask extends CompilerTask {
|
| @@ -188,6 +189,9 @@ class SsaBuilder extends ast.Visitor
|
| /// Handles the building of loops.
|
| LoopHandler<ast.Node> loopHandler;
|
|
|
| + /// Handles type check building.
|
| + TypeBuilder typeBuilder;
|
| +
|
| // TODO(sigmund): make most args optional
|
| SsaBuilder(
|
| this.target,
|
| @@ -213,6 +217,7 @@ class SsaBuilder extends ast.Visitor
|
| sourceInformationBuilder.buildVariableDeclaration();
|
| localsHandler = new LocalsHandler(this, target, null, compiler);
|
| loopHandler = new SsaLoopHandler(this);
|
| + typeBuilder = new TypeBuilder(this);
|
| }
|
|
|
| BackendHelpers get helpers => backend.helpers;
|
| @@ -223,6 +228,8 @@ class SsaBuilder extends ast.Visitor
|
|
|
| CoreClasses get coreClasses => compiler.coreClasses;
|
|
|
| + Element get targetElement => target;
|
| +
|
| /// Reference to resolved elements in [target]'s AST.
|
| TreeElements get elements => resolvedAst.elements;
|
|
|
| @@ -244,6 +251,7 @@ class SsaBuilder extends ast.Visitor
|
| /// The returned element is a declaration element.
|
| // TODO(johnniwinther): Check that all usages of sourceElement agree on
|
| // implementation/declaration distinction.
|
| + @override
|
| Element get sourceElement => sourceElementStack.last;
|
|
|
| /// Helper to retrieve global inference results for [element] with special
|
| @@ -257,10 +265,6 @@ class SsaBuilder extends ast.Visitor
|
| inferenceResults.resultOf(
|
| element is ConstructorBodyElementX ? element.constructor : element);
|
|
|
| - bool get _checkOrTrustTypes =>
|
| - compiler.options.enableTypeAssertions ||
|
| - compiler.options.trustTypeAnnotations;
|
| -
|
| /// Build the graph for [target].
|
| HGraph build() {
|
| assert(invariant(target, target.isImplementation));
|
| @@ -294,6 +298,25 @@ class SsaBuilder extends ast.Visitor
|
| add(attachPosition(instruction, node));
|
| }
|
|
|
| + HTypeConversion buildFunctionTypeConversion(
|
| + HInstruction original, DartType type, int kind) {
|
| + String name =
|
| + kind == HTypeConversion.CAST_TYPE_CHECK ? '_asCheck' : '_assertCheck';
|
| +
|
| + List<HInstruction> arguments = <HInstruction>[
|
| + buildFunctionType(type),
|
| + original
|
| + ];
|
| + pushInvokeDynamic(
|
| + null,
|
| + new Selector.call(
|
| + new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG),
|
| + null,
|
| + arguments);
|
| +
|
| + return new HTypeConversion(type, kind, original.instructionType, pop());
|
| + }
|
| +
|
| /**
|
| * Returns a complete argument list for a call of [function].
|
| */
|
| @@ -751,7 +774,8 @@ class SsaBuilder extends ast.Visitor
|
| // If the method is intercepted, we want the actual receiver
|
| // to be the first parameter.
|
| graph.entry.addBefore(graph.entry.last, parameter);
|
| - HInstruction value = potentiallyCheckOrTrustType(parameter, field.type);
|
| + HInstruction value =
|
| + typeBuilder.potentiallyCheckOrTrustType(parameter, field.type);
|
| add(new HFieldSet(field, thisInstruction, value));
|
| return closeFunction();
|
| }
|
| @@ -767,7 +791,7 @@ class SsaBuilder extends ast.Visitor
|
| openFunction(variable, node);
|
| visit(initializer);
|
| HInstruction value = pop();
|
| - value = potentiallyCheckOrTrustType(value, variable.type);
|
| + value = typeBuilder.potentiallyCheckOrTrustType(value, variable.type);
|
| // In the case of multiple declarations (and some definitions) on the same
|
| // line, the source pointer needs to point to the right initialized
|
| // variable. So find the specific initialized variable we are referring to.
|
| @@ -899,7 +923,8 @@ class SsaBuilder extends ast.Visitor
|
| * Run this builder on the body of the [function] to be inlined.
|
| */
|
| void visitInlinedFunction(ResolvedAst resolvedAst) {
|
| - potentiallyCheckInlinedParameterTypes(resolvedAst.element.implementation);
|
| + typeBuilder.potentiallyCheckInlinedParameterTypes(
|
| + resolvedAst.element.implementation);
|
|
|
| if (resolvedAst.element.isGenerativeConstructor) {
|
| buildFactory(resolvedAst);
|
| @@ -932,20 +957,6 @@ class SsaBuilder extends ast.Visitor
|
| }
|
|
|
| /**
|
| - * In checked mode, generate type tests for the parameters of the inlined
|
| - * function.
|
| - */
|
| - void potentiallyCheckInlinedParameterTypes(FunctionElement function) {
|
| - if (!_checkOrTrustTypes) return;
|
| -
|
| - FunctionSignature signature = function.functionSignature;
|
| - signature.orderedForEachParameter((ParameterElement parameter) {
|
| - HInstruction argument = localsHandler.readLocal(parameter);
|
| - potentiallyCheckOrTrustType(argument, parameter.type);
|
| - });
|
| - }
|
| -
|
| - /**
|
| * Documentation wanted -- johnniwinther
|
| *
|
| * Invariant: [constructors] must contain only implementation elements.
|
| @@ -980,7 +991,7 @@ class SsaBuilder extends ast.Visitor
|
| TypeVariableType typeVariable = variables.current;
|
| localsHandler.updateLocal(
|
| localsHandler.getTypeVariableAsLocal(typeVariable),
|
| - analyzeTypeArgument(argument));
|
| + typeBuilder.analyzeTypeArgument(argument, sourceElement));
|
| });
|
| } else {
|
| // If the supertype is a raw type, we need to set to null the
|
| @@ -1282,7 +1293,8 @@ class SsaBuilder extends ast.Visitor
|
| } else {
|
| fields.add(member);
|
| DartType type = localsHandler.substInContext(member.type);
|
| - constructorArguments.add(potentiallyCheckOrTrustType(value, type));
|
| + constructorArguments
|
| + .add(typeBuilder.potentiallyCheckOrTrustType(value, type));
|
| }
|
| }, includeSuperAndInjectedMembers: true);
|
|
|
| @@ -1480,8 +1492,8 @@ class SsaBuilder extends ast.Visitor
|
| // new A("foo"); // invalid in checked mode.
|
| //
|
| // Only the final target is allowed to check for the argument types.
|
| - newParameter =
|
| - potentiallyCheckOrTrustType(newParameter, parameterElement.type);
|
| + newParameter = typeBuilder.potentiallyCheckOrTrustType(
|
| + newParameter, parameterElement.type);
|
| }
|
| localsHandler.directLocals[parameterElement] = newParameter;
|
| });
|
| @@ -1519,112 +1531,12 @@ class SsaBuilder extends ast.Visitor
|
| }
|
| }
|
|
|
| - /// Check that [type] is valid in the context of `localsHandler.contextClass`.
|
| - /// This should only be called in assertions.
|
| - bool assertTypeInContext(DartType type, [Spannable spannable]) {
|
| - return invariant(spannable == null ? CURRENT_ELEMENT_SPANNABLE : spannable,
|
| - () {
|
| - ClassElement contextClass = Types.getClassContext(type);
|
| - return contextClass == null || contextClass == localsHandler.contextClass;
|
| - },
|
| - message: "Type '$type' is not valid context of "
|
| - "${localsHandler.contextClass}.");
|
| - }
|
| -
|
| - /// Build a [HTypeConversion] for converting [original] to type [type].
|
| - ///
|
| - /// Invariant: [type] must be valid in the context.
|
| - /// See [LocalsHandler.substInContext].
|
| - HInstruction buildTypeConversion(
|
| - HInstruction original, DartType type, int kind) {
|
| - if (type == null) return original;
|
| - // GENERIC_METHODS: The following statement was added for parsing and
|
| - // ignoring method type variables; must be generalized for full support of
|
| - // generic methods.
|
| - type = type.dynamifyMethodTypeVariableType;
|
| - type = type.unaliased;
|
| - assert(assertTypeInContext(type, original));
|
| - if (type.isInterfaceType && !type.treatAsRaw) {
|
| - TypeMask subtype =
|
| - new TypeMask.subtype(type.element, compiler.closedWorld);
|
| - HInstruction representations = buildTypeArgumentRepresentations(type);
|
| - add(representations);
|
| - return new HTypeConversion.withTypeRepresentation(
|
| - type, kind, subtype, original, representations);
|
| - } else if (type.isTypeVariable) {
|
| - TypeMask subtype = original.instructionType;
|
| - HInstruction typeVariable = addTypeVariableReference(type);
|
| - return new HTypeConversion.withTypeRepresentation(
|
| - type, kind, subtype, original, typeVariable);
|
| - } else if (type.isFunctionType) {
|
| - String name =
|
| - kind == HTypeConversion.CAST_TYPE_CHECK ? '_asCheck' : '_assertCheck';
|
| -
|
| - List<HInstruction> arguments = <HInstruction>[
|
| - buildFunctionType(type),
|
| - original
|
| - ];
|
| - pushInvokeDynamic(
|
| - null,
|
| - new Selector.call(
|
| - new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG),
|
| - null,
|
| - arguments);
|
| -
|
| - return new HTypeConversion(type, kind, original.instructionType, pop());
|
| - } else {
|
| - return original.convertType(compiler, type, kind);
|
| - }
|
| - }
|
| -
|
| - HInstruction _trustType(HInstruction original, DartType type) {
|
| - assert(compiler.options.trustTypeAnnotations);
|
| - assert(type != null);
|
| - type = localsHandler.substInContext(type);
|
| - type = type.unaliased;
|
| - if (type.isDynamic) return original;
|
| - if (!type.isInterfaceType) return original;
|
| - if (type.isObject) return original;
|
| - // The type element is either a class or the void element.
|
| - Element element = type.element;
|
| - TypeMask mask = new TypeMask.subtype(element, compiler.closedWorld);
|
| - return new HTypeKnown.pinned(mask, original);
|
| - }
|
| -
|
| - HInstruction _checkType(HInstruction original, DartType type, int kind) {
|
| - assert(compiler.options.enableTypeAssertions);
|
| - assert(type != null);
|
| - type = localsHandler.substInContext(type);
|
| - HInstruction other = buildTypeConversion(original, type, kind);
|
| - // TODO(johnniwinther): This operation on `registry` may be inconsistent.
|
| - // If it is needed then it seems likely that similar invocations of
|
| - // `buildTypeConversion` in `SsaBuilder.visitAs` should also be followed by
|
| - // a similar operation on `registry`; otherwise, this one might not be
|
| - // needed.
|
| - registry?.registerTypeUse(new TypeUse.isCheck(type));
|
| - return other;
|
| - }
|
| -
|
| - HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type,
|
| - {int kind: HTypeConversion.CHECKED_MODE_CHECK}) {
|
| - if (type == null) return original;
|
| - HInstruction checkedOrTrusted = original;
|
| - if (compiler.options.trustTypeAnnotations) {
|
| - checkedOrTrusted = _trustType(original, type);
|
| - } else if (compiler.options.enableTypeAssertions) {
|
| - checkedOrTrusted = _checkType(original, type, kind);
|
| - }
|
| - if (checkedOrTrusted == original) return original;
|
| - add(checkedOrTrusted);
|
| - return checkedOrTrusted;
|
| - }
|
| -
|
| void assertIsSubtype(
|
| ast.Node node, DartType subtype, DartType supertype, String message) {
|
| - HInstruction subtypeInstruction =
|
| - analyzeTypeArgument(localsHandler.substInContext(subtype));
|
| - HInstruction supertypeInstruction =
|
| - analyzeTypeArgument(localsHandler.substInContext(supertype));
|
| + HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument(
|
| + localsHandler.substInContext(subtype), sourceElement);
|
| + HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument(
|
| + localsHandler.substInContext(supertype), sourceElement);
|
| HInstruction messageInstruction =
|
| graph.addConstantString(new ast.DartString.literal(message), compiler);
|
| MethodElement element = helpers.assertIsSubtype;
|
| @@ -1650,11 +1562,15 @@ class SsaBuilder extends ast.Visitor
|
| push(attachPosition(instruction, node));
|
| }
|
|
|
| + /// Pops the most recent instruction from the stack and 'boolifies' it.
|
| + ///
|
| + /// Boolification is checking if the value is '=== true'.
|
| @override
|
| HInstruction popBoolified() {
|
| HInstruction value = pop();
|
| - if (_checkOrTrustTypes) {
|
| - return potentiallyCheckOrTrustType(value, compiler.coreTypes.boolType,
|
| + if (typeBuilder.checkOrTrustTypes) {
|
| + return typeBuilder.potentiallyCheckOrTrustType(
|
| + value, compiler.coreTypes.boolType,
|
| kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
|
| }
|
| HInstruction result = new HBoolify(value, backend.boolType);
|
| @@ -2445,7 +2361,7 @@ class SsaBuilder extends ast.Visitor
|
| pop();
|
| } else {
|
| FieldElement field = element;
|
| - value = potentiallyCheckOrTrustType(value, field.type);
|
| + value = typeBuilder.potentiallyCheckOrTrustType(value, field.type);
|
| addWithPosition(new HStaticStore(field, value), location);
|
| }
|
| stack.add(value);
|
| @@ -2462,7 +2378,7 @@ class SsaBuilder extends ast.Visitor
|
| value.sourceElement = local;
|
| }
|
| HInstruction checkedOrTrusted =
|
| - potentiallyCheckOrTrustType(value, local.type);
|
| + typeBuilder.potentiallyCheckOrTrustType(value, local.type);
|
| if (!identical(checkedOrTrusted, value)) {
|
| pop();
|
| stack.add(checkedOrTrusted);
|
| @@ -2484,24 +2400,6 @@ class SsaBuilder extends ast.Visitor
|
| return new HLiteralList(inputs, backend.extendableArrayType);
|
| }
|
|
|
| - HInstruction buildTypeArgumentRepresentations(DartType type) {
|
| - assert(!type.isTypeVariable);
|
| - // Compute the representation of the type arguments, including access
|
| - // to the runtime type information for type variables as instructions.
|
| - assert(type.element.isClass);
|
| - InterfaceType interface = type;
|
| - List<HInstruction> inputs = <HInstruction>[];
|
| - for (DartType argument in interface.typeArguments) {
|
| - inputs.add(analyzeTypeArgument(argument));
|
| - }
|
| - HInstruction representation = new HTypeInfoExpression(
|
| - TypeInfoExpressionKind.INSTANCE,
|
| - interface.element.thisType,
|
| - inputs,
|
| - backend.dynamicType);
|
| - return representation;
|
| - }
|
| -
|
| @override
|
| void visitAs(ast.Send node, ast.Node expression, DartType type, _) {
|
| HInstruction expressionInstruction = visitAndPop(expression);
|
| @@ -2514,8 +2412,10 @@ class SsaBuilder extends ast.Visitor
|
| stack.add(expressionInstruction);
|
| }
|
| } else {
|
| - HInstruction converted = buildTypeConversion(expressionInstruction,
|
| - localsHandler.substInContext(type), HTypeConversion.CAST_TYPE_CHECK);
|
| + HInstruction converted = typeBuilder.buildTypeConversion(
|
| + expressionInstruction,
|
| + localsHandler.substInContext(type),
|
| + HTypeConversion.CAST_TYPE_CHECK);
|
| if (converted != expressionInstruction) add(converted);
|
| stack.add(converted);
|
| }
|
| @@ -2561,7 +2461,8 @@ class SsaBuilder extends ast.Visitor
|
| arguments);
|
| return new HIs.compound(type, expression, pop(), backend.boolType);
|
| } else if (type.isTypeVariable) {
|
| - HInstruction runtimeType = addTypeVariableReference(type);
|
| + HInstruction runtimeType =
|
| + typeBuilder.addTypeVariableReference(type, sourceElement);
|
| Element helper = helpers.checkSubtypeOfRuntimeType;
|
| List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
|
| pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType);
|
| @@ -2570,7 +2471,8 @@ class SsaBuilder extends ast.Visitor
|
| } else if (RuntimeTypes.hasTypeArguments(type)) {
|
| ClassElement element = type.element;
|
| Element helper = helpers.checkSubtype;
|
| - HInstruction representations = buildTypeArgumentRepresentations(type);
|
| + HInstruction representations =
|
| + typeBuilder.buildTypeArgumentRepresentations(type, sourceElement);
|
| add(representations);
|
| js.Name operator = backend.namer.operatorIs(element);
|
| HInstruction isFieldName = addConstantStringFromName(operator);
|
| @@ -2598,11 +2500,6 @@ class SsaBuilder extends ast.Visitor
|
| }
|
| }
|
|
|
| - HInstruction buildFunctionType(FunctionType type) {
|
| - type.accept(new TypeBuilder(compiler.closedWorld), this);
|
| - return pop();
|
| - }
|
| -
|
| void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) {
|
| CallStructure callStructure = elements.getSelector(node).callStructure;
|
| if (callStructure.namedArgumentCount == 0) {
|
| @@ -3389,113 +3286,6 @@ class SsaBuilder extends ast.Visitor
|
| });
|
| }
|
|
|
| - /**
|
| - * Generate code to extract the type argument from the object.
|
| - */
|
| - HInstruction readTypeVariable(TypeVariableType variable,
|
| - {SourceInformation sourceInformation}) {
|
| - assert(sourceElement.isInstanceMember);
|
| - assert(variable is! MethodTypeVariableType);
|
| - HInstruction target = localsHandler.readThis();
|
| - push(new HTypeInfoReadVariable(variable, target, backend.dynamicType)
|
| - ..sourceInformation = sourceInformation);
|
| - return pop();
|
| - }
|
| -
|
| - // TODO(karlklose): this is needed to avoid a bug where the resolved type is
|
| - // not stored on a type annotation in the closure translator. Remove when
|
| - // fixed.
|
| - bool hasDirectLocal(Local local) {
|
| - return !localsHandler.isAccessedDirectly(local) ||
|
| - localsHandler.directLocals[local] != null;
|
| - }
|
| -
|
| - /**
|
| - * Helper to create an instruction that gets the value of a type variable.
|
| - */
|
| - HInstruction addTypeVariableReference(TypeVariableType type,
|
| - {SourceInformation sourceInformation}) {
|
| - assert(assertTypeInContext(type));
|
| - if (type is MethodTypeVariableType) {
|
| - return graph.addConstantNull(compiler);
|
| - }
|
| - Element member = sourceElement;
|
| - bool isClosure = member.enclosingElement.isClosure;
|
| - if (isClosure) {
|
| - ClosureClassElement closureClass = member.enclosingElement;
|
| - member = closureClass.methodElement;
|
| - member = member.outermostEnclosingMemberOrTopLevel;
|
| - }
|
| - bool isInConstructorContext =
|
| - member.isConstructor || member.isGenerativeConstructorBody;
|
| - Local typeVariableLocal = localsHandler.getTypeVariableAsLocal(type);
|
| - if (isClosure) {
|
| - if (member.isFactoryConstructor ||
|
| - (isInConstructorContext && hasDirectLocal(typeVariableLocal))) {
|
| - // The type variable is used from a closure in a factory constructor.
|
| - // The value of the type argument is stored as a local on the closure
|
| - // itself.
|
| - return localsHandler.readLocal(typeVariableLocal,
|
| - sourceInformation: sourceInformation);
|
| - } else if (member.isFunction ||
|
| - member.isGetter ||
|
| - member.isSetter ||
|
| - isInConstructorContext) {
|
| - // The type variable is stored on the "enclosing object" and needs to be
|
| - // accessed using the this-reference in the closure.
|
| - return readTypeVariable(type, sourceInformation: sourceInformation);
|
| - } else {
|
| - assert(member.isField);
|
| - // The type variable is stored in a parameter of the method.
|
| - return localsHandler.readLocal(typeVariableLocal);
|
| - }
|
| - } else if (isInConstructorContext ||
|
| - // When [member] is a field, we can be either
|
| - // generating a checked setter or inlining its
|
| - // initializer in a constructor. An initializer is
|
| - // never built standalone, so in that case [target] is not
|
| - // the [member] itself.
|
| - (member.isField && member != target)) {
|
| - // The type variable is stored in a parameter of the method.
|
| - return localsHandler.readLocal(typeVariableLocal,
|
| - sourceInformation: sourceInformation);
|
| - } else if (member.isInstanceMember) {
|
| - // The type variable is stored on the object.
|
| - return readTypeVariable(type, sourceInformation: sourceInformation);
|
| - } else {
|
| - reporter.internalError(
|
| - type.element, 'Unexpected type variable in static context.');
|
| - return null;
|
| - }
|
| - }
|
| -
|
| - HInstruction analyzeTypeArgument(DartType argument,
|
| - {SourceInformation sourceInformation}) {
|
| - assert(assertTypeInContext(argument));
|
| - argument = argument.unaliased;
|
| - if (argument.treatAsDynamic) {
|
| - // Represent [dynamic] as [null].
|
| - return graph.addConstantNull(compiler);
|
| - }
|
| -
|
| - if (argument.isTypeVariable) {
|
| - return addTypeVariableReference(argument,
|
| - sourceInformation: sourceInformation);
|
| - }
|
| -
|
| - List<HInstruction> inputs = <HInstruction>[];
|
| - argument.forEachTypeVariable((variable) {
|
| - if (variable is! MethodTypeVariableType) {
|
| - inputs.add(analyzeTypeArgument(variable));
|
| - }
|
| - });
|
| - HInstruction result = new HTypeInfoExpression(
|
| - TypeInfoExpressionKind.COMPLETE, argument, inputs, backend.dynamicType)
|
| - ..sourceInformation = sourceInformation;
|
| - add(result);
|
| - return result;
|
| - }
|
| -
|
| HInstruction handleListConstructor(
|
| InterfaceType type, ast.Node currentNode, HInstruction newObject) {
|
| if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
|
| @@ -3504,7 +3294,7 @@ class SsaBuilder extends ast.Visitor
|
| List<HInstruction> inputs = <HInstruction>[];
|
| type = localsHandler.substInContext(type);
|
| type.typeArguments.forEach((DartType argument) {
|
| - inputs.add(analyzeTypeArgument(argument));
|
| + inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
|
| });
|
| // TODO(15489): Register at codegen.
|
| registry?.registerInstantiation(type);
|
| @@ -3752,7 +3542,8 @@ class SsaBuilder extends ast.Visitor
|
|
|
| // Finally, if we called a redirecting factory constructor, check the type.
|
| if (isRedirected) {
|
| - HInstruction checked = potentiallyCheckOrTrustType(newInstance, type);
|
| + HInstruction checked =
|
| + typeBuilder.potentiallyCheckOrTrustType(newInstance, type);
|
| if (checked != newInstance) {
|
| pop();
|
| stack.add(checked);
|
| @@ -3766,8 +3557,8 @@ class SsaBuilder extends ast.Visitor
|
| if (!backend.classNeedsRti(cls)) return;
|
| assert(cls.typeVariables.length == expectedType.typeArguments.length);
|
| expectedType.typeArguments.forEach((DartType argument) {
|
| - inputs.add(
|
| - analyzeTypeArgument(argument, sourceInformation: sourceInformation));
|
| + inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
|
| + sourceInformation: sourceInformation));
|
| });
|
| }
|
|
|
| @@ -4039,7 +3830,7 @@ class SsaBuilder extends ast.Visitor
|
| generateTypeError(node, "Method type variables are not reified");
|
| } else {
|
| DartType type = localsHandler.substInContext(typeVariable);
|
| - HInstruction value = analyzeTypeArgument(type,
|
| + HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement,
|
| sourceInformation: sourceInformationBuilder.buildGet(node));
|
| pushInvokeStatic(node, helpers.runtimeTypeToString, [value],
|
| typeMask: backend.stringType);
|
| @@ -5365,7 +5156,7 @@ class SsaBuilder extends ast.Visitor
|
| redirectingConstructor.computeEffectiveTargetType(cls.thisType);
|
| targetType = localsHandler.substInContext(targetType);
|
| targetType.typeArguments.forEach((DartType argument) {
|
| - inputs.add(analyzeTypeArgument(argument));
|
| + inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
|
| });
|
| }
|
| pushInvokeStatic(node, targetConstructor.declaration, inputs);
|
| @@ -5415,7 +5206,7 @@ class SsaBuilder extends ast.Visitor
|
| return;
|
| }
|
| } else {
|
| - value = potentiallyCheckOrTrustType(value, returnType);
|
| + value = typeBuilder.potentiallyCheckOrTrustType(value, returnType);
|
| }
|
| }
|
|
|
| @@ -5477,7 +5268,7 @@ class SsaBuilder extends ast.Visitor
|
| }
|
| List<HInstruction> arguments = <HInstruction>[];
|
| for (DartType argument in type.typeArguments) {
|
| - arguments.add(analyzeTypeArgument(argument));
|
| + arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
|
| }
|
| // TODO(15489): Register at codegen.
|
| registry?.registerInstantiation(type);
|
| @@ -5925,7 +5716,8 @@ class SsaBuilder extends ast.Visitor
|
| if (backend.classNeedsRti(cls)) {
|
| List<HInstruction> typeInputs = <HInstruction>[];
|
| expectedType.typeArguments.forEach((DartType argument) {
|
| - typeInputs.add(analyzeTypeArgument(argument));
|
| + typeInputs
|
| + .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
|
| });
|
|
|
| // We lift this common call pattern into a helper function to save space
|
| @@ -7002,94 +6794,3 @@ class AstInliningState extends InliningState {
|
| this.oldElementInferenceResults)
|
| : super(function);
|
| }
|
| -
|
| -class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> {
|
| - final ClosedWorld closedWorld;
|
| -
|
| - TypeBuilder(this.closedWorld);
|
| -
|
| - void visit(DartType type, SsaBuilder builder) => type.accept(this, builder);
|
| -
|
| - void visitVoidType(VoidType type, SsaBuilder builder) {
|
| - ClassElement cls = builder.backend.helpers.VoidRuntimeType;
|
| - builder.push(new HVoidType(type, new TypeMask.exact(cls, closedWorld)));
|
| - }
|
| -
|
| - void visitTypeVariableType(TypeVariableType type, SsaBuilder builder) {
|
| - ClassElement cls = builder.backend.helpers.RuntimeType;
|
| - TypeMask instructionType = new TypeMask.subclass(cls, closedWorld);
|
| - if (!builder.sourceElement.enclosingElement.isClosure &&
|
| - builder.sourceElement.isInstanceMember) {
|
| - HInstruction receiver = builder.localsHandler.readThis();
|
| - builder.push(new HReadTypeVariable(type, receiver, instructionType));
|
| - } else {
|
| - builder.push(new HReadTypeVariable.noReceiver(
|
| - type, builder.addTypeVariableReference(type), instructionType));
|
| - }
|
| - }
|
| -
|
| - void visitFunctionType(FunctionType type, SsaBuilder builder) {
|
| - type.returnType.accept(this, builder);
|
| - HInstruction returnType = builder.pop();
|
| - List<HInstruction> inputs = <HInstruction>[returnType];
|
| -
|
| - for (DartType parameter in type.parameterTypes) {
|
| - parameter.accept(this, builder);
|
| - inputs.add(builder.pop());
|
| - }
|
| -
|
| - for (DartType parameter in type.optionalParameterTypes) {
|
| - parameter.accept(this, builder);
|
| - inputs.add(builder.pop());
|
| - }
|
| -
|
| - List<DartType> namedParameterTypes = type.namedParameterTypes;
|
| - List<String> names = type.namedParameters;
|
| - for (int index = 0; index < names.length; index++) {
|
| - ast.DartString dartString = new ast.DartString.literal(names[index]);
|
| - inputs.add(builder.graph.addConstantString(dartString, builder.compiler));
|
| - namedParameterTypes[index].accept(this, builder);
|
| - inputs.add(builder.pop());
|
| - }
|
| -
|
| - ClassElement cls = builder.backend.helpers.RuntimeFunctionType;
|
| - builder.push(
|
| - new HFunctionType(inputs, type, new TypeMask.exact(cls, closedWorld)));
|
| - }
|
| -
|
| - void visitMalformedType(MalformedType type, SsaBuilder builder) {
|
| - visitDynamicType(const DynamicType(), builder);
|
| - }
|
| -
|
| - void visitStatementType(StatementType type, SsaBuilder builder) {
|
| - throw 'not implemented visitStatementType($type)';
|
| - }
|
| -
|
| - void visitInterfaceType(InterfaceType type, SsaBuilder builder) {
|
| - List<HInstruction> inputs = <HInstruction>[];
|
| - for (DartType typeArgument in type.typeArguments) {
|
| - typeArgument.accept(this, builder);
|
| - inputs.add(builder.pop());
|
| - }
|
| - ClassElement cls;
|
| - if (type.typeArguments.isEmpty) {
|
| - cls = builder.backend.helpers.RuntimeTypePlain;
|
| - } else {
|
| - cls = builder.backend.helpers.RuntimeTypeGeneric;
|
| - }
|
| - builder.push(
|
| - new HInterfaceType(inputs, type, new TypeMask.exact(cls, closedWorld)));
|
| - }
|
| -
|
| - void visitTypedefType(TypedefType type, SsaBuilder builder) {
|
| - DartType unaliased = type.unaliased;
|
| - if (unaliased is TypedefType) throw 'unable to unalias $type';
|
| - unaliased.accept(this, builder);
|
| - }
|
| -
|
| - void visitDynamicType(DynamicType type, SsaBuilder builder) {
|
| - JavaScriptBackend backend = builder.compiler.backend;
|
| - ClassElement cls = backend.helpers.DynamicRuntimeType;
|
| - builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld)));
|
| - }
|
| -}
|
|
|