55
55
size_t length = end - start;
56
56
57
57
namespace node {
58
-
59
- // if true, all Buffer and SlowBuffer instances will automatically zero-fill
60
- bool zero_fill_all_buffers = false ;
61
-
62
- namespace {
63
-
64
- inline void * BufferMalloc (size_t length) {
65
- return zero_fill_all_buffers ? node::UncheckedCalloc (length) :
66
- node::UncheckedMalloc (length);
67
- }
68
-
69
- } // namespace
70
-
71
58
namespace Buffer {
72
59
73
60
using v8::ArrayBuffer;
@@ -245,7 +232,7 @@ MaybeLocal<Object> New(Isolate* isolate,
245
232
char * data = nullptr ;
246
233
247
234
if (length > 0 ) {
248
- data = static_cast < char *>( BufferMalloc ( length) );
235
+ data = UncheckedMalloc ( length);
249
236
250
237
if (data == nullptr )
251
238
return Local<Object>();
@@ -261,13 +248,7 @@ MaybeLocal<Object> New(Isolate* isolate,
261
248
}
262
249
}
263
250
264
- Local<Object> buf;
265
- if (New (isolate, data, actual).ToLocal (&buf))
266
- return scope.Escape (buf);
267
-
268
- // Object failed to be created. Clean up resources.
269
- free (data);
270
- return Local<Object>();
251
+ return scope.EscapeMaybe (New (isolate, data, actual));
271
252
}
272
253
273
254
@@ -290,28 +271,16 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
290
271
return Local<Object>();
291
272
}
292
273
293
- void * data ;
274
+ AllocatedBuffer ret (env) ;
294
275
if (length > 0 ) {
295
- data = BufferMalloc (length);
296
- if (data == nullptr )
276
+ ret = env->AllocateManaged (length, false );
277
+ if (ret.data () == nullptr ) {
278
+ THROW_ERR_MEMORY_ALLOCATION_FAILED (env);
297
279
return Local<Object>();
298
- } else {
299
- data = nullptr ;
300
- }
301
-
302
- Local<ArrayBuffer> ab =
303
- ArrayBuffer::New (env->isolate (),
304
- data,
305
- length,
306
- ArrayBufferCreationMode::kInternalized );
307
- MaybeLocal<Uint8Array> ui = Buffer::New (env, ab, 0 , length);
308
-
309
- if (ui.IsEmpty ()) {
310
- // Object failed to be created. Clean up resources.
311
- free (data);
280
+ }
312
281
}
313
282
314
- return scope.Escape (ui. FromMaybe (Local<Uint8Array>() ));
283
+ return scope.EscapeMaybe (ret. ToBuffer ( ));
315
284
}
316
285
317
286
@@ -334,30 +303,18 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
334
303
return Local<Object>();
335
304
}
336
305
337
- void * new_data ;
306
+ AllocatedBuffer ret (env) ;
338
307
if (length > 0 ) {
339
308
CHECK_NOT_NULL (data);
340
- new_data = node::UncheckedMalloc (length);
341
- if (new_data == nullptr )
309
+ ret = env->AllocateManaged (length, false );
310
+ if (ret.data () == nullptr ) {
311
+ THROW_ERR_MEMORY_ALLOCATION_FAILED (env);
342
312
return Local<Object>();
343
- memcpy (new_data, data, length);
344
- } else {
345
- new_data = nullptr ;
346
- }
347
-
348
- Local<ArrayBuffer> ab =
349
- ArrayBuffer::New (env->isolate (),
350
- new_data,
351
- length,
352
- ArrayBufferCreationMode::kInternalized );
353
- MaybeLocal<Uint8Array> ui = Buffer::New (env, ab, 0 , length);
354
-
355
- if (ui.IsEmpty ()) {
356
- // Object failed to be created. Clean up resources.
357
- free (new_data);
313
+ }
314
+ memcpy (ret.data (), data, length);
358
315
}
359
316
360
- return scope.Escape (ui. FromMaybe (Local<Uint8Array>() ));
317
+ return scope.EscapeMaybe (ret. ToBuffer ( ));
361
318
}
362
319
363
320
@@ -403,24 +360,44 @@ MaybeLocal<Object> New(Environment* env,
403
360
return scope.Escape (ui.ToLocalChecked ());
404
361
}
405
362
406
-
363
+ // Warning: This function needs `data` to be allocated with malloc() and not
364
+ // necessarily isolate's ArrayBuffer::Allocator.
407
365
MaybeLocal<Object> New (Isolate* isolate, char * data, size_t length) {
408
366
EscapableHandleScope handle_scope (isolate);
409
367
Environment* env = Environment::GetCurrent (isolate);
410
368
CHECK_NOT_NULL (env); // TODO(addaleax): Handle nullptr here.
411
369
Local<Object> obj;
412
- if (Buffer::New (env, data, length).ToLocal (&obj))
370
+ if (Buffer::New (env, data, length, true ).ToLocal (&obj))
413
371
return handle_scope.Escape (obj);
414
372
return Local<Object>();
415
373
}
416
374
417
-
418
- MaybeLocal<Object> New (Environment* env, char * data, size_t length) {
375
+ // Warning: If this call comes through the public node_buffer.h API,
376
+ // the contract for this function is that `data` is allocated with malloc()
377
+ // and not necessarily isolate's ArrayBuffer::Allocator.
378
+ MaybeLocal<Object> New (Environment* env,
379
+ char * data,
380
+ size_t length,
381
+ bool uses_malloc) {
419
382
if (length > 0 ) {
420
383
CHECK_NOT_NULL (data);
421
384
CHECK (length <= kMaxLength );
422
385
}
423
386
387
+ if (uses_malloc) {
388
+ if (!env->isolate_data ()->uses_node_allocator ()) {
389
+ // We don't know for sure that the allocator is malloc()-based, so we need
390
+ // to fall back to the FreeCallback variant.
391
+ auto free_callback = [](char * data, void * hint) { free (data); };
392
+ return New (env, data, length, free_callback, nullptr );
393
+ } else {
394
+ // This is malloc()-based, so we can acquire it into our own
395
+ // ArrayBufferAllocator.
396
+ CHECK_NOT_NULL (env->isolate_data ()->node_allocator ());
397
+ env->isolate_data ()->node_allocator ()->RegisterPointer (data, length);
398
+ }
399
+ }
400
+
424
401
Local<ArrayBuffer> ab =
425
402
ArrayBuffer::New (env->isolate (),
426
403
data,
@@ -1020,15 +997,13 @@ static void EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
1020
997
1021
998
Local<String> str = args[0 ].As <String>();
1022
999
size_t length = str->Utf8Length (isolate);
1023
- char * data = node::UncheckedMalloc (length);
1000
+ AllocatedBuffer buf = env-> AllocateManaged (length);
1024
1001
str->WriteUtf8 (isolate,
1025
- data,
1002
+ buf. data () ,
1026
1003
-1 , // We are certain that `data` is sufficiently large
1027
1004
nullptr ,
1028
1005
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
1029
- auto array_buf = ArrayBuffer::New (
1030
- isolate, data, length, ArrayBufferCreationMode::kInternalized );
1031
- auto array = Uint8Array::New (array_buf, 0 , length);
1006
+ auto array = Uint8Array::New (buf.ToArrayBuffer (), 0 , length);
1032
1007
args.GetReturnValue ().Set (array);
1033
1008
}
1034
1009
@@ -1055,7 +1030,8 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
1055
1030
env->SetMethod (proto, " ucs2Write" , StringWrite<UCS2>);
1056
1031
env->SetMethod (proto, " utf8Write" , StringWrite<UTF8>);
1057
1032
1058
- if (auto zero_fill_field = env->isolate_data ()->zero_fill_field ()) {
1033
+ if (ArrayBufferAllocator* allocator = env->isolate_data ()->node_allocator ()) {
1034
+ uint32_t * zero_fill_field = allocator->zero_fill_field ();
1059
1035
CHECK (args[1 ]->IsObject ());
1060
1036
auto binding_object = args[1 ].As <Object>();
1061
1037
auto array_buffer = ArrayBuffer::New (env->isolate (),
0 commit comments