Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
=================================================================== |
--- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 23016) |
+++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
@@ -103,10 +103,7 @@ |
} |
HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) { |
- // The body of the constructor will be generated in a separate function. |
- final ClassElement classElement = work.element.getEnclosingClass(); |
- return builder.buildFactory(classElement.implementation, |
- work.element.implementation); |
+ return builder.buildFactory(work.element); |
} |
} |
@@ -279,8 +276,7 @@ |
builder.graph.thisInstruction = thisInstruction; |
builder.graph.entry.addAtEntry(thisInstruction); |
updateLocal(closureData.closureElement, thisInstruction); |
- } else if (element.isInstanceMember() |
- || element.isGenerativeConstructor()) { |
+ } else if (element.isInstanceMember()) { |
// Once closures have been mapped to classes their instance members might |
// not have any thisElement if the closure was created inside a static |
// context. |
@@ -1117,6 +1113,7 @@ |
} |
HParameterValue addParameter(Element element) { |
+ assert(inliningStack.isEmpty); |
HParameterValue result = new HParameterValue(element); |
if (lastAddedParameter == null) { |
graph.entry.addBefore(graph.entry.first, result); |
@@ -1179,7 +1176,7 @@ |
// may have an impact on the state of the current method. |
InliningState state = new InliningState( |
function, returnElement, returnType, elements, stack, localsHandler); |
- LocalsHandler newLocalsHandler = new LocalsHandler.from(localsHandler); |
+ LocalsHandler newLocalsHandler = new LocalsHandler(this); |
newLocalsHandler.closureData = |
compiler.closureToClassMapper.computeClosureToClassMapping( |
function, function.parseNode(compiler), elements); |
@@ -1273,7 +1270,6 @@ |
if (element is !PartialFunctionElement) return false; |
// TODO(ngeoffray): try to inline generative constructors. They |
// don't have any body, which make it more difficult. |
- if (element.isGenerativeConstructor()) return false; |
if (inliningStack.length > MAX_INLINING_DEPTH) return false; |
// Don't inline recursive calls. We use the same elements for the inlined |
// functions and would thus clobber our local variables. |
@@ -1331,7 +1327,9 @@ |
InliningState state = enterInlinedMethod( |
function, selector, argumentsNodes, providedArguments, currentNode); |
inlinedFrom(element, () { |
- functionExpression.body.accept(this); |
+ element.isGenerativeConstructor() |
+ ? buildFactory(element) |
+ : functionExpression.body.accept(this); |
}); |
leaveInlinedMethod(state); |
return true; |
@@ -1437,11 +1435,6 @@ |
ClosureClassMap newClosureData = |
compiler.closureToClassMapper.computeClosureToClassMapping( |
constructor, node, elements); |
- // The [:this:] element now refers to the one in the new closure |
- // data, that is the [:this:] of the super constructor. We |
- // update the element to refer to the current [:this:]. |
- localsHandler.updateLocal(newClosureData.thisElement, |
- localsHandler.readThis()); |
localsHandler.closureData = newClosureData; |
params.orderedForEachParameter((Element parameterElement) { |
@@ -1577,21 +1570,20 @@ |
* to, starting from the current constructor. |
* - Call the the constructor bodies, starting from the constructor(s) in the |
* super class(es). |
- * |
- * Invariant: Both [classElement] and [functionElement] must be |
- * implementation elements. |
*/ |
- HGraph buildFactory(ClassElement classElement, |
- FunctionElement functionElement) { |
- assert(invariant(classElement, classElement.isImplementation)); |
- assert(invariant(functionElement, functionElement.isImplementation)); |
+ HGraph buildFactory(FunctionElement functionElement) { |
+ functionElement = functionElement.implementation; |
+ ClassElement classElement = |
+ functionElement.getEnclosingClass().implementation; |
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 |
// arguments as if they were positional. |
- // The initializer list could contain closures. |
- openFunction(functionElement, function); |
+ if (inliningStack.isEmpty) { |
+ // The initializer list could contain closures. |
+ openFunction(functionElement, function); |
+ } |
Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); |
@@ -1699,8 +1691,13 @@ |
invoke.sideEffects = compiler.world.getSideEffectsOfElement(constructor); |
add(invoke); |
} |
- closeAndGotoExit(new HReturn(newObject)); |
- return closeFunction(); |
+ if (inliningStack.isEmpty) { |
+ closeAndGotoExit(new HReturn(newObject)); |
+ return closeFunction(); |
+ } else { |
+ localsHandler.updateLocal(returnElement, newObject); |
+ return null; |
+ } |
} |
void addParameterCheckInstruction(Element element) { |
@@ -5058,6 +5055,7 @@ |
static bool canBeInlined(FunctionExpression functionExpression, |
TreeElements elements) { |
InlineWeeder weeder = new InlineWeeder(elements); |
+ weeder.visit(functionExpression.initializers); |
weeder.visit(functionExpression.body); |
if (weeder.tooDifficult) return false; |
return true; |
@@ -5073,7 +5071,7 @@ |
} |
void visit(Node node) { |
- node.accept(this); |
+ if (node != null) node.accept(this); |
} |
void visitNode(Node node) { |