Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f6e341a

Browse filesBrowse files
committed
src: improve ToV8Value() functions
- Cache the `isolate` value between calls - Introduce an overload for dealing with integers/numbers - Use the vectored `v8::Array::New` constructor + `MaybeStackBuffer` for faster array creation PR-URL: #25288 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent b9b2ba2 commit f6e341a
Copy full SHA for f6e341a

File tree

Expand file treeCollapse file tree

2 files changed

+53
-17
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+53
-17
lines changed
Open diff view settings
Collapse file

‎src/util-inl.h‎

Copy file name to clipboardExpand all lines: src/util-inl.h
+41-14Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,9 @@ inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc<char>(n); }
377377
void ThrowErrStringTooLong(v8::Isolate* isolate);
378378

379379
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();
382383
if (UNLIKELY(str.size() >= static_cast<size_t>(v8::String::kMaxLength))) {
383384
// V8 only has a TODO comment about adding an exception when the maximum
384385
// string size is exceeded.
@@ -393,33 +394,33 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
393394

394395
template <typename T>
395396
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();
398400
v8::EscapableHandleScope handle_scope(isolate);
399401

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());
401404
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]))
405406
return v8::MaybeLocal<v8::Value>();
406-
}
407407
}
408408

409-
return handle_scope.Escape(arr);
409+
return handle_scope.Escape(v8::Array::New(isolate, arr.out(), arr.length()));
410410
}
411411

412412
template <typename T, typename U>
413413
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();
416417
v8::EscapableHandleScope handle_scope(isolate);
417418

418419
v8::Local<v8::Map> ret = v8::Map::New(isolate);
419420
for (const auto& item : map) {
420421
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) ||
423424
ret->Set(context, first, second).IsEmpty()) {
424425
return v8::MaybeLocal<v8::Value>();
425426
}
@@ -428,6 +429,32 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
428429
return handle_scope.Escape(ret);
429430
}
430431

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+
431458
} // namespace node
432459

433460
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Collapse file

‎src/util.h‎

Copy file name to clipboardExpand all lines: src/util.h
+12-3Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <string.h>
3636

3737
#include <functional> // std::function
38+
#include <limits>
3839
#include <set>
3940
#include <string>
4041
#include <array>
@@ -519,13 +520,21 @@ using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
519520
std::set<std::string> ParseCommaSeparatedSet(const std::string& in);
520521

521522
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
522-
const std::string& str);
523+
const std::string& str,
524+
v8::Isolate* isolate = nullptr);
525+
template <typename T, typename test_for_number =
526+
typename std::enable_if<std::numeric_limits<T>::is_specialized, bool>::type>
527+
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
528+
const T& number,
529+
v8::Isolate* isolate = nullptr);
523530
template <typename T>
524531
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
525-
const std::vector<T>& vec);
532+
const std::vector<T>& vec,
533+
v8::Isolate* isolate = nullptr);
526534
template <typename T, typename U>
527535
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
528-
const std::unordered_map<T, U>& map);
536+
const std::unordered_map<T, U>& map,
537+
v8::Isolate* isolate = nullptr);
529538

530539
// These macros expects a `Isolate* isolate` and a `Local<Context> context`
531540
// to be in the scope.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.