Commit 1dd8624b authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[api] Re-introduce v8::String::IsExternal

After deprecation and removal of the old misleading API we re-add
v8::String::IsExternal which returns true for both, external one-byte and
external two-byte strings.

Bug: v8:10641
Change-Id: I4c66d4df891f7180c7a727a45c1fbd254a7f5c02
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2726512Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73137}
parent d0fd577f
...@@ -3247,6 +3247,11 @@ class V8_EXPORT String : public Name { ...@@ -3247,6 +3247,11 @@ class V8_EXPORT String : public Name {
*/ */
V8_INLINE static Local<String> Empty(Isolate* isolate); V8_INLINE static Local<String> Empty(Isolate* isolate);
/**
* Returns true if the string is external.
*/
bool IsExternal() const;
/** /**
* Returns true if the string is both external and two-byte. * Returns true if the string is both external and two-byte.
*/ */
......
...@@ -5404,6 +5404,11 @@ int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length, ...@@ -5404,6 +5404,11 @@ int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
start, length, options); start, length, options);
} }
bool v8::String::IsExternal() const {
i::Handle<i::String> str = Utils::OpenHandle(this);
return i::StringShape(*str).IsExternal();
}
bool v8::String::IsExternalTwoByte() const { bool v8::String::IsExternalTwoByte() const {
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
return i::StringShape(*str).IsExternalTwoByte(); return i::StringShape(*str).IsExternalTwoByte();
......
...@@ -514,6 +514,7 @@ THREADED_TEST(ScriptUsingStringResource) { ...@@ -514,6 +514,7 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CHECK_EQ(7, value->Int32Value(env.local()).FromJust());
CHECK(source->IsExternalTwoByte()); CHECK(source->IsExternalTwoByte());
CHECK(source->IsExternal());
CHECK_EQ(resource, CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource())); static_cast<TestResource*>(source->GetExternalStringResource()));
String::Encoding encoding = String::UNKNOWN_ENCODING; String::Encoding encoding = String::UNKNOWN_ENCODING;
...@@ -541,6 +542,8 @@ THREADED_TEST(ScriptUsingOneByteStringResource) { ...@@ -541,6 +542,8 @@ THREADED_TEST(ScriptUsingOneByteStringResource) {
String::NewExternalOneByte(env->GetIsolate(), resource) String::NewExternalOneByte(env->GetIsolate(), resource)
.ToLocalChecked(); .ToLocalChecked();
CHECK(source->IsExternalOneByte()); CHECK(source->IsExternalOneByte());
CHECK(source->IsExternal());
CHECK(!source->IsExternalTwoByte());
CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
source->GetExternalOneByteStringResource()); source->GetExternalOneByteStringResource());
String::Encoding encoding = String::UNKNOWN_ENCODING; String::Encoding encoding = String::UNKNOWN_ENCODING;
...@@ -574,6 +577,7 @@ THREADED_TEST(ScriptMakingExternalString) { ...@@ -574,6 +577,7 @@ THREADED_TEST(ScriptMakingExternalString) {
CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
CHECK(!source->IsExternalTwoByte()); CHECK(!source->IsExternalTwoByte());
CHECK(!source->IsExternalOneByte()); CHECK(!source->IsExternalOneByte());
CHECK(!source->IsExternal());
String::Encoding encoding = String::UNKNOWN_ENCODING; String::Encoding encoding = String::UNKNOWN_ENCODING;
CHECK(!source->GetExternalStringResourceBase(&encoding)); CHECK(!source->GetExternalStringResourceBase(&encoding));
CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); CHECK_EQ(String::ONE_BYTE_ENCODING, encoding);
...@@ -16803,6 +16807,7 @@ class VisitorImpl : public v8::ExternalResourceVisitor { ...@@ -16803,6 +16807,7 @@ class VisitorImpl : public v8::ExternalResourceVisitor {
} }
~VisitorImpl() override = default; ~VisitorImpl() override = default;
void VisitExternalString(v8::Local<v8::String> string) override { void VisitExternalString(v8::Local<v8::String> string) override {
CHECK(string->IsExternal());
if (string->IsExternalOneByte()) { if (string->IsExternalOneByte()) {
CHECK(!string->IsExternalTwoByte()); CHECK(!string->IsExternalTwoByte());
return; return;
...@@ -16847,6 +16852,7 @@ TEST(ExternalizeOldSpaceTwoByteCons) { ...@@ -16847,6 +16852,7 @@ TEST(ExternalizeOldSpaceTwoByteCons) {
cons->MakeExternal(resource); cons->MakeExternal(resource);
CHECK(cons->IsExternalTwoByte()); CHECK(cons->IsExternalTwoByte());
CHECK(cons->IsExternal());
CHECK_EQ(resource, cons->GetExternalStringResource()); CHECK_EQ(resource, cons->GetExternalStringResource());
String::Encoding encoding; String::Encoding encoding;
CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding));
...@@ -16884,7 +16890,7 @@ TEST(VisitExternalStrings) { ...@@ -16884,7 +16890,7 @@ TEST(VisitExternalStrings) {
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
const char string[] = "Some string"; const char string[] = "Some string";
uint16_t* two_byte_string = AsciiToTwoByteString(string); uint16_t* two_byte_string = AsciiToTwoByteString(string);
TestResource* resource[4]; TestResource* resource[5];
resource[0] = new TestResource(two_byte_string); resource[0] = new TestResource(two_byte_string);
v8::Local<v8::String> string0 = v8::Local<v8::String> string0 =
v8::String::NewExternalTwoByte(env->GetIsolate(), resource[0]) v8::String::NewExternalTwoByte(env->GetIsolate(), resource[0])
...@@ -16912,11 +16918,29 @@ TEST(VisitExternalStrings) { ...@@ -16912,11 +16918,29 @@ TEST(VisitExternalStrings) {
string3_i).is_null()); string3_i).is_null());
CHECK(string3_i->IsInternalizedString()); CHECK(string3_i->IsInternalizedString());
// Externalized one-byte string.
auto one_byte_resource =
new TestOneByteResource(i::StrDup(string), nullptr, 0);
v8::Local<v8::String> string4 =
String::NewExternalOneByte(env->GetIsolate(), one_byte_resource)
.ToLocalChecked();
// We need to add usages for string* to avoid warnings in GCC 4.7 // We need to add usages for string* to avoid warnings in GCC 4.7
CHECK(string0->IsExternalTwoByte()); CHECK(string0->IsExternalTwoByte());
CHECK(string1->IsExternalTwoByte()); CHECK(string1->IsExternalTwoByte());
CHECK(string2->IsExternalTwoByte()); CHECK(string2->IsExternalTwoByte());
CHECK(string3->IsExternalTwoByte()); CHECK(string3->IsExternalTwoByte());
CHECK(!string4->IsExternalTwoByte());
CHECK(string0->IsExternal());
CHECK(string1->IsExternal());
CHECK(string2->IsExternal());
CHECK(string3->IsExternal());
CHECK(string4->IsExternal());
CHECK(!string0->IsExternalOneByte());
CHECK(!string1->IsExternalOneByte());
CHECK(!string2->IsExternalOneByte());
CHECK(!string3->IsExternalOneByte());
CHECK(string4->IsExternalOneByte());
VisitorImpl visitor(resource); VisitorImpl visitor(resource);
isolate->VisitExternalResources(&visitor); isolate->VisitExternalResources(&visitor);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment