| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| index f560372ba4fbdf3755b3e2054bf8df42f8160304..94c3f7d2af6af95d2648d3119c954a571b7f63f5 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| @@ -40,7 +40,8 @@ import 'cps_ir_builder.dart';
|
| * re-implemented to work directly on the IR.
|
| */
|
| class IrBuilderTask extends CompilerTask {
|
| - final Map<Element, ir.RootNode> nodes = <Element, ir.RootNode>{};
|
| + final Map<Element, ir.FunctionDefinition> nodes =
|
| + <Element, ir.FunctionDefinition>{};
|
| final SourceInformationFactory sourceInformationFactory;
|
|
|
| String bailoutMessage = null;
|
| @@ -52,20 +53,16 @@ class IrBuilderTask extends CompilerTask {
|
|
|
| bool hasIr(Element element) => nodes.containsKey(element.implementation);
|
|
|
| - ir.RootNode getIr(ExecutableElement element) {
|
| + ir.FunctionDefinition getIr(ExecutableElement element) {
|
| return nodes[element.implementation];
|
| }
|
|
|
| - ir.RootNode buildNode(AstElement element) {
|
| + ir.FunctionDefinition buildNode(AstElement element) {
|
| return measure(() => _buildNode(element));
|
| }
|
|
|
| - ir.RootNode _buildNode(AstElement element) {
|
| + ir.FunctionDefinition _buildNode(AstElement element) {
|
| bailoutMessage = null;
|
| - if (!canBuild(element)) {
|
| - bailoutMessage = 'unsupported element ${element.name}:${element.kind}';
|
| - return null;
|
| - }
|
|
|
| TreeElements elementsMapping = element.resolvedAst.elements;
|
| element = element.implementation;
|
| @@ -74,12 +71,9 @@ class IrBuilderTask extends CompilerTask {
|
| sourceInformationFactory.forContext(element);
|
|
|
| IrBuilderVisitor builder =
|
| - compiler.backend is JavaScriptBackend
|
| - ? new JsIrBuilderVisitor(
|
| - elementsMapping, compiler, sourceInformationBuilder)
|
| - : new DartIrBuilderVisitor(
|
| + new JsIrBuilderVisitor(
|
| elementsMapping, compiler, sourceInformationBuilder);
|
| - ir.RootNode irNode = builder.buildExecutable(element);
|
| + ir.FunctionDefinition irNode = builder.buildExecutable(element);
|
| if (irNode == null) {
|
| bailoutMessage = builder.bailoutMessage;
|
| } else {
|
| @@ -96,31 +90,6 @@ class IrBuilderTask extends CompilerTask {
|
| });
|
| }
|
|
|
| - bool canBuild(Element element) {
|
| - // If using JavaScript backend, don't try to bail out early.
|
| - if (compiler.backend is JavaScriptBackend) return true;
|
| -
|
| - if (element is TypedefElement) return false;
|
| - if (element is FunctionElement) {
|
| - // TODO(sigurdm): Support native functions for dart2js.
|
| - assert(invariant(element, !element.isNative));
|
| -
|
| - if (element is ConstructorElement) {
|
| - if (!element.isGenerativeConstructor) {
|
| - // TODO(kmillikin,sigurdm): Support constructors.
|
| - return false;
|
| - }
|
| - if (element.isSynthesized) {
|
| - // Do generate CPS for synthetic constructors.
|
| - return true;
|
| - }
|
| - }
|
| - } else if (element is! FieldElement) {
|
| - compiler.internalError(element, "Unexpected element type $element");
|
| - }
|
| - return compiler.backend.shouldOutput(element);
|
| - }
|
| -
|
| bool get inCheckedMode {
|
| bool result = false;
|
| assert((result = true));
|
| @@ -191,11 +160,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| SemanticSendVisitor get sendVisitor => this;
|
|
|
| /**
|
| - * Builds the [ir.RootNode] for an executable element. In case the
|
| + * Builds the [ir.FunctionDefinition] for an executable element. In case the
|
| * function uses features that cannot be expressed in the IR, this element
|
| * returns `null`.
|
| */
|
| - ir.RootNode buildExecutable(ExecutableElement element);
|
| + ir.FunctionDefinition buildExecutable(ExecutableElement element);
|
|
|
| ClosureClassMap get closureClassMap;
|
| ClosureScope getClosureScopeForNode(ast.Node node);
|
| @@ -248,8 +217,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return useSelectorType(newSelector, elements.getSelector(node));
|
| }
|
|
|
| - ir.RootNode _makeFunctionBody(FunctionElement element,
|
| - ast.FunctionExpression node) {
|
| + ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
|
| + ast.FunctionExpression node) {
|
| FunctionSignature signature = element.functionSignature;
|
| List<ParameterElement> parameters = [];
|
| signature.orderedForEachParameter(parameters.add);
|
| @@ -258,104 +227,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| closureScope: getClosureScopeForNode(node),
|
| env: getClosureEnvironment());
|
|
|
| - List<ConstantExpression> defaults = new List<ConstantExpression>();
|
| - signature.orderedOptionalParameters.forEach((ParameterElement element) {
|
| - defaults.add(getConstantForVariable(element));
|
| - });
|
| -
|
| - List<ir.Initializer> initializers;
|
| - if (element.isSynthesized) {
|
| - assert(element is ConstructorElement);
|
| - return irBuilder.makeConstructorDefinition(const <ConstantExpression>[],
|
| - const <ir.Initializer>[]);
|
| - } else if (element.isGenerativeConstructor) {
|
| - if (element.isExternal) {
|
| - return irBuilder.makeAbstractConstructorDefinition(defaults);
|
| - } else {
|
| - initializers = buildConstructorInitializers(node, element);
|
| - visit(node.body);
|
| - return irBuilder.makeConstructorDefinition(defaults, initializers);
|
| - }
|
| - } else {
|
| - visit(node.body);
|
| - return irBuilder.makeFunctionDefinition(defaults);
|
| - }
|
| - }
|
| -
|
| - List<ir.Initializer> buildConstructorInitializers(
|
| - ast.FunctionExpression function, ConstructorElement element) {
|
| - List<ir.Initializer> result = <ir.Initializer>[];
|
| - FunctionSignature signature = element.functionSignature;
|
| -
|
| - void tryAddInitializingFormal(ParameterElement parameterElement) {
|
| - if (parameterElement.isInitializingFormal) {
|
| - InitializingFormalElement initializingFormal = parameterElement;
|
| - withBuilder(irBuilder.makeInitializerBuilder(), () {
|
| - ir.Primitive value =
|
| - irBuilder.buildLocalVariableGet(parameterElement);
|
| - result.add(irBuilder.makeFieldInitializer(
|
| - initializingFormal.fieldElement,
|
| - irBuilder.makeBody(value)));
|
| - });
|
| - }
|
| - }
|
| -
|
| - // TODO(sigurdm): Preserve initializing formals as initializing formals.
|
| - signature.orderedForEachParameter(tryAddInitializingFormal);
|
| -
|
| - if (function.initializers == null) return result;
|
| - bool explicitSuperInitializer = false;
|
| - for(ast.Node initializer in function.initializers) {
|
| - if (initializer is ast.SendSet) {
|
| - // Field initializer.
|
| - FieldElement field = elements[initializer];
|
| - withBuilder(irBuilder.makeInitializerBuilder(), () {
|
| - ir.Primitive value = visit(initializer.arguments.head);
|
| - ir.Body body = irBuilder.makeBody(value);
|
| - result.add(irBuilder.makeFieldInitializer(field, body));
|
| - });
|
| - } else if (initializer is ast.Send) {
|
| - // Super or this initializer.
|
| - if (ast.Initializers.isConstructorRedirect(initializer)) {
|
| - giveup(initializer, "constructor redirect (this) initializer");
|
| - }
|
| - ConstructorElement constructor = elements[initializer].implementation;
|
| - Selector selector = elements.getSelector(initializer);
|
| - List<ir.Body> arguments =
|
| - initializer.arguments.mapToList((ast.Node argument) {
|
| - return withBuilder(irBuilder.makeInitializerBuilder(), () {
|
| - ir.Primitive value = visit(argument);
|
| - return irBuilder.makeBody(value);
|
| - });
|
| - });
|
| - result.add(irBuilder.makeSuperInitializer(constructor,
|
| - arguments,
|
| - selector));
|
| - explicitSuperInitializer = true;
|
| - } else {
|
| - compiler.internalError(initializer,
|
| - "Unexpected initializer type $initializer");
|
| - }
|
| -
|
| - }
|
| - if (!explicitSuperInitializer) {
|
| - // No super initializer found. Try to find the default constructor if
|
| - // the class is not Object.
|
| - ClassElement enclosingClass = element.enclosingClass;
|
| - if (!enclosingClass.isObject) {
|
| - ClassElement superClass = enclosingClass.superclass;
|
| - FunctionElement target = superClass.lookupDefaultConstructor();
|
| - if (target == null) {
|
| - compiler.internalError(superClass,
|
| - "No default constructor available.");
|
| - }
|
| - Selector selector = new Selector.callDefaultConstructor();
|
| - result.add(irBuilder.makeSuperInitializer(target,
|
| - <ir.Body>[],
|
| - selector));
|
| - }
|
| - }
|
| - return result;
|
| + visit(node.body);
|
| + return irBuilder.makeFunctionDefinition();
|
| }
|
|
|
| ir.Primitive visit(ast.Node node) => node.accept(this);
|
| @@ -1923,7 +1796,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return buildInstanceNoSuchMethod(selector, args);
|
| }
|
|
|
| - ir.RootNode nullIfGiveup(ir.RootNode action()) {
|
| + ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
|
| try {
|
| return action();
|
| } catch(e) {
|
| @@ -2110,185 +1983,6 @@ class DartCapturedVariables extends ast.Visitor {
|
| }
|
| }
|
|
|
| -/// IR builder specific to the Dart backend, coupled to the [DartIrBuilder].
|
| -class DartIrBuilderVisitor extends IrBuilderVisitor {
|
| - /// Promote the type of [irBuilder] to [DartIrBuilder].
|
| - DartIrBuilder get irBuilder => super.irBuilder;
|
| -
|
| - DartIrBuilderVisitor(TreeElements elements,
|
| - Compiler compiler,
|
| - SourceInformationBuilder sourceInformationBuilder)
|
| - : super(elements, compiler, sourceInformationBuilder);
|
| -
|
| - DartIrBuilder makeIRBuilder(ExecutableElement element,
|
| - Set<Local> capturedVariables) {
|
| - return new DartIrBuilder(compiler.backend.constantSystem,
|
| - element,
|
| - capturedVariables);
|
| - }
|
| -
|
| - DartCapturedVariables _analyzeCapturedVariables(ExecutableElement element,
|
| - ast.Node node) {
|
| - DartCapturedVariables variables = new DartCapturedVariables(elements);
|
| - if (!element.isSynthesized) {
|
| - try {
|
| - variables.analyze(node);
|
| - } catch (e) {
|
| - bailoutMessage = variables.bailoutMessage;
|
| - rethrow;
|
| - }
|
| - }
|
| - return variables;
|
| - }
|
| -
|
| - /// Recursively builds the IR for the given nested function.
|
| - ir.FunctionDefinition makeSubFunction(ast.FunctionExpression node) {
|
| - FunctionElement element = elements[node];
|
| - assert(invariant(element, element.isImplementation));
|
| -
|
| - IrBuilder builder = irBuilder.makeInnerFunctionBuilder(element);
|
| -
|
| - return withBuilder(builder, () => _makeFunctionBody(element, node));
|
| - }
|
| -
|
| - ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
|
| - return irBuilder.buildFunctionExpression(makeSubFunction(node));
|
| - }
|
| -
|
| - visitFunctionDeclaration(ast.FunctionDeclaration node) {
|
| - LocalFunctionElement element = elements[node.function];
|
| - Object inner = makeSubFunction(node.function);
|
| - irBuilder.declareLocalFunction(element, inner);
|
| - }
|
| -
|
| - ClosureClassMap get closureClassMap => null;
|
| - ClosureScope getClosureScopeForNode(ast.Node node) => null;
|
| - ClosureEnvironment getClosureEnvironment() => null;
|
| -
|
| - ir.RootNode buildExecutable(ExecutableElement element) {
|
| - return nullIfGiveup(() {
|
| - ir.RootNode root;
|
| - if (element is FieldElement) {
|
| - root = buildField(element);
|
| - } else if (element is FunctionElement || element is ConstructorElement) {
|
| - root = buildFunction(element);
|
| - } else {
|
| - compiler.internalError(element, "Unexpected element type $element");
|
| - }
|
| - new CleanupPass().visit(root);
|
| - return root;
|
| - });
|
| - }
|
| -
|
| - /// Returns a [ir.FieldDefinition] describing the initializer of [element].
|
| - ir.FieldDefinition buildField(FieldElement element) {
|
| - assert(invariant(element, element.isImplementation));
|
| - ast.VariableDefinitions definitions = element.node;
|
| - ast.Node fieldDefinition = definitions.definitions.nodes.first;
|
| - if (definitions.modifiers.isConst) {
|
| - // TODO(sigurdm): Just return const value.
|
| - }
|
| - assert(fieldDefinition != null);
|
| - assert(elements[fieldDefinition] != null);
|
| -
|
| - DartCapturedVariables variables =
|
| - _analyzeCapturedVariables(element, fieldDefinition);
|
| - tryStatements = variables.tryStatements;
|
| - IrBuilder builder = makeIRBuilder(element, variables.capturedVariables);
|
| -
|
| - return withBuilder(builder, () {
|
| - builder.buildFieldInitializerHeader(
|
| - closureScope: getClosureScopeForNode(fieldDefinition));
|
| - ir.Primitive initializer;
|
| - if (fieldDefinition is ast.SendSet) {
|
| - ast.SendSet sendSet = fieldDefinition;
|
| - initializer = visit(sendSet.arguments.first);
|
| - }
|
| - return builder.makeFieldDefinition(initializer);
|
| - });
|
| - }
|
| -
|
| - ir.RootNode buildFunction(FunctionElement element) {
|
| - assert(invariant(element, element.isImplementation));
|
| - ast.FunctionExpression node = element.node;
|
| - if (element.asyncMarker != AsyncMarker.SYNC) {
|
| - giveup(null, 'cannot handle async-await');
|
| - }
|
| -
|
| - if (!element.isSynthesized) {
|
| - assert(node != null);
|
| - assert(elements[node] != null);
|
| - } else {
|
| - SynthesizedConstructorElementX constructor = element;
|
| - if (!constructor.isDefaultConstructor) {
|
| - giveup(null, 'cannot handle synthetic forwarding constructors');
|
| - }
|
| - }
|
| -
|
| - DartCapturedVariables variables =
|
| - _analyzeCapturedVariables(element, node);
|
| - tryStatements = variables.tryStatements;
|
| - IrBuilder builder = makeIRBuilder(element, variables.capturedVariables);
|
| -
|
| - return withBuilder(builder, () => _makeFunctionBody(element, node));
|
| - }
|
| -
|
| - List<ir.Primitive> normalizeStaticArguments(
|
| - CallStructure callStructure,
|
| - FunctionElement target,
|
| - List<ir.Primitive> arguments) {
|
| - return arguments;
|
| - }
|
| -
|
| - List<ir.Primitive> normalizeDynamicArguments(
|
| - CallStructure callStructure,
|
| - List<ir.Primitive> arguments) {
|
| - return arguments;
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive handleConstructorInvoke(
|
| - ast.NewExpression node,
|
| - ConstructorElement constructor,
|
| - DartType type,
|
| - ast.NodeList arguments,
|
| - CallStructure callStructure, _) {
|
| - List<ir.Primitive> arguments =
|
| - node.send.arguments.mapToList(visit, growable:false);
|
| - return irBuilder.buildConstructorInvocation(
|
| - constructor,
|
| - callStructure,
|
| - type,
|
| - arguments);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildStaticNoSuchMethod(Selector selector,
|
| - List<ir.Primitive> arguments) {
|
| - return giveup(null, 'Static noSuchMethod');
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildInstanceNoSuchMethod(Selector selector,
|
| - List<ir.Primitive> arguments) {
|
| - return giveup(null, 'Instance noSuchMethod');
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildRuntimeError(String message) {
|
| - return giveup(null, 'Build runtime error: $message');
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildAbstractClassInstantiationError(ClassElement element) {
|
| - return giveup(null, 'Abstract class instantiation: ${element.name}');
|
| - }
|
| -
|
| - ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
|
| - return irBuilder.buildStaticFieldLazyGet(field, src);
|
| - }
|
| -}
|
| -
|
| /// The [IrBuilder]s view on the information about the program that has been
|
| /// computed in resolution and and type interence.
|
| class GlobalProgramInformation {
|
| @@ -2410,9 +2104,9 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| scope.boxedLoopVariables);
|
| }
|
|
|
| - ir.RootNode buildExecutable(ExecutableElement element) {
|
| + ir.FunctionDefinition buildExecutable(ExecutableElement element) {
|
| return nullIfGiveup(() {
|
| - ir.RootNode root;
|
| + ir.FunctionDefinition root;
|
| switch (element.kind) {
|
| case ElementKind.GENERATIVE_CONSTRUCTOR:
|
| root = buildConstructor(element);
|
| @@ -2458,9 +2152,10 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| elements);
|
| IrBuilder builder = getBuilderFor(element);
|
| return withBuilder(builder, () {
|
| + irBuilder.buildFunctionHeader(<Local>[]);
|
| ir.Primitive initialValue = visit(element.initializer);
|
| irBuilder.buildReturn(initialValue);
|
| - return irBuilder.makeLazyFieldInitializer();
|
| + return irBuilder.makeFunctionDefinition();
|
| });
|
| }
|
|
|
| @@ -2596,7 +2291,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| // --- step 4: return the created object ----
|
| irBuilder.buildReturn(instance);
|
|
|
| - return irBuilder.makeFunctionDefinition([]);
|
| + return irBuilder.makeFunctionDefinition();
|
| });
|
| }
|
|
|
| @@ -2880,7 +2575,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body),
|
| getClosureScopeForNode(node));
|
| visit(node.body);
|
| - return irBuilder.makeFunctionDefinition([]);
|
| + return irBuilder.makeFunctionDefinition();
|
| });
|
| }
|
|
|
| @@ -2977,6 +2672,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| }
|
| return result;
|
| }
|
| +
|
| @override
|
| ir.Primitive handleConstructorInvoke(
|
| ast.NewExpression node,
|
| @@ -3078,6 +2774,10 @@ class CleanupPass extends ir.RecursiveVisitor {
|
| return expression;
|
| }
|
|
|
| + processFunctionDefinition(ir.FunctionDefinition node) {
|
| + node.body = replacementFor(node.body);
|
| + }
|
| +
|
| processLetPrim(ir.LetPrim node) {
|
| node.body = replacementFor(node.body);
|
| }
|
| @@ -3098,10 +2798,6 @@ class CleanupPass extends ir.RecursiveVisitor {
|
| node.body = replacementFor(node.body);
|
| }
|
|
|
| - processDeclareFunction(ir.DeclareFunction node) {
|
| - node.body = replacementFor(node.body);
|
| - }
|
| -
|
| processSetField(ir.SetField node) {
|
| node.body = replacementFor(node.body);
|
| }
|
| @@ -3113,10 +2809,6 @@ class CleanupPass extends ir.RecursiveVisitor {
|
| processContinuation(ir.Continuation node) {
|
| node.body = replacementFor(node.body);
|
| }
|
| -
|
| - processBody(ir.Body node) {
|
| - node.body = replacementFor(node.body);
|
| - }
|
| }
|
|
|
| /// Visit a just-deleted subterm and unlink all [Reference]s in it.
|
|
|