| 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 614845e7bcd39927a9d612064424fec060f30974..d75cbbe48ec6441eaa1793e22e07d4215d8841b9 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| @@ -219,10 +219,25 @@ class IrBuilderDelimitedState {
|
| final ExecutableElement currentElement;
|
|
|
| final ir.Continuation returnContinuation = new ir.Continuation.retrn();
|
| + ir.Parameter _thisParameter;
|
| + ir.Parameter enclosingMethodThisParameter;
|
|
|
| final List<ir.Definition> functionParameters = <ir.Definition>[];
|
|
|
| IrBuilderDelimitedState(this.constantSystem, this.currentElement);
|
| +
|
| + ir.Parameter get thisParameter => _thisParameter;
|
| + void set thisParameter(ir.Parameter value) {
|
| + assert(_thisParameter == null);
|
| + _thisParameter = value;
|
| + }
|
| +}
|
| +
|
| +class ThisParameterLocal implements Local {
|
| + final ExecutableElement executableContext;
|
| + ThisParameterLocal(this.executableContext);
|
| + String get name => 'this';
|
| + toString() => 'ThisParameterLocal($executableContext)';
|
| }
|
|
|
| /// A factory for building the cps IR.
|
| @@ -296,6 +311,7 @@ abstract class IrBuilder {
|
| /// Add the given function parameter to the IR, and bind it in the environment
|
| /// or put it in its box, if necessary.
|
| void _createFunctionParameter(ParameterElement parameterElement);
|
| + void _createThisParameter();
|
|
|
| /// Creates an access to the receiver from the current (or enclosing) method.
|
| ///
|
| @@ -387,8 +403,11 @@ abstract class IrBuilder {
|
|
|
| /// Construct a builder for an inner function.
|
| IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) {
|
| + IrBuilderDelimitedState innerState =
|
| + new IrBuilderDelimitedState(state.constantSystem, currentElement)
|
| + ..enclosingMethodThisParameter = state.enclosingMethodThisParameter;
|
| return _makeInstance()
|
| - ..state = new IrBuilderDelimitedState(state.constantSystem, currentElement)
|
| + ..state = innerState
|
| ..environment = new Environment.empty();
|
| }
|
|
|
| @@ -402,6 +421,7 @@ abstract class IrBuilder {
|
| List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters,
|
| {ClosureScope closureScope,
|
| ClosureEnvironment env}) {
|
| + _createThisParameter();
|
| _enterClosureEnvironment(env);
|
| _enterScope(closureScope);
|
| parameters.forEach(_createFunctionParameter);
|
| @@ -658,11 +678,11 @@ abstract class IrBuilder {
|
| message: "Local constants for abstract method $element: "
|
| "${state.localConstants}"));
|
| return new ir.FunctionDefinition.abstract(
|
| - element, state.functionParameters, defaults);
|
| + element, state.thisParameter, state.functionParameters, defaults);
|
| } else {
|
| ir.RunnableBody body = makeRunnableBody();
|
| return new ir.FunctionDefinition(
|
| - element, state.functionParameters, body,
|
| + element, state.thisParameter, state.functionParameters, body,
|
| state.localConstants, defaults);
|
| }
|
| }
|
| @@ -686,7 +706,7 @@ abstract class IrBuilder {
|
| FunctionElement element = state.currentElement;
|
| ir.RunnableBody body = makeRunnableBody();
|
| return new ir.ConstructorDefinition(
|
| - element, state.functionParameters, body, initializers,
|
| + element, state.thisParameter, state.functionParameters, body, initializers,
|
| state.localConstants, defaults);
|
| }
|
|
|
| @@ -1147,13 +1167,17 @@ abstract class IrBuilder {
|
| bodyBuilder.add(new ir.LetCont(currentInvoked,
|
| new ir.InvokeMethod(iterator, new Selector.getter("current", null),
|
| currentInvoked, emptyArguments)));
|
| + // TODO(sra): Does this cover all cases? The general setter case include
|
| + // super.
|
| if (Elements.isLocal(variableElement)) {
|
| bodyBuilder.buildLocalSet(variableElement, currentValue);
|
| - } else if (Elements.isStaticOrTopLevel(variableElement)) {
|
| + } else if (Elements.isStaticOrTopLevel(variableElement) ||
|
| + Elements.isErroneous(variableElement)) {
|
| bodyBuilder.buildStaticSet(
|
| variableElement, variableSelector, currentValue);
|
| } else {
|
| ir.Primitive receiver = bodyBuilder.buildThis();
|
| + assert(receiver != null);
|
| bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
|
| }
|
|
|
| @@ -2037,6 +2061,26 @@ class DartIrBuilder extends IrBuilder {
|
| }
|
| }
|
|
|
| + 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);
|
| @@ -2095,7 +2139,9 @@ class DartIrBuilder extends IrBuilder {
|
| return value;
|
| }
|
|
|
| - ir.Primitive buildThis() => addPrimitive(new ir.This());
|
| + ir.Primitive buildThis() {
|
| + return state.enclosingMethodThisParameter;
|
| + }
|
|
|
| ir.Primitive buildSuperInvocation(Element target,
|
| Selector selector,
|
| @@ -2142,7 +2188,7 @@ class JsIrBuilder extends IrBuilder {
|
| if (env == null) return;
|
|
|
| // Obtain a reference to the function object (this).
|
| - ir.Primitive thisPrim = addPrimitive(new ir.This());
|
| + ir.Parameter thisPrim = state.thisParameter;
|
|
|
| // Obtain access to the free variables.
|
| env.freeVariables.forEach((Local local, ClosureLocation location) {
|
| @@ -2203,6 +2249,13 @@ class JsIrBuilder extends IrBuilder {
|
| }
|
| }
|
|
|
| + void _createThisParameter() {
|
| + if (Elements.isStaticOrTopLevel(state.currentElement)) return;
|
| + if (state.currentElement.isLocal) return;
|
| + state.thisParameter =
|
| + new ir.Parameter(new ThisParameterLocal(state.currentElement));
|
| + }
|
| +
|
| void declareLocalVariable(LocalElement variableElement,
|
| {ir.Primitive initialValue}) {
|
| assert(isOpen);
|
| @@ -2306,7 +2359,7 @@ class JsIrBuilder extends IrBuilder {
|
|
|
| ir.Primitive buildThis() {
|
| if (jsState.receiver != null) return jsState.receiver;
|
| - return addPrimitive(new ir.This());
|
| + return state.thisParameter;
|
| }
|
|
|
| ir.Primitive buildSuperInvocation(Element target,
|
| @@ -2348,6 +2401,7 @@ class JsIrBuilder extends IrBuilder {
|
| /// instead of being created in the header.
|
| void buildConstructorBodyHeader(Iterable<Local> parameters,
|
| ClosureScope closureScope) {
|
| + _createThisParameter();
|
| for (Local param in parameters) {
|
| ir.Parameter parameter = createLocalParameter(param);
|
| state.functionParameters.add(parameter);
|
|
|