diff --git a/src/util-inl.h b/src/util-inl.h index 864f6d86cdf689..80444d73a92fd5 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -401,6 +401,29 @@ inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc(n); } // headers than we really need to. void ThrowErrStringTooLong(v8::Isolate* isolate); +struct ArrayIterationData { + std::vector>* out; + v8::Isolate* isolate = nullptr; +}; + +inline v8::Array::CallbackResult PushItemToVector(uint32_t index, + v8::Local element, + void* data) { + auto vec = static_cast(data)->out; + auto isolate = static_cast(data)->isolate; + vec->push_back(v8::Global(isolate, element)); + return v8::Array::CallbackResult::kContinue; +} + +v8::Maybe FromV8Array(v8::Local context, + v8::Local js_array, + std::vector>* out) { + uint32_t count = js_array->Length(); + out->reserve(count); + ArrayIterationData data{out, context->GetIsolate()}; + return js_array->Iterate(context, PushItemToVector, &data); +} + v8::MaybeLocal ToV8Value(v8::Local context, std::string_view str, v8::Isolate* isolate) { diff --git a/src/util.h b/src/util.h index 83e5d226701b9b..a9d1ec039e8517 100644 --- a/src/util.h +++ b/src/util.h @@ -697,6 +697,16 @@ struct FunctionDeleter { template using DeleteFnPtr = typename FunctionDeleter::Pointer; +// Convert a v8::Array into an std::vector using the callback-based API. +// This can be faster than calling Array::Get() repeatedly when the array +// has more than 2 entries. +// Note that iterating over an array in C++ and performing operations on each +// element in a C++ loop is still slower than iterating over the array in JS +// and calling into native in the JS loop repeatedly on each element, +// as of V8 11.9. +inline v8::Maybe FromV8Array(v8::Local context, + v8::Local js_array, + std::vector>* out); std::vector SplitString(const std::string_view in, const std::string_view delim);