Skip to content

Commit 1a8ae9d

Browse files
committed
src: use callback-based array iteration in Blob
PR-URL: #51758 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
1 parent 5cd2ec8 commit 1a8ae9d

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/node_blob.cc

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ namespace {
4141
// Concatenate multiple ArrayBufferView/ArrayBuffers into a single ArrayBuffer.
4242
// This method treats all ArrayBufferView types the same.
4343
void Concat(const FunctionCallbackInfo<Value>& args) {
44-
Environment* env = Environment::GetCurrent(args);
44+
Isolate* isolate = args.GetIsolate();
45+
Local<Context> context = isolate->GetCurrentContext();
46+
Environment* env = Environment::GetCurrent(context);
47+
4548
CHECK(args[0]->IsArray());
4649
Local<Array> array = args[0].As<Array>();
4750

@@ -54,9 +57,14 @@ void Concat(const FunctionCallbackInfo<Value>& args) {
5457
std::vector<View> views;
5558
size_t total = 0;
5659

57-
for (uint32_t n = 0; n < array->Length(); n++) {
58-
Local<Value> val;
59-
if (!array->Get(env->context(), n).ToLocal(&val)) return;
60+
std::vector<v8::Global<Value>> buffers;
61+
if (FromV8Array(context, array, &buffers).IsNothing()) {
62+
return;
63+
}
64+
65+
size_t count = buffers.size();
66+
for (uint32_t i = 0; i < count; i++) {
67+
Local<Value> val = buffers[i].Get(isolate);
6068
if (val->IsArrayBuffer()) {
6169
auto ab = val.As<ArrayBuffer>();
6270
views.push_back(View{ab->GetBackingStore(), ab->ByteLength(), 0});
@@ -169,21 +177,27 @@ BaseObjectPtr<Blob> Blob::Create(Environment* env,
169177
}
170178

171179
void Blob::New(const FunctionCallbackInfo<Value>& args) {
172-
Environment* env = Environment::GetCurrent(args);
180+
Isolate* isolate = args.GetIsolate();
181+
Local<Context> context = isolate->GetCurrentContext();
182+
Environment* env = Environment::GetCurrent(context);
183+
173184
CHECK(args[0]->IsArray()); // sources
174185

175186
Local<Array> array = args[0].As<Array>();
176187
std::vector<std::unique_ptr<DataQueue::Entry>> entries(array->Length());
177188

178-
for (size_t i = 0; i < array->Length(); i++) {
179-
Local<Value> entry;
180-
if (!array->Get(env->context(), i).ToLocal(&entry)) {
181-
return;
182-
}
189+
std::vector<v8::Global<Value>> sources;
190+
if (FromV8Array(context, array, &sources).IsNothing()) {
191+
return;
192+
}
193+
194+
size_t count = sources.size();
195+
for (size_t i = 0; i < count; i++) {
196+
Local<Value> entry = sources[i].Get(isolate);
183197

184-
const auto entryFromArrayBuffer = [env](v8::Local<v8::ArrayBuffer> buf,
185-
size_t byte_length,
186-
size_t byte_offset = 0) {
198+
const auto entryFromArrayBuffer = [isolate](v8::Local<v8::ArrayBuffer> buf,
199+
size_t byte_length,
200+
size_t byte_offset = 0) {
187201
if (buf->IsDetachable()) {
188202
std::shared_ptr<BackingStore> store = buf->GetBackingStore();
189203
USE(buf->Detach(Local<Value>()));
@@ -193,7 +207,7 @@ void Blob::New(const FunctionCallbackInfo<Value>& args) {
193207

194208
// If the ArrayBuffer is not detachable, we will copy from it instead.
195209
std::shared_ptr<BackingStore> store =
196-
ArrayBuffer::NewBackingStore(env->isolate(), byte_length);
210+
ArrayBuffer::NewBackingStore(isolate, byte_length);
197211
uint8_t* ptr = static_cast<uint8_t*>(buf->Data()) + byte_offset;
198212
std::copy(ptr, ptr + byte_length, static_cast<uint8_t*>(store->Data()));
199213
return DataQueue::CreateInMemoryEntryFromBackingStore(

0 commit comments

Comments
 (0)