Chromium Code Reviews| Index: frog/leg/ssa/builder.dart |
| diff --git a/frog/leg/ssa/builder.dart b/frog/leg/ssa/builder.dart |
| index d17f73f1fb12b3403ebba5866b3f02ccff28c2c3..d154942c2e10c4434a5d74c902ad6cc0f9225e09 100644 |
| --- a/frog/leg/ssa/builder.dart |
| +++ b/frog/leg/ssa/builder.dart |
| @@ -10,8 +10,19 @@ class SsaBuilderTask extends CompilerTask { |
| return measure(() { |
| FunctionExpression function = element.node; |
| HInstruction.idCounter = 0; |
| - HGraph graph = |
| - compileMethod(function.parameters, function.body, elements); |
| + SsaBuilder builder = new SsaBuilder(compiler, elements); |
| + HGraph graph; |
| + switch (element.kind) { |
| + case ElementKind.CONSTRUCTOR: |
| + graph = compileConstructor(builder, function, element, elements); |
|
ngeoffray
2011/12/08 16:01:40
I wouuld have the same API between compileConstruc
floitsch
2011/12/08 16:36:00
Done.
|
| + break; |
| + case ElementKind.CONSTRUCTOR_BODY: |
| + graph = compileConstructorBody(builder, function); |
| + break; |
| + case ElementKind.FUNCTION: |
| + graph = compileMethod(builder, function); |
| + break; |
| + } |
| assert(graph.isValid()); |
| if (GENERATE_SSA_TRACE) { |
| Identifier name = function.name; |
| @@ -22,12 +33,29 @@ class SsaBuilderTask extends CompilerTask { |
| }); |
| } |
| - HGraph compileMethod(NodeList parameters, |
| - Node body, |
| - TreeElements elements) { |
| - SsaBuilder builder = new SsaBuilder(compiler, elements); |
| - HGraph graph = builder.build(parameters, body); |
| - return graph; |
| + HGraph compileConstructor(SsaBuilder builder, |
| + FunctionExpression function, |
| + FunctionElement element, |
| + TreeElements elements) { |
| + // The body of the constructor will be generated in a separate function. |
| + ConstructorBodyElement bodyElement = new ConstructorBodyElement(element); |
| + compiler.worklist.add(new WorkElement.toCodegen(bodyElement, elements)); |
| + ClassElement classElement = element.enclosingElement; |
| + classElement.backendMembers.add(bodyElement); |
| + // TODO(floitsch): pass initializer-list to builder. |
| + return builder.buildFactory(classElement, bodyElement, function.parameters); |
| + } |
| + |
| + HGraph compileConstructorBody(SsaBuilder builder, |
| + FunctionExpression function) { |
| + // TODO(floitsch): find super call and pass it to the builder. |
| + return builder.buildConstructorBody(null, |
| + function.parameters, |
| + function.body); |
| + } |
| + |
| + HGraph compileMethod(SsaBuilder builder, FunctionExpression function) { |
| + return builder.buildMethod(function.parameters, function.body); |
| } |
| } |
| @@ -51,7 +79,54 @@ class SsaBuilder implements Visitor { |
| SsaBuilder(this.compiler, this.elements); |
| - HGraph build(NodeList parameters, Node body) { |
| + HGraph buildMethod(NodeList parameters, Node body) { |
| + openFunction(parameters); |
| + body.accept(this); |
| + return closeFunction(); |
| + } |
| + |
| + HGraph buildFactory(ClassElement classElement, |
| + ConstructorBodyElement bodyElement, |
| + NodeList parameters) { |
| + openFunction(parameters); |
| + HForeignNew newObject = new HForeignNew(classElement, []); |
| + add(newObject); |
| + String methodName = |
| + compiler.namer.constructorBodyName(bodyElement.constructor); |
| + List bodyCallInputs = <HInstruction>[]; |
| + bodyCallInputs.add(newObject); |
| + Link link = parameters.nodes; |
| + for (; !link.isEmpty(); link = link.tail) { |
| + Element parameterElement = elements[link.head]; |
| + HInstruction currentValue = definitions[parameterElement]; |
| + bodyCallInputs.add(currentValue); |
| + } |
| + add(new HInvokeDynamic(methodName, bodyCallInputs)); |
| + close(new HReturn(newObject)).addSuccessor(graph.exit); |
| + return closeFunction(); |
| + } |
| + |
| + HGraph buildConstructorBody(Send superInvocation, |
| + NodeList parameters, |
| + Node body) { |
| + openFunction(parameters); |
| + if (superInvocation !== null) { |
|
ngeoffray
2011/12/08 16:01:40
I'm not really fund of having code that we know is
floitsch
2011/12/08 16:36:00
Done.
|
| + Element superElement = elements[superInvocation]; |
| + String methodName = compiler.namer.constructorBodyName(superElement); |
| + List superInputs = <HInstruction>[]; |
| + superInputs.add(new HThis()); |
| + Link link = superInvocation.arguments.head; |
| + for (; !link.isEmpty(); link = link.tail) { |
| + visit(link.head); |
| + superInputs.add(pop()); |
| + } |
| + add(new HInvokeDynamic(methodName, superInputs)); |
| + } |
| + body.accept(this); |
| + return closeFunction(); |
| + } |
| + |
| + void openFunction(NodeList parameters) { |
| stack = new List<HInstruction>(); |
| definitions = new Map<Element, HInstruction>(); |
| @@ -62,9 +137,10 @@ class SsaBuilder implements Visitor { |
| visitParameterValues(parameters); |
| close(new HGoto()).addSuccessor(block); |
| - open(block); |
| - body.accept(this); |
| + open(block); |
| + } |
| + HGraph closeFunction() { |
| // TODO(kasperl): Make this goto an implicit return. |
| if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); |
| graph.finalize(); |
| @@ -590,7 +666,7 @@ class SsaBuilder implements Visitor { |
| } |
| visitNewExpression(NewExpression node) { |
| - compiler.unimplemented("SsaBuilder: new expression"); |
| + visitSend(node.send); |
|
ngeoffray
2011/12/08 16:01:40
=> syntax?
floitsch
2011/12/08 16:36:00
Done.
|
| } |
| HInstruction updateDefinition(Node node, HInstruction value) { |