Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2249)

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 25675002: Generative constructor factories for native objects (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 054170945afacdfc5180699b48f3b581c57e2bfa..60bb2adbed4f60cf0403efa1466817b36b487f8e 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()
ngeoffray 2013/10/17 09:08:59 What is a native upgrade factory?
sra1 2013/10/18 04:09:32 Added comment
+ && 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();
ngeoffray 2013/10/17 09:08:59 This seems very similar to the code line 281 to 29
sra1 2013/10/18 04:09:32 In the fixed version there are more differences, e
}
}
@@ -1267,6 +1277,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
}
+ // Generative constructors of native classes should not be called directly
+ // and have an extra argument that causes problems with inlining.
+ if (element.isGenerativeConstructor()
+ && 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 +1603,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);
ngeoffray 2013/10/17 09:08:59 Avoid the temporary?
sra1 2013/10/18 04:09:32 Done.
+ fieldValues[member] = value;
+ }
} else {
Node right = assignment.arguments.head;
TreeElements savedElements = elements;
@@ -1599,9 +1620,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;
ngeoffray 2013/10/17 09:08:59 Avoid the temporary?
sra1 2013/10/18 04:09:32 Done.
}
- fieldValues[member] = value;
});
});
}
@@ -1619,6 +1640,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 +1677,20 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
// Call the JavaScript constructor with the fields as argument.
List<HInstruction> constructorArguments = <HInstruction>[];
+ List<Element> fields = <Element>[];
+
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 +1701,25 @@ 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;
+ // Null guard ensures an error if we are being called from an explicit
+ // 'new' of the constructor instead of via an upgrade. It is optimized out
+ // if there are field initializers.
+ add(new HFieldGet(null, newObject, isAssignable: false));
+ 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 +1731,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 +1754,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 +1780,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement));
}
- if (tryInlineMethod(body, null, bodyCallInputs, function)) {
+ if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
+ tryInlineMethod(body, null, bodyCallInputs, function)) {
pop();
} else {
HInvokeConstructorBody invoke =
@@ -3565,6 +3622,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
var inputs = <HInstruction>[];
+ if (constructor.isGenerativeConstructor() &&
+ Elements.isNativeOrExtendsNative(constructor.getEnclosingClass())) {
+ // Native class generative constructors take a pre-constructed object.
+ inputs.add(graph.addConstantNull(compiler));
+ }
// TODO(5347): Try to avoid the need for calling [implementation] before
// calling [addStaticSendArgumentsToList].
bool succeeded = addStaticSendArgumentsToList(selector, send.arguments,

Powered by Google App Engine
This is Rietveld 408576698