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 4061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4072 | 4072 |
4073 Handle<Value> Function::GetDisplayName() const { | 4073 Handle<Value> Function::GetDisplayName() const { |
4074 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 4074 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
4075 ON_BAILOUT(isolate, "v8::Function::GetDisplayName()", | 4075 ON_BAILOUT(isolate, "v8::Function::GetDisplayName()", |
4076 return ToApiHandle<Primitive>( | 4076 return ToApiHandle<Primitive>( |
4077 isolate->factory()->undefined_value())); | 4077 isolate->factory()->undefined_value())); |
4078 ENTER_V8(isolate); | 4078 ENTER_V8(isolate); |
4079 i::Handle<i::JSFunction> func = Utils::OpenHandle(this); | 4079 i::Handle<i::JSFunction> func = Utils::OpenHandle(this); |
4080 i::Handle<i::String> property_name = | 4080 i::Handle<i::String> property_name = |
4081 isolate->factory()->InternalizeOneByteString( | 4081 isolate->factory()->InternalizeOneByteString( |
4082 STATIC_ASCII_VECTOR("displayName")); | 4082 STATIC_CHAR_VECTOR("displayName")); |
4083 | 4083 |
4084 i::Handle<i::Object> value = | 4084 i::Handle<i::Object> value = |
4085 i::JSObject::GetDataProperty(func, property_name); | 4085 i::JSObject::GetDataProperty(func, property_name); |
4086 if (value->IsString()) { | 4086 if (value->IsString()) { |
4087 i::Handle<i::String> name = i::Handle<i::String>::cast(value); | 4087 i::Handle<i::String> name = i::Handle<i::String>::cast(value); |
4088 if (name->length() > 0) return Utils::ToLocal(name); | 4088 if (name->length() > 0) return Utils::ToLocal(name); |
4089 } | 4089 } |
4090 | 4090 |
4091 return ToApiHandle<Primitive>(isolate->factory()->undefined_value()); | 4091 return ToApiHandle<Primitive>(isolate->factory()->undefined_value()); |
4092 } | 4092 } |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4310 static inline bool StartsWithSurrogate(uint8_t state) { | 4310 static inline bool StartsWithSurrogate(uint8_t state) { |
4311 return state & kStartsWithTrailingSurrogate; | 4311 return state & kStartsWithTrailingSurrogate; |
4312 } | 4312 } |
4313 | 4313 |
4314 class Visitor { | 4314 class Visitor { |
4315 public: | 4315 public: |
4316 Visitor() : utf8_length_(0), state_(kInitialState) {} | 4316 Visitor() : utf8_length_(0), state_(kInitialState) {} |
4317 | 4317 |
4318 void VisitOneByteString(const uint8_t* chars, int length) { | 4318 void VisitOneByteString(const uint8_t* chars, int length) { |
4319 int utf8_length = 0; | 4319 int utf8_length = 0; |
4320 // Add in length 1 for each non-ASCII character. | 4320 // Add in length 1 for each non-Latin1 character. |
4321 for (int i = 0; i < length; i++) { | 4321 for (int i = 0; i < length; i++) { |
4322 utf8_length += *chars++ >> 7; | 4322 utf8_length += *chars++ >> 7; |
4323 } | 4323 } |
4324 // Add in length 1 for each character. | 4324 // Add in length 1 for each character. |
4325 utf8_length_ = utf8_length + length; | 4325 utf8_length_ = utf8_length + length; |
4326 state_ = kInitialState; | 4326 state_ = kInitialState; |
4327 } | 4327 } |
4328 | 4328 |
4329 void VisitTwoByteString(const uint16_t* chars, int length) { | 4329 void VisitTwoByteString(const uint16_t* chars, int length) { |
4330 int utf8_length = 0; | 4330 int utf8_length = 0; |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4712 // First check if we can just write the string without checking capacity. | 4712 // First check if we can just write the string without checking capacity. |
4713 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) { | 4713 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) { |
4714 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8); | 4714 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8); |
4715 const int kMaxRecursion = 100; | 4715 const int kMaxRecursion = 100; |
4716 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion); | 4716 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion); |
4717 if (success) return writer.CompleteWrite(write_null, nchars_ref); | 4717 if (success) return writer.CompleteWrite(write_null, nchars_ref); |
4718 } else if (capacity >= string_length) { | 4718 } else if (capacity >= string_length) { |
4719 // First check that the buffer is large enough. | 4719 // First check that the buffer is large enough. |
4720 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate()); | 4720 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate()); |
4721 if (utf8_bytes <= capacity) { | 4721 if (utf8_bytes <= capacity) { |
4722 // ASCII fast path. | 4722 // one-byte fast path. |
4723 if (utf8_bytes == string_length) { | 4723 if (utf8_bytes == string_length) { |
4724 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options); | 4724 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options); |
4725 if (nchars_ref != NULL) *nchars_ref = string_length; | 4725 if (nchars_ref != NULL) *nchars_ref = string_length; |
4726 if (write_null && (utf8_bytes+1 <= capacity)) { | 4726 if (write_null && (utf8_bytes+1 <= capacity)) { |
4727 return string_length + 1; | 4727 return string_length + 1; |
4728 } | 4728 } |
4729 return string_length; | 4729 return string_length; |
4730 } | 4730 } |
4731 if (write_null && (utf8_bytes+1 > capacity)) { | 4731 if (write_null && (utf8_bytes+1 > capacity)) { |
4732 options |= NO_NULL_TERMINATION; | 4732 options |= NO_NULL_TERMINATION; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4791 } | 4791 } |
4792 | 4792 |
4793 | 4793 |
4794 bool v8::String::IsExternal() const { | 4794 bool v8::String::IsExternal() const { |
4795 i::Handle<i::String> str = Utils::OpenHandle(this); | 4795 i::Handle<i::String> str = Utils::OpenHandle(this); |
4796 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()"); | 4796 EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()"); |
4797 return i::StringShape(*str).IsExternalTwoByte(); | 4797 return i::StringShape(*str).IsExternalTwoByte(); |
4798 } | 4798 } |
4799 | 4799 |
4800 | 4800 |
4801 bool v8::String::IsExternalAscii() const { | 4801 bool v8::String::IsExternalOneByte() const { |
4802 i::Handle<i::String> str = Utils::OpenHandle(this); | 4802 i::Handle<i::String> str = Utils::OpenHandle(this); |
4803 return i::StringShape(*str).IsExternalAscii(); | 4803 return i::StringShape(*str).IsExternalOneByte(); |
4804 } | 4804 } |
4805 | 4805 |
4806 | 4806 |
4807 void v8::String::VerifyExternalStringResource( | 4807 void v8::String::VerifyExternalStringResource( |
4808 v8::String::ExternalStringResource* value) const { | 4808 v8::String::ExternalStringResource* value) const { |
4809 i::Handle<i::String> str = Utils::OpenHandle(this); | 4809 i::Handle<i::String> str = Utils::OpenHandle(this); |
4810 const v8::String::ExternalStringResource* expected; | 4810 const v8::String::ExternalStringResource* expected; |
4811 if (i::StringShape(*str).IsExternalTwoByte()) { | 4811 if (i::StringShape(*str).IsExternalTwoByte()) { |
4812 const void* resource = | 4812 const void* resource = |
4813 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); | 4813 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); |
4814 expected = reinterpret_cast<const ExternalStringResource*>(resource); | 4814 expected = reinterpret_cast<const ExternalStringResource*>(resource); |
4815 } else { | 4815 } else { |
4816 expected = NULL; | 4816 expected = NULL; |
4817 } | 4817 } |
4818 CHECK_EQ(expected, value); | 4818 CHECK_EQ(expected, value); |
4819 } | 4819 } |
4820 | 4820 |
4821 void v8::String::VerifyExternalStringResourceBase( | 4821 void v8::String::VerifyExternalStringResourceBase( |
4822 v8::String::ExternalStringResourceBase* value, Encoding encoding) const { | 4822 v8::String::ExternalStringResourceBase* value, Encoding encoding) const { |
4823 i::Handle<i::String> str = Utils::OpenHandle(this); | 4823 i::Handle<i::String> str = Utils::OpenHandle(this); |
4824 const v8::String::ExternalStringResourceBase* expected; | 4824 const v8::String::ExternalStringResourceBase* expected; |
4825 Encoding expectedEncoding; | 4825 Encoding expectedEncoding; |
4826 if (i::StringShape(*str).IsExternalAscii()) { | 4826 if (i::StringShape(*str).IsExternalOneByte()) { |
4827 const void* resource = | 4827 const void* resource = |
4828 i::Handle<i::ExternalAsciiString>::cast(str)->resource(); | 4828 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); |
4829 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); | 4829 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); |
4830 expectedEncoding = ASCII_ENCODING; | 4830 expectedEncoding = ONE_BYTE_ENCODING; |
4831 } else if (i::StringShape(*str).IsExternalTwoByte()) { | 4831 } else if (i::StringShape(*str).IsExternalTwoByte()) { |
4832 const void* resource = | 4832 const void* resource = |
4833 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); | 4833 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); |
4834 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); | 4834 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); |
4835 expectedEncoding = TWO_BYTE_ENCODING; | 4835 expectedEncoding = TWO_BYTE_ENCODING; |
4836 } else { | 4836 } else { |
4837 expected = NULL; | 4837 expected = NULL; |
4838 expectedEncoding = str->IsOneByteRepresentation() ? ASCII_ENCODING | 4838 expectedEncoding = |
4839 : TWO_BYTE_ENCODING; | 4839 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING; |
4840 } | 4840 } |
4841 CHECK_EQ(expected, value); | 4841 CHECK_EQ(expected, value); |
4842 CHECK_EQ(expectedEncoding, encoding); | 4842 CHECK_EQ(expectedEncoding, encoding); |
4843 } | 4843 } |
4844 | 4844 |
4845 const v8::String::ExternalAsciiStringResource* | 4845 const v8::String::ExternalOneByteStringResource* |
4846 v8::String::GetExternalAsciiStringResource() const { | 4846 v8::String::GetExternalOneByteStringResource() const { |
4847 i::Handle<i::String> str = Utils::OpenHandle(this); | 4847 i::Handle<i::String> str = Utils::OpenHandle(this); |
4848 if (i::StringShape(*str).IsExternalAscii()) { | 4848 if (i::StringShape(*str).IsExternalOneByte()) { |
4849 const void* resource = | 4849 const void* resource = |
4850 i::Handle<i::ExternalAsciiString>::cast(str)->resource(); | 4850 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); |
4851 return reinterpret_cast<const ExternalAsciiStringResource*>(resource); | 4851 return reinterpret_cast<const ExternalOneByteStringResource*>(resource); |
4852 } else { | 4852 } else { |
4853 return NULL; | 4853 return NULL; |
4854 } | 4854 } |
4855 } | 4855 } |
4856 | 4856 |
4857 | 4857 |
4858 Local<Value> Symbol::Name() const { | 4858 Local<Value> Symbol::Name() const { |
4859 i::Handle<i::Symbol> sym = Utils::OpenHandle(this); | 4859 i::Handle<i::Symbol> sym = Utils::OpenHandle(this); |
4860 i::Handle<i::Object> name(sym->name(), sym->GetIsolate()); | 4860 i::Handle<i::Object> name(sym->name(), sym->GetIsolate()); |
4861 return Utils::ToLocal(name); | 4861 return Utils::ToLocal(name); |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5463 | 5463 |
5464 static i::Handle<i::String> NewExternalStringHandle( | 5464 static i::Handle<i::String> NewExternalStringHandle( |
5465 i::Isolate* isolate, | 5465 i::Isolate* isolate, |
5466 v8::String::ExternalStringResource* resource) { | 5466 v8::String::ExternalStringResource* resource) { |
5467 // We do not expect this to fail. Change this if it does. | 5467 // We do not expect this to fail. Change this if it does. |
5468 return isolate->factory()->NewExternalStringFromTwoByte( | 5468 return isolate->factory()->NewExternalStringFromTwoByte( |
5469 resource).ToHandleChecked(); | 5469 resource).ToHandleChecked(); |
5470 } | 5470 } |
5471 | 5471 |
5472 | 5472 |
5473 static i::Handle<i::String> NewExternalAsciiStringHandle( | 5473 static i::Handle<i::String> NewExternalOneByteStringHandle( |
5474 i::Isolate* isolate, | 5474 i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { |
5475 v8::String::ExternalAsciiStringResource* resource) { | |
5476 // We do not expect this to fail. Change this if it does. | 5475 // We do not expect this to fail. Change this if it does. |
5477 return isolate->factory()->NewExternalStringFromAscii( | 5476 return isolate->factory() |
5478 resource).ToHandleChecked(); | 5477 ->NewExternalStringFromOneByte(resource) |
| 5478 .ToHandleChecked(); |
5479 } | 5479 } |
5480 | 5480 |
5481 | 5481 |
5482 Local<String> v8::String::NewExternal( | 5482 Local<String> v8::String::NewExternal( |
5483 Isolate* isolate, | 5483 Isolate* isolate, |
5484 v8::String::ExternalStringResource* resource) { | 5484 v8::String::ExternalStringResource* resource) { |
5485 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5485 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
5486 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); | 5486 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); |
5487 LOG_API(i_isolate, "String::NewExternal"); | 5487 LOG_API(i_isolate, "String::NewExternal"); |
5488 ENTER_V8(i_isolate); | 5488 ENTER_V8(i_isolate); |
(...skipping 24 matching lines...) Expand all Loading... |
5513 DCHECK(!CanMakeExternal() || result); | 5513 DCHECK(!CanMakeExternal() || result); |
5514 if (result) { | 5514 if (result) { |
5515 DCHECK(obj->IsExternalString()); | 5515 DCHECK(obj->IsExternalString()); |
5516 isolate->heap()->external_string_table()->AddString(*obj); | 5516 isolate->heap()->external_string_table()->AddString(*obj); |
5517 } | 5517 } |
5518 return result; | 5518 return result; |
5519 } | 5519 } |
5520 | 5520 |
5521 | 5521 |
5522 Local<String> v8::String::NewExternal( | 5522 Local<String> v8::String::NewExternal( |
5523 Isolate* isolate, | 5523 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { |
5524 v8::String::ExternalAsciiStringResource* resource) { | |
5525 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5524 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
5526 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); | 5525 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); |
5527 LOG_API(i_isolate, "String::NewExternal"); | 5526 LOG_API(i_isolate, "String::NewExternal"); |
5528 ENTER_V8(i_isolate); | 5527 ENTER_V8(i_isolate); |
5529 CHECK(resource && resource->data()); | 5528 CHECK(resource && resource->data()); |
5530 i::Handle<i::String> result = | 5529 i::Handle<i::String> result = |
5531 NewExternalAsciiStringHandle(i_isolate, resource); | 5530 NewExternalOneByteStringHandle(i_isolate, resource); |
5532 i_isolate->heap()->external_string_table()->AddString(*result); | 5531 i_isolate->heap()->external_string_table()->AddString(*result); |
5533 return Utils::ToLocal(result); | 5532 return Utils::ToLocal(result); |
5534 } | 5533 } |
5535 | 5534 |
5536 | 5535 |
5537 bool v8::String::MakeExternal( | 5536 bool v8::String::MakeExternal( |
5538 v8::String::ExternalAsciiStringResource* resource) { | 5537 v8::String::ExternalOneByteStringResource* resource) { |
5539 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5538 i::Handle<i::String> obj = Utils::OpenHandle(this); |
5540 i::Isolate* isolate = obj->GetIsolate(); | 5539 i::Isolate* isolate = obj->GetIsolate(); |
5541 if (i::StringShape(*obj).IsExternal()) { | 5540 if (i::StringShape(*obj).IsExternal()) { |
5542 return false; // Already an external string. | 5541 return false; // Already an external string. |
5543 } | 5542 } |
5544 ENTER_V8(isolate); | 5543 ENTER_V8(isolate); |
5545 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5544 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5546 return false; | 5545 return false; |
5547 } | 5546 } |
5548 if (isolate->heap()->IsInGCPostProcessing()) { | 5547 if (isolate->heap()->IsInGCPostProcessing()) { |
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6942 ENTER_V8(isolate); | 6941 ENTER_V8(isolate); |
6943 v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); | 6942 v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); |
6944 i::Debug* isolate_debug = isolate->debug(); | 6943 i::Debug* isolate_debug = isolate->debug(); |
6945 EXCEPTION_PREAMBLE(isolate); | 6944 EXCEPTION_PREAMBLE(isolate); |
6946 has_pending_exception = !isolate_debug->Load(); | 6945 has_pending_exception = !isolate_debug->Load(); |
6947 v8::Local<v8::Value> result; | 6946 v8::Local<v8::Value> result; |
6948 if (!has_pending_exception) { | 6947 if (!has_pending_exception) { |
6949 i::Handle<i::JSObject> debug( | 6948 i::Handle<i::JSObject> debug( |
6950 isolate_debug->debug_context()->global_object()); | 6949 isolate_debug->debug_context()->global_object()); |
6951 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString( | 6950 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString( |
6952 STATIC_ASCII_VECTOR("MakeMirror")); | 6951 STATIC_CHAR_VECTOR("MakeMirror")); |
6953 i::Handle<i::Object> fun_obj = | 6952 i::Handle<i::Object> fun_obj = |
6954 i::Object::GetProperty(debug, name).ToHandleChecked(); | 6953 i::Object::GetProperty(debug, name).ToHandleChecked(); |
6955 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj); | 6954 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj); |
6956 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun); | 6955 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun); |
6957 const int kArgc = 1; | 6956 const int kArgc = 1; |
6958 v8::Handle<v8::Value> argv[kArgc] = { obj }; | 6957 v8::Handle<v8::Value> argv[kArgc] = { obj }; |
6959 result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv); | 6958 result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv); |
6960 has_pending_exception = result.IsEmpty(); | 6959 has_pending_exception = result.IsEmpty(); |
6961 } | 6960 } |
6962 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); | 6961 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7626 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7625 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7627 Address callback_address = | 7626 Address callback_address = |
7628 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7627 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7629 VMState<EXTERNAL> state(isolate); | 7628 VMState<EXTERNAL> state(isolate); |
7630 ExternalCallbackScope call_scope(isolate, callback_address); | 7629 ExternalCallbackScope call_scope(isolate, callback_address); |
7631 callback(info); | 7630 callback(info); |
7632 } | 7631 } |
7633 | 7632 |
7634 | 7633 |
7635 } } // namespace v8::internal | 7634 } } // namespace v8::internal |
OLD | NEW |