| 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 |