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 = |