@@ -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
+ reinterpret_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,8 @@ 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 ();
226
+ IsolateData* isolate_data = env->isolate_data ();
219
227
CHECK (args[0 ]->IsObject ());
220
228
CHECK (args[1 ]->IsString ());
221
229
@@ -230,9 +238,9 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
230
238
// computing their actual size, rather than tripling the storage.
231
239
size_t storage_size;
232
240
if (enc == UTF8 && string->Length () > 65535 &&
233
- !StringBytes::Size (env-> isolate () , string, enc).To (&storage_size))
241
+ !StringBytes::Size (isolate, string, enc).To (&storage_size))
234
242
return 0 ;
235
- else if (!StringBytes::StorageSize (env-> isolate () , string, enc)
243
+ else if (!StringBytes::StorageSize (isolate, string, enc)
236
244
.To (&storage_size))
237
245
return 0 ;
238
246
@@ -248,7 +256,7 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
248
256
bool try_write = storage_size <= sizeof (stack_storage) &&
249
257
(!IsIPCPipe () || send_handle_obj.IsEmpty ());
250
258
if (try_write) {
251
- data_size = StringBytes::Write (env-> isolate () ,
259
+ data_size = StringBytes::Write (isolate,
252
260
stack_storage,
253
261
storage_size,
254
262
string,
@@ -274,26 +282,28 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
274
282
CHECK_EQ (count, 1 );
275
283
}
276
284
277
- AllocatedBuffer data ;
285
+ std::unique_ptr<BackingStore> bs ;
278
286
279
287
if (try_write) {
280
288
// Copy partial data
281
- data = AllocatedBuffer::AllocateManaged (env, buf.len );
282
- memcpy (data.data (), buf.base , buf.len );
289
+ NoArrayBufferZeroFillScope no_zero_fill_scope (isolate_data);
290
+ bs = ArrayBuffer::NewBackingStore (isolate, buf.len );
291
+ memcpy (reinterpret_cast <char *>(bs->Data ()), buf.base , buf.len );
283
292
data_size = buf.len ;
284
293
} else {
285
294
// Write it
286
- data = AllocatedBuffer::AllocateManaged (env, storage_size);
287
- data_size = StringBytes::Write (env->isolate (),
288
- data.data (),
295
+ NoArrayBufferZeroFillScope no_zero_fill_scope (isolate_data);
296
+ bs = ArrayBuffer::NewBackingStore (isolate, storage_size);
297
+ data_size = StringBytes::Write (isolate,
298
+ reinterpret_cast <char *>(bs->Data ()),
289
299
storage_size,
290
300
string,
291
301
enc);
292
302
}
293
303
294
304
CHECK_LE (data_size, storage_size);
295
305
296
- buf = uv_buf_init (data. data ( ), data_size);
306
+ buf = uv_buf_init (reinterpret_cast < char *>(bs-> Data () ), data_size);
297
307
298
308
uv_stream_t * send_handle = nullptr ;
299
309
@@ -312,9 +322,8 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
312
322
res.bytes += synchronously_written;
313
323
314
324
SetWriteResult (res);
315
- if (res.wrap != nullptr ) {
316
- res.wrap ->SetAllocatedStorage (std::move (data));
317
- }
325
+ if (res.wrap != nullptr )
326
+ res.wrap ->SetBackingStore (std::move (bs));
318
327
319
328
return res.err ;
320
329
}
@@ -511,27 +520,28 @@ void StreamResource::ClearError() {
511
520
uv_buf_t EmitToJSStreamListener::OnStreamAlloc (size_t suggested_size) {
512
521
CHECK_NOT_NULL (stream_);
513
522
Environment* env = static_cast <StreamBase*>(stream_)->stream_env ();
514
- return AllocatedBuffer::AllocateManaged ( env, suggested_size). release ( );
523
+ return env-> allocate_managed_buffer (suggested_size );
515
524
}
516
525
517
526
void EmitToJSStreamListener::OnStreamRead (ssize_t nread, const uv_buf_t & buf_) {
518
527
CHECK_NOT_NULL (stream_);
519
528
StreamBase* stream = static_cast <StreamBase*>(stream_);
520
529
Environment* env = stream->stream_env ();
521
- HandleScope handle_scope (env->isolate ());
530
+ Isolate* isolate = env->isolate ();
531
+ HandleScope handle_scope (isolate);
522
532
Context::Scope context_scope (env->context ());
523
- AllocatedBuffer buf (env, buf_);
533
+ std::unique_ptr<BackingStore> bs = env-> release_managed_buffer ( buf_);
524
534
525
535
if (nread <= 0 ) {
526
536
if (nread < 0 )
527
537
stream->CallJSOnreadMethod (nread, Local<ArrayBuffer>());
528
538
return ;
529
539
}
530
540
531
- CHECK_LE (static_cast <size_t >(nread), buf. size ());
532
- buf. Resize ( nread);
541
+ CHECK_LE (static_cast <size_t >(nread), bs-> ByteLength ());
542
+ bs = BackingStore::Reallocate (isolate, std::move (bs), nread);
533
543
534
- stream->CallJSOnreadMethod (nread, buf. ToArrayBuffer ( ));
544
+ stream->CallJSOnreadMethod (nread, ArrayBuffer::New (isolate, std::move (bs) ));
535
545
}
536
546
537
547
0 commit comments