@@ -377,8 +377,9 @@ inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc<char>(n); }
377
377
void ThrowErrStringTooLong (v8::Isolate* isolate);
378
378
379
379
v8::MaybeLocal<v8::Value> ToV8Value (v8::Local<v8::Context> context,
380
- const std::string& str) {
381
- v8::Isolate* isolate = context->GetIsolate ();
380
+ const std::string& str,
381
+ v8::Isolate* isolate) {
382
+ if (isolate == nullptr ) isolate = context->GetIsolate ();
382
383
if (UNLIKELY (str.size () >= static_cast <size_t >(v8::String::kMaxLength ))) {
383
384
// V8 only has a TODO comment about adding an exception when the maximum
384
385
// string size is exceeded.
@@ -393,33 +394,33 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
393
394
394
395
template <typename T>
395
396
v8::MaybeLocal<v8::Value> ToV8Value (v8::Local<v8::Context> context,
396
- const std::vector<T>& vec) {
397
- v8::Isolate* isolate = context->GetIsolate ();
397
+ const std::vector<T>& vec,
398
+ v8::Isolate* isolate) {
399
+ if (isolate == nullptr ) isolate = context->GetIsolate ();
398
400
v8::EscapableHandleScope handle_scope (isolate);
399
401
400
- v8::Local<v8::Array> arr = v8::Array::New (isolate, vec.size ());
402
+ MaybeStackBuffer<v8::Local<v8::Value>, 128 > arr (vec.size ());
403
+ arr.SetLength (vec.size ());
401
404
for (size_t i = 0 ; i < vec.size (); ++i) {
402
- v8::Local<v8::Value> val;
403
- if (!ToV8Value (context, vec[i]).ToLocal (&val) ||
404
- arr->Set (context, i, val).IsNothing ()) {
405
+ if (!ToV8Value (context, vec[i], isolate).ToLocal (&arr[i]))
405
406
return v8::MaybeLocal<v8::Value>();
406
- }
407
407
}
408
408
409
- return handle_scope.Escape (arr);
409
+ return handle_scope.Escape (v8::Array::New (isolate, arr. out (), arr. length ()) );
410
410
}
411
411
412
412
template <typename T, typename U>
413
413
v8::MaybeLocal<v8::Value> ToV8Value (v8::Local<v8::Context> context,
414
- const std::unordered_map<T, U>& map) {
415
- v8::Isolate* isolate = context->GetIsolate ();
414
+ const std::unordered_map<T, U>& map,
415
+ v8::Isolate* isolate) {
416
+ if (isolate == nullptr ) isolate = context->GetIsolate ();
416
417
v8::EscapableHandleScope handle_scope (isolate);
417
418
418
419
v8::Local<v8::Map> ret = v8::Map::New (isolate);
419
420
for (const auto & item : map) {
420
421
v8::Local<v8::Value> first, second;
421
- if (!ToV8Value (context, item.first ).ToLocal (&first) ||
422
- !ToV8Value (context, item.second ).ToLocal (&second) ||
422
+ if (!ToV8Value (context, item.first , isolate ).ToLocal (&first) ||
423
+ !ToV8Value (context, item.second , isolate ).ToLocal (&second) ||
423
424
ret->Set (context, first, second).IsEmpty ()) {
424
425
return v8::MaybeLocal<v8::Value>();
425
426
}
@@ -428,6 +429,32 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
428
429
return handle_scope.Escape (ret);
429
430
}
430
431
432
+ template <typename T, typename >
433
+ v8::MaybeLocal<v8::Value> ToV8Value (v8::Local<v8::Context> context,
434
+ const T& number,
435
+ v8::Isolate* isolate) {
436
+ if (isolate == nullptr ) isolate = context->GetIsolate ();
437
+
438
+ using Limits = std::numeric_limits<T>;
439
+ // Choose Uint32, Int32, or Double depending on range checks.
440
+ // These checks should all collapse at compile time.
441
+ if (static_cast <uint32_t >(Limits::max ()) <=
442
+ std::numeric_limits<uint32_t >::max () &&
443
+ static_cast <uint32_t >(Limits::min ()) >=
444
+ std::numeric_limits<uint32_t >::min () && Limits::is_exact) {
445
+ return v8::Integer::NewFromUnsigned (isolate, static_cast <uint32_t >(number));
446
+ }
447
+
448
+ if (static_cast <int32_t >(Limits::max ()) <=
449
+ std::numeric_limits<int32_t >::max () &&
450
+ static_cast <int32_t >(Limits::min ()) >=
451
+ std::numeric_limits<int32_t >::min () && Limits::is_exact) {
452
+ return v8::Integer::New (isolate, static_cast <int32_t >(number));
453
+ }
454
+
455
+ return v8::Number::New (isolate, static_cast <double >(number));
456
+ }
457
+
431
458
} // namespace node
432
459
433
460
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
0 commit comments