OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 (value == '\f') || | 351 (value == '\f') || |
352 (value == '\b') || | 352 (value == '\b') || |
353 (value == '\t') || | 353 (value == '\t') || |
354 (value == '\v') || | 354 (value == '\v') || |
355 (value == '\r') || | 355 (value == '\r') || |
356 (value == '\\') || | 356 (value == '\\') || |
357 (value == '$')); | 357 (value == '$')); |
358 } | 358 } |
359 | 359 |
360 | 360 |
| 361 static bool IsAsciiPrintChar(int32_t code_point) { |
| 362 return (code_point >= ' ') && (code_point <= '~'); |
| 363 } |
| 364 |
| 365 |
| 366 static inline bool IsAsciiNonprintable(int32_t c) { |
| 367 return ((0 <= c) && (c < 32)) || (c == 127); |
| 368 } |
| 369 |
| 370 |
| 371 static inline bool NeedsEscapeSequence(int32_t c) { |
| 372 return (c == '"') || |
| 373 (c == '\\') || |
| 374 (c == '$') || |
| 375 IsAsciiNonprintable(c); |
| 376 } |
| 377 |
| 378 |
| 379 static int32_t EscapeOverhead(int32_t c) { |
| 380 if (IsSpecialCharacter(c)) { |
| 381 return 1; // 1 additional byte for the backslash. |
| 382 } else if (IsAsciiNonprintable(c)) { |
| 383 return 3; // 3 additional bytes to encode c as \x00. |
| 384 } |
| 385 return 0; |
| 386 } |
| 387 |
| 388 |
361 template<typename type> | 389 template<typename type> |
362 static type SpecialCharacter(type value) { | 390 static type SpecialCharacter(type value) { |
363 if (value == '"') { | 391 if (value == '"') { |
364 return '"'; | 392 return '"'; |
365 } else if (value == '\n') { | 393 } else if (value == '\n') { |
366 return 'n'; | 394 return 'n'; |
367 } else if (value == '\f') { | 395 } else if (value == '\f') { |
368 return 'f'; | 396 return 'f'; |
369 } else if (value == '\b') { | 397 } else if (value == '\b') { |
370 return 'b'; | 398 return 'b'; |
(...skipping 6717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7088 obj = iterator.CurrentToken(); | 7116 obj = iterator.CurrentToken(); |
7089 literal = iterator.MakeLiteralToken(obj); | 7117 literal = iterator.MakeLiteralToken(obj); |
7090 // Advance to be able to use next token kind. | 7118 // Advance to be able to use next token kind. |
7091 iterator.Advance(); | 7119 iterator.Advance(); |
7092 Token::Kind next = iterator.CurrentTokenKind(); | 7120 Token::Kind next = iterator.CurrentTokenKind(); |
7093 | 7121 |
7094 // Handle the current token. | 7122 // Handle the current token. |
7095 if (curr == Token::kSTRING) { | 7123 if (curr == Token::kSTRING) { |
7096 bool escape_characters = false; | 7124 bool escape_characters = false; |
7097 for (intptr_t i = 0; i < literal.Length(); i++) { | 7125 for (intptr_t i = 0; i < literal.Length(); i++) { |
7098 if (IsSpecialCharacter(literal.CharAt(i))) { | 7126 if (NeedsEscapeSequence(literal.CharAt(i))) { |
7099 escape_characters = true; | 7127 escape_characters = true; |
7100 } | 7128 } |
7101 } | 7129 } |
7102 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { | 7130 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { |
7103 literals.Add(Symbols::DoubleQuotes()); | 7131 literals.Add(Symbols::DoubleQuotes()); |
7104 } | 7132 } |
7105 if (escape_characters) { | 7133 if (escape_characters) { |
7106 literal = String::EscapeSpecialCharacters(literal); | 7134 literal = String::EscapeSpecialCharacters(literal); |
7107 literals.Add(literal); | 7135 literals.Add(literal); |
7108 } else { | 7136 } else { |
(...skipping 9140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16249 } | 16277 } |
16250 const intptr_t len = Utf8::Length(*this); | 16278 const intptr_t len = Utf8::Length(*this); |
16251 Zone* zone = Isolate::Current()->current_zone(); | 16279 Zone* zone = Isolate::Current()->current_zone(); |
16252 uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 16280 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
16253 ToUTF8(result, len); | 16281 ToUTF8(result, len); |
16254 result[len] = 0; | 16282 result[len] = 0; |
16255 return reinterpret_cast<const char*>(result); | 16283 return reinterpret_cast<const char*>(result); |
16256 } | 16284 } |
16257 | 16285 |
16258 | 16286 |
16259 static bool IsAsciiPrintChar(intptr_t code_point) { | |
16260 return code_point >= ' ' && code_point <= '~'; | |
16261 } | |
16262 | |
16263 | |
16264 // Does not null-terminate. | 16287 // Does not null-terminate. |
16265 intptr_t String::EscapedString(char* buffer, int max_len) const { | 16288 intptr_t String::EscapedString(char* buffer, int max_len) const { |
16266 int pos = 0; | 16289 int pos = 0; |
16267 | 16290 |
16268 CodePointIterator cpi(*this); | 16291 CodePointIterator cpi(*this); |
16269 while (cpi.Next()) { | 16292 while (cpi.Next()) { |
16270 int32_t code_point = cpi.Current(); | 16293 int32_t code_point = cpi.Current(); |
16271 if (IsSpecialCharacter(code_point)) { | 16294 if (IsSpecialCharacter(code_point)) { |
16272 if (pos + 2 > max_len) { | 16295 if (pos + 2 > max_len) { |
16273 return pos; | 16296 return pos; |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16616 index_ = end_; | 16639 index_ = end_; |
16617 return false; | 16640 return false; |
16618 } | 16641 } |
16619 | 16642 |
16620 | 16643 |
16621 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { | 16644 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { |
16622 intptr_t len = str.Length(); | 16645 intptr_t len = str.Length(); |
16623 if (len > 0) { | 16646 if (len > 0) { |
16624 intptr_t num_escapes = 0; | 16647 intptr_t num_escapes = 0; |
16625 for (intptr_t i = 0; i < len; i++) { | 16648 for (intptr_t i = 0; i < len; i++) { |
16626 if (IsSpecialCharacter(*CharAddr(str, i))) { | 16649 num_escapes += EscapeOverhead(*CharAddr(str, i)); |
16627 num_escapes += 1; | |
16628 } | |
16629 } | 16650 } |
16630 const String& dststr = String::Handle( | 16651 const String& dststr = String::Handle( |
16631 OneByteString::New(len + num_escapes, Heap::kNew)); | 16652 OneByteString::New(len + num_escapes, Heap::kNew)); |
16632 intptr_t index = 0; | 16653 intptr_t index = 0; |
16633 for (intptr_t i = 0; i < len; i++) { | 16654 for (intptr_t i = 0; i < len; i++) { |
16634 if (IsSpecialCharacter(*CharAddr(str, i))) { | 16655 uint8_t ch = CharAt(str, i); |
16635 *(CharAddr(dststr, index)) = '\\'; | 16656 if (IsSpecialCharacter(ch)) { |
16636 *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i)); | 16657 SetCharAt(dststr, index, '\\'); |
| 16658 SetCharAt(dststr, index + 1, SpecialCharacter(ch)); |
16637 index += 2; | 16659 index += 2; |
| 16660 } else if (IsAsciiNonprintable(ch)) { |
| 16661 SetCharAt(dststr, index, '\\'); |
| 16662 SetCharAt(dststr, index + 1, 'x'); |
| 16663 SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4)); |
| 16664 SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF)); |
| 16665 index += 4; |
16638 } else { | 16666 } else { |
16639 *(CharAddr(dststr, index)) = *CharAddr(str, i); | 16667 SetCharAt(dststr, index, ch); |
16640 index += 1; | 16668 index += 1; |
16641 } | 16669 } |
16642 } | 16670 } |
16643 return OneByteString::raw(dststr); | 16671 return OneByteString::raw(dststr); |
16644 } | 16672 } |
16645 return OneByteString::raw(Symbols::Empty()); | 16673 return OneByteString::raw(Symbols::Empty()); |
16646 } | 16674 } |
16647 | 16675 |
| 16676 |
16648 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( | 16677 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( |
16649 const String& str) { | 16678 const String& str) { |
16650 intptr_t len = str.Length(); | 16679 intptr_t len = str.Length(); |
16651 if (len > 0) { | 16680 if (len > 0) { |
16652 intptr_t num_escapes = 0; | 16681 intptr_t num_escapes = 0; |
16653 for (intptr_t i = 0; i < len; i++) { | 16682 for (intptr_t i = 0; i < len; i++) { |
16654 if (IsSpecialCharacter(*CharAddr(str, i))) { | 16683 num_escapes += EscapeOverhead(*CharAddr(str, i)); |
16655 num_escapes += 1; | |
16656 } | |
16657 } | 16684 } |
16658 const String& dststr = String::Handle( | 16685 const String& dststr = String::Handle( |
16659 OneByteString::New(len + num_escapes, Heap::kNew)); | 16686 OneByteString::New(len + num_escapes, Heap::kNew)); |
16660 intptr_t index = 0; | 16687 intptr_t index = 0; |
16661 for (intptr_t i = 0; i < len; i++) { | 16688 for (intptr_t i = 0; i < len; i++) { |
16662 if (IsSpecialCharacter(*CharAddr(str, i))) { | 16689 uint8_t ch = CharAt(str, i); |
16663 *(OneByteString::CharAddr(dststr, index)) = '\\'; | 16690 if (IsSpecialCharacter(ch)) { |
16664 *(OneByteString::CharAddr(dststr, index + 1)) = | 16691 OneByteString::SetCharAt(dststr, index, '\\'); |
16665 SpecialCharacter(*CharAddr(str, i)); | 16692 OneByteString::SetCharAt(dststr, index + 1, SpecialCharacter(ch)); |
16666 index += 2; | 16693 index += 2; |
| 16694 } else if (IsAsciiNonprintable(ch)) { |
| 16695 OneByteString::SetCharAt(dststr, index, '\\'); |
| 16696 OneByteString::SetCharAt(dststr, index + 1, 'x'); |
| 16697 OneByteString::SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4)); |
| 16698 OneByteString::SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF)); |
| 16699 index += 4; |
16667 } else { | 16700 } else { |
16668 *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i); | 16701 *(OneByteString::CharAddr(dststr, index)) = ch; |
16669 index += 1; | 16702 index += 1; |
16670 } | 16703 } |
16671 } | 16704 } |
16672 return OneByteString::raw(dststr); | 16705 return OneByteString::raw(dststr); |
16673 } | 16706 } |
16674 return OneByteString::raw(Symbols::Empty()); | 16707 return OneByteString::raw(Symbols::Empty()); |
16675 } | 16708 } |
16676 | 16709 |
16677 | 16710 |
16678 RawOneByteString* OneByteString::New(intptr_t len, | 16711 RawOneByteString* OneByteString::New(intptr_t len, |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16879 void* peer) { | 16912 void* peer) { |
16880 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); | 16913 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); |
16881 } | 16914 } |
16882 | 16915 |
16883 | 16916 |
16884 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { | 16917 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { |
16885 intptr_t len = str.Length(); | 16918 intptr_t len = str.Length(); |
16886 if (len > 0) { | 16919 if (len > 0) { |
16887 intptr_t num_escapes = 0; | 16920 intptr_t num_escapes = 0; |
16888 for (intptr_t i = 0; i < len; i++) { | 16921 for (intptr_t i = 0; i < len; i++) { |
16889 if (IsSpecialCharacter(*CharAddr(str, i))) { | 16922 num_escapes += EscapeOverhead(*CharAddr(str, i)); |
16890 num_escapes += 1; | |
16891 } | |
16892 } | 16923 } |
16893 const String& dststr = String::Handle( | 16924 const String& dststr = String::Handle( |
16894 TwoByteString::New(len + num_escapes, Heap::kNew)); | 16925 TwoByteString::New(len + num_escapes, Heap::kNew)); |
16895 intptr_t index = 0; | 16926 intptr_t index = 0; |
16896 for (intptr_t i = 0; i < len; i++) { | 16927 for (intptr_t i = 0; i < len; i++) { |
16897 if (IsSpecialCharacter(*CharAddr(str, i))) { | 16928 uint16_t ch = CharAt(str, i); |
16898 *(CharAddr(dststr, index)) = '\\'; | 16929 if (IsSpecialCharacter(ch)) { |
16899 *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i)); | 16930 SetCharAt(dststr, index, '\\'); |
| 16931 SetCharAt(dststr, index + 1, SpecialCharacter(ch)); |
16900 index += 2; | 16932 index += 2; |
| 16933 } else if (IsAsciiNonprintable(ch)) { |
| 16934 SetCharAt(dststr, index, '\\'); |
| 16935 SetCharAt(dststr, index + 1, 'x'); |
| 16936 SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4)); |
| 16937 SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF)); |
| 16938 index += 4; |
16901 } else { | 16939 } else { |
16902 *(CharAddr(dststr, index)) = *CharAddr(str, i); | 16940 SetCharAt(dststr, index, ch); |
16903 index += 1; | 16941 index += 1; |
16904 } | 16942 } |
16905 } | 16943 } |
16906 return TwoByteString::raw(dststr); | 16944 return TwoByteString::raw(dststr); |
16907 } | 16945 } |
16908 return TwoByteString::New(0, Heap::kNew); | 16946 return TwoByteString::New(0, Heap::kNew); |
16909 } | 16947 } |
16910 | 16948 |
16911 | 16949 |
16912 RawTwoByteString* TwoByteString::New(intptr_t len, | 16950 RawTwoByteString* TwoByteString::New(intptr_t len, |
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18553 return tag_label.ToCString(); | 18591 return tag_label.ToCString(); |
18554 } | 18592 } |
18555 | 18593 |
18556 | 18594 |
18557 void UserTag::PrintToJSONStream(JSONStream* stream, bool ref) const { | 18595 void UserTag::PrintToJSONStream(JSONStream* stream, bool ref) const { |
18558 Instance::PrintToJSONStream(stream, ref); | 18596 Instance::PrintToJSONStream(stream, ref); |
18559 } | 18597 } |
18560 | 18598 |
18561 | 18599 |
18562 } // namespace dart | 18600 } // namespace dart |
OLD | NEW |