| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/api.h" | 5 #include "src/api.h" |
| 6 | 6 |
| 7 #include <string.h> // For memcpy, strlen. | 7 #include <string.h> // For memcpy, strlen. |
| 8 #ifdef V8_USE_ADDRESS_SANITIZER | 8 #ifdef V8_USE_ADDRESS_SANITIZER |
| 9 #include <sanitizer/asan_interface.h> | 9 #include <sanitizer/asan_interface.h> |
| 10 #endif // V8_USE_ADDRESS_SANITIZER | 10 #endif // V8_USE_ADDRESS_SANITIZER |
| (...skipping 5281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5292 i::Handle<i::String> str = Utils::OpenHandle(this); | 5292 i::Handle<i::String> str = Utils::OpenHandle(this); |
| 5293 return i::StringShape(*str).IsExternalTwoByte(); | 5293 return i::StringShape(*str).IsExternalTwoByte(); |
| 5294 } | 5294 } |
| 5295 | 5295 |
| 5296 | 5296 |
| 5297 bool v8::String::IsExternalOneByte() const { | 5297 bool v8::String::IsExternalOneByte() const { |
| 5298 i::Handle<i::String> str = Utils::OpenHandle(this); | 5298 i::Handle<i::String> str = Utils::OpenHandle(this); |
| 5299 return i::StringShape(*str).IsExternalOneByte(); | 5299 return i::StringShape(*str).IsExternalOneByte(); |
| 5300 } | 5300 } |
| 5301 | 5301 |
| 5302 | 5302 void v8::String::VerifyExternalStringResourceBase( |
| 5303 void v8::String::VerifyExternalStringResource( | 5303 const v8::String::ExternalStringResourceBase* value, |
| 5304 v8::String::ExternalStringResource* value) const { | 5304 Encoding encoding) const { |
| 5305 i::Handle<i::String> str = Utils::OpenHandle(this); | 5305 i::Handle<i::String> str = Utils::OpenHandle(this); |
| 5306 const v8::String::ExternalStringResource* expected; | 5306 const v8::String::ExternalStringResourceBase* expected = nullptr; |
| 5307 if (i::StringShape(*str).IsExternalTwoByte()) { | 5307 Encoding expected_encoding; |
| 5308 const void* resource = | 5308 const void* actual_data_ptr = nullptr; |
| 5309 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); | 5309 size_t actual_length = 0; |
| 5310 expected = reinterpret_cast<const ExternalStringResource*>(resource); | 5310 if (i::StringShape(*str).IsExternalOneByte()) { |
| 5311 const ExternalOneByteStringResource* resource = |
| 5312 reinterpret_cast<const ExternalOneByteStringResource*>( |
| 5313 i::Handle<i::ExternalOneByteString>::cast(str)->resource()); |
| 5314 expected = static_cast<const ExternalStringResourceBase*>(resource); |
| 5315 expected_encoding = ONE_BYTE_ENCODING; |
| 5316 actual_data_ptr = reinterpret_cast<const void*>(resource->data()); |
| 5317 actual_length = resource->length(); |
| 5318 } else if (i::StringShape(*str).IsExternalTwoByte()) { |
| 5319 const ExternalStringResource* resource = |
| 5320 reinterpret_cast<const ExternalStringResource*>( |
| 5321 i::Handle<i::ExternalTwoByteString>::cast(str)->resource()); |
| 5322 expected = static_cast<const ExternalStringResourceBase*>(resource); |
| 5323 expected_encoding = TWO_BYTE_ENCODING; |
| 5324 actual_data_ptr = reinterpret_cast<const void*>(resource->data()); |
| 5325 actual_length = resource->length(); |
| 5311 } else { | 5326 } else { |
| 5312 expected = NULL; | 5327 expected_encoding = |
| 5313 } | |
| 5314 CHECK_EQ(expected, value); | |
| 5315 } | |
| 5316 | |
| 5317 void v8::String::VerifyExternalStringResourceBase( | |
| 5318 v8::String::ExternalStringResourceBase* value, Encoding encoding) const { | |
| 5319 i::Handle<i::String> str = Utils::OpenHandle(this); | |
| 5320 const v8::String::ExternalStringResourceBase* expected; | |
| 5321 Encoding expectedEncoding; | |
| 5322 if (i::StringShape(*str).IsExternalOneByte()) { | |
| 5323 const void* resource = | |
| 5324 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); | |
| 5325 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); | |
| 5326 expectedEncoding = ONE_BYTE_ENCODING; | |
| 5327 } else if (i::StringShape(*str).IsExternalTwoByte()) { | |
| 5328 const void* resource = | |
| 5329 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); | |
| 5330 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); | |
| 5331 expectedEncoding = TWO_BYTE_ENCODING; | |
| 5332 } else { | |
| 5333 expected = NULL; | |
| 5334 expectedEncoding = | |
| 5335 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING; | 5328 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING; |
| 5336 } | 5329 } |
| 5337 CHECK_EQ(expected, value); | 5330 CHECK_EQ(expected, value); |
| 5338 CHECK_EQ(expectedEncoding, encoding); | 5331 CHECK_EQ(expected_encoding, encoding); |
| 5332 CHECK_EQ(i::Handle<i::ExternalString>::cast(str)->resource_data(), |
| 5333 actual_data_ptr); |
| 5334 CHECK_EQ(str->length(), static_cast<int>(actual_length)); |
| 5339 } | 5335 } |
| 5340 | 5336 |
| 5337 |
| 5341 const v8::String::ExternalOneByteStringResource* | 5338 const v8::String::ExternalOneByteStringResource* |
| 5342 v8::String::GetExternalOneByteStringResource() const { | 5339 v8::String::GetExternalOneByteStringResource() const { |
| 5343 i::Handle<i::String> str = Utils::OpenHandle(this); | 5340 i::Handle<i::String> str = Utils::OpenHandle(this); |
| 5341 const ExternalOneByteStringResource* result; |
| 5344 if (i::StringShape(*str).IsExternalOneByte()) { | 5342 if (i::StringShape(*str).IsExternalOneByte()) { |
| 5345 const void* resource = | 5343 const void* resource = |
| 5346 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); | 5344 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); |
| 5347 return reinterpret_cast<const ExternalOneByteStringResource*>(resource); | 5345 result = reinterpret_cast<const ExternalOneByteStringResource*>(resource); |
| 5348 } else { | 5346 } else { |
| 5349 return NULL; | 5347 result = nullptr; |
| 5350 } | 5348 } |
| 5349 #ifdef V8_ENABLE_CHECKS |
| 5350 VerifyExternalStringResourceBase(result, ONE_BYTE_ENCODING); |
| 5351 #endif |
| 5352 return result; |
| 5351 } | 5353 } |
| 5352 | 5354 |
| 5353 | 5355 |
| 5354 Local<Value> Symbol::Name() const { | 5356 Local<Value> Symbol::Name() const { |
| 5355 i::Handle<i::Symbol> sym = Utils::OpenHandle(this); | 5357 i::Handle<i::Symbol> sym = Utils::OpenHandle(this); |
| 5356 i::Handle<i::Object> name(sym->name(), sym->GetIsolate()); | 5358 i::Handle<i::Object> name(sym->name(), sym->GetIsolate()); |
| 5357 return Utils::ToLocal(name); | 5359 return Utils::ToLocal(name); |
| 5358 } | 5360 } |
| 5359 | 5361 |
| 5360 | 5362 |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5917 // TODO(dcarney): throw a context free exception. | 5919 // TODO(dcarney): throw a context free exception. |
| 5918 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { | 5920 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { |
| 5919 return MaybeLocal<String>(); | 5921 return MaybeLocal<String>(); |
| 5920 } | 5922 } |
| 5921 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5923 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 5922 ENTER_V8(i_isolate); | 5924 ENTER_V8(i_isolate); |
| 5923 LOG_API(i_isolate, "String::NewExternalTwoByte"); | 5925 LOG_API(i_isolate, "String::NewExternalTwoByte"); |
| 5924 i::Handle<i::String> string = i_isolate->factory() | 5926 i::Handle<i::String> string = i_isolate->factory() |
| 5925 ->NewExternalStringFromTwoByte(resource) | 5927 ->NewExternalStringFromTwoByte(resource) |
| 5926 .ToHandleChecked(); | 5928 .ToHandleChecked(); |
| 5929 #ifdef V8_ENABLE_CHECKS |
| 5930 Utils::ToLocal(string) |
| 5931 ->VerifyExternalStringResourceBase(resource, TWO_BYTE_ENCODING); |
| 5932 #endif |
| 5927 i_isolate->heap()->external_string_table()->AddString(*string); | 5933 i_isolate->heap()->external_string_table()->AddString(*string); |
| 5928 return Utils::ToLocal(string); | 5934 return Utils::ToLocal(string); |
| 5929 } | 5935 } |
| 5930 | 5936 |
| 5931 | 5937 |
| 5932 Local<String> v8::String::NewExternal( | 5938 Local<String> v8::String::NewExternal( |
| 5933 Isolate* isolate, v8::String::ExternalStringResource* resource) { | 5939 Isolate* isolate, v8::String::ExternalStringResource* resource) { |
| 5934 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String); | 5940 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String); |
| 5935 } | 5941 } |
| 5936 | 5942 |
| 5937 | 5943 |
| 5938 MaybeLocal<String> v8::String::NewExternalOneByte( | 5944 MaybeLocal<String> v8::String::NewExternalOneByte( |
| 5939 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { | 5945 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { |
| 5940 CHECK(resource && resource->data()); | 5946 CHECK(resource && resource->data()); |
| 5941 // TODO(dcarney): throw a context free exception. | 5947 // TODO(dcarney): throw a context free exception. |
| 5942 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { | 5948 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { |
| 5943 return MaybeLocal<String>(); | 5949 return MaybeLocal<String>(); |
| 5944 } | 5950 } |
| 5945 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5951 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 5946 ENTER_V8(i_isolate); | 5952 ENTER_V8(i_isolate); |
| 5947 LOG_API(i_isolate, "String::NewExternalOneByte"); | 5953 LOG_API(i_isolate, "String::NewExternalOneByte"); |
| 5948 i::Handle<i::String> string = i_isolate->factory() | 5954 i::Handle<i::String> string = i_isolate->factory() |
| 5949 ->NewExternalStringFromOneByte(resource) | 5955 ->NewExternalStringFromOneByte(resource) |
| 5950 .ToHandleChecked(); | 5956 .ToHandleChecked(); |
| 5951 i_isolate->heap()->external_string_table()->AddString(*string); | 5957 i_isolate->heap()->external_string_table()->AddString(*string); |
| 5958 #ifdef V8_ENABLE_CHECKS |
| 5959 Utils::ToLocal(string) |
| 5960 ->VerifyExternalStringResourceBase(resource, ONE_BYTE_ENCODING); |
| 5961 #endif |
| 5952 return Utils::ToLocal(string); | 5962 return Utils::ToLocal(string); |
| 5953 } | 5963 } |
| 5954 | 5964 |
| 5955 | 5965 |
| 5956 Local<String> v8::String::NewExternal( | 5966 Local<String> v8::String::NewExternal( |
| 5957 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { | 5967 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { |
| 5958 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String); | 5968 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String); |
| 5959 } | 5969 } |
| 5960 | 5970 |
| 5961 | 5971 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5972 if (isolate->heap()->IsInGCPostProcessing()) { | 5982 if (isolate->heap()->IsInGCPostProcessing()) { |
| 5973 return false; | 5983 return false; |
| 5974 } | 5984 } |
| 5975 CHECK(resource && resource->data()); | 5985 CHECK(resource && resource->data()); |
| 5976 | 5986 |
| 5977 bool result = obj->MakeExternal(resource); | 5987 bool result = obj->MakeExternal(resource); |
| 5978 // Assert that if CanMakeExternal(), then externalizing actually succeeds. | 5988 // Assert that if CanMakeExternal(), then externalizing actually succeeds. |
| 5979 DCHECK(!CanMakeExternal() || result); | 5989 DCHECK(!CanMakeExternal() || result); |
| 5980 if (result) { | 5990 if (result) { |
| 5981 DCHECK(obj->IsExternalString()); | 5991 DCHECK(obj->IsExternalString()); |
| 5992 #ifdef V8_ENABLE_CHECKS |
| 5993 VerifyExternalStringResourceBase(resource, TWO_BYTE_ENCODING); |
| 5994 #endif |
| 5982 isolate->heap()->external_string_table()->AddString(*obj); | 5995 isolate->heap()->external_string_table()->AddString(*obj); |
| 5983 } | 5996 } |
| 5984 return result; | 5997 return result; |
| 5985 } | 5998 } |
| 5986 | 5999 |
| 5987 | 6000 |
| 5988 bool v8::String::MakeExternal( | 6001 bool v8::String::MakeExternal( |
| 5989 v8::String::ExternalOneByteStringResource* resource) { | 6002 v8::String::ExternalOneByteStringResource* resource) { |
| 5990 i::Handle<i::String> obj = Utils::OpenHandle(this); | 6003 i::Handle<i::String> obj = Utils::OpenHandle(this); |
| 5991 i::Isolate* isolate = obj->GetIsolate(); | 6004 i::Isolate* isolate = obj->GetIsolate(); |
| 5992 if (i::StringShape(*obj).IsExternal()) { | 6005 if (i::StringShape(*obj).IsExternal()) { |
| 5993 return false; // Already an external string. | 6006 return false; // Already an external string. |
| 5994 } | 6007 } |
| 5995 ENTER_V8(isolate); | 6008 ENTER_V8(isolate); |
| 5996 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 6009 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
| 5997 return false; | 6010 return false; |
| 5998 } | 6011 } |
| 5999 if (isolate->heap()->IsInGCPostProcessing()) { | 6012 if (isolate->heap()->IsInGCPostProcessing()) { |
| 6000 return false; | 6013 return false; |
| 6001 } | 6014 } |
| 6002 CHECK(resource && resource->data()); | 6015 CHECK(resource && resource->data()); |
| 6003 | 6016 |
| 6004 bool result = obj->MakeExternal(resource); | 6017 bool result = obj->MakeExternal(resource); |
| 6005 // Assert that if CanMakeExternal(), then externalizing actually succeeds. | 6018 // Assert that if CanMakeExternal(), then externalizing actually succeeds. |
| 6006 DCHECK(!CanMakeExternal() || result); | 6019 DCHECK(!CanMakeExternal() || result); |
| 6007 if (result) { | 6020 if (result) { |
| 6008 DCHECK(obj->IsExternalString()); | 6021 DCHECK(obj->IsExternalString()); |
| 6022 #ifdef V8_ENABLE_CHECKS |
| 6023 VerifyExternalStringResourceBase(resource, ONE_BYTE_ENCODING); |
| 6024 #endif |
| 6009 isolate->heap()->external_string_table()->AddString(*obj); | 6025 isolate->heap()->external_string_table()->AddString(*obj); |
| 6010 } | 6026 } |
| 6011 return result; | 6027 return result; |
| 6012 } | 6028 } |
| 6013 | 6029 |
| 6014 | 6030 |
| 6015 bool v8::String::CanMakeExternal() { | 6031 bool v8::String::CanMakeExternal() { |
| 6016 i::Handle<i::String> obj = Utils::OpenHandle(this); | 6032 i::Handle<i::String> obj = Utils::OpenHandle(this); |
| 6017 i::Isolate* isolate = obj->GetIsolate(); | 6033 i::Isolate* isolate = obj->GetIsolate(); |
| 6018 | 6034 |
| (...skipping 2371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8390 Address callback_address = | 8406 Address callback_address = |
| 8391 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 8407 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
| 8392 VMState<EXTERNAL> state(isolate); | 8408 VMState<EXTERNAL> state(isolate); |
| 8393 ExternalCallbackScope call_scope(isolate, callback_address); | 8409 ExternalCallbackScope call_scope(isolate, callback_address); |
| 8394 callback(info); | 8410 callback(info); |
| 8395 } | 8411 } |
| 8396 | 8412 |
| 8397 | 8413 |
| 8398 } // namespace internal | 8414 } // namespace internal |
| 8399 } // namespace v8 | 8415 } // namespace v8 |
| OLD | NEW |