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/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 10091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10102 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); | 10102 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); |
10103 return String::New(utf8_array, array_len, space); | 10103 return String::New(utf8_array, array_len, space); |
10104 } | 10104 } |
10105 | 10105 |
10106 | 10106 |
10107 RawString* String::New(const uint8_t* utf8_array, | 10107 RawString* String::New(const uint8_t* utf8_array, |
10108 intptr_t array_len, | 10108 intptr_t array_len, |
10109 Heap::Space space) { | 10109 Heap::Space space) { |
10110 Utf8::Type type; | 10110 Utf8::Type type; |
10111 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); | 10111 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); |
10112 if (type == Utf8::kAscii) { | 10112 if (type == Utf8::kLatin1) { |
10113 const String& strobj = String::Handle(OneByteString::New(len, space)); | 10113 const String& strobj = String::Handle(OneByteString::New(len, space)); |
10114 if (len > 0) { | 10114 if (len > 0) { |
10115 NoGCScope no_gc; | 10115 NoGCScope no_gc; |
10116 Utf8::DecodeToAscii(utf8_array, array_len, | 10116 Utf8::DecodeToLatin1(utf8_array, array_len, |
10117 OneByteString::CharAddr(strobj, 0), len); | 10117 OneByteString::CharAddr(strobj, 0), len); |
10118 } | 10118 } |
10119 return strobj.raw(); | 10119 return strobj.raw(); |
10120 } | 10120 } |
10121 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); | 10121 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); |
10122 const String& strobj = String::Handle(TwoByteString::New(len, space)); | 10122 const String& strobj = String::Handle(TwoByteString::New(len, space)); |
10123 NoGCScope no_gc; | 10123 NoGCScope no_gc; |
10124 Utf8::DecodeToUTF16(utf8_array, array_len, | 10124 Utf8::DecodeToUTF16(utf8_array, array_len, |
10125 TwoByteString::CharAddr(strobj, 0), len); | 10125 TwoByteString::CharAddr(strobj, 0), len); |
10126 return strobj.raw(); | 10126 return strobj.raw(); |
10127 } | 10127 } |
10128 | 10128 |
10129 | 10129 |
10130 RawString* String::New(const uint16_t* utf16_array, | 10130 RawString* String::New(const uint16_t* utf16_array, |
10131 intptr_t array_len, | 10131 intptr_t array_len, |
10132 Heap::Space space) { | 10132 Heap::Space space) { |
10133 bool is_one_byte_string = true; | 10133 bool is_one_byte_string = true; |
10134 for (intptr_t i = 0; i < array_len; ++i) { | 10134 for (intptr_t i = 0; i < array_len; ++i) { |
10135 if (utf16_array[i] > 0x7F) { | 10135 if (utf16_array[i] > 0xFF) { |
10136 is_one_byte_string = false; | 10136 is_one_byte_string = false; |
10137 break; | 10137 break; |
10138 } | 10138 } |
10139 } | 10139 } |
10140 if (is_one_byte_string) { | 10140 if (is_one_byte_string) { |
10141 return OneByteString::New(utf16_array, array_len, space); | 10141 return OneByteString::New(utf16_array, array_len, space); |
10142 } | 10142 } |
10143 return TwoByteString::New(utf16_array, array_len, space); | 10143 return TwoByteString::New(utf16_array, array_len, space); |
10144 } | 10144 } |
10145 | 10145 |
10146 | 10146 |
10147 RawString* String::New(const uint32_t* utf32_array, | 10147 RawString* String::New(const uint32_t* utf32_array, |
10148 intptr_t array_len, | 10148 intptr_t array_len, |
10149 Heap::Space space) { | 10149 Heap::Space space) { |
10150 bool is_one_byte_string = true; | 10150 bool is_one_byte_string = true; |
10151 intptr_t utf16_len = array_len; | 10151 intptr_t utf16_len = array_len; |
10152 for (intptr_t i = 0; i < array_len; ++i) { | 10152 for (intptr_t i = 0; i < array_len; ++i) { |
10153 if (utf32_array[i] > 0x7F) { | 10153 if (utf32_array[i] > 0xFF) { |
10154 is_one_byte_string = false; | 10154 is_one_byte_string = false; |
10155 } | 10155 } |
10156 if (utf32_array[i] > 0xFFFF) { | 10156 if (utf32_array[i] > 0xFFFF) { |
10157 utf16_len += 1; | 10157 utf16_len += 1; |
10158 } | 10158 } |
10159 } | 10159 } |
10160 if (is_one_byte_string) { | 10160 if (is_one_byte_string) { |
10161 return OneByteString::New(utf32_array, array_len, space); | 10161 return OneByteString::New(utf32_array, array_len, space); |
10162 } | 10162 } |
10163 return TwoByteString::New(utf16_len, utf32_array, array_len, space); | 10163 return TwoByteString::New(utf16_len, utf32_array, array_len, space); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10224 | 10224 |
10225 void String::Copy(const String& dst, intptr_t dst_offset, | 10225 void String::Copy(const String& dst, intptr_t dst_offset, |
10226 const uint16_t* utf16_array, | 10226 const uint16_t* utf16_array, |
10227 intptr_t array_len) { | 10227 intptr_t array_len) { |
10228 ASSERT(dst_offset >= 0); | 10228 ASSERT(dst_offset >= 0); |
10229 ASSERT(array_len >= 0); | 10229 ASSERT(array_len >= 0); |
10230 ASSERT(array_len <= (dst.Length() - dst_offset)); | 10230 ASSERT(array_len <= (dst.Length() - dst_offset)); |
10231 if (dst.IsOneByteString()) { | 10231 if (dst.IsOneByteString()) { |
10232 NoGCScope no_gc; | 10232 NoGCScope no_gc; |
10233 for (intptr_t i = 0; i < array_len; ++i) { | 10233 for (intptr_t i = 0; i < array_len; ++i) { |
10234 ASSERT(utf16_array[i] <= 0x7F); | 10234 ASSERT(utf16_array[i] <= 0xFF); |
10235 *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; | 10235 *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; |
10236 } | 10236 } |
10237 } else { | 10237 } else { |
10238 ASSERT(dst.IsTwoByteString()); | 10238 ASSERT(dst.IsTwoByteString()); |
10239 NoGCScope no_gc; | 10239 NoGCScope no_gc; |
10240 if (array_len > 0) { | 10240 if (array_len > 0) { |
10241 memmove(TwoByteString::CharAddr(dst, dst_offset), | 10241 memmove(TwoByteString::CharAddr(dst, dst_offset), |
10242 utf16_array, | 10242 utf16_array, |
10243 array_len * 2); | 10243 array_len * 2); |
10244 } | 10244 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10379 return Symbols::Empty(); | 10379 return Symbols::Empty(); |
10380 } | 10380 } |
10381 if (begin_index > str.Length()) { | 10381 if (begin_index > str.Length()) { |
10382 return String::null(); | 10382 return String::null(); |
10383 } | 10383 } |
10384 String& result = String::Handle(); | 10384 String& result = String::Handle(); |
10385 bool is_one_byte_string = true; | 10385 bool is_one_byte_string = true; |
10386 intptr_t char_size = str.CharSize(); | 10386 intptr_t char_size = str.CharSize(); |
10387 if (char_size == kTwoByteChar) { | 10387 if (char_size == kTwoByteChar) { |
10388 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | 10388 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
10389 if (str.CharAt(i) > 0x7F) { | 10389 if (str.CharAt(i) > 0xFF) { |
10390 is_one_byte_string = false; | 10390 is_one_byte_string = false; |
10391 break; | 10391 break; |
10392 } | 10392 } |
10393 } | 10393 } |
10394 } | 10394 } |
10395 if (is_one_byte_string) { | 10395 if (is_one_byte_string) { |
10396 result ^= OneByteString::New(length, space); | 10396 result ^= OneByteString::New(length, space); |
10397 } else { | 10397 } else { |
10398 result ^= TwoByteString::New(length, space); | 10398 result ^= TwoByteString::New(length, space); |
10399 } | 10399 } |
10400 String::Copy(result, 0, str, begin_index, length); | 10400 String::Copy(result, 0, str, begin_index, length); |
10401 return result.raw(); | 10401 return result.raw(); |
10402 } | 10402 } |
10403 | 10403 |
10404 | 10404 |
10405 const char* String::ToCString() const { | 10405 const char* String::ToCString() const { |
10406 intptr_t len = Utf8::Length(*this); | 10406 intptr_t len = Utf8::Length(*this); |
10407 Zone* zone = Isolate::Current()->current_zone(); | 10407 Zone* zone = Isolate::Current()->current_zone(); |
10408 uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 10408 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
10409 ToUTF8(result, len); | 10409 ToUTF8(result, len); |
10410 result[len] = 0; | 10410 result[len] = 0; |
10411 return reinterpret_cast<const char*>(result); | 10411 return reinterpret_cast<const char*>(result); |
10412 } | 10412 } |
10413 | 10413 |
10414 | 10414 |
10415 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { | 10415 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { |
10416 if (CharSize() == kOneByteChar) { | 10416 ASSERT(array_len >= Utf8::Length(*this)); |
10417 const String& obj = *this; | 10417 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |
10418 ASSERT(array_len >= obj.Length()); | |
10419 if (obj.Length() > 0) { | |
10420 memmove(utf8_array, OneByteString::CharAddr(obj, 0), obj.Length()); | |
10421 } | |
10422 } else { | |
10423 ASSERT(array_len >= Utf8::Length(*this)); | |
10424 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); | |
10425 } | |
10426 } | 10418 } |
10427 | 10419 |
10428 | 10420 |
10429 static void AddFinalizer(const Object& referent, | 10421 static void AddFinalizer(const Object& referent, |
10430 void* peer, | 10422 void* peer, |
10431 Dart_WeakPersistentHandleFinalizer callback) { | 10423 Dart_WeakPersistentHandleFinalizer callback) { |
10432 ASSERT(callback != NULL); | 10424 ASSERT(callback != NULL); |
10433 ApiState* state = Isolate::Current()->api_state(); | 10425 ApiState* state = Isolate::Current()->api_state(); |
10434 ASSERT(state != NULL); | 10426 ASSERT(state != NULL); |
10435 FinalizablePersistentHandle* weak_ref = | 10427 FinalizablePersistentHandle* weak_ref = |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10523 int32_t src = str.CharAt(i); | 10515 int32_t src = str.CharAt(i); |
10524 int32_t dst = mapping(src); | 10516 int32_t dst = mapping(src); |
10525 if (src != dst) { | 10517 if (src != dst) { |
10526 has_mapping = true; | 10518 has_mapping = true; |
10527 } | 10519 } |
10528 dst_max = Utils::Maximum(dst_max, dst); | 10520 dst_max = Utils::Maximum(dst_max, dst); |
10529 } | 10521 } |
10530 if (!has_mapping) { | 10522 if (!has_mapping) { |
10531 return str.raw(); | 10523 return str.raw(); |
10532 } | 10524 } |
10533 if (dst_max <= 0x7F) { | 10525 if (dst_max <= 0xFF) { |
10534 return OneByteString::Transform(mapping, str, space); | 10526 return OneByteString::Transform(mapping, str, space); |
10535 } | 10527 } |
10536 ASSERT(dst_max > 0x7F); | 10528 ASSERT(dst_max > 0xFF); |
10537 return TwoByteString::Transform(mapping, str, space); | 10529 return TwoByteString::Transform(mapping, str, space); |
10538 } | 10530 } |
10539 | 10531 |
10540 | 10532 |
10541 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10533 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
10542 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10534 // TODO(cshapiro): create a fast-path for OneByteString instances. |
10543 return Transform(CaseMapping::ToUpper, str, space); | 10535 return Transform(CaseMapping::ToUpper, str, space); |
10544 } | 10536 } |
10545 | 10537 |
10546 | 10538 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10674 } | 10666 } |
10675 return OneByteString::raw(result); | 10667 return OneByteString::raw(result); |
10676 } | 10668 } |
10677 | 10669 |
10678 | 10670 |
10679 RawOneByteString* OneByteString::New(const uint16_t* characters, | 10671 RawOneByteString* OneByteString::New(const uint16_t* characters, |
10680 intptr_t len, | 10672 intptr_t len, |
10681 Heap::Space space) { | 10673 Heap::Space space) { |
10682 const String& result =String::Handle(OneByteString::New(len, space)); | 10674 const String& result =String::Handle(OneByteString::New(len, space)); |
10683 for (intptr_t i = 0; i < len; ++i) { | 10675 for (intptr_t i = 0; i < len; ++i) { |
10684 ASSERT(characters[i] <= 0x7F); | 10676 ASSERT(characters[i] <= 0xFF); |
10685 *CharAddr(result, i) = characters[i]; | 10677 *CharAddr(result, i) = characters[i]; |
10686 } | 10678 } |
10687 return OneByteString::raw(result); | 10679 return OneByteString::raw(result); |
10688 } | 10680 } |
10689 | 10681 |
10690 | 10682 |
10691 RawOneByteString* OneByteString::New(const uint32_t* characters, | 10683 RawOneByteString* OneByteString::New(const uint32_t* characters, |
10692 intptr_t len, | 10684 intptr_t len, |
10693 Heap::Space space) { | 10685 Heap::Space space) { |
10694 const String& result = String::Handle(OneByteString::New(len, space)); | 10686 const String& result = String::Handle(OneByteString::New(len, space)); |
10695 for (intptr_t i = 0; i < len; ++i) { | 10687 for (intptr_t i = 0; i < len; ++i) { |
10696 ASSERT(characters[i] <= 0x7F); | 10688 ASSERT(characters[i] <= 0xFF); |
10697 *CharAddr(result, i) = characters[i]; | 10689 *CharAddr(result, i) = characters[i]; |
10698 } | 10690 } |
10699 return OneByteString::raw(result); | 10691 return OneByteString::raw(result); |
10700 } | 10692 } |
10701 | 10693 |
10702 | 10694 |
10703 RawOneByteString* OneByteString::New(const String& str, | 10695 RawOneByteString* OneByteString::New(const String& str, |
10704 Heap::Space space) { | 10696 Heap::Space space) { |
10705 intptr_t len = str.Length(); | 10697 intptr_t len = str.Length(); |
10706 const String& result = String::Handle(OneByteString::New(len, space)); | 10698 const String& result = String::Handle(OneByteString::New(len, space)); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10740 | 10732 |
10741 | 10733 |
10742 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 10734 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
10743 const String& str, | 10735 const String& str, |
10744 Heap::Space space) { | 10736 Heap::Space space) { |
10745 ASSERT(!str.IsNull()); | 10737 ASSERT(!str.IsNull()); |
10746 intptr_t len = str.Length(); | 10738 intptr_t len = str.Length(); |
10747 const String& result = String::Handle(OneByteString::New(len, space)); | 10739 const String& result = String::Handle(OneByteString::New(len, space)); |
10748 for (intptr_t i = 0; i < len; ++i) { | 10740 for (intptr_t i = 0; i < len; ++i) { |
10749 int32_t ch = mapping(str.CharAt(i)); | 10741 int32_t ch = mapping(str.CharAt(i)); |
10750 ASSERT(ch >= 0 && ch <= 0x7F); | 10742 ASSERT(ch >= 0 && ch <= 0xFF); |
10751 *CharAddr(result, i) = ch; | 10743 *CharAddr(result, i) = ch; |
10752 } | 10744 } |
10753 return OneByteString::raw(result); | 10745 return OneByteString::raw(result); |
10754 } | 10746 } |
10755 | 10747 |
10756 | 10748 |
10757 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, | 10749 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, |
10758 bool raw_str) { | 10750 bool raw_str) { |
10759 intptr_t len = str.Length(); | 10751 intptr_t len = str.Length(); |
10760 if (len > 0) { | 10752 if (len > 0) { |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12091 } | 12083 } |
12092 return result.raw(); | 12084 return result.raw(); |
12093 } | 12085 } |
12094 | 12086 |
12095 | 12087 |
12096 const char* WeakProperty::ToCString() const { | 12088 const char* WeakProperty::ToCString() const { |
12097 return "_WeakProperty"; | 12089 return "_WeakProperty"; |
12098 } | 12090 } |
12099 | 12091 |
12100 } // namespace dart | 12092 } // namespace dart |
OLD | NEW |