| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| index a62a69c033750fd13729f460e51c01d20b52df6c..b9d1595feb12336435a855702e518073886b93db 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| @@ -395,7 +395,7 @@ class IrBuilderSharedState {
|
| ir.Parameter _thisParameter;
|
| ir.Parameter enclosingMethodThisParameter;
|
|
|
| - final List<ir.Definition> functionParameters = <ir.Definition>[];
|
| + final List<ir.Parameter> functionParameters = <ir.Parameter>[];
|
|
|
| IrBuilderSharedState(this.constantSystem, this.currentElement);
|
|
|
| @@ -565,34 +565,8 @@ abstract class IrBuilder {
|
| ..mutableVariables = mutableVariables;
|
| }
|
|
|
| - /// Construct a builder for making constructor field initializers.
|
| - IrBuilder makeInitializerBuilder() {
|
| - return _makeInstance()
|
| - ..state = new IrBuilderSharedState(state.constantSystem,
|
| - state.currentElement)
|
| - ..environment = new Environment.from(environment)
|
| - ..mutableVariables = mutableVariables;
|
| - }
|
| -
|
| - /// Construct a builder for an inner function.
|
| - IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) {
|
| - IrBuilderSharedState innerState =
|
| - new IrBuilderSharedState(state.constantSystem, currentElement)
|
| - ..enclosingMethodThisParameter = state.enclosingMethodThisParameter;
|
| - return _makeInstance()
|
| - ..state = innerState
|
| - ..environment = new Environment.empty()
|
| - ..mutableVariables =
|
| - new Map<Local, ir.MutableVariable>.from(mutableVariables);
|
| - }
|
| -
|
| bool get isOpen => _root == null || _current != null;
|
|
|
| -
|
| - void buildFieldInitializerHeader({ClosureScope closureScope}) {
|
| - _enterScope(closureScope);
|
| - }
|
| -
|
| List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters,
|
| {ClosureScope closureScope,
|
| ClosureEnvironment env}) {
|
| @@ -832,87 +806,20 @@ abstract class IrBuilder {
|
| _current = null;
|
| }
|
|
|
| - ir.SuperInitializer makeSuperInitializer(ConstructorElement target,
|
| - List<ir.Body> arguments,
|
| - Selector selector) {
|
| - return new ir.SuperInitializer(target, arguments, selector);
|
| - }
|
| -
|
| - ir.FieldInitializer makeFieldInitializer(FieldElement element,
|
| - ir.Body body) {
|
| - return new ir.FieldInitializer(element, body);
|
| - }
|
| -
|
| - /// Create a [ir.FieldDefinition] for the current [Element] using [_root] as
|
| - /// the body using [initializer] as the initial value.
|
| - ir.FieldDefinition makeFieldDefinition(ir.Primitive initializer) {
|
| - if (initializer == null) {
|
| - return new ir.FieldDefinition.withoutInitializer(state.currentElement);
|
| - } else {
|
| - ir.Body body = makeBody(initializer);
|
| - return new ir.FieldDefinition(state.currentElement, body);
|
| - }
|
| - }
|
| -
|
| - ir.Body makeBody([ir.Primitive value]) {
|
| - if (value == null) {
|
| - _ensureReturn();
|
| - } else {
|
| - buildReturn(value);
|
| - }
|
| - return new ir.Body(_root, state.returnContinuation);
|
| - }
|
| -
|
| - /// Create a [ir.FunctionDefinition] for [element] using [_root] as the body.
|
| + /// Create a [ir.FunctionDefinition] using [_root] as the body.
|
| ///
|
| - /// Parameters must be created before the construction of the body using
|
| - /// [createFunctionParameter].
|
| - ir.FunctionDefinition makeFunctionDefinition(
|
| - List<ConstantExpression> defaults) {
|
| - FunctionElement element = state.currentElement;
|
| - if (element.isAbstract || element.isExternal) {
|
| - assert(invariant(element, _root == null,
|
| - message: "Non-empty body for abstract method $element: $_root"));
|
| - assert(invariant(element, state.localConstants.isEmpty,
|
| - message: "Local constants for abstract method $element: "
|
| - "${state.localConstants}"));
|
| - return new ir.FunctionDefinition.abstract(
|
| - element, state.functionParameters, defaults);
|
| - } else {
|
| - ir.Body body = makeBody();
|
| - return new ir.FunctionDefinition(
|
| - element, state.thisParameter, state.functionParameters, body,
|
| - state.localConstants, defaults);
|
| - }
|
| - }
|
| -
|
| - /// Create a constructor definition without a body, for representing
|
| - /// external constructors declarations.
|
| - ir.ConstructorDefinition makeAbstractConstructorDefinition(
|
| - List<ConstantExpression> defaults) {
|
| - FunctionElement element = state.currentElement;
|
| - assert(invariant(element, _root == null,
|
| - message: "Non-empty body for external constructor $element: $_root"));
|
| - assert(invariant(element, state.localConstants.isEmpty,
|
| - message: "Local constants for external constructor $element: "
|
| - "${state.localConstants}"));
|
| - return new ir.ConstructorDefinition.abstract(
|
| - element, state.functionParameters, defaults);
|
| - }
|
| -
|
| - ir.ConstructorDefinition makeConstructorDefinition(
|
| - List<ConstantExpression> defaults, List<ir.Initializer> initializers) {
|
| - FunctionElement element = state.currentElement;
|
| - ir.Body body = makeBody();
|
| - return new ir.ConstructorDefinition(
|
| - element, state.thisParameter, state.functionParameters, body, initializers,
|
| - state.localConstants, defaults);
|
| - }
|
| -
|
| - ir.FunctionDefinition makeLazyFieldInitializer() {
|
| - ir.Body body = makeBody();
|
| - FieldElement element = state.currentElement;
|
| - return new ir.FunctionDefinition(element, null, [], body, [], []);
|
| + /// The protocol for building a function is:
|
| + /// 1. Call [buildFunctionHeader].
|
| + /// 2. Call `buildXXX` methods to build the body.
|
| + /// 3. Call [makeFunctionDefinition] to finish.
|
| + ir.FunctionDefinition makeFunctionDefinition() {
|
| + _ensureReturn();
|
| + return new ir.FunctionDefinition(
|
| + state.currentElement,
|
| + state.thisParameter,
|
| + state.functionParameters,
|
| + state.returnContinuation,
|
| + _root);
|
| }
|
|
|
| /// Create a invocation of the [method] on the super class where the call
|
| @@ -2103,217 +2010,6 @@ abstract class IrBuilder {
|
| }
|
| }
|
|
|
| -/// Shared state between DartIrBuilders within the same method.
|
| -class DartIrBuilderSharedState {
|
| - /// [MutableVariable]s that should temporarily be treated as registers.
|
| - final Set<Local> registerizedMutableVariables = new Set<Local>();
|
| -}
|
| -
|
| -/// Dart-specific subclass of [IrBuilder].
|
| -///
|
| -/// Inner functions are represented by a [FunctionDefinition] with the
|
| -/// IR for the inner function nested inside.
|
| -///
|
| -/// Captured variables are translated to ref cells (see [MutableVariable])
|
| -/// using [GetMutableVariable] and [SetMutableVariable].
|
| -class DartIrBuilder extends IrBuilder {
|
| - final DartIrBuilderSharedState dartState;
|
| -
|
| - IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState);
|
| - DartIrBuilder._blank(this.dartState);
|
| -
|
| - DartIrBuilder(ConstantSystem constantSystem,
|
| - ExecutableElement currentElement,
|
| - Set<Local> capturedVariables)
|
| - : dartState = new DartIrBuilderSharedState() {
|
| - _init(constantSystem, currentElement);
|
| - capturedVariables.forEach(makeMutableVariable);
|
| - }
|
| -
|
| - @override
|
| - bool isInMutableVariable(Local local) {
|
| - return mutableVariables.containsKey(local) &&
|
| - !dartState.registerizedMutableVariables.contains(local);
|
| - }
|
| -
|
| - void _enterScope(ClosureScope scope) {
|
| - assert(scope == null);
|
| - }
|
| -
|
| - void _enterClosureEnvironment(ClosureEnvironment env) {
|
| - assert(env == null);
|
| - }
|
| -
|
| - void _enterForLoopInitializer(ClosureScope scope,
|
| - List<LocalElement> loopVariables) {
|
| - assert(scope == null);
|
| - for (LocalElement loopVariable in loopVariables) {
|
| - if (mutableVariables.containsKey(loopVariable)) {
|
| - // Temporarily keep the loop variable in a primitive.
|
| - // The loop variable will be added to environment when
|
| - // [declareLocalVariable] is called.
|
| - dartState.registerizedMutableVariables.add(loopVariable);
|
| - }
|
| - }
|
| - }
|
| -
|
| - void _enterForLoopBody(ClosureScope scope,
|
| - List<LocalElement> loopVariables) {
|
| - assert(scope == null);
|
| - for (LocalElement loopVariable in loopVariables) {
|
| - if (mutableVariables.containsKey(loopVariable)) {
|
| - // Move from [Primitive] into [MutableVariable].
|
| - dartState.registerizedMutableVariables.remove(loopVariable);
|
| - add(new ir.LetMutable(getMutableVariable(loopVariable),
|
| - environment.lookup(loopVariable)));
|
| - }
|
| - }
|
| - }
|
| -
|
| - void _enterForLoopUpdate(ClosureScope scope,
|
| - List<LocalElement> loopVariables) {
|
| - assert(scope == null);
|
| - // Move captured loop variables back into the local environment.
|
| - // The update expression will use the values we put in the environment,
|
| - // and then the environments for the initializer and update will be
|
| - // joined at the head of the body.
|
| - for (LocalElement loopVariable in loopVariables) {
|
| - if (isInMutableVariable(loopVariable)) {
|
| - ir.MutableVariable mutableVariable = getMutableVariable(loopVariable);
|
| - ir.Primitive value =
|
| - addPrimitive(new ir.GetMutableVariable(mutableVariable));
|
| - environment.update(loopVariable, value);
|
| - dartState.registerizedMutableVariables.add(loopVariable);
|
| - }
|
| - }
|
| - }
|
| -
|
| - void _createFunctionParameter(Local parameterElement) {
|
| - ir.Parameter parameter = new ir.Parameter(parameterElement);
|
| - _parameters.add(parameter);
|
| - if (isInMutableVariable(parameterElement)) {
|
| - state.functionParameters.add(getMutableVariable(parameterElement));
|
| - } else {
|
| - state.functionParameters.add(parameter);
|
| - environment.extend(parameterElement, parameter);
|
| - }
|
| - }
|
| -
|
| - void _createThisParameter() {
|
| - void create() {
|
| - ir.Parameter thisParameter =
|
| - new ir.Parameter(new ThisParameterLocal(state.currentElement));
|
| - state.thisParameter = thisParameter;
|
| - state.enclosingMethodThisParameter = thisParameter;
|
| - }
|
| - if (state.currentElement.isLocal) return;
|
| - if (state.currentElement.isStatic) return;
|
| - if (state.currentElement.isGenerativeConstructor) {
|
| - create();
|
| - return;
|
| - }
|
| - if (state.currentElement.isStatic) return;
|
| - if (state.currentElement.isInstanceMember) {
|
| - create();
|
| - return;
|
| - }
|
| - }
|
| -
|
| - void declareLocalVariable(LocalVariableElement variableElement,
|
| - {ir.Primitive initialValue}) {
|
| - assert(isOpen);
|
| - if (initialValue == null) {
|
| - initialValue = buildNullConstant();
|
| - }
|
| - if (isInMutableVariable(variableElement)) {
|
| - add(new ir.LetMutable(getMutableVariable(variableElement),
|
| - initialValue));
|
| - } else {
|
| - initialValue.useElementAsHint(variableElement);
|
| - environment.extend(variableElement, initialValue);
|
| - }
|
| - }
|
| -
|
| - /// Add [functionElement] to the environment with provided [definition].
|
| - void declareLocalFunction(LocalFunctionElement functionElement,
|
| - ir.FunctionDefinition definition) {
|
| - assert(isOpen);
|
| - if (isInMutableVariable(functionElement)) {
|
| - ir.MutableVariable variable = getMutableVariable(functionElement);
|
| - add(new ir.DeclareFunction(variable, definition));
|
| - } else {
|
| - ir.CreateFunction prim = addPrimitive(new ir.CreateFunction(definition));
|
| - environment.extend(functionElement, prim);
|
| - prim.useElementAsHint(functionElement);
|
| - }
|
| - }
|
| -
|
| - /// Create a function expression from [definition].
|
| - ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) {
|
| - return addPrimitive(new ir.CreateFunction(definition));
|
| - }
|
| -
|
| - /// Create a read access of [local].
|
| - @override
|
| - ir.Primitive _buildLocalGet(LocalElement local) {
|
| - assert(isOpen);
|
| - if (isInMutableVariable(local)) {
|
| - // Do not use [local] as a hint on [result]. The variable should always
|
| - // be inlined, but the hint prevents it.
|
| - return addPrimitive(new ir.GetMutableVariable(getMutableVariable(local)));
|
| - } else {
|
| - return environment.lookup(local);
|
| - }
|
| - }
|
| -
|
| - /// Create a write access to [local] with the provided [value].
|
| - @override
|
| - ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) {
|
| - assert(isOpen);
|
| - if (isInMutableVariable(local)) {
|
| - add(new ir.SetMutableVariable(getMutableVariable(local), value));
|
| - } else {
|
| - value.useElementAsHint(local);
|
| - environment.update(local, value);
|
| - }
|
| - return value;
|
| - }
|
| -
|
| - ir.Primitive buildThis() {
|
| - return state.enclosingMethodThisParameter;
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildConstructorInvocation(ConstructorElement element,
|
| - CallStructure callStructure,
|
| - DartType type,
|
| - List<ir.Primitive> arguments) {
|
| - assert(isOpen);
|
| - Selector selector =
|
| - new Selector(SelectorKind.CALL, element.memberName, callStructure);
|
| - return _continueWithExpression(
|
| - (k) => new ir.InvokeConstructor(type, element, selector,
|
| - arguments, k));
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildReifyTypeVariable(TypeVariableType variable) {
|
| - return addPrimitive(new ir.ReifyTypeVar(variable.element));
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive buildTypeOperator(ir.Primitive value,
|
| - DartType type,
|
| - {bool isTypeTest}) {
|
| - assert(isOpen);
|
| - assert(isTypeTest != null);
|
| - ir.Primitive check = _continueWithExpression(
|
| - (k) => new ir.TypeOperator(value, type,
|
| - const <ir.Primitive>[], k, isTypeTest: isTypeTest));
|
| - return check;
|
| - }
|
| -}
|
| -
|
| /// State shared between JsIrBuilders within the same function.
|
| ///
|
| /// Note that this is not shared between builders of nested functions.
|
|
|