Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| index dcaf7e96cc29f6238ccdad8799335290f3bf3981..f75d56fa174c464a8b8e9c959cb82cb187c5df9d 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| @@ -65,6 +65,19 @@ class Variable extends Expression { |
| } |
| /** |
| + * A sequence of expressions. |
| + */ |
| +class Sequence extends Expression { |
| + final List<Expression> expressions; |
| + |
| + Sequence(this.expressions); |
| + |
| + bool get isPure => expressions.every((e) => e.isPure); |
| + |
| + accept(Visitor visitor) => visitor.visitSequence(this); |
| +} |
| + |
| +/** |
| * A local binding of a [Variable] to an [Expression]. |
| * |
| * In contrast to the CPS-based IR, non-primitive expressions can be named |
| @@ -134,6 +147,7 @@ abstract class Visitor<T> { |
| // Concrete classes. |
| T visitVariable(Variable node) => visitExpression(node); |
| + T visitSequence(Sequence node) => visitExpression(node); |
| T visitLetVal(LetVal node) => visitExpression(node); |
| T visitInvokeStatic(InvokeStatic node) => visitExpression(node); |
| T visitReturn(Return node) => visitExpression(node); |
| @@ -197,10 +211,14 @@ class Builder extends ir.Visitor<Expression> { |
| Expression visitLetPrim(ir.LetPrim node) { |
| // LetPrim is translated to LetVal. |
| - Variable variable = new Variable(); |
| Expression definition = node.primitive.accept(this); |
| - variables[node.primitive] = variable; |
| - return new LetVal(variable, definition, node.body.accept(this)); |
| + if (node.primitive.hasAtLeastOneUse) { |
| + Variable variable = new Variable(); |
| + variables[node.primitive] = variable; |
| + return new LetVal(variable, definition, node.body.accept(this)); |
| + } else { |
| + return new Sequence([definition, node.body.accept(this)]); |
| + } |
| } |
| Expression visitLetCont(ir.LetCont node) { |
| @@ -220,9 +238,13 @@ class Builder extends ir.Visitor<Expression> { |
| return new Return(invoke); |
| } else { |
| assert(cont.hasExactlyOneUse); |
| - Variable variable = new Variable(); |
| - variables[cont.parameter] = variable; |
| - return new LetVal(variable, invoke, cont.body.accept(this)); |
| + if (cont.parameter.hasAtLeastOneUse) { |
| + Variable variable = new Variable(); |
| + variables[cont.parameter] = variable; |
| + return new LetVal(variable, invoke, cont.body.accept(this)); |
| + } else { |
| + return new Sequence([invoke, cont.body.accept(this)]); |
| + } |
| } |
| } |
| @@ -320,6 +342,13 @@ class Unnamer extends Visitor<Expression> { |
| return node; |
| } |
| + Expression visitSequence(Sequence node) { |
| + for (int i = 0; i < node.expressions.length; ++i) { |
| + node.expressions[i] = node.expressions[i].accept(this); |
| + } |
| + return node; |
| + } |
| + |
| Expression visitLetVal(LetVal node) { |
| environment.add(node); |
| Expression body = node.body.accept(this); |
| @@ -479,6 +508,19 @@ class Emitter extends Visitor<ast.Node> { |
| semicolon, |
| value); |
| } |
| + } else if (body is ast.Block) { |
| + // Remove a final 'return null' that ends the body block. |
| + Link<ast.Node> nodes = (body as ast.Block).statements.nodes; |
| + ast.Node last; |
| + for (var n in nodes) { |
|
floitsch
2014/04/04 11:14:27
Why not ast.Node last = nodes.last; or even
if (no
|
| + last = n; |
| + } |
| + if (last is ast.Return) { |
| + List<ast.Node> statements = |
| + (body as ast.Block).statements.nodes.toList(); |
| + statements.removeLast(); |
| + body = makeBlock(statements); |
| + } |
| } |
| return new ast.FunctionExpression(name, parameters, body, returnType, |
| @@ -534,6 +576,10 @@ class Emitter extends Visitor<ast.Node> { |
| return new ast.Send(null, node.identifier); |
| } |
| + ast.Node visitSequence(Sequence node) { |
| + return node.expressions.map((e) => e.accept(this)).reduce(concatenate); |
| + } |
| + |
| ast.Node visitLetVal(LetVal node) { |
| // Let bindings translate into assignments. |
| ast.Identifier identifier = node.variable.assignIdentifier(); |