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

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: Refactor juxtaposition handling. 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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 } 1916 }
1916 1917
1917 void visitLiteralBool(LiteralBool node) { 1918 void visitLiteralBool(LiteralBool node) {
1918 stack.add(graph.addConstantBool(node.value)); 1919 stack.add(graph.addConstantBool(node.value));
1919 } 1920 }
1920 1921
1921 void visitLiteralString(LiteralString node) { 1922 void visitLiteralString(LiteralString node) {
1922 stack.add(graph.addConstantString(node.dartString)); 1923 stack.add(graph.addConstantString(node.dartString));
1923 } 1924 }
1924 1925
1925 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { 1926 void visitStringJuxtaposition(StringJuxtaposition node) {
1926 visitLiteralString(node); 1927 if (!node.isInterpolation) {
1928 // This is a simple string with no interpolations.
1929 stack.add(graph.addConstantString(node.dartString));
1930 return;
1931 }
1932 int offset = node.getBeginToken().charOffset;
1933 StringBuilderVisitor stringBuilder =
1934 new StringBuilderVisitor(this, offset);
1935 stringBuilder.visit(node);
1936 stack.add(stringBuilder.result());
1927 } 1937 }
1928 1938
1929 void visitLiteralNull(LiteralNull node) { 1939 void visitLiteralNull(LiteralNull node) {
1930 stack.add(graph.addConstantNull()); 1940 stack.add(graph.addConstantNull());
1931 } 1941 }
1932 1942
1933 visitNodeList(NodeList node) { 1943 visitNodeList(NodeList node) {
1934 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 1944 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
1935 if (isAborted()) { 1945 if (isAborted()) {
1936 compiler.reportWarning(link.head, 'dead code'); 1946 compiler.reportWarning(link.head, 'dead code');
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 open(joinBlock); 2049 open(joinBlock);
2040 2050
2041 localsHandler.mergeWith(thenLocals, joinBlock); 2051 localsHandler.mergeWith(thenLocals, joinBlock);
2042 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]); 2052 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]);
2043 joinBlock.addPhi(phi); 2053 joinBlock.addPhi(phi);
2044 stack.add(phi); 2054 stack.add(phi);
2045 } 2055 }
2046 2056
2047 visitStringInterpolation(StringInterpolation node) { 2057 visitStringInterpolation(StringInterpolation node) {
2048 int offset = node.getBeginToken().charOffset; 2058 int offset = node.getBeginToken().charOffset;
2049 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset)); 2059 StringBuilderVisitor stringBuilder =
2050 HInstruction target = new HStatic(interceptors.getOperatorInterceptor(op)); 2060 new StringBuilderVisitor(this, offset);
2051 add(target); 2061 stringBuilder.visit(node);
2052 visit(node.string); 2062 stack.add(stringBuilder.result());
2053 // Handle the parts here, to avoid recreating [target].
2054 for (StringInterpolationPart part in node.parts) {
2055 HInstruction prefix = pop();
2056 visit(part.expression);
2057 push(new HAdd(target, prefix, pop()));
2058 prefix = pop();
2059 visit(part.string);
2060 push(new HAdd(target, prefix, pop()));
2061 }
2062 } 2063 }
2063 2064
2064 visitStringInterpolationPart(StringInterpolationPart node) { 2065 visitStringInterpolationPart(StringInterpolationPart node) {
2065 // The parts are iterated in visitStringInterpolation. 2066 // The parts are iterated in visitStringInterpolation.
2066 unreachable(); 2067 unreachable();
2067 } 2068 }
2068 2069
2069 visitEmptyStatement(EmptyStatement node) { 2070 visitEmptyStatement(EmptyStatement node) {
2070 // Do nothing, empty statement. 2071 // Do nothing, empty statement.
2071 } 2072 }
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
2520 buildBody() { 2521 buildBody() {
2521 // TODO(lrn): Make sure to take continue into account. 2522 // TODO(lrn): Make sure to take continue into account.
2522 visit(body); 2523 visit(body);
2523 if (isAborted()) { 2524 if (isAborted()) {
2524 compiler.reportWarning(body, "aborting loop body"); 2525 compiler.reportWarning(body, "aborting loop body");
2525 } 2526 }
2526 } 2527 }
2527 handleIf(buildBody, null); 2528 handleIf(buildBody, null);
2528 } 2529 }
2529 } 2530 }
2531
2532 /**
2533 * Visitor that handles generation of string literals (LiteralString,
2534 * StringInterpolation), and otherwise delegates to the given visitor for
2535 * non-literal subexpressions.
2536 * TODO(lrn): Consider whether to handle compile time constant int/boolean
2537 * expressions as well.
2538 */
2539 class StringBuilderVisitor extends AbstractVisitor {
2540 final SsaBuilder builder;
2541 // Offset used for the synthetic operator token used by concat.
2542 // Can probably be removed when we stop using String.operator+.
2543 final int offset;
2544 // Used to collect concatenated string literals into a single literal
2545 // instead of introducing unnecessary concatenations.
2546 DartString accumulator = const LiteralDartString("");
2547 // The string value generated so far (not including that which is still
2548 // in [accumulator]).
2549 HInstruction prefix = null;
2550
2551 StringBuilderVisitor(this.builder, this.offset);
2552
2553 void visit(Node node) {
2554 node.accept(this);
2555 }
2556
2557 void visitNode() {
2558 unreachable();
2559 }
2560
2561 void visitExpression(Node node) {
2562 flushAccumulator();
2563 node.accept(builder);
2564 prefix = concat(prefix, builder.pop());
2565 }
2566
2567 void visitStringInterpolation(StringInterpolation node) {
2568 node.visitChildren(this);
2569 }
2570
2571 void visitStringInterpolationPart(StringInterpolationPart node) {
2572 visit(node.expression);
2573 visit(node.string);
2574 }
2575
2576 void visitLiteralString(LiteralString node) {
2577 accumulator = new DartString.concat(accumulator, node.dartString);
2578 }
2579
2580 void visitStringJuxtaposition(StringJuxtaposition node) {
2581 node.visitChildren(this);
2582 }
2583
2584 void visitNodeList(NodeList node) {
2585 node.visitChildren(this);
2586 }
2587
2588 /**
2589 * Combine the strings in [accumulator] into the prefix instruction.
2590 * After this, the [accumulator] is empty and [prefix] is non-null.
2591 */
2592 void flushAccumulator() {
2593 if (accumulator.isEmpty()) {
2594 if (prefix === null) {
2595 prefix = builder.graph.addConstantString(accumulator);
2596 }
2597 return;
2598 }
2599 HInstruction string = builder.graph.addConstantString(accumulator);
2600 accumulator = new DartString.empty();
2601 if (prefix !== null) {
2602 prefix = concat(prefix, string);
2603 } else {
2604 prefix = string;
2605 }
2606 }
2607
2608 HInstruction concat(HInstruction left, HInstruction right) {
2609 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset));
2610 HStatic target =
2611 new HStatic(builder.interceptors.getOperatorInterceptor(op));
2612 builder.add(target);
2613 HInstruction concat = new HAdd(target, left, right);
2614 builder.add(concat);
2615 return concat;
2616 }
2617
2618 HInstruction result() {
2619 flushAccumulator();
2620 return prefix;
2621 }
2622 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698