Chromium Code Reviews| Index: vm/object.cc |
| =================================================================== |
| --- vm/object.cc (revision 9471) |
| +++ vm/object.cc (working copy) |
| @@ -4423,10 +4423,29 @@ |
| String& literal = String::Handle(); |
| String& blank = String::Handle(String::New(" ")); |
| String& newline = String::Handle(String::New("\n")); |
| + String& double_quotes = String::Handle(String::New("\"")); |
| for (intptr_t i = 0; i < Length(); i++) { |
| Token::Kind kind = KindAt(i); |
| literal = LiteralAt(i); |
| - literals.Add(literal); |
| + if (kind == Token::kSTRING) { |
| + bool escape_quotes = false; |
| + for (intptr_t i = 0; i < literal.Length(); i++) { |
| + if (literal.CharAt(i) == '"') { |
| + escape_quotes = true; |
| + break; |
| + } |
| + } |
| + literals.Add(double_quotes); |
| + if (escape_quotes) { |
| + literal = String::EscapeQuotes(literal); |
| + literals.Add(literal); |
| + } else { |
| + literals.Add(literal); |
| + } |
| + literals.Add(double_quotes); |
| + } else { |
| + literals.Add(literal); |
| + } |
| if (kind == Token::kLBRACE) { |
| literals.Add(newline); |
| } else { |
| @@ -8273,6 +8292,65 @@ |
| } |
| +RawString* String::EscapeQuotes(const String& str) { |
| + intptr_t len = str.Length(); |
| + if (len > 0) { |
| + intptr_t num_quotes = 0; |
| + intptr_t index = 0; |
| + for (intptr_t i = 0; i < len; i++) { |
| + if (str.CharAt(i) == '"') { |
|
cshapiro
2012/07/10 19:03:27
This entails one virtual function call per charact
siva
2012/07/10 22:59:10
Done.
|
| + num_quotes += 1; |
| + } |
| + } |
| + if (str.IsOneByteString()) { |
| + const OneByteString& dststr = OneByteString::Handle( |
| + OneByteString::New(len + num_quotes, Heap::kNew)); |
| + for (intptr_t i = 0; i < len; i++) { |
| + if (str.CharAt(i) == '"') { |
| + *(dststr.CharAddr(index)) = '\\'; |
| + *(dststr.CharAddr(index + 1)) = '"'; |
| + index += 2; |
| + } else { |
| + *(dststr.CharAddr(index)) = str.CharAt(i); |
| + index += 1; |
| + } |
| + } |
| + return dststr.raw(); |
| + } |
| + if (str.IsTwoByteString()) { |
| + const TwoByteString& dststr = TwoByteString::Handle( |
| + TwoByteString::New(len + num_quotes, Heap::kNew)); |
| + for (intptr_t i = 0; i < len; i++) { |
| + if (str.CharAt(i) == '"') { |
| + *(dststr.CharAddr(index)) = '\\'; |
| + *(dststr.CharAddr(index + 1)) = '"'; |
| + index += 2; |
| + } else { |
| + *(dststr.CharAddr(index)) = str.CharAt(i); |
| + index += 1; |
| + } |
| + } |
| + return dststr.raw(); |
| + } |
| + ASSERT(str.IsFourByteString()); |
| + const FourByteString& dststr = FourByteString::Handle( |
| + FourByteString::New(len + num_quotes, Heap::kNew)); |
| + for (intptr_t i = 0; i < len; i++) { |
| + if (str.CharAt(i) == '"') { |
| + *(dststr.CharAddr(index)) = '\\'; |
| + *(dststr.CharAddr(index + 1)) = '"'; |
| + index += 2; |
| + } else { |
| + *(dststr.CharAddr(index)) = str.CharAt(i); |
| + index += 1; |
| + } |
| + } |
| + return dststr.raw(); |
| + } |
| + return String::null(); |
| +} |
| + |
| + |
| static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { |
| // TODO(iposva): Avoid exponential growth. |
| intptr_t new_table_size = table_size * 2; |