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

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

Issue 9271037: Inserted string validation as separate task in compiler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments. 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/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);

Powered by Google App Engine
This is Rietveld 408576698