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 5648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5659 inline int StringLength(const uint16_t* string) { | 5659 inline int StringLength(const uint16_t* string) { |
5660 int length = 0; | 5660 int length = 0; |
5661 while (string[length] != '\0') | 5661 while (string[length] != '\0') |
5662 length++; | 5662 length++; |
5663 return length; | 5663 return length; |
5664 } | 5664 } |
5665 | 5665 |
5666 | 5666 |
5667 MUST_USE_RESULT | 5667 MUST_USE_RESULT |
5668 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, | 5668 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, |
5669 String::NewStringType type, | 5669 v8::NewStringType type, |
5670 i::Vector<const char> string) { | 5670 i::Vector<const char> string) { |
5671 if (type == String::kInternalizedString) { | 5671 if (type == v8::NewStringType::kInternalized) { |
5672 return factory->InternalizeUtf8String(string); | 5672 return factory->InternalizeUtf8String(string); |
5673 } | 5673 } |
5674 return factory->NewStringFromUtf8(string); | 5674 return factory->NewStringFromUtf8(string); |
5675 } | 5675 } |
5676 | 5676 |
5677 | 5677 |
5678 MUST_USE_RESULT | 5678 MUST_USE_RESULT |
5679 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, | 5679 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, |
5680 String::NewStringType type, | 5680 v8::NewStringType type, |
5681 i::Vector<const uint8_t> string) { | 5681 i::Vector<const uint8_t> string) { |
5682 if (type == String::kInternalizedString) { | 5682 if (type == v8::NewStringType::kInternalized) { |
5683 return factory->InternalizeOneByteString(string); | 5683 return factory->InternalizeOneByteString(string); |
5684 } | 5684 } |
5685 return factory->NewStringFromOneByte(string); | 5685 return factory->NewStringFromOneByte(string); |
5686 } | 5686 } |
5687 | 5687 |
5688 | 5688 |
5689 MUST_USE_RESULT | 5689 MUST_USE_RESULT |
5690 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, | 5690 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, |
5691 String::NewStringType type, | 5691 v8::NewStringType type, |
5692 i::Vector<const uint16_t> string) { | 5692 i::Vector<const uint16_t> string) { |
5693 if (type == String::kInternalizedString) { | 5693 if (type == v8::NewStringType::kInternalized) { |
5694 return factory->InternalizeTwoByteString(string); | 5694 return factory->InternalizeTwoByteString(string); |
5695 } | 5695 } |
5696 return factory->NewStringFromTwoByte(string); | 5696 return factory->NewStringFromTwoByte(string); |
5697 } | 5697 } |
5698 | 5698 |
5699 | 5699 |
5700 template<typename Char> | 5700 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength); |
5701 inline Local<String> NewString(Isolate* v8_isolate, | 5701 |
5702 const char* location, | 5702 |
5703 const char* env, | 5703 template <typename Char> |
5704 const Char* data, | 5704 inline MaybeLocal<String> NewString(Isolate* v8_isolate, const char* location, |
5705 String::NewStringType type, | 5705 const char* env, const Char* data, |
5706 int length) { | 5706 v8::NewStringType type, int length) { |
5707 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate); | 5707 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate); |
| 5708 if (length == 0) return String::Empty(v8_isolate); |
| 5709 // TODO(dcarney): throw a context free exception. |
| 5710 if (length > i::String::kMaxLength) return MaybeLocal<String>(); |
| 5711 ENTER_V8(isolate); |
5708 LOG_API(isolate, env); | 5712 LOG_API(isolate, env); |
5709 if (length == 0) { | 5713 if (length < 0) length = StringLength(data); |
5710 return String::Empty(v8_isolate); | 5714 i::Handle<i::String> result = |
5711 } | 5715 NewString(isolate->factory(), type, i::Vector<const Char>(data, length)) |
5712 ENTER_V8(isolate); | 5716 .ToHandleChecked(); |
5713 if (length == -1) length = StringLength(data); | |
5714 EXCEPTION_PREAMBLE(isolate); | |
5715 i::Handle<i::String> result; | |
5716 has_pending_exception = | |
5717 !NewString(isolate->factory(), type, i::Vector<const Char>(data, length)) | |
5718 .ToHandle(&result); | |
5719 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>()); | |
5720 return Utils::ToLocal(result); | 5717 return Utils::ToLocal(result); |
5721 } | 5718 } |
5722 | 5719 |
5723 } // anonymous namespace | 5720 } // anonymous namespace |
5724 | 5721 |
5725 | 5722 |
5726 Local<String> String::NewFromUtf8(Isolate* isolate, | 5723 Local<String> String::NewFromUtf8(Isolate* isolate, |
5727 const char* data, | 5724 const char* data, |
5728 NewStringType type, | 5725 NewStringType type, |
5729 int length) { | 5726 int length) { |
5730 return NewString(isolate, | 5727 RETURN_TO_LOCAL_UNCHECKED( |
5731 "v8::String::NewFromUtf8()", | 5728 NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8", |
5732 "String::NewFromUtf8", | 5729 data, static_cast<v8::NewStringType>(type), length), |
5733 data, | 5730 String); |
5734 type, | |
5735 length); | |
5736 } | 5731 } |
5737 | 5732 |
5738 | 5733 |
| 5734 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data, |
| 5735 v8::NewStringType type, int length) { |
| 5736 return NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8", |
| 5737 data, type, length); |
| 5738 } |
| 5739 |
| 5740 |
5739 Local<String> String::NewFromOneByte(Isolate* isolate, | 5741 Local<String> String::NewFromOneByte(Isolate* isolate, |
5740 const uint8_t* data, | 5742 const uint8_t* data, |
5741 NewStringType type, | 5743 NewStringType type, |
5742 int length) { | 5744 int length) { |
5743 return NewString(isolate, | 5745 RETURN_TO_LOCAL_UNCHECKED( |
5744 "v8::String::NewFromOneByte()", | 5746 NewString(isolate, "v8::String::NewFromOneByte()", |
5745 "String::NewFromOneByte", | 5747 "String::NewFromOneByte", data, |
5746 data, | 5748 static_cast<v8::NewStringType>(type), length), |
5747 type, | 5749 String); |
5748 length); | |
5749 } | 5750 } |
5750 | 5751 |
5751 | 5752 |
| 5753 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data, |
| 5754 v8::NewStringType type, int length) { |
| 5755 return NewString(isolate, "v8::String::NewFromOneByte()", |
| 5756 "String::NewFromOneByte", data, type, length); |
| 5757 } |
| 5758 |
| 5759 |
5752 Local<String> String::NewFromTwoByte(Isolate* isolate, | 5760 Local<String> String::NewFromTwoByte(Isolate* isolate, |
5753 const uint16_t* data, | 5761 const uint16_t* data, |
5754 NewStringType type, | 5762 NewStringType type, |
5755 int length) { | 5763 int length) { |
5756 return NewString(isolate, | 5764 RETURN_TO_LOCAL_UNCHECKED( |
5757 "v8::String::NewFromTwoByte()", | 5765 NewString(isolate, "v8::String::NewFromTwoByte()", |
5758 "String::NewFromTwoByte", | 5766 "String::NewFromTwoByte", data, |
5759 data, | 5767 static_cast<v8::NewStringType>(type), length), |
5760 type, | 5768 String); |
5761 length); | 5769 } |
| 5770 |
| 5771 |
| 5772 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate, |
| 5773 const uint16_t* data, |
| 5774 v8::NewStringType type, int length) { |
| 5775 return NewString(isolate, "v8::String::NewFromTwoByte()", |
| 5776 "String::NewFromTwoByte", data, type, length); |
5762 } | 5777 } |
5763 | 5778 |
5764 | 5779 |
5765 Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) { | 5780 Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) { |
5766 i::Handle<i::String> left_string = Utils::OpenHandle(*left); | 5781 i::Handle<i::String> left_string = Utils::OpenHandle(*left); |
5767 i::Isolate* isolate = left_string->GetIsolate(); | 5782 i::Isolate* isolate = left_string->GetIsolate(); |
5768 LOG_API(isolate, "String::New(char)"); | |
5769 ENTER_V8(isolate); | 5783 ENTER_V8(isolate); |
| 5784 LOG_API(isolate, "v8::String::Concat"); |
5770 i::Handle<i::String> right_string = Utils::OpenHandle(*right); | 5785 i::Handle<i::String> right_string = Utils::OpenHandle(*right); |
5771 // If we are steering towards a range error, do not wait for the error to be | 5786 // If we are steering towards a range error, do not wait for the error to be |
5772 // thrown, and return the null handle instead. | 5787 // thrown, and return the null handle instead. |
5773 if (left_string->length() + right_string->length() > i::String::kMaxLength) { | 5788 if (left_string->length() + right_string->length() > i::String::kMaxLength) { |
5774 return Local<String>(); | 5789 return Local<String>(); |
5775 } | 5790 } |
5776 i::Handle<i::String> result = isolate->factory()->NewConsString( | 5791 i::Handle<i::String> result = isolate->factory()->NewConsString( |
5777 left_string, right_string).ToHandleChecked(); | 5792 left_string, right_string).ToHandleChecked(); |
5778 return Utils::ToLocal(result); | 5793 return Utils::ToLocal(result); |
5779 } | 5794 } |
5780 | 5795 |
5781 | 5796 |
5782 static i::MaybeHandle<i::String> NewExternalStringHandle( | 5797 MaybeLocal<String> v8::String::NewExternalTwoByte( |
5783 i::Isolate* isolate, v8::String::ExternalStringResource* resource) { | 5798 Isolate* isolate, v8::String::ExternalStringResource* resource) { |
5784 return isolate->factory()->NewExternalStringFromTwoByte(resource); | 5799 CHECK(resource && resource->data()); |
5785 } | 5800 // TODO(dcarney): throw a context free exception. |
5786 | 5801 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { |
5787 | 5802 return MaybeLocal<String>(); |
5788 static i::MaybeHandle<i::String> NewExternalOneByteStringHandle( | 5803 } |
5789 i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { | 5804 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
5790 return isolate->factory()->NewExternalStringFromOneByte(resource); | 5805 ENTER_V8(i_isolate); |
| 5806 LOG_API(i_isolate, "String::NewExternalTwoByte"); |
| 5807 i::Handle<i::String> string = i_isolate->factory() |
| 5808 ->NewExternalStringFromTwoByte(resource) |
| 5809 .ToHandleChecked(); |
| 5810 i_isolate->heap()->external_string_table()->AddString(*string); |
| 5811 return Utils::ToLocal(string); |
5791 } | 5812 } |
5792 | 5813 |
5793 | 5814 |
5794 Local<String> v8::String::NewExternal( | 5815 Local<String> v8::String::NewExternal( |
5795 Isolate* isolate, | 5816 Isolate* isolate, v8::String::ExternalStringResource* resource) { |
5796 v8::String::ExternalStringResource* resource) { | 5817 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String); |
| 5818 } |
| 5819 |
| 5820 |
| 5821 MaybeLocal<String> v8::String::NewExternalOneByte( |
| 5822 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { |
| 5823 CHECK(resource && resource->data()); |
| 5824 // TODO(dcarney): throw a context free exception. |
| 5825 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { |
| 5826 return MaybeLocal<String>(); |
| 5827 } |
5797 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5828 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
5798 LOG_API(i_isolate, "String::NewExternal"); | |
5799 ENTER_V8(i_isolate); | 5829 ENTER_V8(i_isolate); |
5800 CHECK(resource && resource->data()); | 5830 LOG_API(i_isolate, "String::NewExternalOneByte"); |
5801 EXCEPTION_PREAMBLE(i_isolate); | 5831 i::Handle<i::String> string = i_isolate->factory() |
5802 i::Handle<i::String> string; | 5832 ->NewExternalStringFromOneByte(resource) |
5803 has_pending_exception = | 5833 .ToHandleChecked(); |
5804 !NewExternalStringHandle(i_isolate, resource).ToHandle(&string); | |
5805 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>()); | |
5806 i_isolate->heap()->external_string_table()->AddString(*string); | 5834 i_isolate->heap()->external_string_table()->AddString(*string); |
5807 return Utils::ToLocal(string); | 5835 return Utils::ToLocal(string); |
5808 } | 5836 } |
5809 | 5837 |
5810 | 5838 |
| 5839 Local<String> v8::String::NewExternal( |
| 5840 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { |
| 5841 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String); |
| 5842 } |
| 5843 |
| 5844 |
5811 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { | 5845 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { |
5812 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5846 i::Handle<i::String> obj = Utils::OpenHandle(this); |
5813 i::Isolate* isolate = obj->GetIsolate(); | 5847 i::Isolate* isolate = obj->GetIsolate(); |
5814 if (i::StringShape(*obj).IsExternal()) { | 5848 if (i::StringShape(*obj).IsExternal()) { |
5815 return false; // Already an external string. | 5849 return false; // Already an external string. |
5816 } | 5850 } |
5817 ENTER_V8(isolate); | 5851 ENTER_V8(isolate); |
5818 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5852 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5819 return false; | 5853 return false; |
5820 } | 5854 } |
5821 if (isolate->heap()->IsInGCPostProcessing()) { | 5855 if (isolate->heap()->IsInGCPostProcessing()) { |
5822 return false; | 5856 return false; |
5823 } | 5857 } |
5824 CHECK(resource && resource->data()); | 5858 CHECK(resource && resource->data()); |
5825 | 5859 |
5826 bool result = obj->MakeExternal(resource); | 5860 bool result = obj->MakeExternal(resource); |
5827 // Assert that if CanMakeExternal(), then externalizing actually succeeds. | 5861 // Assert that if CanMakeExternal(), then externalizing actually succeeds. |
5828 DCHECK(!CanMakeExternal() || result); | 5862 DCHECK(!CanMakeExternal() || result); |
5829 if (result) { | 5863 if (result) { |
5830 DCHECK(obj->IsExternalString()); | 5864 DCHECK(obj->IsExternalString()); |
5831 isolate->heap()->external_string_table()->AddString(*obj); | 5865 isolate->heap()->external_string_table()->AddString(*obj); |
5832 } | 5866 } |
5833 return result; | 5867 return result; |
5834 } | 5868 } |
5835 | 5869 |
5836 | 5870 |
5837 Local<String> v8::String::NewExternal( | |
5838 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { | |
5839 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
5840 LOG_API(i_isolate, "String::NewExternal"); | |
5841 ENTER_V8(i_isolate); | |
5842 CHECK(resource && resource->data()); | |
5843 EXCEPTION_PREAMBLE(i_isolate); | |
5844 i::Handle<i::String> string; | |
5845 has_pending_exception = | |
5846 !NewExternalOneByteStringHandle(i_isolate, resource).ToHandle(&string); | |
5847 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>()); | |
5848 i_isolate->heap()->external_string_table()->AddString(*string); | |
5849 return Utils::ToLocal(string); | |
5850 } | |
5851 | |
5852 | |
5853 bool v8::String::MakeExternal( | 5871 bool v8::String::MakeExternal( |
5854 v8::String::ExternalOneByteStringResource* resource) { | 5872 v8::String::ExternalOneByteStringResource* resource) { |
5855 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5873 i::Handle<i::String> obj = Utils::OpenHandle(this); |
5856 i::Isolate* isolate = obj->GetIsolate(); | 5874 i::Isolate* isolate = obj->GetIsolate(); |
5857 if (i::StringShape(*obj).IsExternal()) { | 5875 if (i::StringShape(*obj).IsExternal()) { |
5858 return false; // Already an external string. | 5876 return false; // Already an external string. |
5859 } | 5877 } |
5860 ENTER_V8(isolate); | 5878 ENTER_V8(isolate); |
5861 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5879 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5862 return false; | 5880 return false; |
(...skipping 2131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7994 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 8012 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7995 Address callback_address = | 8013 Address callback_address = |
7996 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 8014 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7997 VMState<EXTERNAL> state(isolate); | 8015 VMState<EXTERNAL> state(isolate); |
7998 ExternalCallbackScope call_scope(isolate, callback_address); | 8016 ExternalCallbackScope call_scope(isolate, callback_address); |
7999 callback(info); | 8017 callback(info); |
8000 } | 8018 } |
8001 | 8019 |
8002 | 8020 |
8003 } } // namespace v8::internal | 8021 } } // namespace v8::internal |
OLD | NEW |