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