| 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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 for (int i = 0; i < inputs.length; i++) { | 483 for (int i = 0; i < inputs.length; i++) { |
| 484 if (i != 0) buffer.add(', '); | 484 if (i != 0) buffer.add(', '); |
| 485 use(inputs[i]); | 485 use(inputs[i]); |
| 486 } | 486 } |
| 487 buffer.add(')'); | 487 buffer.add(')'); |
| 488 } | 488 } |
| 489 | 489 |
| 490 /** | 490 /** |
| 491 * Write the contents of the quoted string to a [StringBuffer] in | 491 * Write the contents of the quoted string to a [StringBuffer] in |
| 492 * a form that is valid as JavaScript string literal content. | 492 * a form that is valid as JavaScript string literal content. |
| 493 * The string is assumed quoted by [quote] characters. | 493 * The string is assumed quoted by single quote characters. |
| 494 */ | 494 */ |
| 495 static void writeEscapedString(QuotedString string, | 495 static void writeEscapedString(DartString string, |
| 496 StringBuffer buffer, | 496 StringBuffer buffer, |
| 497 int quote, | |
| 498 void cancel(String reason)) { | 497 void cancel(String reason)) { |
| 499 bool raw = string.quoting.raw; | |
| 500 Iterator<int> iterator = string.iterator(); | 498 Iterator<int> iterator = string.iterator(); |
| 501 while (iterator.hasNext()) { | 499 while (iterator.hasNext()) { |
| 502 int code = iterator.next(); | 500 int code = iterator.next(); |
| 503 if (code === quote) { | 501 if (code === $SQ) { |
| 504 // We need to add a backslash before quotes, both in normal | 502 buffer.add(@"\'"); |
| 505 // and in raw strings. | |
| 506 buffer.add(@'\'); | |
| 507 buffer.add(code === $SQ ? "'" : '"'); | |
| 508 } else if (code === $LF) { | 503 } else if (code === $LF) { |
| 509 // Newlines in strings only occur in multiline strings. | |
| 510 // They need to be written using escapes in JS. | |
| 511 assert(string.quoting.multiline); | |
| 512 buffer.add(@'\n'); | 504 buffer.add(@'\n'); |
| 513 } else if (code === $CR) { | 505 } else if (code === $CR) { |
| 514 assert(string.quoting.multiline); | |
| 515 buffer.add(@'\r'); | 506 buffer.add(@'\r'); |
| 516 } else if (code === $LS) { | 507 } else if (code === $LS) { |
| 517 // This Unicode line terminator and $PS are invalid in JS string | 508 // This Unicode line terminator and $PS are invalid in JS string |
| 518 // literals. | 509 // literals. |
| 519 buffer.add(@'\u2028'); | 510 buffer.add(@'\u2028'); |
| 520 } else if (code === $PS) { | 511 } else if (code === $PS) { |
| 521 buffer.add(@'\u2029'); | 512 buffer.add(@'\u2029'); |
| 522 } else if (code !== $BACKSLASH) { | 513 } else if (code === $BACKSLASH) { |
| 523 buffer.add(new String.fromCharCodes([code])); | |
| 524 } else if (raw) { | |
| 525 buffer.add(@'\\'); | 514 buffer.add(@'\\'); |
| 526 } else { | 515 } else { |
| 527 assert(code === $BACKSLASH); | 516 if (code > 0xffff) { |
| 528 code = iterator.next(); | 517 cancel("Unhandled non-BMP character: U+" + code.toRadixString(16)); |
| 529 switch (code) { | 518 } |
| 530 case $u: | 519 // TODO(lrn): Consider whether all codes above 0x7f really need to |
| 520 // be escaped. We build a Dart string here, so it should be a literal |
| 521 // stage that converts it to, e.g., UTF-8 for a JS interpreter. |
| 522 if (code < 0x20) { |
| 523 buffer.add(@'\x'); |
| 524 if (code < 0x10) buffer.add('0'); |
| 525 buffer.add(code.toRadixString(16)); |
| 526 } else if (code >= 0x80) { |
| 527 if (code < 0x100) { |
| 528 buffer.add(@'\x'); |
| 529 buffer.add(code.toRadixString(16)); |
| 530 } else { |
| 531 buffer.add(@'\u'); | 531 buffer.add(@'\u'); |
| 532 code = iterator.next(); | 532 if (code < 0x1000) { |
| 533 if (code == $OPEN_CURLY_BRACKET) { | 533 buffer.add('0'); |
| 534 int value = 0; | |
| 535 code = iterator.next(); | |
| 536 do { | |
| 537 value = value * 16 + hexDigitValue(code); | |
| 538 code = iterator.next(); | |
| 539 } while (code !== $CLOSE_CURLY_BRACKET); | |
| 540 if (code > 0xffff) { | |
| 541 cancel("Unhandled non-BMP character: " + | |
| 542 "U+${code.toRadixString(16)}"); | |
| 543 } | |
| 544 for (int i = 12; i >= 0; i -= 4) { | |
| 545 buffer.add(((value >> i) & 0xf).toRadixString(16)); | |
| 546 } | |
| 547 } else { | |
| 548 buffer.add(new String.fromCharCodes([code])); | |
| 549 // Remaining three hex digits will be copied verbatim. | |
| 550 } | 534 } |
| 551 break; | 535 buffer.add(code.toRadixString(16)); |
| 552 case $x: | 536 } |
| 553 buffer.add(@'\x'); | 537 } else { |
| 554 // The two hex digits will be copied verbatim. | 538 buffer.add(new String.fromCharCodes(<int>[code])); |
| 555 break; | |
| 556 // Character escapes that identical in meaning in JS. | |
| 557 case $b: buffer.add(@'\b'); break; | |
| 558 case $f: buffer.add(@'\f'); break; | |
| 559 case $n: buffer.add(@'\n'); break; | |
| 560 case $r: buffer.add(@'\r'); break; | |
| 561 case $t: buffer.add(@'\t'); break; | |
| 562 case $v: buffer.add(@'\v'); break; | |
| 563 // Identity escapes that must be escaped in JS strings. | |
| 564 case $BACKSLASH: buffer.add(@'\\'); break; | |
| 565 case $LF: buffer.add(@'\n'); break; | |
| 566 case $CR: buffer.add(@'\r'); break; | |
| 567 case $LS: buffer.add(@'\u2028'); break; | |
| 568 case $PS: buffer.add(@'\u2029'); break; | |
| 569 // Quotes may or may not need the escape. | |
| 570 case $SQ: | |
| 571 case $DQ: | |
| 572 // Only escape quotes if they match the generated string quotes. | |
| 573 if (code == quote) buffer.add(@'\'); | |
| 574 buffer.add(code === $SQ ? "'" : '"'); | |
| 575 break; | |
| 576 default: | |
| 577 // All other escaped characters are identity escapes, | |
| 578 // and don't need a backslash in JS. | |
| 579 buffer.add(new String.fromCharCodes([code])); | |
| 580 break; | |
| 581 } | 539 } |
| 582 } | 540 } |
| 583 } | 541 } |
| 584 } | 542 } |
| 585 | 543 |
| 586 | 544 |
| 587 visitLiteral(HLiteral node) { | 545 visitLiteral(HLiteral node) { |
| 588 if (node.isLiteralNull()) { | 546 if (node.isLiteralNull()) { |
| 589 buffer.add("(void 0)"); | 547 buffer.add("(void 0)"); |
| 590 } else if (node.value is num && node.value < 0) { | 548 } else if (node.value is num && node.value < 0) { |
| 591 buffer.add('(${node.value})'); | 549 buffer.add('(${node.value})'); |
| 592 } else if (node.isLiteralString()) { | 550 } else if (node.isLiteralString()) { |
| 593 QuotedString string = node.value; | 551 DartString string = node.value; |
| 594 StringQuoting quoting = string.quoting; | 552 buffer.add("'"); |
| 595 String quote = quoting.quoteChar; | 553 writeEscapedString(string, buffer, |
| 596 buffer.add(quote); | |
| 597 writeEscapedString(string, buffer, quoting.quote, | |
| 598 (String reason) { | 554 (String reason) { |
| 599 compiler.cancel(reason, instruction:node); | 555 compiler.cancel(reason, instruction:node); |
| 600 }); | 556 }); |
| 601 buffer.add(quote); | 557 buffer.add("'"); |
| 602 } else { | 558 } else { |
| 603 buffer.add(node.value); | 559 buffer.add(node.value); |
| 604 } | 560 } |
| 605 } | 561 } |
| 606 | 562 |
| 607 visitLoopBranch(HLoopBranch node) { | 563 visitLoopBranch(HLoopBranch node) { |
| 608 HBasicBlock branchBlock = currentBlock; | 564 HBasicBlock branchBlock = currentBlock; |
| 609 handleLoopCondition(node); | 565 handleLoopCondition(node); |
| 610 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; | 566 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
| 611 // For a do while loop, the body has already been visited. | 567 // For a do while loop, the body has already been visited. |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 startBailoutSwitch(); | 1082 startBailoutSwitch(); |
| 1127 } | 1083 } |
| 1128 } | 1084 } |
| 1129 | 1085 |
| 1130 void endElse(HIf node) { | 1086 void endElse(HIf node) { |
| 1131 if (node.elseBlock.hasBailouts()) { | 1087 if (node.elseBlock.hasBailouts()) { |
| 1132 endBailoutSwitch(); | 1088 endBailoutSwitch(); |
| 1133 } | 1089 } |
| 1134 } | 1090 } |
| 1135 } | 1091 } |
| OLD | NEW |