| 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 879c901740bebfc4e354fef5b500643a89895e1c..677603f725c2620ab07b0688ab2601fb55696ee4 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
|
| @@ -59,6 +59,15 @@ import 'type_mask_system.dart' show
|
|
|
| typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode);
|
|
|
| +class ExplicitReceiverParameter implements Local {
|
| + final ExecutableElement executableContext;
|
| +
|
| + ExplicitReceiverParameter(this.executableContext);
|
| +
|
| + String get name => 'receiver';
|
| + String toString() => 'ExplicitReceiverParameter($executableContext)';
|
| +}
|
| +
|
| /// This task provides the interface to build IR nodes from [ast.Node]s, which
|
| /// is used from the [CpsFunctionCompiler] to generate code.
|
| ///
|
| @@ -388,6 +397,10 @@ class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return withBuilder(builder, () {
|
| // Setup parameters and create a box if anything is captured.
|
| List<Local> parameters = <Local>[];
|
| + if (constructor.isGenerativeConstructor &&
|
| + backend.isNativeOrExtendsNative(classElement)) {
|
| + parameters.add(new ExplicitReceiverParameter(constructor));
|
| + }
|
| constructor.functionSignature.orderedForEachParameter(
|
| (ParameterElement p) => parameters.add(p));
|
|
|
| @@ -446,9 +459,11 @@ class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| // --- Create the object ---
|
| // Get the initial field values in the canonical order.
|
| List<ir.Primitive> instanceArguments = <ir.Primitive>[];
|
| + List<FieldElement> fields = <FieldElement>[];
|
| classElement.forEachInstanceField((ClassElement c, FieldElement field) {
|
| ir.Primitive value = fieldValues[field];
|
| if (value != null) {
|
| + fields.add(field);
|
| instanceArguments.add(value);
|
| } else {
|
| assert(backend.isNativeOrExtendsNative(c));
|
| @@ -456,16 +471,30 @@ class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| }
|
| }, includeSuperAndInjectedMembers: true);
|
|
|
| - ir.Primitive instance = new ir.CreateInstance(
|
| + ir.Primitive instance;
|
| + if (constructor.isGenerativeConstructor &&
|
| + backend.isNativeOrExtendsNative(classElement)) {
|
| + instance = irParameters.first;
|
| + instance.type =
|
| + new TypeMask.exact(classElement, typeMaskSystem.classWorld);
|
| + irBuilder.addPrimitive(new ir.ReceiverCheck.nullCheck(
|
| + instance, Selectors.toString_, null));
|
| + for (int i = 0; i < fields.length; i++) {
|
| + irBuilder.addPrimitive(
|
| + new ir.SetField(instance, fields[i], instanceArguments[i]));
|
| + }
|
| + } else {
|
| + instance = new ir.CreateInstance(
|
| classElement,
|
| instanceArguments,
|
| typeInformation,
|
| constructor.hasNode
|
| ? sourceInformationBuilder.buildCreate(constructor.node)
|
| - // TODO(johnniwinther): Provide source information for creation
|
| - // through synthetic constructors.
|
| + // TODO(johnniwinther): Provide source information for creation
|
| + // through synthetic constructors.
|
| : null);
|
| - irBuilder.add(new ir.LetPrim(instance));
|
| + irBuilder.add(new ir.LetPrim(instance));
|
| + }
|
|
|
| // --- Call constructor bodies ---
|
| for (ConstructorElement target in constructorList) {
|
| @@ -2369,6 +2398,10 @@ class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| }
|
|
|
| List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
|
| + if (constructor.isGenerativeConstructor &&
|
| + backend.isNativeOrExtendsNative(constructor.enclosingClass)) {
|
| + arguments.insert(0, irBuilder.buildNullConstant());
|
| + }
|
| // Use default values from the effective target, not the immediate target.
|
| ConstructorElement target;
|
| if (constructor == compiler.symbolConstructor) {
|
|
|