Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2583 void visitLiteralString(LiteralString node) { | 2583 void visitLiteralString(LiteralString node) { |
| 2584 stack.add(graph.addConstantString(node.dartString, node)); | 2584 stack.add(graph.addConstantString(node.dartString, node)); |
| 2585 } | 2585 } |
| 2586 | 2586 |
| 2587 void visitStringJuxtaposition(StringJuxtaposition node) { | 2587 void visitStringJuxtaposition(StringJuxtaposition node) { |
| 2588 if (!node.isInterpolation) { | 2588 if (!node.isInterpolation) { |
| 2589 // This is a simple string with no interpolations. | 2589 // This is a simple string with no interpolations. |
| 2590 stack.add(graph.addConstantString(node.dartString, node)); | 2590 stack.add(graph.addConstantString(node.dartString, node)); |
| 2591 return; | 2591 return; |
| 2592 } | 2592 } |
| 2593 int offset = node.getBeginToken().charOffset; | 2593 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this); |
| 2594 StringBuilderVisitor stringBuilder = | |
| 2595 new StringBuilderVisitor(this, offset); | |
| 2596 stringBuilder.visit(node); | 2594 stringBuilder.visit(node); |
| 2597 stack.add(stringBuilder.result(node)); | 2595 stack.add(stringBuilder.result(node)); |
| 2598 } | 2596 } |
| 2599 | 2597 |
| 2600 void visitLiteralNull(LiteralNull node) { | 2598 void visitLiteralNull(LiteralNull node) { |
| 2601 stack.add(graph.addConstantNull()); | 2599 stack.add(graph.addConstantNull()); |
| 2602 } | 2600 } |
| 2603 | 2601 |
| 2604 visitNodeList(NodeList node) { | 2602 visitNodeList(NodeList node) { |
| 2605 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 2603 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2737 open(joinBlock); | 2735 open(joinBlock); |
| 2738 | 2736 |
| 2739 localsHandler.mergeWith(thenLocals, joinBlock); | 2737 localsHandler.mergeWith(thenLocals, joinBlock); |
| 2740 HPhi phi = new HPhi.manyInputs(null, | 2738 HPhi phi = new HPhi.manyInputs(null, |
| 2741 <HInstruction>[thenInstruction, elseInstruction]); | 2739 <HInstruction>[thenInstruction, elseInstruction]); |
| 2742 joinBlock.addPhi(phi); | 2740 joinBlock.addPhi(phi); |
| 2743 stack.add(phi); | 2741 stack.add(phi); |
| 2744 } | 2742 } |
| 2745 | 2743 |
| 2746 visitStringInterpolation(StringInterpolation node) { | 2744 visitStringInterpolation(StringInterpolation node) { |
| 2747 int offset = node.getBeginToken().charOffset; | 2745 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this); |
| 2748 StringBuilderVisitor stringBuilder = | |
| 2749 new StringBuilderVisitor(this, offset); | |
| 2750 stringBuilder.visit(node); | 2746 stringBuilder.visit(node); |
| 2751 stack.add(stringBuilder.result(node)); | 2747 stack.add(stringBuilder.result(node)); |
| 2752 } | 2748 } |
| 2753 | 2749 |
| 2754 visitStringInterpolationPart(StringInterpolationPart node) { | 2750 visitStringInterpolationPart(StringInterpolationPart node) { |
| 2755 // The parts are iterated in visitStringInterpolation. | 2751 // The parts are iterated in visitStringInterpolation. |
| 2756 compiler.internalError('visitStringInterpolation should not be called', | 2752 compiler.internalError('visitStringInterpolation should not be called', |
| 2757 node: node); | 2753 node: node); |
| 2758 } | 2754 } |
| 2759 | 2755 |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3283 | 3279 |
| 3284 /** | 3280 /** |
| 3285 * Visitor that handles generation of string literals (LiteralString, | 3281 * Visitor that handles generation of string literals (LiteralString, |
| 3286 * StringInterpolation), and otherwise delegates to the given visitor for | 3282 * StringInterpolation), and otherwise delegates to the given visitor for |
| 3287 * non-literal subexpressions. | 3283 * non-literal subexpressions. |
| 3288 * TODO(lrn): Consider whether to handle compile time constant int/boolean | 3284 * TODO(lrn): Consider whether to handle compile time constant int/boolean |
| 3289 * expressions as well. | 3285 * expressions as well. |
| 3290 */ | 3286 */ |
| 3291 class StringBuilderVisitor extends AbstractVisitor { | 3287 class StringBuilderVisitor extends AbstractVisitor { |
| 3292 final SsaBuilder builder; | 3288 final SsaBuilder builder; |
| 3293 final Element stringConcat; | |
| 3294 final Element stringToString; | |
| 3295 | 3289 |
| 3296 /** | 3290 /** |
| 3297 * Offset used for the synthetic operator token used by concat. | 3291 * The string value generated so far. |
| 3298 * Can probably be removed when we stop using String.operator+. | |
| 3299 */ | |
| 3300 final int offset; | |
| 3301 | |
| 3302 /** | |
| 3303 * Used to collect concatenated string literals into a single literal | |
| 3304 * instead of introducing unnecessary concatenations. | |
| 3305 */ | |
| 3306 DartString literalAccumulator = const LiteralDartString(""); | |
| 3307 | |
| 3308 /** | |
| 3309 * The string value generated so far (not including that which is still | |
| 3310 * in [literalAccumulator]). | |
| 3311 */ | 3292 */ |
| 3312 HInstruction prefix = null; | 3293 HInstruction prefix = null; |
|
floitsch
2012/06/06 12:13:34
Maybe rename to 'result' and remove result-method?
kasperl
2012/06/06 13:31:03
Done.
| |
| 3313 | 3294 |
| 3314 StringBuilderVisitor(builder, this.offset) | 3295 StringBuilderVisitor(this.builder); |
| 3315 : this.builder = builder, | |
| 3316 stringConcat = builder.compiler.findHelper( | |
| 3317 const SourceString("stringConcat")), | |
| 3318 stringToString = builder.compiler.findHelper( | |
| 3319 const SourceString("stringToString")); | |
| 3320 | 3296 |
| 3321 void visit(Node node) { | 3297 void visit(Node node) { |
| 3322 node.accept(this); | 3298 node.accept(this); |
| 3323 } | 3299 } |
| 3324 | 3300 |
| 3325 visitNode(Node node) { | 3301 visitNode(Node node) { |
| 3326 builder.compiler.internalError('unexpected node', node: node); | 3302 builder.compiler.internalError('unexpected node', node: node); |
| 3327 } | 3303 } |
| 3328 | 3304 |
| 3329 void visitExpression(Node node) { | 3305 void visitExpression(Node node) { |
| 3330 flushLiterals(node); | |
| 3331 node.accept(builder); | 3306 node.accept(builder); |
| 3332 HInstruction asString = buildToString(node, builder.pop()); | 3307 HInstruction expression = builder.pop(); |
| 3333 prefix = buildConcat(prefix, asString); | 3308 prefix = (prefix === null) ? expression : concat(prefix, expression); |
| 3334 } | |
| 3335 | |
| 3336 void visitLiteralNull(LiteralNull node) { | |
| 3337 addLiteral(const LiteralDartString("null")); | |
| 3338 } | |
| 3339 | |
| 3340 void visitLiteralInt(LiteralInt node) { | |
| 3341 addLiteral(new DartString.literal(node.value.toString())); | |
| 3342 } | |
| 3343 | |
| 3344 void visitLiteralDouble(LiteralDouble node) { | |
| 3345 addLiteral(new DartString.literal(node.value.toString())); | |
| 3346 } | |
| 3347 | |
| 3348 void visitLiteralBool(LiteralBool node) { | |
| 3349 addLiteral(node.value ? const LiteralDartString("true") | |
| 3350 : const LiteralDartString("false")); | |
| 3351 } | 3309 } |
| 3352 | 3310 |
| 3353 void visitStringInterpolation(StringInterpolation node) { | 3311 void visitStringInterpolation(StringInterpolation node) { |
| 3354 node.visitChildren(this); | 3312 node.visitChildren(this); |
| 3355 } | 3313 } |
| 3356 | 3314 |
| 3357 void visitStringInterpolationPart(StringInterpolationPart node) { | 3315 void visitStringInterpolationPart(StringInterpolationPart node) { |
| 3358 visit(node.expression); | 3316 visit(node.expression); |
| 3359 visit(node.string); | 3317 visit(node.string); |
| 3360 } | 3318 } |
| 3361 | 3319 |
| 3362 void visitLiteralString(LiteralString node) { | |
| 3363 addLiteral(node.dartString); | |
| 3364 } | |
| 3365 | |
| 3366 void visitStringJuxtaposition(StringJuxtaposition node) { | 3320 void visitStringJuxtaposition(StringJuxtaposition node) { |
| 3367 node.visitChildren(this); | 3321 node.visitChildren(this); |
| 3368 } | 3322 } |
| 3369 | 3323 |
| 3370 void visitNodeList(NodeList node) { | 3324 void visitNodeList(NodeList node) { |
| 3371 node.visitChildren(this); | 3325 node.visitChildren(this); |
| 3372 } | 3326 } |
| 3373 | 3327 |
| 3374 /** | 3328 HInstruction concat(HInstruction left, HInstruction right) { |
| 3375 * Add another literal string to the literalAccumulator. | 3329 HInstruction result = new HStringConcat([left, right]); |
| 3376 */ | 3330 builder.add(result); |
| 3377 void addLiteral(DartString dartString) { | 3331 return result; |
| 3378 literalAccumulator = new DartString.concat(literalAccumulator, dartString); | |
| 3379 } | |
| 3380 | |
| 3381 /** | |
| 3382 * Combine the strings in [literalAccumulator] into the prefix instruction. | |
| 3383 * After this, the [literalAccumulator] is empty and [prefix] is non-null. | |
| 3384 */ | |
| 3385 void flushLiterals(Node node) { | |
| 3386 if (literalAccumulator.isEmpty()) { | |
| 3387 if (prefix === null) { | |
| 3388 prefix = builder.graph.addConstantString(literalAccumulator, node); | |
| 3389 } | |
| 3390 return; | |
| 3391 } | |
| 3392 HInstruction string = | |
| 3393 builder.graph.addConstantString(literalAccumulator, node); | |
| 3394 literalAccumulator = new DartString.empty(); | |
| 3395 if (prefix !== null) { | |
| 3396 prefix = buildConcat(prefix, string); | |
| 3397 } else { | |
| 3398 prefix = string; | |
| 3399 } | |
| 3400 } | |
| 3401 | |
| 3402 HInstruction buildConcat(HInstruction left, HInstruction right) { | |
| 3403 HStatic target = new HStatic(stringConcat); | |
| 3404 builder.add(target); | |
| 3405 builder.push(new HAdd(target, left, right)); | |
| 3406 return builder.pop(); | |
| 3407 } | |
| 3408 | |
| 3409 HInstruction buildToString(Node node, HInstruction input) { | |
| 3410 HStatic target = new HStatic(stringToString); | |
| 3411 builder.add(target); | |
| 3412 builder.push(new HInvokeStatic(Selector.INVOCATION_1, | |
| 3413 <HInstruction>[target, input], | |
| 3414 HType.STRING)); | |
| 3415 return builder.pop(); | |
| 3416 } | 3332 } |
| 3417 | 3333 |
| 3418 HInstruction result(Node node) { | 3334 HInstruction result(Node node) { |
|
floitsch
2012/06/06 12:13:34
If you keep the result-method, remove the argument
| |
| 3419 flushLiterals(node); | |
| 3420 return prefix; | 3335 return prefix; |
| 3421 } | 3336 } |
| 3422 } | 3337 } |
| OLD | NEW |