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

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: Fix typo 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 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 visit(node.receiver); 1345 visit(node.receiver);
1346 HNot not = new HNot(popBoolified()); 1346 HNot not = new HNot(popBoolified());
1347 push(not); 1347 push(not);
1348 } 1348 }
1349 1349
1350 void visitUnary(Send node, Operator op) { 1350 void visitUnary(Send node, Operator op) {
1351 assert(node.argumentsNode is Prefix); 1351 assert(node.argumentsNode is Prefix);
1352 visit(node.receiver); 1352 visit(node.receiver);
1353 assert(op.token.kind !== PLUS_TOKEN); 1353 assert(op.token.kind !== PLUS_TOKEN);
1354 HInstruction operand = pop(); 1354 HInstruction operand = pop();
1355
1355 HInstruction target = 1356 HInstruction target =
1356 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); 1357 new HStatic(interceptors.getPrefixOperatorInterceptor(op));
1357 add(target); 1358 add(target);
1358 HInvokeUnary result; 1359 HInvokeUnary result;
1359 switch (op.source.stringValue) { 1360 switch (op.source.stringValue) {
1360 case "-": result = new HNegate(target, operand); break; 1361 case "-": result = new HNegate(target, operand); break;
1361 case "~": result = new HBitNot(target, operand); break; 1362 case "~": result = new HBitNot(target, operand); break;
1362 default: unreachable(); 1363 default: unreachable();
1363 } 1364 }
1364 // See if we can constant-fold right away. This avoids rewrites later on. 1365 // See if we can constant-fold right away. This avoids rewrites later on.
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 } 1950 }
1950 1951
1951 void visitLiteralBool(LiteralBool node) { 1952 void visitLiteralBool(LiteralBool node) {
1952 stack.add(graph.addConstantBool(node.value)); 1953 stack.add(graph.addConstantBool(node.value));
1953 } 1954 }
1954 1955
1955 void visitLiteralString(LiteralString node) { 1956 void visitLiteralString(LiteralString node) {
1956 stack.add(graph.addConstantString(node.dartString)); 1957 stack.add(graph.addConstantString(node.dartString));
1957 } 1958 }
1958 1959
1959 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { 1960 void visitStringJuxtaposition(StringJuxtaposition node) {
1960 visitLiteralString(node); 1961 if (!node.isInterpolation) {
1962 // This is a simple string with no interpolations.
1963 stack.add(graph.addConstantString(node.dartString));
1964 return;
1965 }
1966 int offset = node.getBeginToken().charOffset;
1967 StringBuilderVisitor stringBuilder =
1968 new StringBuilderVisitor(this, offset);
1969 stringBuilder.visit(node);
1970 stack.add(stringBuilder.result());
1961 } 1971 }
1962 1972
1963 void visitLiteralNull(LiteralNull node) { 1973 void visitLiteralNull(LiteralNull node) {
1964 stack.add(graph.addConstantNull()); 1974 stack.add(graph.addConstantNull());
1965 } 1975 }
1966 1976
1967 visitNodeList(NodeList node) { 1977 visitNodeList(NodeList node) {
1968 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 1978 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
1969 if (isAborted()) { 1979 if (isAborted()) {
1970 compiler.reportWarning(link.head, 'dead code'); 1980 compiler.reportWarning(link.head, 'dead code');
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 open(joinBlock); 2083 open(joinBlock);
2074 2084
2075 localsHandler.mergeWith(thenLocals, joinBlock); 2085 localsHandler.mergeWith(thenLocals, joinBlock);
2076 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]); 2086 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]);
2077 joinBlock.addPhi(phi); 2087 joinBlock.addPhi(phi);
2078 stack.add(phi); 2088 stack.add(phi);
2079 } 2089 }
2080 2090
2081 visitStringInterpolation(StringInterpolation node) { 2091 visitStringInterpolation(StringInterpolation node) {
2082 int offset = node.getBeginToken().charOffset; 2092 int offset = node.getBeginToken().charOffset;
2083 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset)); 2093 StringBuilderVisitor stringBuilder =
2084 HInstruction target = new HStatic(interceptors.getOperatorInterceptor(op)); 2094 new StringBuilderVisitor(this, offset);
2085 add(target); 2095 stringBuilder.visit(node);
2086 visit(node.string); 2096 stack.add(stringBuilder.result());
2087 // Handle the parts here, to avoid recreating [target].
2088 for (StringInterpolationPart part in node.parts) {
2089 HInstruction prefix = pop();
2090 visit(part.expression);
2091 push(new HAdd(target, prefix, pop()));
2092 prefix = pop();
2093 visit(part.string);
2094 push(new HAdd(target, prefix, pop()));
2095 }
2096 } 2097 }
2097 2098
2098 visitStringInterpolationPart(StringInterpolationPart node) { 2099 visitStringInterpolationPart(StringInterpolationPart node) {
2099 // The parts are iterated in visitStringInterpolation. 2100 // The parts are iterated in visitStringInterpolation.
2100 unreachable(); 2101 unreachable();
2101 } 2102 }
2102 2103
2103 visitEmptyStatement(EmptyStatement node) { 2104 visitEmptyStatement(EmptyStatement node) {
2104 // Do nothing, empty statement. 2105 // Do nothing, empty statement.
2105 } 2106 }
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 buildBody() { 2558 buildBody() {
2558 // TODO(lrn): Make sure to take continue into account. 2559 // TODO(lrn): Make sure to take continue into account.
2559 visit(body); 2560 visit(body);
2560 if (isAborted()) { 2561 if (isAborted()) {
2561 compiler.reportWarning(body, "aborting loop body"); 2562 compiler.reportWarning(body, "aborting loop body");
2562 } 2563 }
2563 } 2564 }
2564 handleIf(buildBody, null); 2565 handleIf(buildBody, null);
2565 } 2566 }
2566 } 2567 }
2568
2569 /**
2570 * Visitor that handles generation of string literals (LiteralString,
2571 * StringInterpolation), and otherwise delegates to the given visitor for
2572 * non-literal subexpressions.
2573 * TODO(lrn): Consider whether to handle compile time constant int/boolean
2574 * expressions as well.
2575 */
2576 class StringBuilderVisitor extends AbstractVisitor {
2577 final SsaBuilder builder;
2578 // Offset used for the synthetic operator token used by concat.
2579 // Can probably be removed when we stop using String.operator+.
2580 final int offset;
2581 // Used to collect concatenated string literals into a single literal
2582 // instead of introducing unnecessary concatenations.
2583 DartString accumulator = const LiteralDartString("");
2584 // The string value generated so far (not including that which is still
2585 // in [accumulator]).
2586 HInstruction prefix = null;
2587
2588 StringBuilderVisitor(this.builder, this.offset);
2589
2590 void visit(Node node) {
2591 node.accept(this);
2592 }
2593
2594 void visitNode() {
2595 unreachable();
2596 }
2597
2598 void visitExpression(Node node) {
2599 flushAccumulator();
2600 node.accept(builder);
2601 prefix = concat(prefix, builder.pop());
2602 }
2603
2604 void visitStringInterpolation(StringInterpolation node) {
2605 node.visitChildren(this);
2606 }
2607
2608 void visitStringInterpolationPart(StringInterpolationPart node) {
2609 visit(node.expression);
2610 visit(node.string);
2611 }
2612
2613 void visitLiteralString(LiteralString node) {
2614 accumulator = new DartString.concat(accumulator, node.dartString);
2615 }
2616
2617 void visitStringJuxtaposition(StringJuxtaposition node) {
2618 node.visitChildren(this);
2619 }
2620
2621 void visitNodeList(NodeList node) {
2622 node.visitChildren(this);
2623 }
2624
2625 /**
2626 * Combine the strings in [accumulator] into the prefix instruction.
2627 * After this, the [accumulator] is empty and [prefix] is non-null.
2628 */
2629 void flushAccumulator() {
2630 if (accumulator.isEmpty()) {
2631 if (prefix === null) {
2632 prefix = builder.graph.addConstantString(accumulator);
2633 }
2634 return;
2635 }
2636 HInstruction string = builder.graph.addConstantString(accumulator);
2637 accumulator = new DartString.empty();
2638 if (prefix !== null) {
2639 prefix = concat(prefix, string);
2640 } else {
2641 prefix = string;
2642 }
2643 }
2644
2645 HInstruction concat(HInstruction left, HInstruction right) {
2646 Operator op = new Operator(new StringToken(PLUS_INFO, "+", offset));
2647 HStatic target =
2648 new HStatic(builder.interceptors.getOperatorInterceptor(op));
2649 builder.add(target);
2650 HInstruction concat = new HAdd(target, left, right);
2651 builder.add(concat);
2652 return concat;
2653 }
2654
2655 HInstruction result() {
2656 flushAccumulator();
2657 return prefix;
2658 }
2659 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698