Chromium Code Reviews| Index: src/api.cc |
| diff --git a/src/api.cc b/src/api.cc |
| index 064a4b013f45e22b2327c4a451fae928cbfff27e..1ee50b62281fbd8ebb77a3e07e67917a0948beff 100644 |
| --- a/src/api.cc |
| +++ b/src/api.cc |
| @@ -4709,25 +4709,38 @@ int String::Write(uint16_t* buffer, |
| bool v8::String::IsExternal() const { |
| - i::Handle<i::String> str = Utils::OpenHandle(this); |
| - EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()"); |
| - return i::StringShape(*str).IsExternalTwoByte(); |
| + i::DisallowHeapAllocation no_gc; |
| + i::String* str = *Utils::OpenHandle(this); |
| + if (i::StringShape(str).IsCons()) { |
|
dcarney
2014/02/04 15:10:05
extract these 4 lines into a static function
|
| + i::ConsString* cons = i::ConsString::cast(str); |
| + if (cons->second()->length() == 0) str = cons->first(); |
| + } |
| + return i::StringShape(str).IsExternalTwoByte(); |
| } |
| bool v8::String::IsExternalAscii() const { |
| - i::Handle<i::String> str = Utils::OpenHandle(this); |
| - return i::StringShape(*str).IsExternalAscii(); |
| + i::DisallowHeapAllocation no_gc; |
| + i::String* str = *Utils::OpenHandle(this); |
| + if (i::StringShape(str).IsCons()) { |
| + i::ConsString* cons = i::ConsString::cast(str); |
| + if (cons->second()->length() == 0) str = cons->first(); |
| + } |
| + return i::StringShape(str).IsExternalAscii(); |
| } |
| void v8::String::VerifyExternalStringResource( |
| v8::String::ExternalStringResource* value) const { |
| - i::Handle<i::String> str = Utils::OpenHandle(this); |
| + i::DisallowHeapAllocation no_gc; |
| + i::String* str = *Utils::OpenHandle(this); |
| const v8::String::ExternalStringResource* expected; |
| - if (i::StringShape(*str).IsExternalTwoByte()) { |
| - const void* resource = |
| - i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); |
| + if (i::StringShape(str).IsCons()) { |
| + i::ConsString* cons = i::ConsString::cast(str); |
| + if (cons->second()->length() == 0) str = cons->first(); |
| + } |
| + if (i::StringShape(str).IsExternalTwoByte()) { |
| + const void* resource = i::ExternalTwoByteString::cast(str)->resource(); |
| expected = reinterpret_cast<const ExternalStringResource*>(resource); |
| } else { |
| expected = NULL; |
| @@ -4735,19 +4748,23 @@ void v8::String::VerifyExternalStringResource( |
| CHECK_EQ(expected, value); |
| } |
| + |
| void v8::String::VerifyExternalStringResourceBase( |
| v8::String::ExternalStringResourceBase* value, Encoding encoding) const { |
| - i::Handle<i::String> str = Utils::OpenHandle(this); |
| + i::DisallowHeapAllocation no_gc; |
| + i::String* str = *Utils::OpenHandle(this); |
| const v8::String::ExternalStringResourceBase* expected; |
| Encoding expectedEncoding; |
| - if (i::StringShape(*str).IsExternalAscii()) { |
| - const void* resource = |
| - i::Handle<i::ExternalAsciiString>::cast(str)->resource(); |
| + if (i::StringShape(str).IsCons()) { |
| + i::ConsString* cons = i::ConsString::cast(str); |
| + if (cons->second()->length() == 0) str = cons->first(); |
| + } |
| + if (i::StringShape(str).IsExternalAscii()) { |
| + const void* resource = i::ExternalAsciiString::cast(str)->resource(); |
| expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); |
| expectedEncoding = ASCII_ENCODING; |
| - } else if (i::StringShape(*str).IsExternalTwoByte()) { |
| - const void* resource = |
| - i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); |
| + } else if (str->IsExternalTwoByteString()) { |
| + const void* resource = i::ExternalTwoByteString::cast(str)->resource(); |
| expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); |
| expectedEncoding = TWO_BYTE_ENCODING; |
| } else { |
| @@ -4759,12 +4776,27 @@ void v8::String::VerifyExternalStringResourceBase( |
| CHECK_EQ(expectedEncoding, encoding); |
| } |
| + |
| +i::Object* v8::String::GetRedirectedString(i::Object* cons) { |
| + ASSERT(cons->IsConsString()); |
| + i::ConsString* cons_string = i::ConsString::cast(cons); |
| + if (cons_string->second()->length() == 0) { |
| + return cons_string->first(); |
| + } |
| + return cons; |
| +} |
| + |
| + |
| const v8::String::ExternalAsciiStringResource* |
| v8::String::GetExternalAsciiStringResource() const { |
| - i::Handle<i::String> str = Utils::OpenHandle(this); |
| - if (i::StringShape(*str).IsExternalAscii()) { |
| - const void* resource = |
| - i::Handle<i::ExternalAsciiString>::cast(str)->resource(); |
| + i::DisallowHeapAllocation no_gc; |
| + i::String* str = *Utils::OpenHandle(this); |
| + if (i::StringShape(str).IsCons()) { |
| + i::ConsString* cons = i::ConsString::cast(str); |
| + if (cons->second()->length() == 0) str = cons->first(); |
| + } |
| + if (i::StringShape(str).IsExternalAscii()) { |
| + const void* resource = i::ExternalAsciiString::cast(str)->resource(); |
| return reinterpret_cast<const ExternalAsciiStringResource*>(resource); |
| } else { |
| return NULL; |
| @@ -5429,16 +5461,14 @@ static i::Handle<i::String> NewExternalAsciiStringHandle( |
| static bool RedirectToExternalString(i::Isolate* isolate, |
| i::Handle<i::String> parent, |
| i::Handle<i::String> external) { |
| - if (parent->IsConsString()) { |
| - i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent); |
| - cons->set_first(*external); |
| - cons->set_second(isolate->heap()->empty_string()); |
| - } else { |
| - ASSERT(parent->IsSlicedString()); |
| - i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent); |
| - slice->set_parent(*external); |
| - slice->set_offset(0); |
| - } |
| + ASSERT(parent->IsConsString() || parent->IsSlicedString()); |
| + // Replace the map to a cons string of suitable encoding. |
| + parent->set_map_no_write_barrier(external->IsOneByteRepresentation() |
| + ? isolate->heap()->cons_ascii_string_map() |
| + : isolate->heap()->cons_string_map()); |
| + i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent); |
| + cons->set_first(*external); |
| + cons->set_second(isolate->heap()->empty_string()); |
| return true; |
| } |