src: add a variant of ToV8Value() for primitive arrays

Adds a variant of ToV8Value for array of primitives that
do not need to throw during conversion - there is essentially
no exceptions that can be thrown then an array
of integers is created.

PR-URL: https://github.com/nodejs/node/pull/57576
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
Aditi 2025-03-19 03:48:33 +05:30 committed by James M Snell
parent 6dcd4621bd
commit 28cbc4c956
2 changed files with 46 additions and 22 deletions

View File

@ -392,23 +392,13 @@ static MaybeLocal<Object> ConvertHeapStatsToJSObject(
FIXED_ONE_BYTE_STRING(isolate, "bucket_size"),
FIXED_ONE_BYTE_STRING(isolate, "free_count"),
FIXED_ONE_BYTE_STRING(isolate, "free_size")};
Local<Value> bucket_size_value;
if (!ToV8Value(context, space_stats.free_list_stats.bucket_size)
.ToLocal(&bucket_size_value)) {
return MaybeLocal<Object>();
}
Local<Value> free_count_value;
if (!ToV8Value(context, space_stats.free_list_stats.free_count)
.ToLocal(&free_count_value)) {
return MaybeLocal<Object>();
}
Local<Value> free_size_value;
if (!ToV8Value(context, space_stats.free_list_stats.free_size)
.ToLocal(&free_size_value)) {
return MaybeLocal<Object>();
}
Local<Value> free_list_statistics_values[] = {
bucket_size_value, free_count_value, free_size_value};
ToV8ValuePrimitiveArray(
context, space_stats.free_list_stats.bucket_size, isolate),
ToV8ValuePrimitiveArray(
context, space_stats.free_list_stats.free_count, isolate),
ToV8ValuePrimitiveArray(
context, space_stats.free_list_stats.free_size, isolate)};
Local<Object> free_list_statistics_obj =
Object::New(isolate,

View File

@ -448,12 +448,9 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
return handle_scope.Escape(ret);
}
template <typename T, typename >
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const T& number,
v8::Isolate* isolate) {
if (isolate == nullptr) isolate = context->GetIsolate();
template <typename T>
v8::Local<v8::Value> ConvertNumberToV8Value(v8::Isolate* isolate,
const T& number) {
using Limits = std::numeric_limits<T>;
// Choose Uint32, Int32, or Double depending on range checks.
// These checks should all collapse at compile time.
@ -474,6 +471,43 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
return v8::Number::New(isolate, static_cast<double>(number));
}
template <typename T, typename>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const T& number,
v8::Isolate* isolate) {
if (isolate == nullptr) isolate = context->GetIsolate();
return ConvertNumberToV8Value(isolate, number);
}
template <typename T>
v8::Local<v8::Array> ToV8ValuePrimitiveArray(v8::Local<v8::Context> context,
const std::vector<T>& vec,
v8::Isolate* isolate) {
static_assert(
std::is_same_v<T, bool> || std::is_integral_v<T> ||
std::is_floating_point_v<T>,
"Only primitive types (bool, integral, floating-point) are supported.");
if (isolate == nullptr) isolate = context->GetIsolate();
v8::EscapableHandleScope handle_scope(isolate);
v8::LocalVector<v8::Value> elements(isolate);
elements.reserve(vec.size());
for (const auto& value : vec) {
if constexpr (std::is_same_v<T, bool>) {
elements.emplace_back(v8::Boolean::New(isolate, value));
} else {
v8::Local<v8::Value> v = ConvertNumberToV8Value(isolate, value);
elements.emplace_back(v);
}
}
v8::Local<v8::Array> arr =
v8::Array::New(isolate, elements.data(), elements.size());
return handle_scope.Escape(arr);
}
SlicedArguments::SlicedArguments(
const v8::FunctionCallbackInfo<v8::Value>& args, size_t start) {
const size_t length = static_cast<size_t>(args.Length());