From 3e1c53fe3790f366ed37ce8208e489364e0ad89e Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 6 Nov 2018 18:05:48 +0800 Subject: deps: cherry-pick 0483e9a from upstream V8 Original commit message: [api] Allow embedder to construct an Array from Local* Currently to obtain a v8::Array out of a C array or a std::vector, one needs to loop through the elements and call array->Set() multiple times, and these calls go into v8::Object::Set() which can be slow. This patch adds a new Array::New overload that converts a Local* with known size into a Local. Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188 Reviewed-on: https://chromium-review.googlesource.com/c/1317049 Reviewed-by: Yang Guo Reviewed-by: Adam Klein Commit-Queue: Joyee Cheung Cr-Commit-Position: refs/heads/master@{#57261} Refs: https://github.com/v8/v8/commit/0483e9a9abe77a73632fd85b9c0cd608efa9aa0d PR-URL: https://github.com/nodejs/node/pull/24125 Reviewed-By: Anna Henningsen Reviewed-By: Yang Guo Reviewed-By: Gus Caplan Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: Refael Ackermann --- deps/v8/include/v8.h | 6 ++++++ deps/v8/src/api.cc | 17 +++++++++++++++++ deps/v8/test/cctest/test-api.cc | 16 ++++++++++++++++ 3 files changed, 39 insertions(+) (limited to 'deps') diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index c48025871aa..e1951ec2705 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -3779,6 +3779,12 @@ class V8_EXPORT Array : public Object { */ static Local New(Isolate* isolate, int length = 0); + /** + * Creates a JavaScript array out of a Local array in C++ + * with a known length. + */ + static Local New(Isolate* isolate, Local* elements, + size_t length); V8_INLINE static Array* Cast(Value* obj); private: Array(); diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 54d1ba1afc7..c1afe8d93b9 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -6981,6 +6981,23 @@ Local v8::Array::New(Isolate* isolate, int length) { return Utils::ToLocal(obj); } +Local v8::Array::New(Isolate* isolate, Local* elements, + size_t length) { + i::Isolate* i_isolate = reinterpret_cast(isolate); + i::Factory* factory = i_isolate->factory(); + LOG_API(i_isolate, Array, New); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + int len = static_cast(length); + + i::Handle result = factory->NewFixedArray(len); + for (int i = 0; i < len; i++) { + i::Handle element = Utils::OpenHandle(*elements[i]); + result->set(i, *element); + } + + return Utils::ToLocal( + factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len)); +} uint32_t v8::Array::Length() const { i::Handle obj = Utils::OpenHandle(this); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index bf5aba2df66..f7365c8f31a 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -5247,6 +5247,22 @@ THREADED_TEST(Array) { CHECK_EQ(27u, array->Length()); array = v8::Array::New(context->GetIsolate(), -27); CHECK_EQ(0u, array->Length()); + + std::vector> vector = {v8_num(1), v8_num(2), v8_num(3)}; + array = v8::Array::New(context->GetIsolate(), vector.data(), vector.size()); + CHECK_EQ(vector.size(), array->Length()); + CHECK_EQ(1, arr->Get(context.local(), 0) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(2, arr->Get(context.local(), 1) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(3, arr->Get(context.local(), 2) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } -- cgit v1.2.3