| Index: frog/leg/ssa/codegen.dart
|
| diff --git a/frog/leg/ssa/codegen.dart b/frog/leg/ssa/codegen.dart
|
| index 6a02fc44aea093949b1baf9a6e32d95ebc35efe4..c826043368793d31ea4bf8107514d017ca3cc299 100644
|
| --- a/frog/leg/ssa/codegen.dart
|
| +++ b/frog/leg/ssa/codegen.dart
|
| @@ -489,6 +489,103 @@ class SsaCodeGenerator implements HVisitor {
|
| buffer.add(')');
|
| }
|
|
|
| + /**
|
| + * Write the contents of the quoted string to a [StringBuffer] in
|
| + * a form that is valid as JavaScript string literal content.
|
| + * The string is assumed quoted by [quote] characters.
|
| + */
|
| + static void writeEscapedString(QuotedString string,
|
| + StringBuffer buffer,
|
| + int quote,
|
| + void cancel(String reason)) {
|
| + bool raw = string.quoting.raw;
|
| + Iterator<int> iterator = string.iterator();
|
| + while (iterator.hasNext()) {
|
| + int code = iterator.next();
|
| + if (code === quote) {
|
| + // We need to add a backslash before quotes, both in normal
|
| + // and in raw strings.
|
| + buffer.add(@'\');
|
| + buffer.add(code === $SQ ? "'" : '"');
|
| + } else if (code === $LF) {
|
| + // Newlines in strings only occur in multiline strings.
|
| + // They need to be written using escapes in JS.
|
| + assert(string.quoting.multiline);
|
| + buffer.add(@'\n');
|
| + } else if (code === $CR) {
|
| + assert(string.quoting.multiline);
|
| + buffer.add(@'\r');
|
| + } else if (code === $LS) {
|
| + // This Unicode line terminator and $PS are invalid in JS string
|
| + // literals.
|
| + buffer.add(@'\u2028');
|
| + } else if (code === $PS) {
|
| + buffer.add(@'\u2029');
|
| + } else if (code !== $BACKSLASH) {
|
| + buffer.add(new String.fromCharCodes([code]));
|
| + } else if (raw) {
|
| + buffer.add(@'\\');
|
| + } else {
|
| + assert(code === $BACKSLASH);
|
| + code = iterator.next();
|
| + switch (code) {
|
| + case $u:
|
| + buffer.add(@'\u');
|
| + code = iterator.next();
|
| + if (code == $OPEN_CURLY_BRACKET) {
|
| + int value = 0;
|
| + code = iterator.next();
|
| + do {
|
| + value = value * 16 + hexDigitValue(code);
|
| + code = iterator.next();
|
| + } while (code !== $CLOSE_CURLY_BRACKET);
|
| + if (code > 0xffff) {
|
| + cancel("Unhandled non-BMP character: " +
|
| + "U+${code.toRadixString(16)}");
|
| + }
|
| + for (int i = 12; i >= 0; i -= 4) {
|
| + buffer.add(((value >> i) & 0xf).toRadixString(16));
|
| + }
|
| + } else {
|
| + buffer.add(new String.fromCharCodes([code]));
|
| + // Remaining three hex digits will be copied verbatim.
|
| + }
|
| + break;
|
| + case $x:
|
| + buffer.add(@'\x');
|
| + // The two hex digits will be copied verbatim.
|
| + break;
|
| + // Character escapes that identical in meaning in JS.
|
| + case $b: buffer.add(@'\b'); break;
|
| + case $f: buffer.add(@'\f'); break;
|
| + case $n: buffer.add(@'\n'); break;
|
| + case $r: buffer.add(@'\r'); break;
|
| + case $t: buffer.add(@'\t'); break;
|
| + case $v: buffer.add(@'\v'); break;
|
| + // Identity escapes that must be escaped in JS strings.
|
| + case $BACKSLASH: buffer.add(@'\\'); break;
|
| + case $LF: buffer.add(@'\n'); break;
|
| + case $CR: buffer.add(@'\r'); break;
|
| + case $LS: buffer.add(@'\u2028'); break;
|
| + case $PS: buffer.add(@'\u2029'); break;
|
| + // Quotes may or may not need the escape.
|
| + case $SQ:
|
| + case $DQ:
|
| + // Only escape quotes if they match the generated string quotes.
|
| + if (code == quote) buffer.add(@'\');
|
| + buffer.add(code === $SQ ? "'" : '"');
|
| + break;
|
| + default:
|
| + // All other escaped characters are identity escapes,
|
| + // and don't need a backslash in JS.
|
| + buffer.add(new String.fromCharCodes([code]));
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| +
|
| visitLiteral(HLiteral node) {
|
| if (node.isLiteralNull()) {
|
| buffer.add("(void 0)");
|
| @@ -496,12 +593,13 @@ class SsaCodeGenerator implements HVisitor {
|
| buffer.add('(${node.value})');
|
| } else if (node.isLiteralString()) {
|
| QuotedString string = node.value;
|
| - String quote = string.quoteChar;
|
| + StringQuoting quoting = string.quoting;
|
| + String quote = quoting.quoteChar;
|
| buffer.add(quote);
|
| - string.writeEscaped(buffer, string.quoteCharCode,
|
| - (String reason) {
|
| - compiler.cancel(reason, instruction: node);
|
| - });
|
| + writeEscapedString(string, buffer, quoting.quote,
|
| + (String reason) {
|
| + compiler.cancel(reason, instruction:node);
|
| + });
|
| buffer.add(quote);
|
| } else {
|
| buffer.add(node.value);
|
|
|