| 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 SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); | 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); |
| 7 String get name() => 'SSA code generator'; | 7 String get name() => 'SSA code generator'; |
| 8 | 8 |
| 9 String generate(WorkItem work, HGraph graph) { | 9 String generate(WorkItem work, HGraph graph) { |
| 10 return measure(() { | 10 return measure(() { |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 buffer.add('new $jsClassReference('); | 482 buffer.add('new $jsClassReference('); |
| 483 // We can't use 'visitArguments', since our arguments start at input[0]. | 483 // We can't use 'visitArguments', since our arguments start at input[0]. |
| 484 List<HInstruction> inputs = node.inputs; | 484 List<HInstruction> inputs = node.inputs; |
| 485 for (int i = 0; i < inputs.length; i++) { | 485 for (int i = 0; i < inputs.length; i++) { |
| 486 if (i != 0) buffer.add(', '); | 486 if (i != 0) buffer.add(', '); |
| 487 use(inputs[i]); | 487 use(inputs[i]); |
| 488 } | 488 } |
| 489 buffer.add(')'); | 489 buffer.add(')'); |
| 490 } | 490 } |
| 491 | 491 |
| 492 /** |
| 493 * Write the contents of the quoted string to a [StringBuffer] in |
| 494 * a form that is valid as JavaScript string literal content. |
| 495 * The string is assumed quoted by [quote] characters. |
| 496 */ |
| 497 static void writeEscapedString(QuotedString string, |
| 498 StringBuffer buffer, |
| 499 int quote, |
| 500 void cancel(String reason)) { |
| 501 bool raw = string.quoting.raw; |
| 502 Iterator<int> iterator = string.iterator(); |
| 503 while (iterator.hasNext()) { |
| 504 int code = iterator.next(); |
| 505 if (code === quote) { |
| 506 // We need to add a backslash before quotes, both in normal |
| 507 // and in raw strings. |
| 508 buffer.add(@'\'); |
| 509 buffer.add(code === $SQ ? "'" : '"'); |
| 510 } else if (code === $LF) { |
| 511 // Newlines in strings only occur in multiline strings. |
| 512 // They need to be written using escapes in JS. |
| 513 assert(string.quoting.multiline); |
| 514 buffer.add(@'\n'); |
| 515 } else if (code === $CR) { |
| 516 assert(string.quoting.multiline); |
| 517 buffer.add(@'\r'); |
| 518 } else if (code === $LS) { |
| 519 // This Unicode line terminator and $PS are invalid in JS string |
| 520 // literals. |
| 521 buffer.add(@'\u2028'); |
| 522 } else if (code === $PS) { |
| 523 buffer.add(@'\u2029'); |
| 524 } else if (code !== $BACKSLASH) { |
| 525 buffer.add(new String.fromCharCodes([code])); |
| 526 } else if (raw) { |
| 527 buffer.add(@'\\'); |
| 528 } else { |
| 529 assert(code === $BACKSLASH); |
| 530 code = iterator.next(); |
| 531 switch (code) { |
| 532 case $u: |
| 533 buffer.add(@'\u'); |
| 534 code = iterator.next(); |
| 535 if (code == $OPEN_CURLY_BRACKET) { |
| 536 int value = 0; |
| 537 code = iterator.next(); |
| 538 do { |
| 539 value = value * 16 + hexDigitValue(code); |
| 540 code = iterator.next(); |
| 541 } while (code !== $CLOSE_CURLY_BRACKET); |
| 542 if (code > 0xffff) { |
| 543 cancel("Unhandled non-BMP character: " + |
| 544 "U+${code.toRadixString(16)}"); |
| 545 } |
| 546 for (int i = 12; i >= 0; i -= 4) { |
| 547 buffer.add(((value >> i) & 0xf).toRadixString(16)); |
| 548 } |
| 549 } else { |
| 550 buffer.add(new String.fromCharCodes([code])); |
| 551 // Remaining three hex digits will be copied verbatim. |
| 552 } |
| 553 break; |
| 554 case $x: |
| 555 buffer.add(@'\x'); |
| 556 // The two hex digits will be copied verbatim. |
| 557 break; |
| 558 // Character escapes that identical in meaning in JS. |
| 559 case $b: buffer.add(@'\b'); break; |
| 560 case $f: buffer.add(@'\f'); break; |
| 561 case $n: buffer.add(@'\n'); break; |
| 562 case $r: buffer.add(@'\r'); break; |
| 563 case $t: buffer.add(@'\t'); break; |
| 564 case $v: buffer.add(@'\v'); break; |
| 565 // Identity escapes that must be escaped in JS strings. |
| 566 case $BACKSLASH: buffer.add(@'\\'); break; |
| 567 case $LF: buffer.add(@'\n'); break; |
| 568 case $CR: buffer.add(@'\r'); break; |
| 569 case $LS: buffer.add(@'\u2028'); break; |
| 570 case $PS: buffer.add(@'\u2029'); break; |
| 571 // Quotes may or may not need the escape. |
| 572 case $SQ: |
| 573 case $DQ: |
| 574 // Only escape quotes if they match the generated string quotes. |
| 575 if (code == quote) buffer.add(@'\'); |
| 576 buffer.add(code === $SQ ? "'" : '"'); |
| 577 break; |
| 578 default: |
| 579 // All other escaped characters are identity escapes, |
| 580 // and don't need a backslash in JS. |
| 581 buffer.add(new String.fromCharCodes([code])); |
| 582 break; |
| 583 } |
| 584 } |
| 585 } |
| 586 } |
| 587 |
| 588 |
| 492 visitLiteral(HLiteral node) { | 589 visitLiteral(HLiteral node) { |
| 493 if (node.isLiteralNull()) { | 590 if (node.isLiteralNull()) { |
| 494 buffer.add("(void 0)"); | 591 buffer.add("(void 0)"); |
| 495 } else if (node.value is num && node.value < 0) { | 592 } else if (node.value is num && node.value < 0) { |
| 496 buffer.add('(${node.value})'); | 593 buffer.add('(${node.value})'); |
| 497 } else if (node.isLiteralString()) { | 594 } else if (node.isLiteralString()) { |
| 498 QuotedString string = node.value; | 595 QuotedString string = node.value; |
| 499 String quote = string.quoteChar; | 596 StringQuoting quoting = string.quoting; |
| 597 String quote = quoting.quoteChar; |
| 500 buffer.add(quote); | 598 buffer.add(quote); |
| 501 string.writeEscaped(buffer, string.quoteCharCode, | 599 writeEscapedString(string, buffer, quoting.quote, |
| 502 (String reason) { | 600 (String reason) { |
| 503 compiler.cancel(reason, instruction: node); | 601 compiler.cancel(reason, instruction:node); |
| 504 }); | 602 }); |
| 505 buffer.add(quote); | 603 buffer.add(quote); |
| 506 } else { | 604 } else { |
| 507 buffer.add(node.value); | 605 buffer.add(node.value); |
| 508 } | 606 } |
| 509 } | 607 } |
| 510 | 608 |
| 511 visitLoopBranch(HLoopBranch node) { | 609 visitLoopBranch(HLoopBranch node) { |
| 512 HBasicBlock branchBlock = currentBlock; | 610 HBasicBlock branchBlock = currentBlock; |
| 513 handleLoopCondition(node); | 611 handleLoopCondition(node); |
| 514 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; | 612 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 startBailoutSwitch(); | 1128 startBailoutSwitch(); |
| 1031 } | 1129 } |
| 1032 } | 1130 } |
| 1033 | 1131 |
| 1034 void endElse(HIf node) { | 1132 void endElse(HIf node) { |
| 1035 if (node.elseBlock.hasBailouts()) { | 1133 if (node.elseBlock.hasBailouts()) { |
| 1036 endBailoutSwitch(); | 1134 endBailoutSwitch(); |
| 1037 } | 1135 } |
| 1038 } | 1136 } |
| 1039 } | 1137 } |
| OLD | NEW |