Chromium Code Reviews| Index: frog/leg/ssa/nodes.dart |
| diff --git a/frog/leg/ssa/nodes.dart b/frog/leg/ssa/nodes.dart |
| index 7bc4afbfa615b5d12eb637435ddd58962b334b26..601e90abf86a678d9b9810e17d9532089e761ddc 100644 |
| --- a/frog/leg/ssa/nodes.dart |
| +++ b/frog/leg/ssa/nodes.dart |
| @@ -1064,9 +1064,6 @@ class HInvokeInterceptor extends HInvokeStatic { |
| if (name == 'length' && inputs[1].isLiteralString()) { |
| // TODO(lrn): Account for escapes in string. Currently we count characters |
| // in the uninterpreted (but unquoted) string. |
| - QuotedString string = inputs[1].value; |
| - int contentLength = string.contentEnd - string.contentStart; |
| - return new HLiteral(contentLength, HType.INTEGER); |
| } |
| return this; |
| } |
| @@ -1556,6 +1553,82 @@ class HLoopBranch extends HConditionalBranch { |
| bool isEmpty() => contentStart == contentEnd; |
| + static int hexValue(int hexDigit) { |
| + // hexDigit is one of '0'..'9', 'A'..'F' and 'a'..'f'. |
| + if (hexDigit <= 0x39) { |
| + return hexDigit - 0x30; |
|
floitsch
2012/01/12 12:30:28
Don't use random constants. I would prefer not to
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Now uses $9, etc.
|
| + } |
| + // Make letters lowercase. |
| + hexDigit |= 0x20; |
| + hexDigit -= 0x61 - 10; |
| + assert(0 <= hexDigit && hexDigit <= 15); |
| + return hexDigit; |
| + } |
| + |
| + /* Write the contents of the quoted string to a [StringBuffer] in |
|
floitsch
2012/01/12 12:30:28
/**
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Done.
|
| + * a form that is valid as JavaScript string literal content. |
| + * The string is assumed quoted by [quote] characters. |
| + * This method doesn't try to make the shortest string, but rather |
| + * to be as close to the original string as possible. |
| + */ |
| + void writeEscaped(StringBuffer buffer, String quote) { |
| + bool raw = this.isRaw; |
| + int from = contentStart; |
| + int end = contentEnd; |
| + for (int i = from; i < end; i++) { |
| + String character = wrappedString[i]; |
| + if (character == quote) { |
| + // Insert backslash before unquoted quote character. |
| + wrappedString.printSubstringOn(buffer, from, i); |
| + buffer.add(@'\'); |
| + from = i; |
| + } else if (character == @'\') { |
| + if (raw) { |
| + wrappedString.printSubstringOn(buffer, from, i); |
| + buffer.add(@'\'); |
|
floitsch
2012/01/12 12:30:28
Don't you need to update from?
Lasse Reichstein Nielsen
2012/01/16 13:30:23
I did. It's now completely rewritten.
|
| + } else { |
| + character = wrappedString[++i]; |
|
floitsch
2012/01/12 12:30:28
I find it easier to i++; first:
i++;
character = w
Lasse Reichstein Nielsen
2012/01/16 13:30:23
In many cases I'd agree. In this, I actually read
|
| + if (character == 'u') { |
| + if (wrappedString[++i] == '{') { |
|
floitsch
2012/01/12 12:30:28
ditto
floitsch
2012/01/12 12:30:28
Maybe move the \u{...} section into a (local/neste
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Moved.
|
| + // In Dart, \u{x+} is a valid escape, but not in |
| + // JS. Convert to a \uxxxx escape. |
| + wrappedString.printSubstringOn(buffer, from, i); |
| + int value = 0; |
| + int hexDigit = wrappedString.charCodeAt(++i); |
|
floitsch
2012/01/12 12:30:28
ditto. (maybe also move i++ up, so that it is clea
Lasse Reichstein Nielsen
2012/01/16 13:30:23
gone.
|
| + do { |
| + value = value * 16 + hexValue(hexDigit); |
| + hexDigit = wrappedString.charCodeAt(++i); |
|
floitsch
2012/01/12 12:30:28
use i++
|
| + } while (hexDigit !== 0x7d); // until '}'. |
|
floitsch
2012/01/12 12:30:28
magic value.
|
| + // JavaScript only supports characters in the BMP. |
|
floitsch
2012/01/12 12:30:28
That's not true. It allows for the full UTF-16. We
|
| + if (value > 0xffff) value = 0xfffd; |
| + |
| + for (int j = 12; j >= 0; j -= 4) { |
| + int digit = (value >> j) & 0xf; |
| + buffer.add("0123456789abcdef"[digit]); |
| + } |
| + from = i + 1; |
| + } |
| + } else if ('0' == character || |
| + '1' == character || |
| + '2' == character || |
| + '3' == character || |
| + '4' == character || |
| + '5' == character || |
| + '6' == character || |
| + '7' == character) { |
| + // In Dart "\[0-9]" are identity escapes. In JS, |
| + // they start an octal escape, so we need to remove the '\'. |
| + wrappedString.printSubstringOn(buffer, from, i - 1); |
| + from = i; |
| + } |
| + // All other valid Dart escapes are also valid JS escapes |
| + // with the same meaning, so we include them verbatim. |
|
floitsch
2012/01/12 12:30:28
I would still prefer to have them explicitly handl
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Done.
|
| + } |
| + } |
| + } |
| + wrappedString.printSubstringOn(buffer, from, end); |
| + } |
| + |
| /** |
| * Does a conservative test for equality between two quoted strings. |
| * Returns true if the two definitly have the same string. |