Skip to content

Commit

Permalink
src: use new versions of V8 String APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
targos authored and nodejs-github-bot committed Jan 21, 2025
1 parent aca5e15 commit 726adce
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 76 deletions.
5 changes: 3 additions & 2 deletions benchmark/napi/function_args/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ void CallWithString(const FunctionCallbackInfo<Value>& args) {
assert(args.Length() == 1 && args[0]->IsString());
if (args.Length() == 1 && args[0]->IsString()) {
Local<String> str = args[0].As<String>();
const int32_t length = str->Utf8Length(args.GetIsolate()) + 1;
const size_t length = str->Utf8LengthV2(args.GetIsolate()) + 1;
char* buf = new char[length];
str->WriteUtf8(args.GetIsolate(), buf, length);
str->WriteUtf8V2(
args.GetIsolate(), buf, length, String::WriteFlags::kNullTerminate);
delete[] buf;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/crypto/crypto_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,12 @@ ByteSource ByteSource::FromStringOrBuffer(Environment* env,
ByteSource ByteSource::FromString(Environment* env, Local<String> str,
bool ntc) {
CHECK(str->IsString());
size_t size = str->Utf8Length(env->isolate());
size_t size = str->Utf8LengthV2(env->isolate());
size_t alloc_size = ntc ? size + 1 : size;
ByteSource::Builder out(alloc_size);
int opts = String::NO_OPTIONS;
if (!ntc) opts |= String::NO_NULL_TERMINATION;
str->WriteUtf8(env->isolate(), out.data<char>(), alloc_size, nullptr, opts);
int opts = String::WriteFlags::kNone;
if (ntc) opts |= String::WriteFlags::kNullTerminate;
str->WriteUtf8V2(env->isolate(), out.data<char>(), alloc_size, opts);
return std::move(out).release();
}

Expand Down
13 changes: 7 additions & 6 deletions src/encoding_binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void BindingData::EncodeInto(const FunctionCallbackInfo<Value>& args) {
size_t dest_length = dest->ByteLength();

int nchars;
// TODO: Use `WriteUtf8V2`, which has no `nchars_ref` parameter.
int written = source->WriteUtf8(
isolate,
write_result,
Expand All @@ -120,7 +121,7 @@ void BindingData::EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());

Local<String> str = args[0].As<String>();
size_t length = str->Utf8Length(isolate);
size_t length = str->Utf8LengthV2(isolate);

Local<ArrayBuffer> ab;
{
Expand All @@ -130,11 +131,11 @@ void BindingData::EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {

CHECK(bs);

str->WriteUtf8(isolate,
static_cast<char*>(bs->Data()),
-1, // We are certain that `data` is sufficiently large
nullptr,
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
str->WriteUtf8V2(
isolate,
static_cast<char*>(bs->Data()),
length, // We are certain that `data` is sufficiently large
String::WriteFlags::kReplaceInvalidUtf8);

ab = ArrayBuffer::New(isolate, std::move(bs));
}
Expand Down
32 changes: 13 additions & 19 deletions src/js_native_api_v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2446,16 +2446,13 @@ napi_status NAPI_CDECL napi_get_value_string_latin1(
CHECK_ARG(env, result);
*result = val.As<v8::String>()->Length();
} else if (bufsize != 0) {
int copied =
val.As<v8::String>()->WriteOneByte(env->isolate,
reinterpret_cast<uint8_t*>(buf),
0,
bufsize - 1,
v8::String::NO_NULL_TERMINATION);
size_t length = bufsize - 1;
val.As<v8::String>()->WriteOneByteV2(
env->isolate, 0, length, reinterpret_cast<uint8_t*>(buf));

buf[copied] = '\0';
buf[length] = '\0';
if (result != nullptr) {
*result = copied;
*result = length;
}
} else if (result != nullptr) {
*result = 0;
Expand All @@ -2482,14 +2479,13 @@ napi_status NAPI_CDECL napi_get_value_string_utf8(

if (!buf) {
CHECK_ARG(env, result);
*result = val.As<v8::String>()->Utf8Length(env->isolate);
*result = val.As<v8::String>()->Utf8LengthV2(env->isolate);
} else if (bufsize != 0) {
int copied = val.As<v8::String>()->WriteUtf8(
size_t copied = val.As<v8::String>()->WriteUtf8V2(
env->isolate,
buf,
bufsize - 1,
nullptr,
v8::String::REPLACE_INVALID_UTF8 | v8::String::NO_NULL_TERMINATION);
v8::String::WriteFlags::kReplaceInvalidUtf8);

buf[copied] = '\0';
if (result != nullptr) {
Expand Down Expand Up @@ -2526,15 +2522,13 @@ napi_status NAPI_CDECL napi_get_value_string_utf16(napi_env env,
// V8 assumes UTF-16 length is the same as the number of characters.
*result = val.As<v8::String>()->Length();
} else if (bufsize != 0) {
int copied = val.As<v8::String>()->Write(env->isolate,
reinterpret_cast<uint16_t*>(buf),
0,
bufsize - 1,
v8::String::NO_NULL_TERMINATION);
size_t length = bufsize - 1;
val.As<v8::String>()->WriteV2(
env->isolate, 0, length, reinterpret_cast<uint16_t*>(buf));

buf[copied] = '\0';
buf[length] = '\0';
if (result != nullptr) {
*result = copied;
*result = length;
}
} else if (result != nullptr) {
*result = 0;
Expand Down
21 changes: 7 additions & 14 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
// Can't use StringBytes::Write() in all cases. For example if attempting
// to write a two byte character into a one byte Buffer.
if (enc == UTF8) {
str_length = str_obj->Utf8Length(env->isolate());
str_length = str_obj->Utf8LengthV2(env->isolate());
node::Utf8Value str(env->isolate(), args[1]);
memcpy(ts_obj_data + start, *str, std::min(str_length, fill_length));

Expand Down Expand Up @@ -736,7 +736,8 @@ void SlowByteLengthUtf8(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());

// Fast case: avoid StringBytes on UTF8 string. Jump to v8.
args.GetReturnValue().Set(args[0].As<String>()->Utf8Length(env->isolate()));
size_t length = args[0].As<String>()->Utf8LengthV2(env->isolate());
args.GetReturnValue().Set(static_cast<uint64_t>(length));
}

uint32_t FastByteLengthUtf8(Local<Value> receiver,
Expand Down Expand Up @@ -1003,8 +1004,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
if (needle_data == nullptr) {
return args.GetReturnValue().Set(-1);
}
needle->WriteOneByte(
isolate, needle_data, 0, needle_length, String::NO_NULL_TERMINATION);
needle->WriteOneByteV2(isolate, 0, needle_length, needle_data);

result = nbytes::SearchString(reinterpret_cast<const uint8_t*>(haystack),
haystack_length,
Expand Down Expand Up @@ -1254,11 +1254,7 @@ static void Btoa(const FunctionCallbackInfo<Value>& args) {
simdutf::binary_to_base64(ext->data(), ext->length(), buffer.out());
} else if (input->IsOneByte()) {
MaybeStackBuffer<uint8_t> stack_buf(input->Length());
input->WriteOneByte(env->isolate(),
stack_buf.out(),
0,
input->Length(),
String::NO_NULL_TERMINATION);
input->WriteOneByteV2(env->isolate(), 0, input->Length(), stack_buf.out());

size_t expected_length =
simdutf::base64_length_from_binary(input->Length());
Expand Down Expand Up @@ -1317,11 +1313,8 @@ static void Atob(const FunctionCallbackInfo<Value>& args) {
ext->data(), ext->length(), buffer.out(), simdutf::base64_default);
} else if (input->IsOneByte()) {
MaybeStackBuffer<uint8_t> stack_buf(input->Length());
input->WriteOneByte(args.GetIsolate(),
stack_buf.out(),
0,
input->Length(),
String::NO_NULL_TERMINATION);
input->WriteOneByteV2(
args.GetIsolate(), 0, input->Length(), stack_buf.out());
const char* data = reinterpret_cast<const char*>(*stack_buf);
size_t expected_length =
simdutf::maximal_binary_length_from_base64(data, input->Length());
Expand Down
20 changes: 11 additions & 9 deletions src/node_http2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,10 @@ Origins::Origins(

CHECK_LE(origin_contents + origin_string_len,
static_cast<char*>(bs_->Data()) + bs_->ByteLength());
CHECK_EQ(origin_string->WriteOneByte(
env->isolate(),
reinterpret_cast<uint8_t*>(origin_contents),
0,
origin_string_len,
String::NO_NULL_TERMINATION),
origin_string_len);
origin_string->WriteOneByteV2(env->isolate(),
0,
origin_string_len,
reinterpret_cast<uint8_t*>(origin_contents));

size_t n = 0;
char* p;
Expand Down Expand Up @@ -3103,8 +3100,13 @@ void Http2Session::AltSvc(const FunctionCallbackInfo<Value>& args) {

MaybeStackBuffer<uint8_t> origin(origin_len);
MaybeStackBuffer<uint8_t> value(value_len);
origin_str->WriteOneByte(env->isolate(), *origin);
value_str->WriteOneByte(env->isolate(), *value);
origin_str->WriteOneByteV2(env->isolate(),
0,
origin_len,
*origin,
String::WriteFlags::kNullTerminate);
value_str->WriteOneByteV2(
env->isolate(), 0, value_len, *value, String::WriteFlags::kNullTerminate);

session->AltSvc(id, *origin, origin_len, *value, value_len);
}
Expand Down
6 changes: 2 additions & 4 deletions src/node_http_common-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,11 @@ NgHeaders<T>::NgHeaders(Environment* env, v8::Local<v8::Array> headers) {
nv_t* const nva = reinterpret_cast<nv_t*>(start);

CHECK_LE(header_contents + header_string_len, *buf_ + buf_.length());
CHECK_EQ(header_string.As<v8::String>()->WriteOneByte(
header_string.As<v8::String>()->WriteOneByteV2(
env->isolate(),
reinterpret_cast<uint8_t*>(header_contents),
0,
header_string_len,
v8::String::NO_NULL_TERMINATION),
header_string_len);
reinterpret_cast<uint8_t*>(header_contents));

size_t n = 0;
char* p;
Expand Down
25 changes: 14 additions & 11 deletions src/string_bytes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,11 @@ MaybeLocal<Value> ExternTwoByteString::NewSimpleFromCopy(Isolate* isolate,

} // anonymous namespace

size_t StringBytes::WriteUCS2(
Isolate* isolate, char* buf, size_t buflen, Local<String> str, int flags) {
size_t StringBytes::WriteUCS2(Isolate* isolate,
char* buf,
size_t buflen,
Local<String> str,
int flags = String::WriteFlags::kNone) {
uint16_t* const dst = reinterpret_cast<uint16_t*>(buf);

size_t max_chars = buflen / sizeof(*dst);
Expand All @@ -212,7 +215,8 @@ size_t StringBytes::WriteUCS2(
uint16_t* const aligned_dst = nbytes::AlignUp(dst, sizeof(*dst));
size_t nchars;
if (aligned_dst == dst) {
nchars = str->Write(isolate, dst, 0, max_chars, flags);
nchars = max_chars;
str->WriteV2(isolate, 0, nchars, dst, flags);
return nchars * sizeof(*dst);
}

Expand All @@ -223,15 +227,15 @@ size_t StringBytes::WriteUCS2(
if (max_chars == 0) {
return 0;
}
nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
CHECK_EQ(nchars, max_chars - 1);
nchars = max_chars - 1;
str->WriteV2(isolate, 0, nchars, aligned_dst, flags);

// Shift everything to unaligned-left
memmove(dst, aligned_dst, nchars * sizeof(*dst));

// One more char to be written
uint16_t last;
CHECK_EQ(str->Write(isolate, &last, nchars, 1, flags), 1);
str->WriteV2(isolate, nchars, 1, &last, flags);
memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
nchars++;

Expand All @@ -250,9 +254,7 @@ size_t StringBytes::Write(Isolate* isolate,
Local<String> str = val.As<String>();
String::ValueView input_view(isolate, str);

int flags = String::HINT_MANY_WRITES_EXPECTED |
String::NO_NULL_TERMINATION |
String::REPLACE_INVALID_UTF8;
int flags = String::WriteFlags::kReplaceInvalidUtf8;

switch (encoding) {
case ASCII:
Expand All @@ -262,13 +264,14 @@ size_t StringBytes::Write(Isolate* isolate,
memcpy(buf, input_view.data8(), nbytes);
} else {
uint8_t* const dst = reinterpret_cast<uint8_t*>(buf);
nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags);
str->WriteOneByteV2(isolate, 0, buflen, dst, flags);
nbytes = buflen;
}
break;

case BUFFER:
case UTF8:
nbytes = str->WriteUtf8(isolate, buf, buflen, nullptr, flags);
nbytes = str->WriteUtf8V2(isolate, buf, buflen, flags);
break;

case UCS2: {
Expand Down
12 changes: 5 additions & 7 deletions src/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ static void MakeUtf8String(Isolate* isolate,

// TODO(@anonrig): Use simdutf to speed up non-one-byte strings once it's
// implemented
const int flags =
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8;
const int length =
string->WriteUtf8(isolate, target->out(), storage, nullptr, flags);
const int flags = String::WriteFlags::kReplaceInvalidUtf8;
const size_t length =
string->WriteUtf8V2(isolate, target->out(), storage, flags);
target->SetLengthAndZeroTerminate(length);
}

Expand All @@ -154,9 +153,8 @@ TwoByteValue::TwoByteValue(Isolate* isolate, Local<Value> value) {
const size_t storage = string->Length() + 1;
AllocateSufficientStorage(storage);

const int flags = String::NO_NULL_TERMINATION;
const int length = string->Write(isolate, out(), 0, storage, flags);
SetLengthAndZeroTerminate(length);
string->WriteV2(isolate, 0, storage - 1, out());
SetLengthAndZeroTerminate(storage);
}

BufferValue::BufferValue(Isolate* isolate, Local<Value> value) {
Expand Down

0 comments on commit 726adce

Please sign in to comment.