@@ -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