@@ -19,6 +19,7 @@ namespace node {
19
19
20
20
using v8::Array;
21
21
using v8::ArrayBuffer;
22
+ using v8::BackingStore;
22
23
using v8::ConstructorBehavior;
23
24
using v8::Context;
24
25
using v8::DontDelete;
@@ -29,6 +30,7 @@ using v8::FunctionCallbackInfo;
29
30
using v8::FunctionTemplate;
30
31
using v8::HandleScope;
31
32
using v8::Integer;
33
+ using v8::Isolate;
32
34
using v8::Local;
33
35
using v8::MaybeLocal;
34
36
using v8::Object;
@@ -80,6 +82,8 @@ void StreamBase::SetWriteResult(const StreamWriteResult& res) {
80
82
81
83
int StreamBase::Writev (const FunctionCallbackInfo<Value>& args) {
82
84
Environment* env = Environment::GetCurrent (args);
85
+ Isolate* isolate = env->isolate ();
86
+ Local<Context> context = env->context ();
83
87
84
88
CHECK (args[0 ]->IsObject ());
85
89
CHECK (args[1 ]->IsArray ());
@@ -102,21 +106,21 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
102
106
if (!all_buffers) {
103
107
// Determine storage size first
104
108
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 ();
106
110
107
111
if (Buffer::HasInstance (chunk))
108
112
continue ;
109
113
// Buffer chunk, no additional storage required
110
114
111
115
// 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 ());
115
119
size_t chunk_size;
116
120
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))
118
122
return 0 ;
119
- else if (!StringBytes::StorageSize (env-> isolate () , string, encoding)
123
+ else if (!StringBytes::StorageSize (isolate, string, encoding)
120
124
.To (&chunk_size))
121
125
return 0 ;
122
126
storage_size += chunk_size;
@@ -126,20 +130,22 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
126
130
return UV_ENOBUFS;
127
131
} else {
128
132
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 ();
130
134
bufs[i].base = Buffer::Data (chunk);
131
135
bufs[i].len = Buffer::Length (chunk);
132
136
}
133
137
}
134
138
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
+ }
138
144
139
145
offset = 0 ;
140
146
if (!all_buffers) {
141
147
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 ();
143
149
144
150
// Write buffer
145
151
if (Buffer::HasInstance (chunk)) {
@@ -150,13 +156,14 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
150
156
151
157
// Write string
152
158
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,
160
167
str_storage,
161
168
str_size,
162
169
string,
@@ -169,9 +176,8 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
169
176
170
177
StreamWriteResult res = Write (*bufs, count, nullptr , req_wrap_obj);
171
178
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));
175
181
return res.err ;
176
182
}
177
183
@@ -216,6 +222,7 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
216
222
template <enum encoding enc>
217
223
int StreamBase::WriteString (const FunctionCallbackInfo<Value>& args) {
218
224
Environment* env = Environment::GetCurrent (args);
225
+ Isolate* isolate = env->isolate ();
219
226
CHECK (args[0 ]->IsObject ());
220
227
CHECK (args[1 ]->IsString ());
221
228
@@ -230,9 +237,9 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
230
237
// computing their actual size, rather than tripling the storage.
231
238
size_t storage_size;
232
239
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))
234
241
return 0 ;
235
- else if (!StringBytes::StorageSize (env-> isolate () , string, enc)
242
+ else if (!StringBytes::StorageSize (isolate, string, enc)
236
243
.To (&storage_size))
237
244
return 0 ;
238
245
@@ -248,7 +255,7 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
248
255
bool try_write = storage_size <= sizeof (stack_storage) &&
249
256
(!IsIPCPipe () || send_handle_obj.IsEmpty ());
250
257
if (try_write) {
251
- data_size = StringBytes::Write (env-> isolate () ,
258
+ data_size = StringBytes::Write (isolate,
252
259
stack_storage,
253
260
storage_size,
254
261
string,
@@ -274,26 +281,28 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
274
281
CHECK_EQ (count, 1 );
275
282
}
276
283
277
- AllocatedBuffer data ;
284
+ std::unique_ptr<BackingStore> bs ;
278
285
279
286
if (try_write) {
280
287
// 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 );
283
291
data_size = buf.len ;
284
292
} else {
285
293
// 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 ()),
289
298
storage_size,
290
299
string,
291
300
enc);
292
301
}
293
302
294
303
CHECK_LE (data_size, storage_size);
295
304
296
- buf = uv_buf_init (data. data ( ), data_size);
305
+ buf = uv_buf_init (static_cast < char *>(bs-> Data () ), data_size);
297
306
298
307
uv_stream_t * send_handle = nullptr ;
299
308
@@ -312,9 +321,8 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
312
321
res.bytes += synchronously_written;
313
322
314
323
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));
318
326
319
327
return res.err ;
320
328
}
@@ -511,27 +519,28 @@ void StreamResource::ClearError() {
511
519
uv_buf_t EmitToJSStreamListener::OnStreamAlloc (size_t suggested_size) {
512
520
CHECK_NOT_NULL (stream_);
513
521
Environment* env = static_cast <StreamBase*>(stream_)->stream_env ();
514
- return AllocatedBuffer::AllocateManaged ( env, suggested_size). release ( );
522
+ return env-> allocate_managed_buffer (suggested_size );
515
523
}
516
524
517
525
void EmitToJSStreamListener::OnStreamRead (ssize_t nread, const uv_buf_t & buf_) {
518
526
CHECK_NOT_NULL (stream_);
519
527
StreamBase* stream = static_cast <StreamBase*>(stream_);
520
528
Environment* env = stream->stream_env ();
521
- HandleScope handle_scope (env->isolate ());
529
+ Isolate* isolate = env->isolate ();
530
+ HandleScope handle_scope (isolate);
522
531
Context::Scope context_scope (env->context ());
523
- AllocatedBuffer buf (env, buf_);
532
+ std::unique_ptr<BackingStore> bs = env-> release_managed_buffer ( buf_);
524
533
525
534
if (nread <= 0 ) {
526
535
if (nread < 0 )
527
536
stream->CallJSOnreadMethod (nread, Local<ArrayBuffer>());
528
537
return ;
529
538
}
530
539
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);
533
542
534
- stream->CallJSOnreadMethod (nread, buf. ToArrayBuffer ( ));
543
+ stream->CallJSOnreadMethod (nread, ArrayBuffer::New (isolate, std::move (bs) ));
535
544
}
536
545
537
546
0 commit comments