54
54
size_t length = end - start;
55
55
56
56
namespace node {
57
-
58
- namespace {
59
-
60
- inline void * BufferMalloc (size_t length) {
61
- return per_process::cli_options->zero_fill_all_buffers ?
62
- node::UncheckedCalloc (length) :
63
- node::UncheckedMalloc (length);
64
- }
65
-
66
- } // namespace
67
-
68
57
namespace Buffer {
69
58
70
59
using v8::ArrayBuffer;
@@ -260,7 +249,7 @@ MaybeLocal<Object> New(Isolate* isolate,
260
249
char * data = nullptr ;
261
250
262
251
if (length > 0 ) {
263
- data = static_cast < char *>( BufferMalloc ( length) );
252
+ data = UncheckedMalloc ( length);
264
253
265
254
if (data == nullptr ) {
266
255
THROW_ERR_MEMORY_ALLOCATION_FAILED (isolate);
@@ -278,13 +267,7 @@ MaybeLocal<Object> New(Isolate* isolate,
278
267
}
279
268
}
280
269
281
- Local<Object> buf;
282
- if (New (isolate, data, actual).ToLocal (&buf))
283
- return scope.Escape (buf);
284
-
285
- // Object failed to be created. Clean up resources.
286
- free (data);
287
- return Local<Object>();
270
+ return scope.EscapeMaybe (New (isolate, data, actual));
288
271
}
289
272
290
273
@@ -311,26 +294,16 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
311
294
return Local<Object>();
312
295
}
313
296
314
- void * data ;
297
+ AllocatedBuffer ret (env) ;
315
298
if (length > 0 ) {
316
- data = BufferMalloc (length);
317
- if (data == nullptr ) {
299
+ ret = env-> AllocateManaged (length, false );
300
+ if (ret. data () == nullptr ) {
318
301
THROW_ERR_MEMORY_ALLOCATION_FAILED (env);
319
302
return Local<Object>();
320
303
}
321
- } else {
322
- data = nullptr ;
323
304
}
324
305
325
- Local<ArrayBuffer> ab =
326
- ArrayBuffer::New (env->isolate (),
327
- data,
328
- length,
329
- ArrayBufferCreationMode::kInternalized );
330
- Local<Object> obj;
331
- if (Buffer::New (env, ab, 0 , length).ToLocal (&obj))
332
- return scope.Escape (obj);
333
- return Local<Object>();
306
+ return scope.EscapeMaybe (ret.ToBuffer ());
334
307
}
335
308
336
309
@@ -357,28 +330,18 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
357
330
return Local<Object>();
358
331
}
359
332
360
- void * new_data ;
333
+ AllocatedBuffer ret (env) ;
361
334
if (length > 0 ) {
362
335
CHECK_NOT_NULL (data);
363
- new_data = node::UncheckedMalloc (length);
364
- if (new_data == nullptr ) {
336
+ ret = env-> AllocateManaged (length, false );
337
+ if (ret. data () == nullptr ) {
365
338
THROW_ERR_MEMORY_ALLOCATION_FAILED (env);
366
339
return Local<Object>();
367
340
}
368
- memcpy (new_data, data, length);
369
- } else {
370
- new_data = nullptr ;
341
+ memcpy (ret.data (), data, length);
371
342
}
372
343
373
- Local<ArrayBuffer> ab =
374
- ArrayBuffer::New (env->isolate (),
375
- new_data,
376
- length,
377
- ArrayBufferCreationMode::kInternalized );
378
- Local<Object> obj;
379
- if (Buffer::New (env, ab, 0 , length).ToLocal (&obj))
380
- return scope.Escape (obj);
381
- return Local<Object>();
344
+ return scope.EscapeMaybe (ret.ToBuffer ());
382
345
}
383
346
384
347
@@ -425,7 +388,8 @@ MaybeLocal<Object> New(Environment* env,
425
388
return scope.Escape (ui.ToLocalChecked ());
426
389
}
427
390
428
-
391
+ // Warning: This function needs `data` to be allocated with malloc() and not
392
+ // necessarily isolate's ArrayBuffer::Allocator.
429
393
MaybeLocal<Object> New (Isolate* isolate, char * data, size_t length) {
430
394
EscapableHandleScope handle_scope (isolate);
431
395
Environment* env = Environment::GetCurrent (isolate);
@@ -435,18 +399,37 @@ MaybeLocal<Object> New(Isolate* isolate, char* data, size_t length) {
435
399
return MaybeLocal<Object>();
436
400
}
437
401
Local<Object> obj;
438
- if (Buffer::New (env, data, length).ToLocal (&obj))
402
+ if (Buffer::New (env, data, length, true ).ToLocal (&obj))
439
403
return handle_scope.Escape (obj);
440
404
return Local<Object>();
441
405
}
442
406
443
-
444
- MaybeLocal<Object> New (Environment* env, char * data, size_t length) {
407
+ // Warning: If this call comes through the public node_buffer.h API,
408
+ // the contract for this function is that `data` is allocated with malloc()
409
+ // and not necessarily isolate's ArrayBuffer::Allocator.
410
+ MaybeLocal<Object> New (Environment* env,
411
+ char * data,
412
+ size_t length,
413
+ bool uses_malloc) {
445
414
if (length > 0 ) {
446
415
CHECK_NOT_NULL (data);
447
416
CHECK (length <= kMaxLength );
448
417
}
449
418
419
+ if (uses_malloc) {
420
+ if (env->isolate_data ()->uses_node_allocator ()) {
421
+ // We don't know for sure that the allocator is malloc()-based, so we need
422
+ // to fall back to the FreeCallback variant.
423
+ auto free_callback = [](char * data, void * hint) { free (data); };
424
+ return New (env, data, length, free_callback, nullptr );
425
+ } else {
426
+ // This is malloc()-based, so we can acquire it into our own
427
+ // ArrayBufferAllocator.
428
+ CHECK_NOT_NULL (env->isolate_data ()->node_allocator ());
429
+ env->isolate_data ()->node_allocator ()->RegisterPointer (data, length);
430
+ }
431
+ }
432
+
450
433
Local<ArrayBuffer> ab =
451
434
ArrayBuffer::New (env->isolate (),
452
435
data,
@@ -1053,15 +1036,13 @@ static void EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
1053
1036
1054
1037
Local<String> str = args[0 ].As <String>();
1055
1038
size_t length = str->Utf8Length (isolate);
1056
- char * data = node::UncheckedMalloc (length);
1039
+ AllocatedBuffer buf = env-> AllocateManaged (length);
1057
1040
str->WriteUtf8 (isolate,
1058
- data,
1041
+ buf. data () ,
1059
1042
-1 , // We are certain that `data` is sufficiently large
1060
1043
nullptr ,
1061
1044
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
1062
- auto array_buf = ArrayBuffer::New (
1063
- isolate, data, length, ArrayBufferCreationMode::kInternalized );
1064
- auto array = Uint8Array::New (array_buf, 0 , length);
1045
+ auto array = Uint8Array::New (buf.ToArrayBuffer (), 0 , length);
1065
1046
args.GetReturnValue ().Set (array);
1066
1047
}
1067
1048
@@ -1123,7 +1104,8 @@ void Initialize(Local<Object> target,
1123
1104
1124
1105
// It can be a nullptr when running inside an isolate where we
1125
1106
// do not own the ArrayBuffer allocator.
1126
- if (uint32_t * zero_fill_field = env->isolate_data ()->zero_fill_field ()) {
1107
+ if (ArrayBufferAllocator* allocator = env->isolate_data ()->node_allocator ()) {
1108
+ uint32_t * zero_fill_field = allocator->zero_fill_field ();
1127
1109
Local<ArrayBuffer> array_buffer = ArrayBuffer::New (
1128
1110
env->isolate (), zero_fill_field, sizeof (*zero_fill_field));
1129
1111
CHECK (target
0 commit comments