@@ -19,6 +19,7 @@ namespace node {
1919
2020using v8::Array;
2121using v8::ArrayBuffer;
22+ using v8::BackingStore;
2223using v8::ConstructorBehavior;
2324using v8::Context;
2425using v8::DontDelete;
@@ -29,6 +30,7 @@ using v8::FunctionCallbackInfo;
2930using v8::FunctionTemplate;
3031using v8::HandleScope;
3132using v8::Integer;
33+ using v8::Isolate;
3234using v8::Local;
3335using v8::MaybeLocal;
3436using v8::Object;
@@ -80,6 +82,8 @@ void StreamBase::SetWriteResult(const StreamWriteResult& res) {
8082
8183int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
8284 Environment* env = Environment::GetCurrent(args);
85+ Isolate* isolate = env->isolate();
86+ Local<Context> context = env->context();
8387
8488 CHECK(args[0]->IsObject());
8589 CHECK(args[1]->IsArray());
@@ -102,21 +106,21 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
102106 if (!all_buffers) {
103107 // Determine storage size first
104108 for (size_t i = 0; i < count; i++) {
105- Local<Value> chunk = chunks->Get(env-> context() , i * 2).ToLocalChecked();
109+ Local<Value> chunk = chunks->Get(context, i * 2).ToLocalChecked();
106110
107111 if (Buffer::HasInstance(chunk))
108112 continue;
109113 // Buffer chunk, no additional storage required
110114
111115 // String chunk
112- Local<String> string = chunk->ToString(env-> context() ).ToLocalChecked();
113- enum encoding encoding = ParseEncoding(env-> isolate() ,
114- chunks->Get(env-> context() , i * 2 + 1).ToLocalChecked());
116+ Local<String> string = chunk->ToString(context).ToLocalChecked();
117+ enum encoding encoding = ParseEncoding(isolate,
118+ chunks->Get(context, i * 2 + 1).ToLocalChecked());
115119 size_t chunk_size;
116120 if (encoding == UTF8 && string->Length() > 65535 &&
117- !StringBytes::Size(env-> isolate() , string, encoding).To(&chunk_size))
121+ !StringBytes::Size(isolate, string, encoding).To(&chunk_size))
118122 return 0;
119- else if (!StringBytes::StorageSize(env-> isolate() , string, encoding)
123+ else if (!StringBytes::StorageSize(isolate, string, encoding)
120124 .To(&chunk_size))
121125 return 0;
122126 storage_size += chunk_size;
@@ -126,20 +130,22 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
126130 return UV_ENOBUFS;
127131 } else {
128132 for (size_t i = 0; i < count; i++) {
129- Local<Value> chunk = chunks->Get(env-> context() , i).ToLocalChecked();
133+ Local<Value> chunk = chunks->Get(context, i).ToLocalChecked();
130134 bufs[i].base = Buffer::Data(chunk);
131135 bufs[i].len = Buffer::Length(chunk);
132136 }
133137 }
134138
135- AllocatedBuffer storage;
136- if (storage_size > 0)
137- storage = AllocatedBuffer::AllocateManaged(env, storage_size);
139+ std::unique_ptr<BackingStore> bs;
140+ if (storage_size > 0) {
141+ NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
142+ bs = ArrayBuffer::NewBackingStore(isolate, storage_size);
143+ }
138144
139145 offset = 0;
140146 if (!all_buffers) {
141147 for (size_t i = 0; i < count; i++) {
142- Local<Value> chunk = chunks->Get(env-> context() , i * 2).ToLocalChecked();
148+ Local<Value> chunk = chunks->Get(context, i * 2).ToLocalChecked();
143149
144150 // Write buffer
145151 if (Buffer::HasInstance(chunk)) {
@@ -150,13 +156,14 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
150156
151157 // Write string
152158 CHECK_LE(offset, storage_size);
153- char* str_storage = storage.data() + offset;
154- size_t str_size = storage.size() - offset;
155-
156- Local<String> string = chunk->ToString(env->context()).ToLocalChecked();
157- enum encoding encoding = ParseEncoding(env->isolate(),
158- chunks->Get(env->context(), i * 2 + 1).ToLocalChecked());
159- str_size = StringBytes::Write(env->isolate(),
159+ char* str_storage =
160+ static_cast<char*>(bs ? bs->Data() : nullptr) + offset;
161+ size_t str_size = (bs ? bs->ByteLength() : 0) - offset;
162+
163+ Local<String> string = chunk->ToString(context).ToLocalChecked();
164+ enum encoding encoding = ParseEncoding(isolate,
165+ chunks->Get(context, i * 2 + 1).ToLocalChecked());
166+ str_size = StringBytes::Write(isolate,
160167 str_storage,
161168 str_size,
162169 string,
@@ -169,9 +176,8 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
169176
170177 StreamWriteResult res = Write(*bufs, count, nullptr, req_wrap_obj);
171178 SetWriteResult(res);
172- if (res.wrap != nullptr && storage_size > 0) {
173- res.wrap->SetAllocatedStorage(std::move(storage));
174- }
179+ if (res.wrap != nullptr && storage_size > 0)
180+ res.wrap->SetBackingStore(std::move(bs));
175181 return res.err;
176182}
177183
@@ -216,6 +222,7 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
216222template <enum encoding enc>
217223int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
218224 Environment* env = Environment::GetCurrent(args);
225+ Isolate* isolate = env->isolate();
219226 CHECK(args[0]->IsObject());
220227 CHECK(args[1]->IsString());
221228
@@ -230,9 +237,9 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
230237 // computing their actual size, rather than tripling the storage.
231238 size_t storage_size;
232239 if (enc == UTF8 && string->Length() > 65535 &&
233- !StringBytes::Size(env-> isolate() , string, enc).To(&storage_size))
240+ !StringBytes::Size(isolate, string, enc).To(&storage_size))
234241 return 0;
235- else if (!StringBytes::StorageSize(env-> isolate() , string, enc)
242+ else if (!StringBytes::StorageSize(isolate, string, enc)
236243 .To(&storage_size))
237244 return 0;
238245
@@ -248,7 +255,7 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
248255 bool try_write = storage_size <= sizeof(stack_storage) &&
249256 (!IsIPCPipe() || send_handle_obj.IsEmpty());
250257 if (try_write) {
251- data_size = StringBytes::Write(env-> isolate() ,
258+ data_size = StringBytes::Write(isolate,
252259 stack_storage,
253260 storage_size,
254261 string,
@@ -274,26 +281,28 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
274281 CHECK_EQ(count, 1);
275282 }
276283
277- AllocatedBuffer data ;
284+ std::unique_ptr<BackingStore> bs ;
278285
279286 if (try_write) {
280287 // Copy partial data
281- data = AllocatedBuffer::AllocateManaged(env, buf.len);
282- memcpy(data.data(), buf.base, buf.len);
288+ NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
289+ bs = ArrayBuffer::NewBackingStore(isolate, buf.len);
290+ memcpy(static_cast<char*>(bs->Data()), buf.base, buf.len);
283291 data_size = buf.len;
284292 } else {
285293 // Write it
286- data = AllocatedBuffer::AllocateManaged(env, storage_size);
287- data_size = StringBytes::Write(env->isolate(),
288- data.data(),
294+ NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
295+ bs = ArrayBuffer::NewBackingStore(isolate, storage_size);
296+ data_size = StringBytes::Write(isolate,
297+ static_cast<char*>(bs->Data()),
289298 storage_size,
290299 string,
291300 enc);
292301 }
293302
294303 CHECK_LE(data_size, storage_size);
295304
296- buf = uv_buf_init(data.data( ), data_size);
305+ buf = uv_buf_init(static_cast<char*>(bs->Data() ), data_size);
297306
298307 uv_stream_t* send_handle = nullptr;
299308
@@ -312,9 +321,8 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
312321 res.bytes += synchronously_written;
313322
314323 SetWriteResult(res);
315- if (res.wrap != nullptr) {
316- res.wrap->SetAllocatedStorage(std::move(data));
317- }
324+ if (res.wrap != nullptr)
325+ res.wrap->SetBackingStore(std::move(bs));
318326
319327 return res.err;
320328}
@@ -511,27 +519,28 @@ void StreamResource::ClearError() {
511519uv_buf_t EmitToJSStreamListener::OnStreamAlloc(size_t suggested_size) {
512520 CHECK_NOT_NULL(stream_);
513521 Environment* env = static_cast<StreamBase*>(stream_)->stream_env();
514- return AllocatedBuffer::AllocateManaged( env, suggested_size).release( );
522+ return env->allocate_managed_buffer(suggested_size );
515523}
516524
517525void EmitToJSStreamListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf_) {
518526 CHECK_NOT_NULL(stream_);
519527 StreamBase* stream = static_cast<StreamBase*>(stream_);
520528 Environment* env = stream->stream_env();
521- HandleScope handle_scope(env->isolate());
529+ Isolate* isolate = env->isolate();
530+ HandleScope handle_scope(isolate);
522531 Context::Scope context_scope(env->context());
523- AllocatedBuffer buf(env, buf_);
532+ std::unique_ptr<BackingStore> bs = env->release_managed_buffer( buf_);
524533
525534 if (nread <= 0) {
526535 if (nread < 0)
527536 stream->CallJSOnreadMethod(nread, Local<ArrayBuffer>());
528537 return;
529538 }
530539
531- CHECK_LE(static_cast<size_t>(nread), buf.size ());
532- buf.Resize( nread);
540+ CHECK_LE(static_cast<size_t>(nread), bs->ByteLength ());
541+ bs = BackingStore::Reallocate(isolate, std::move(bs), nread);
533542
534- stream->CallJSOnreadMethod(nread, buf.ToArrayBuffer( ));
543+ stream->CallJSOnreadMethod(nread, ArrayBuffer::New(isolate, std::move(bs) ));
535544}
536545
537546
0 commit comments