Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Unified Diff: frog/leg/ssa/nodes.dart

Issue 9190038: Handle escapes in string literals. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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.

Powered by Google App Engine
This is Rietveld 408576698