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