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 10049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10060 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); | 10060 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); |
10061 return String::New(utf8_array, array_len, space); | 10061 return String::New(utf8_array, array_len, space); |
10062 } | 10062 } |
10063 | 10063 |
10064 | 10064 |
10065 RawString* String::New(const uint8_t* utf8_array, | 10065 RawString* String::New(const uint8_t* utf8_array, |
10066 intptr_t array_len, | 10066 intptr_t array_len, |
10067 Heap::Space space) { | 10067 Heap::Space space) { |
10068 Utf8::Type type; | 10068 Utf8::Type type; |
10069 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); | 10069 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); |
10070 if (type == Utf8::kAscii) { | 10070 if (type == Utf8::kLatin1) { |
10071 const String& strobj = String::Handle(OneByteString::New(len, space)); | 10071 const String& strobj = String::Handle(OneByteString::New(len, space)); |
10072 if (len > 0) { | 10072 if (len > 0) { |
10073 NoGCScope no_gc; | 10073 NoGCScope no_gc; |
10074 Utf8::DecodeToAscii(utf8_array, array_len, | 10074 Utf8::DecodeToLatin1(utf8_array, array_len, |
10075 OneByteString::CharAddr(strobj, 0), len); | 10075 OneByteString::CharAddr(strobj, 0), len); |
10076 } | 10076 } |
10077 return strobj.raw(); | 10077 return strobj.raw(); |
10078 } | 10078 } |
10079 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); | 10079 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); |
10080 const String& strobj = String::Handle(TwoByteString::New(len, space)); | 10080 const String& strobj = String::Handle(TwoByteString::New(len, space)); |
10081 NoGCScope no_gc; | 10081 NoGCScope no_gc; |
10082 Utf8::DecodeToUTF16(utf8_array, array_len, | 10082 Utf8::DecodeToUTF16(utf8_array, array_len, |
10083 TwoByteString::CharAddr(strobj, 0), len); | 10083 TwoByteString::CharAddr(strobj, 0), len); |
10084 return strobj.raw(); | 10084 return strobj.raw(); |
10085 } | 10085 } |
10086 | 10086 |
10087 | 10087 |
10088 RawString* String::New(const uint16_t* utf16_array, | 10088 RawString* String::New(const uint16_t* utf16_array, |
10089 intptr_t array_len, | 10089 intptr_t array_len, |
10090 Heap::Space space) { | 10090 Heap::Space space) { |
10091 bool is_one_byte_string = true; | 10091 bool is_one_byte_string = true; |
10092 for (intptr_t i = 0; i < array_len; ++i) { | 10092 for (intptr_t i = 0; i < array_len; ++i) { |
10093 if (utf16_array[i] > 0x7F) { | 10093 if (utf16_array[i] > 0xFF) { |
10094 is_one_byte_string = false; | 10094 is_one_byte_string = false; |
10095 break; | 10095 break; |
10096 } | 10096 } |
10097 } | 10097 } |
10098 if (is_one_byte_string) { | 10098 if (is_one_byte_string) { |
10099 return OneByteString::New(utf16_array, array_len, space); | 10099 return OneByteString::New(utf16_array, array_len, space); |
10100 } | 10100 } |
10101 return TwoByteString::New(utf16_array, array_len, space); | 10101 return TwoByteString::New(utf16_array, array_len, space); |
10102 } | 10102 } |
10103 | 10103 |
10104 | 10104 |
10105 RawString* String::New(const uint32_t* utf32_array, | 10105 RawString* String::New(const uint32_t* utf32_array, |
10106 intptr_t array_len, | 10106 intptr_t array_len, |
10107 Heap::Space space) { | 10107 Heap::Space space) { |
10108 bool is_one_byte_string = true; | 10108 bool is_one_byte_string = true; |
10109 intptr_t utf16_len = array_len; | 10109 intptr_t utf16_len = array_len; |
10110 for (intptr_t i = 0; i < array_len; ++i) { | 10110 for (intptr_t i = 0; i < array_len; ++i) { |
10111 if (utf32_array[i] > 0x7F) { | 10111 if (utf32_array[i] > 0xFF) { |
10112 is_one_byte_string = false; | 10112 is_one_byte_string = false; |
10113 } | 10113 } |
10114 if (utf32_array[i] > 0xFFFF) { | 10114 if (utf32_array[i] > 0xFFFF) { |
10115 utf16_len += 1; | 10115 utf16_len += 1; |
10116 } | 10116 } |
10117 } | 10117 } |
10118 if (is_one_byte_string) { | 10118 if (is_one_byte_string) { |
10119 return OneByteString::New(utf32_array, array_len, space); | 10119 return OneByteString::New(utf32_array, array_len, space); |
10120 } | 10120 } |
10121 return TwoByteString::New(utf16_len, utf32_array, array_len, space); | 10121 return TwoByteString::New(utf16_len, utf32_array, array_len, space); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10182 | 10182 |
10183 void String::Copy(const String& dst, intptr_t dst_offset, | 10183 void String::Copy(const String& dst, intptr_t dst_offset, |
10184 const uint16_t* utf16_array, | 10184 const uint16_t* utf16_array, |
10185 intptr_t array_len) { | 10185 intptr_t array_len) { |
10186 ASSERT(dst_offset >= 0); | 10186 ASSERT(dst_offset >= 0); |
10187 ASSERT(array_len >= 0); | 10187 ASSERT(array_len >= 0); |
10188 ASSERT(array_len <= (dst.Length() - dst_offset)); | 10188 ASSERT(array_len <= (dst.Length() - dst_offset)); |
10189 if (dst.IsOneByteString()) { | 10189 if (dst.IsOneByteString()) { |
10190 NoGCScope no_gc; | 10190 NoGCScope no_gc; |
10191 for (intptr_t i = 0; i < array_len; ++i) { | 10191 for (intptr_t i = 0; i < array_len; ++i) { |
10192 ASSERT(utf16_array[i] <= 0x7F); | 10192 ASSERT(utf16_array[i] <= 0xFF); |
10193 *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; | 10193 *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; |
10194 } | 10194 } |
10195 } else { | 10195 } else { |
10196 ASSERT(dst.IsTwoByteString()); | 10196 ASSERT(dst.IsTwoByteString()); |
10197 NoGCScope no_gc; | 10197 NoGCScope no_gc; |
10198 if (array_len > 0) { | 10198 if (array_len > 0) { |
10199 memmove(TwoByteString::CharAddr(dst, dst_offset), | 10199 memmove(TwoByteString::CharAddr(dst, dst_offset), |
10200 utf16_array, | 10200 utf16_array, |
10201 array_len * 2); | 10201 array_len * 2); |
10202 } | 10202 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10337 return Symbols::Empty(); | 10337 return Symbols::Empty(); |
10338 } | 10338 } |
10339 if (begin_index > str.Length()) { | 10339 if (begin_index > str.Length()) { |
10340 return String::null(); | 10340 return String::null(); |
10341 } | 10341 } |
10342 String& result = String::Handle(); | 10342 String& result = String::Handle(); |
10343 bool is_one_byte_string = true; | 10343 bool is_one_byte_string = true; |
10344 intptr_t char_size = str.CharSize(); | 10344 intptr_t char_size = str.CharSize(); |
10345 if (char_size == kTwoByteChar) { | 10345 if (char_size == kTwoByteChar) { |
10346 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | 10346 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
10347 if (str.CharAt(i) > 0x7F) { | 10347 if (str.CharAt(i) > 0xFF) { |
10348 is_one_byte_string = false; | 10348 is_one_byte_string = false; |
10349 break; | 10349 break; |
10350 } | 10350 } |
10351 } | 10351 } |
10352 } | 10352 } |
10353 if (is_one_byte_string) { | 10353 if (is_one_byte_string) { |
10354 result ^= OneByteString::New(length, space); | 10354 result ^= OneByteString::New(length, space); |
10355 } else { | 10355 } else { |
10356 result ^= TwoByteString::New(length, space); | 10356 result ^= TwoByteString::New(length, space); |
10357 } | 10357 } |
10358 String::Copy(result, 0, str, begin_index, length); | 10358 String::Copy(result, 0, str, begin_index, length); |
10359 return result.raw(); | 10359 return result.raw(); |
10360 } | 10360 } |
10361 | 10361 |
10362 | 10362 |
10363 const char* String::ToCString() const { | 10363 const char* String::ToCString() const { |
10364 intptr_t len = Utf8::Length(*this); | 10364 intptr_t len = Utf8::Length(*this); |
10365 Zone* zone = Isolate::Current()->current_zone(); | 10365 Zone* zone = Isolate::Current()->current_zone(); |
10366 uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 10366 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
10367 ToUTF8(result, len); | 10367 ToUTF8(result, len); |
10368 result[len] = 0; | 10368 result[len] = 0; |
10369 return reinterpret_cast<const char*>(result); | 10369 return reinterpret_cast<const char*>(result); |
10370 } | 10370 } |
10371 | 10371 |
10372 | 10372 |
10373 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { | 10373 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { |
10374 if (CharSize() == kOneByteChar) { | 10374 ASSERT(array_len >= Utf8::Length(*this)); |
10375 const String& obj = *this; | 10375 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |
10376 ASSERT(array_len >= obj.Length()); | |
10377 if (obj.Length() > 0) { | |
10378 memmove(utf8_array, OneByteString::CharAddr(obj, 0), obj.Length()); | |
10379 } | |
10380 } else { | |
10381 ASSERT(array_len >= Utf8::Length(*this)); | |
10382 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); | |
10383 } | |
10384 } | 10376 } |
10385 | 10377 |
10386 | 10378 |
10387 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 10379 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
10388 const String& str, | 10380 const String& str, |
10389 Heap::Space space) { | 10381 Heap::Space space) { |
10390 ASSERT(!str.IsNull()); | 10382 ASSERT(!str.IsNull()); |
10391 bool has_mapping = false; | 10383 bool has_mapping = false; |
10392 int32_t dst_max = 0; | 10384 int32_t dst_max = 0; |
10393 intptr_t len = str.Length(); | 10385 intptr_t len = str.Length(); |
10394 // TODO(cshapiro): assume a transform is required, rollback if not. | 10386 // TODO(cshapiro): assume a transform is required, rollback if not. |
10395 for (intptr_t i = 0; i < len; ++i) { | 10387 for (intptr_t i = 0; i < len; ++i) { |
10396 int32_t src = str.CharAt(i); | 10388 int32_t src = str.CharAt(i); |
10397 int32_t dst = mapping(src); | 10389 int32_t dst = mapping(src); |
10398 if (src != dst) { | 10390 if (src != dst) { |
10399 has_mapping = true; | 10391 has_mapping = true; |
10400 } | 10392 } |
10401 dst_max = Utils::Maximum(dst_max, dst); | 10393 dst_max = Utils::Maximum(dst_max, dst); |
10402 } | 10394 } |
10403 if (!has_mapping) { | 10395 if (!has_mapping) { |
10404 return str.raw(); | 10396 return str.raw(); |
10405 } | 10397 } |
10406 if (dst_max <= 0x7F) { | 10398 if (dst_max <= 0xFF) { |
10407 return OneByteString::Transform(mapping, str, space); | 10399 return OneByteString::Transform(mapping, str, space); |
10408 } | 10400 } |
10409 ASSERT(dst_max > 0x7F); | 10401 ASSERT(dst_max > 0xFF); |
10410 return TwoByteString::Transform(mapping, str, space); | 10402 return TwoByteString::Transform(mapping, str, space); |
10411 } | 10403 } |
10412 | 10404 |
10413 | 10405 |
10414 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10406 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
10415 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10407 // TODO(cshapiro): create a fast-path for OneByteString instances. |
10416 return Transform(CaseMapping::ToUpper, str, space); | 10408 return Transform(CaseMapping::ToUpper, str, space); |
10417 } | 10409 } |
10418 | 10410 |
10419 | 10411 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10547 } | 10539 } |
10548 return OneByteString::raw(result); | 10540 return OneByteString::raw(result); |
10549 } | 10541 } |
10550 | 10542 |
10551 | 10543 |
10552 RawOneByteString* OneByteString::New(const uint16_t* characters, | 10544 RawOneByteString* OneByteString::New(const uint16_t* characters, |
10553 intptr_t len, | 10545 intptr_t len, |
10554 Heap::Space space) { | 10546 Heap::Space space) { |
10555 const String& result =String::Handle(OneByteString::New(len, space)); | 10547 const String& result =String::Handle(OneByteString::New(len, space)); |
10556 for (intptr_t i = 0; i < len; ++i) { | 10548 for (intptr_t i = 0; i < len; ++i) { |
10557 ASSERT(characters[i] <= 0x7F); | 10549 ASSERT(characters[i] <= 0xFF); |
10558 *CharAddr(result, i) = characters[i]; | 10550 *CharAddr(result, i) = characters[i]; |
10559 } | 10551 } |
10560 return OneByteString::raw(result); | 10552 return OneByteString::raw(result); |
10561 } | 10553 } |
10562 | 10554 |
10563 | 10555 |
10564 RawOneByteString* OneByteString::New(const uint32_t* characters, | 10556 RawOneByteString* OneByteString::New(const uint32_t* characters, |
10565 intptr_t len, | 10557 intptr_t len, |
10566 Heap::Space space) { | 10558 Heap::Space space) { |
10567 const String& result = String::Handle(OneByteString::New(len, space)); | 10559 const String& result = String::Handle(OneByteString::New(len, space)); |
10568 for (intptr_t i = 0; i < len; ++i) { | 10560 for (intptr_t i = 0; i < len; ++i) { |
10569 ASSERT(characters[i] <= 0x7F); | 10561 ASSERT(characters[i] <= 0xFF); |
10570 *CharAddr(result, i) = characters[i]; | 10562 *CharAddr(result, i) = characters[i]; |
10571 } | 10563 } |
10572 return OneByteString::raw(result); | 10564 return OneByteString::raw(result); |
10573 } | 10565 } |
10574 | 10566 |
10575 | 10567 |
10576 RawOneByteString* OneByteString::New(const String& str, | 10568 RawOneByteString* OneByteString::New(const String& str, |
10577 Heap::Space space) { | 10569 Heap::Space space) { |
10578 intptr_t len = str.Length(); | 10570 intptr_t len = str.Length(); |
10579 const String& result = String::Handle(OneByteString::New(len, space)); | 10571 const String& result = String::Handle(OneByteString::New(len, space)); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10613 | 10605 |
10614 | 10606 |
10615 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 10607 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
10616 const String& str, | 10608 const String& str, |
10617 Heap::Space space) { | 10609 Heap::Space space) { |
10618 ASSERT(!str.IsNull()); | 10610 ASSERT(!str.IsNull()); |
10619 intptr_t len = str.Length(); | 10611 intptr_t len = str.Length(); |
10620 const String& result = String::Handle(OneByteString::New(len, space)); | 10612 const String& result = String::Handle(OneByteString::New(len, space)); |
10621 for (intptr_t i = 0; i < len; ++i) { | 10613 for (intptr_t i = 0; i < len; ++i) { |
10622 int32_t ch = mapping(str.CharAt(i)); | 10614 int32_t ch = mapping(str.CharAt(i)); |
10623 ASSERT(ch >= 0 && ch <= 0x7F); | 10615 ASSERT(ch >= 0 && ch <= 0xFF); |
10624 *CharAddr(result, i) = ch; | 10616 *CharAddr(result, i) = ch; |
10625 } | 10617 } |
10626 return OneByteString::raw(result); | 10618 return OneByteString::raw(result); |
10627 } | 10619 } |
10628 | 10620 |
10629 | 10621 |
10630 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, | 10622 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, |
10631 bool raw_str) { | 10623 bool raw_str) { |
10632 intptr_t len = str.Length(); | 10624 intptr_t len = str.Length(); |
10633 if (len > 0) { | 10625 if (len > 0) { |
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12003 } | 11995 } |
12004 return result.raw(); | 11996 return result.raw(); |
12005 } | 11997 } |
12006 | 11998 |
12007 | 11999 |
12008 const char* WeakProperty::ToCString() const { | 12000 const char* WeakProperty::ToCString() const { |
12009 return "_WeakProperty"; | 12001 return "_WeakProperty"; |
12010 } | 12002 } |
12011 | 12003 |
12012 } // namespace dart | 12004 } // namespace dart |
OLD | NEW |