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

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: Addressed comments so far. 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 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 visit(node.receiver); 1398 visit(node.receiver);
1399 HNot not = new HNot(popBoolified()); 1399 HNot not = new HNot(popBoolified());
1400 push(not); 1400 push(not);
1401 } 1401 }
1402 1402
1403 void visitUnary(Send node, Operator op) { 1403 void visitUnary(Send node, Operator op) {
1404 assert(node.argumentsNode is Prefix); 1404 assert(node.argumentsNode is Prefix);
1405 visit(node.receiver); 1405 visit(node.receiver);
1406 assert(op.token.kind !== PLUS_TOKEN); 1406 assert(op.token.kind !== PLUS_TOKEN);
1407 HInstruction operand = pop(); 1407 HInstruction operand = pop();
1408
1408 HInstruction target = 1409 HInstruction target =
1409 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); 1410 new HStatic(interceptors.getPrefixOperatorInterceptor(op));
1410 add(target); 1411 add(target);
1411 HInvokeUnary result; 1412 HInvokeUnary result;
1412 switch (op.source.stringValue) { 1413 switch (op.source.stringValue) {
1413 case "-": result = new HNegate(target, operand); break; 1414 case "-": result = new HNegate(target, operand); break;
1414 case "~": result = new HBitNot(target, operand); break; 1415 case "~": result = new HBitNot(target, operand); break;
1415 default: unreachable(); 1416 default: unreachable();
1416 } 1417 }
1417 // See if we can constant-fold right away. This avoids rewrites later on. 1418 // See if we can constant-fold right away. This avoids rewrites later on.
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 } 2074 }
2074 2075
2075 void visitLiteralBool(LiteralBool node) { 2076 void visitLiteralBool(LiteralBool node) {
2076 stack.add(graph.addConstantBool(node.value)); 2077 stack.add(graph.addConstantBool(node.value));
2077 } 2078 }
2078 2079
2079 void visitLiteralString(LiteralString node) { 2080 void visitLiteralString(LiteralString node) {
2080 stack.add(graph.addConstantString(node.dartString)); 2081 stack.add(graph.addConstantString(node.dartString));
2081 } 2082 }
2082 2083
2083 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { 2084 void visitStringJuxtaposition(StringJuxtaposition node) {
2084 visitLiteralString(node); 2085 if (!node.isInterpolation) {
2086 // This is a simple string with no interpolations.
2087 stack.add(graph.addConstantString(node.dartString));
2088 return;
2089 }
2090 int offset = node.getBeginToken().charOffset;
2091 StringBuilderVisitor stringBuilder =
2092 new StringBuilderVisitor(this, offset);
2093 stringBuilder.visit(node);
2094 stack.add(stringBuilder.result());
2085 } 2095 }
2086 2096
2087 void visitLiteralNull(LiteralNull node) { 2097 void visitLiteralNull(LiteralNull node) {
2088 stack.add(graph.addConstantNull()); 2098 stack.add(graph.addConstantNull());
2089 } 2099 }
2090 2100
2091 visitNodeList(NodeList node) { 2101 visitNodeList(NodeList node) {
2092 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 2102 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
2093 if (isAborted()) { 2103 if (isAborted()) {
2094 compiler.reportWarning(link.head, 'dead code'); 2104 compiler.reportWarning(link.head, 'dead code');
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2197 open(joinBlock); 2207 open(joinBlock);
2198 2208
2199 localsHandler.mergeWith(thenLocals, joinBlock); 2209 localsHandler.mergeWith(thenLocals, joinBlock);
2200 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]); 2210 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]);
2201 joinBlock.addPhi(phi); 2211 joinBlock.addPhi(phi);
2202 stack.add(phi); 2212 stack.add(phi);
2203 } 2213 }
2204 2214
2205 visitStringInterpolation(StringInterpolation node) { 2215 visitStringInterpolation(StringInterpolation node) {
2206 int offset = node.getBeginToken().charOffset; 2216 int offset = node.getBeginToken().charOffset;
2207 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset)); 2217 StringBuilderVisitor stringBuilder =
2208 HInstruction target = new HStatic(interceptors.getOperatorInterceptor(op)); 2218 new StringBuilderVisitor(this, offset);
2209 add(target); 2219 stringBuilder.visit(node);
2210 visit(node.string); 2220 stack.add(stringBuilder.result());
2211 // Handle the parts here, to avoid recreating [target].
2212 for (StringInterpolationPart part in node.parts) {
2213 HInstruction prefix = pop();
2214 visit(part.expression);
2215 push(new HAdd(target, prefix, pop()));
2216 prefix = pop();
2217 visit(part.string);
2218 push(new HAdd(target, prefix, pop()));
2219 }
2220 } 2221 }
2221 2222
2222 visitStringInterpolationPart(StringInterpolationPart node) { 2223 visitStringInterpolationPart(StringInterpolationPart node) {
2223 // The parts are iterated in visitStringInterpolation. 2224 // The parts are iterated in visitStringInterpolation.
2224 unreachable(); 2225 unreachable();
2225 } 2226 }
2226 2227
2227 visitEmptyStatement(EmptyStatement node) { 2228 visitEmptyStatement(EmptyStatement node) {
2228 // Do nothing, empty statement. 2229 // Do nothing, empty statement.
2229 } 2230 }
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
2701 buildBody() { 2702 buildBody() {
2702 // TODO(lrn): Make sure to take continue into account. 2703 // TODO(lrn): Make sure to take continue into account.
2703 visit(body); 2704 visit(body);
2704 if (isAborted()) { 2705 if (isAborted()) {
2705 compiler.reportWarning(body, "aborting loop body"); 2706 compiler.reportWarning(body, "aborting loop body");
2706 } 2707 }
2707 } 2708 }
2708 handleIf(buildBody, null); 2709 handleIf(buildBody, null);
2709 } 2710 }
2710 } 2711 }
2712
2713 /**
2714 * Visitor that handles generation of string literals (LiteralString,
2715 * StringInterpolation), and otherwise delegates to the given visitor for
2716 * non-literal subexpressions.
2717 * TODO(lrn): Consider whether to handle compile time constant int/boolean
2718 * expressions as well.
2719 */
2720 class StringBuilderVisitor extends AbstractVisitor {
2721 final SsaBuilder builder;
2722 // Offset used for the synthetic operator token used by concat.
ahe 2012/03/19 15:53:06 Documentation comment.
Lasse Reichstein Nielsen 2012/03/20 09:34:33 Done.
2723 // Can probably be removed when we stop using String.operator+.
2724 final int offset;
2725 // Used to collect concatenated string literals into a single literal
2726 // instead of introducing unnecessary concatenations.
ahe 2012/03/19 15:53:06 Ditto.
Lasse Reichstein Nielsen 2012/03/20 09:34:33 Done.
2727 DartString accumulator = const LiteralDartString("");
2728 // The string value generated so far (not including that which is still
ahe 2012/03/19 15:53:06 Ditto.
Lasse Reichstein Nielsen 2012/03/20 09:34:33 Done.
2729 // in [accumulator]).
2730 HInstruction prefix = null;
2731
2732 StringBuilderVisitor(this.builder, this.offset);
2733
2734 void visit(Node node) {
2735 node.accept(this);
2736 }
2737
2738 void visitNode() {
2739 unreachable();
ahe 2012/03/19 15:53:06 There is no node argument to visitNode, and there
Lasse Reichstein Nielsen 2012/03/20 09:34:33 Good catch. It'll most likely never get hit (requi
2740 }
2741
2742 void visitExpression(Node node) {
2743 flushAccumulator();
2744 node.accept(builder);
2745 prefix = concat(prefix, builder.pop());
2746 }
2747
2748 void visitStringInterpolation(StringInterpolation node) {
2749 node.visitChildren(this);
2750 }
2751
2752 void visitStringInterpolationPart(StringInterpolationPart node) {
2753 visit(node.expression);
2754 visit(node.string);
2755 }
2756
2757 void visitLiteralString(LiteralString node) {
2758 accumulator = new DartString.concat(accumulator, node.dartString);
2759 }
2760
2761 void visitStringJuxtaposition(StringJuxtaposition node) {
2762 node.visitChildren(this);
2763 }
2764
2765 void visitNodeList(NodeList node) {
2766 node.visitChildren(this);
2767 }
2768
2769 /**
2770 * Combine the strings in [accumulator] into the prefix instruction.
2771 * After this, the [accumulator] is empty and [prefix] is non-null.
2772 */
2773 void flushAccumulator() {
2774 if (accumulator.isEmpty()) {
2775 if (prefix === null) {
2776 prefix = builder.graph.addConstantString(accumulator);
2777 }
2778 return;
2779 }
2780 HInstruction string = builder.graph.addConstantString(accumulator);
2781 accumulator = new DartString.empty();
2782 if (prefix !== null) {
2783 prefix = concat(prefix, string);
2784 } else {
2785 prefix = string;
2786 }
2787 }
2788
2789 HInstruction concat(HInstruction left, HInstruction right) {
2790 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset));
2791 HStatic target =
2792 new HStatic(builder.interceptors.getOperatorInterceptor(op));
2793 builder.add(target);
2794 HInstruction concat = new HAdd(target, left, right);
2795 builder.add(concat);
2796 return concat;
2797 }
2798
2799 HInstruction result() {
2800 flushAccumulator();
2801 return prefix;
2802 }
2803 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698