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

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9642001: Make string juxtaposition combine properly with string interpolations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove last bugs and clean up builder. Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 visit(node.receiver); 1313 visit(node.receiver);
1314 HNot not = new HNot(popBoolified()); 1314 HNot not = new HNot(popBoolified());
1315 push(not); 1315 push(not);
1316 } 1316 }
1317 1317
1318 void visitUnary(Send node, Operator op) { 1318 void visitUnary(Send node, Operator op) {
1319 assert(node.argumentsNode is Prefix); 1319 assert(node.argumentsNode is Prefix);
1320 visit(node.receiver); 1320 visit(node.receiver);
1321 assert(op.token.kind !== PLUS_TOKEN); 1321 assert(op.token.kind !== PLUS_TOKEN);
1322 HInstruction operand = pop(); 1322 HInstruction operand = pop();
1323
1323 HInstruction target = 1324 HInstruction target =
1324 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); 1325 new HStatic(interceptors.getPrefixOperatorInterceptor(op));
1325 add(target); 1326 add(target);
1326 HInvokeUnary result; 1327 HInvokeUnary result;
1327 switch (op.source.stringValue) { 1328 switch (op.source.stringValue) {
1328 case "-": result = new HNegate(target, operand); break; 1329 case "-": result = new HNegate(target, operand); break;
1329 case "~": result = new HBitNot(target, operand); break; 1330 case "~": result = new HBitNot(target, operand); break;
1330 default: unreachable(); 1331 default: unreachable();
1331 } 1332 }
1332 // See if we can constant-fold right away. This avoids rewrites later on. 1333 // See if we can constant-fold right away. This avoids rewrites later on.
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 } 1957 }
1957 1958
1958 void visitLiteralBool(LiteralBool node) { 1959 void visitLiteralBool(LiteralBool node) {
1959 stack.add(graph.addConstantBool(node.value)); 1960 stack.add(graph.addConstantBool(node.value));
1960 } 1961 }
1961 1962
1962 void visitLiteralString(LiteralString node) { 1963 void visitLiteralString(LiteralString node) {
1963 stack.add(graph.addConstantString(node.dartString)); 1964 stack.add(graph.addConstantString(node.dartString));
1964 } 1965 }
1965 1966
1966 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { 1967 void visitStringJuxtaposition(StringJuxtaposition node) {
1967 visitLiteralString(node); 1968 if (node.dartString !== null) {
ngeoffray 2012/03/14 12:29:58 !node.isInterpolation
Lasse Reichstein Nielsen 2012/03/14 13:04:49 Done. At this point, we know that things are eithe
1969 // This is a simple string with no interpolations.
1970 stack.add(graph.addConstantString(node.dartString));
1971 return;
1972 }
1973 int offset = node.getBeginToken().charOffset;
1974 StringBuilderVisitor stringBuilder =
1975 new StringBuilderVisitor(this, offset);
1976 stringBuilder.visit(node);
1977 stack.add(stringBuilder.result());
1968 } 1978 }
1969 1979
1970 void visitLiteralNull(LiteralNull node) { 1980 void visitLiteralNull(LiteralNull node) {
1971 stack.add(graph.addConstantNull()); 1981 stack.add(graph.addConstantNull());
1972 } 1982 }
1973 1983
1974 visitNodeList(NodeList node) { 1984 visitNodeList(NodeList node) {
1975 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 1985 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
1976 if (isAborted()) { 1986 if (isAborted()) {
1977 compiler.reportWarning(link.head, 'dead code'); 1987 compiler.reportWarning(link.head, 'dead code');
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 open(joinBlock); 2090 open(joinBlock);
2081 2091
2082 localsHandler.mergeWith(thenLocals, joinBlock); 2092 localsHandler.mergeWith(thenLocals, joinBlock);
2083 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]); 2093 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]);
2084 joinBlock.addPhi(phi); 2094 joinBlock.addPhi(phi);
2085 stack.add(phi); 2095 stack.add(phi);
2086 } 2096 }
2087 2097
2088 visitStringInterpolation(StringInterpolation node) { 2098 visitStringInterpolation(StringInterpolation node) {
2089 int offset = node.getBeginToken().charOffset; 2099 int offset = node.getBeginToken().charOffset;
2090 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset)); 2100 StringBuilderVisitor stringBuilder =
2091 HInstruction target = new HStatic(interceptors.getOperatorInterceptor(op)); 2101 new StringBuilderVisitor(this, offset);
2092 add(target); 2102 stringBuilder.visit(node);
2093 visit(node.string); 2103 stack.add(stringBuilder.result());
2094 // Handle the parts here, to avoid recreating [target].
2095 for (StringInterpolationPart part in node.parts) {
2096 HInstruction prefix = pop();
2097 visit(part.expression);
2098 push(new HAdd(target, prefix, pop()));
2099 prefix = pop();
2100 visit(part.string);
2101 push(new HAdd(target, prefix, pop()));
2102 }
2103 } 2104 }
2104 2105
2105 visitStringInterpolationPart(StringInterpolationPart node) { 2106 visitStringInterpolationPart(StringInterpolationPart node) {
2106 // The parts are iterated in visitStringInterpolation. 2107 // The parts are iterated in visitStringInterpolation.
2107 unreachable(); 2108 unreachable();
2108 } 2109 }
2109 2110
2110 visitEmptyStatement(EmptyStatement node) { 2111 visitEmptyStatement(EmptyStatement node) {
2111 // Do nothing, empty statement. 2112 // Do nothing, empty statement.
2112 } 2113 }
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
2561 buildBody() { 2562 buildBody() {
2562 // TODO(lrn): Make sure to take continue into account. 2563 // TODO(lrn): Make sure to take continue into account.
2563 visit(body); 2564 visit(body);
2564 if (isAborted()) { 2565 if (isAborted()) {
2565 compiler.reportWarning(body, "aborting loop body"); 2566 compiler.reportWarning(body, "aborting loop body");
2566 } 2567 }
2567 } 2568 }
2568 handleIf(buildBody, null); 2569 handleIf(buildBody, null);
2569 } 2570 }
2570 } 2571 }
2572
2573 /**
2574 * Visitor that handles generation of string literals (LiteralString,
2575 * StringInterpolation), and otherwise delegates to the given visitor for
2576 * non-literal subexpressions.
2577 * TODO(lrn): Consider whether to handle compile time constant int/boolan
ngeoffray 2012/03/14 12:29:58 boolan -> boolean
Lasse Reichstein Nielsen 2012/03/14 13:04:49 Done.
2578 * expressions as well.
2579 */
2580 class StringBuilderVisitor extends AbstractVisitor {
2581 final SsaBuilder builder;
2582 // Offset used for the synthetic operator token used by concat.
2583 // Can probably be removed when we stop using String.operator+.
2584 final int offset;
2585 // Used to collect concatenated string literals into a single literal
2586 // instead of introducing unnecessary concatenations.
2587 DartString accumulator = const LiteralDartString("");
2588 // The string value generated so far (not including that which is still
2589 // in [accumulator]).
2590 HInstruction prefix = null;
ngeoffray 2012/03/14 12:29:58 IMO 'current' would be better than 'prefix'. But t
Lasse Reichstein Nielsen 2012/03/14 13:04:49 Yes, it's really an "instruction accumulator" (as
2591
2592 StringBuilderVisitor(this.builder, this.offset);
2593
2594 void visit(Node node) {
2595 node.accept(this);
2596 }
2597
2598 void visitNode() {
2599 unreachable();
2600 }
2601
2602 void visitExpression(Node node) {
2603 flushAccumulator();
2604 node.accept(builder);
2605 prefix = concat(prefix, builder.pop());
2606 }
2607
2608 void visitStringInterpolation(StringInterpolation node) {
2609 node.visitChildren(this);
2610 }
2611
2612 void visitStringInterpolationPart(StringInterpolationPart node) {
2613 visit(node.expression);
2614 visit(node.string);
2615 }
2616
2617 void visitLiteralString(LiteralString node) {
2618 accumulator = new DartString.concat(accumulator, node.dartString);
2619 }
2620
2621 void visitStringJuxtaposition(StringJuxtaposition node) {
2622 node.visitChildren(this);
2623 }
2624
2625 void visitNodeList(NodeList node) {
2626 node.visitChildren(this);
2627 }
2628
2629 /**
2630 * Combine the strings in [accumulator] into the prefix instruction.
2631 * After this, the [accumulator] is empty and [prefix] is non-null.
2632 */
2633 void flushAccumulator() {
2634 if (accumulator.isEmpty()) {
2635 if (prefix === null) {
2636 prefix = builder.graph.addConstantString(accumulator);
2637 }
2638 return;
2639 }
2640 HInstruction string = builder.graph.addConstantString(accumulator);
2641 accumulator = new DartString.empty();
2642 if (prefix !== null) {
2643 prefix = concat(prefix, string);
2644 } else {
2645 prefix = string;
2646 }
2647 }
2648
2649 HInstruction concat(HInstruction left, HInstruction right) {
2650 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset));
2651 HStatic target =
2652 new HStatic(builder.interceptors.getOperatorInterceptor(op));
2653 builder.add(target);
2654 HInstruction concat = new HAdd(target, left, right);
2655 builder.add(concat);
2656 return concat;
2657 }
2658
2659 HInstruction result() {
2660 flushAccumulator();
2661 return prefix;
2662 }
2663 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698