| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| index 70713dad882d0a1001d0ca5d9df52d3f68575730..09905eb5c2ceda9d4447902f074a5ac0d173a96d 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| @@ -275,6 +275,8 @@ class LocalsHandler {
|
| // classes, or the same as [:this:] for non-intercepted classes.
|
| ClassElement cls = element.getEnclosingClass();
|
| JavaScriptBackend backend = compiler.backend;
|
| + bool isNativeUpgradeFactory = element.isGenerativeConstructor()
|
| + && Elements.isNativeOrExtendsNative(cls);
|
| if (backend.isInterceptedMethod(element)) {
|
| bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
|
| SourceString name = isInterceptorClass
|
| @@ -291,6 +293,14 @@ class LocalsHandler {
|
| directLocals[closureData.thisElement] = value;
|
| }
|
| value.instructionType = builder.getTypeOfThis();
|
| + } else if (isNativeUpgradeFactory) {
|
| + bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
|
| + Element parameter = new InterceptedElement(
|
| + cls.computeType(compiler), const SourceString('receiver'), element);
|
| + HParameterValue value = new HParameterValue(parameter);
|
| + builder.graph.explicitReceiverParameter = value;
|
| + builder.graph.entry.addAtEntry(value);
|
| + value.instructionType = builder.getTypeOfThis();
|
| }
|
| }
|
|
|
| @@ -1267,6 +1277,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| }
|
| }
|
|
|
| + if (element.isGenerativeConstructor()) {
|
| + if (Elements.isNativeOrExtendsNative(element.getEnclosingClass())) {
|
| + return false;
|
| + }
|
| + }
|
| // A generative constructor body is not seen by global analysis,
|
| // so we should not query for its type.
|
| if (!element.isGenerativeConstructorBody()) {
|
| @@ -1586,9 +1601,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| TreeElements definitions = compiler.analyzeElement(member);
|
| Node node = member.parseNode(compiler);
|
| SendSet assignment = node.asSendSet();
|
| - HInstruction value;
|
| if (assignment == null) {
|
| - value = graph.addConstantNull(compiler);
|
| + // Unassigned fields of native classes are not initialized to
|
| + // prevent overwriting pre-initialized native properties.
|
| + if (!Elements.isNativeOrExtendsNative(classElement)) {
|
| + HInstruction value = graph.addConstantNull(compiler);
|
| + fieldValues[member] = value;
|
| + }
|
| } else {
|
| Node right = assignment.arguments.head;
|
| TreeElements savedElements = elements;
|
| @@ -1599,9 +1618,9 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| member, node, elements);
|
| inlinedFrom(member, () => right.accept(this));
|
| elements = savedElements;
|
| - value = pop();
|
| + HInstruction value = pop();
|
| + fieldValues[member] = value;
|
| }
|
| - fieldValues[member] = value;
|
| });
|
| });
|
| }
|
| @@ -1619,6 +1638,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| functionElement = functionElement.implementation;
|
| ClassElement classElement =
|
| functionElement.getEnclosingClass().implementation;
|
| + bool isNativeUpgradeFactory =
|
| + Elements.isNativeOrExtendsNative(classElement);
|
| FunctionExpression function = functionElement.parseNode(compiler);
|
| // Note that constructors (like any other static function) do not need
|
| // to deal with optional arguments. It is the callers job to provide all
|
| @@ -1654,10 +1675,20 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
|
|
| // Call the JavaScript constructor with the fields as argument.
|
| List<HInstruction> constructorArguments = <HInstruction>[];
|
| + List<FieldElement> fields = <FieldElement>[];
|
| +
|
| classElement.forEachInstanceField(
|
| (ClassElement enclosingClass, Element member) {
|
| - constructorArguments.add(potentiallyCheckType(
|
| - fieldValues[member], member.computeType(compiler)));
|
| + HInstruction value = fieldValues[member];
|
| + if (value == null) {
|
| + // Uninitialized native fields are pre-initialized by the native
|
| + // implementation.
|
| + assert(isNativeUpgradeFactory);
|
| + } else {
|
| + fields.add(member);
|
| + constructorArguments.add(
|
| + potentiallyCheckType(value, member.computeType(compiler)));
|
| + }
|
| },
|
| includeSuperAndInjectedMembers: true);
|
|
|
| @@ -1668,11 +1699,21 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| if (!currentInlinedInstantiations.isEmpty) {
|
| instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
|
| }
|
| - HForeignNew newObject = new HForeignNew(classElement,
|
| - ssaType,
|
| - constructorArguments,
|
| - instantiatedTypes);
|
| - add(newObject);
|
| +
|
| + HInstruction newObject;
|
| + if (!isNativeUpgradeFactory) {
|
| + newObject = new HForeignNew(classElement,
|
| + ssaType,
|
| + constructorArguments,
|
| + instantiatedTypes);
|
| + add(newObject);
|
| + } else {
|
| + // Bulk assign to the initialized fields.
|
| + newObject = graph.explicitReceiverParameter;
|
| + for (int i = 0; i < fields.length; i++) {
|
| + add(new HFieldSet(fields[i], newObject, constructorArguments[i]));
|
| + }
|
| + }
|
| removeInlinedInstantiation(type);
|
| // Create the runtime type information, if needed.
|
| if (backend.classNeedsRti(classElement)) {
|
| @@ -1684,12 +1725,22 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| }
|
|
|
| // Generate calls to the constructor bodies.
|
| + HInstruction interceptor = null;
|
| for (int index = constructors.length - 1; index >= 0; index--) {
|
| FunctionElement constructor = constructors[index];
|
| assert(invariant(functionElement, constructor.isImplementation));
|
| ConstructorBodyElement body = getConstructorBody(constructor);
|
| if (body == null) continue;
|
| +
|
| List bodyCallInputs = <HInstruction>[];
|
| + if (isNativeUpgradeFactory) {
|
| + if (interceptor == null) {
|
| + Constant constant = new InterceptorConstant(
|
| + classElement.computeType(compiler));
|
| + interceptor = graph.addConstant(constant, compiler);
|
| + }
|
| + bodyCallInputs.add(interceptor);
|
| + }
|
| bodyCallInputs.add(newObject);
|
| TreeElements elements =
|
| compiler.enqueuer.resolution.getCachedElements(constructor);
|
| @@ -1697,7 +1748,6 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| ClosureClassMap parameterClosureData =
|
| compiler.closureToClassMapper.getMappingForNestedFunction(node);
|
|
|
| -
|
| FunctionSignature functionSignature = body.computeSignature(compiler);
|
| // Provide the parameters to the generative constructor body.
|
| functionSignature.orderedForEachParameter((parameter) {
|
| @@ -1724,7 +1774,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement));
|
| }
|
|
|
| - if (tryInlineMethod(body, null, bodyCallInputs, function)) {
|
| + if (!isNativeUpgradeFactory && // TODO(sra): Fix inlining.
|
| + tryInlineMethod(body, null, bodyCallInputs, function)) {
|
| pop();
|
| } else {
|
| HInvokeConstructorBody invoke =
|
|
|