Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/nodejs/src/util.h
$ cat -n /usr/include/nodejs/src/util.h 1 // Copyright Joyent, Inc. and other Node contributors. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a 4 // copy of this software and associated documentation files (the 5 // "Software"), to deal in the Software without restriction, including 6 // without limitation the rights to use, copy, modify, merge, publish, 7 // distribute, sublicense, and/or sell copies of the Software, and to permit 8 // persons to whom the Software is furnished to do so, subject to the 9 // following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included 12 // in all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 #ifndef SRC_UTIL_H_ 23 #define SRC_UTIL_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "v8.h" 28 29 #include "node.h" 30 31 #include
32 #include
33 #include
34 #include
35 #include
36 37 #include
38 #include
39 #include
40 #include
41 #include
42 #include
43 #include
44 #include
45 #include
46 #include
47 48 #ifdef __GNUC__ 49 #define MUST_USE_RESULT __attribute__((warn_unused_result)) 50 #else 51 #define MUST_USE_RESULT 52 #endif 53 54 namespace node { 55 56 // Maybe remove kPathSeparator when cpp17 is ready 57 #ifdef _WIN32 58 constexpr char kPathSeparator = '\\'; 59 /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ 60 #define PATH_MAX_BYTES (MAX_PATH * 4) 61 #else 62 constexpr char kPathSeparator = '/'; 63 #define PATH_MAX_BYTES (PATH_MAX) 64 #endif 65 66 // These should be used in our code as opposed to the native 67 // versions as they abstract out some platform and or 68 // compiler version specific functionality 69 // malloc(0) and realloc(ptr, 0) have implementation-defined behavior in 70 // that the standard allows them to either return a unique pointer or a 71 // nullptr for zero-sized allocation requests. Normalize by always using 72 // a nullptr. 73 template
74 inline T* UncheckedRealloc(T* pointer, size_t n); 75 template
76 inline T* UncheckedMalloc(size_t n); 77 template
78 inline T* UncheckedCalloc(size_t n); 79 80 // Same things, but aborts immediately instead of returning nullptr when 81 // no memory is available. 82 template
83 inline T* Realloc(T* pointer, size_t n); 84 template
85 inline T* Malloc(size_t n); 86 template
87 inline T* Calloc(size_t n); 88 89 inline char* Malloc(size_t n); 90 inline char* Calloc(size_t n); 91 inline char* UncheckedMalloc(size_t n); 92 inline char* UncheckedCalloc(size_t n); 93 94 template
95 inline T MultiplyWithOverflowCheck(T a, T b); 96 97 namespace per_process { 98 // Tells whether the per-process V8::Initialize() is called and 99 // if it is safe to call v8::Isolate::TryGetCurrent(). 100 extern bool v8_initialized; 101 } // namespace per_process 102 103 // Used by the allocation functions when allocation fails. 104 // Thin wrapper around v8::Isolate::LowMemoryNotification() that checks 105 // whether V8 is initialized. 106 void LowMemoryNotification(); 107 108 // The reason that Assert() takes a struct argument instead of individual 109 // const char*s is to ease instruction cache pressure in calls from CHECK. 110 struct AssertionInfo { 111 const char* file_line; // filename:line 112 const char* message; 113 const char* function; 114 }; 115 [[noreturn]] void NODE_EXTERN_PRIVATE Assert(const AssertionInfo& info); 116 [[noreturn]] void NODE_EXTERN_PRIVATE Abort(); 117 void DumpBacktrace(FILE* fp); 118 119 // Windows 8+ does not like abort() in Release mode 120 #ifdef _WIN32 121 #define ABORT_NO_BACKTRACE() _exit(134) 122 #else 123 #define ABORT_NO_BACKTRACE() abort() 124 #endif 125 126 #define ABORT() node::Abort() 127 128 #define ERROR_AND_ABORT(expr) \ 129 do { \ 130 /* Make sure that this struct does not end up in inline code, but */ \ 131 /* rather in a read-only data section when modifying this code. */ \ 132 static const node::AssertionInfo args = { \ 133 __FILE__ ":" STRINGIFY(__LINE__), #expr, PRETTY_FUNCTION_NAME \ 134 }; \ 135 node::Assert(args); \ 136 } while (0) 137 138 #ifdef __GNUC__ 139 #define LIKELY(expr) __builtin_expect(!!(expr), 1) 140 #define UNLIKELY(expr) __builtin_expect(!!(expr), 0) 141 #define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__ 142 #else 143 #define LIKELY(expr) expr 144 #define UNLIKELY(expr) expr 145 #define PRETTY_FUNCTION_NAME "" 146 #endif 147 148 #define STRINGIFY_(x) #x 149 #define STRINGIFY(x) STRINGIFY_(x) 150 151 #define CHECK(expr) \ 152 do { \ 153 if (UNLIKELY(!(expr))) { \ 154 ERROR_AND_ABORT(expr); \ 155 } \ 156 } while (0) 157 158 #define CHECK_EQ(a, b) CHECK((a) == (b)) 159 #define CHECK_GE(a, b) CHECK((a) >= (b)) 160 #define CHECK_GT(a, b) CHECK((a) > (b)) 161 #define CHECK_LE(a, b) CHECK((a) <= (b)) 162 #define CHECK_LT(a, b) CHECK((a) < (b)) 163 #define CHECK_NE(a, b) CHECK((a) != (b)) 164 #define CHECK_NULL(val) CHECK((val) == nullptr) 165 #define CHECK_NOT_NULL(val) CHECK((val) != nullptr) 166 #define CHECK_IMPLIES(a, b) CHECK(!(a) || (b)) 167 168 #ifdef DEBUG 169 #define DCHECK(expr) CHECK(expr) 170 #define DCHECK_EQ(a, b) CHECK((a) == (b)) 171 #define DCHECK_GE(a, b) CHECK((a) >= (b)) 172 #define DCHECK_GT(a, b) CHECK((a) > (b)) 173 #define DCHECK_LE(a, b) CHECK((a) <= (b)) 174 #define DCHECK_LT(a, b) CHECK((a) < (b)) 175 #define DCHECK_NE(a, b) CHECK((a) != (b)) 176 #define DCHECK_NULL(val) CHECK((val) == nullptr) 177 #define DCHECK_NOT_NULL(val) CHECK((val) != nullptr) 178 #define DCHECK_IMPLIES(a, b) CHECK(!(a) || (b)) 179 #else 180 #define DCHECK(expr) 181 #define DCHECK_EQ(a, b) 182 #define DCHECK_GE(a, b) 183 #define DCHECK_GT(a, b) 184 #define DCHECK_LE(a, b) 185 #define DCHECK_LT(a, b) 186 #define DCHECK_NE(a, b) 187 #define DCHECK_NULL(val) 188 #define DCHECK_NOT_NULL(val) 189 #define DCHECK_IMPLIES(a, b) 190 #endif 191 192 193 #define UNREACHABLE(...) \ 194 ERROR_AND_ABORT("Unreachable code reached" __VA_OPT__(": ") __VA_ARGS__) 195 196 // ECMA262 20.1.2.6 Number.MAX_SAFE_INTEGER (2^53-1) 197 constexpr int64_t kMaxSafeJsInteger = 9007199254740991; 198 199 inline bool IsSafeJsInt(v8::Local
v); 200 201 // TAILQ-style intrusive list node. 202 template
203 class ListNode; 204 205 // TAILQ-style intrusive list head. 206 template
(T::*M)> 207 class ListHead; 208 209 template
210 class ListNode { 211 public: 212 inline ListNode(); 213 inline ~ListNode(); 214 inline void Remove(); 215 inline bool IsEmpty() const; 216 217 ListNode(const ListNode&) = delete; 218 ListNode& operator=(const ListNode&) = delete; 219 220 private: 221 template
(U::*M)> friend class ListHead; 222 friend int GenDebugSymbols(); 223 ListNode* prev_; 224 ListNode* next_; 225 }; 226 227 template
(T::*M)> 228 class ListHead { 229 public: 230 class Iterator { 231 public: 232 inline T* operator*() const; 233 inline const Iterator& operator++(); 234 inline bool operator!=(const Iterator& that) const; 235 236 private: 237 friend class ListHead; 238 inline explicit Iterator(ListNode
* node); 239 ListNode
* node_; 240 }; 241 242 inline ListHead() = default; 243 inline ~ListHead(); 244 inline void PushBack(T* element); 245 inline void PushFront(T* element); 246 inline bool IsEmpty() const; 247 inline T* PopFront(); 248 inline Iterator begin() const; 249 inline Iterator end() const; 250 251 ListHead(const ListHead&) = delete; 252 ListHead& operator=(const ListHead&) = delete; 253 254 private: 255 friend int GenDebugSymbols(); 256 ListNode
head_; 257 }; 258 259 // The helper is for doing safe downcasts from base types to derived types. 260 template
261 class ContainerOfHelper { 262 public: 263 inline ContainerOfHelper(Inner Outer::*field, Inner* pointer); 264 template
265 inline operator TypeName*() const; 266 private: 267 Outer* const pointer_; 268 }; 269 270 // Calculate the address of the outer (i.e. embedding) struct from 271 // the interior pointer to a data member. 272 template
273 constexpr ContainerOfHelper
ContainerOf(Inner Outer::*field, 274 Inner* pointer); 275 276 class KVStore { 277 public: 278 KVStore() = default; 279 virtual ~KVStore() = default; 280 KVStore(const KVStore&) = delete; 281 KVStore& operator=(const KVStore&) = delete; 282 KVStore(KVStore&&) = delete; 283 KVStore& operator=(KVStore&&) = delete; 284 285 virtual v8::MaybeLocal
Get(v8::Isolate* isolate, 286 v8::Local
key) const = 0; 287 virtual v8::Maybe
Get(const char* key) const = 0; 288 virtual void Set(v8::Isolate* isolate, 289 v8::Local
key, 290 v8::Local
value) = 0; 291 virtual int32_t Query(v8::Isolate* isolate, 292 v8::Local
key) const = 0; 293 virtual int32_t Query(const char* key) const = 0; 294 virtual void Delete(v8::Isolate* isolate, v8::Local
key) = 0; 295 virtual v8::Local
Enumerate(v8::Isolate* isolate) const = 0; 296 297 virtual std::shared_ptr
Clone(v8::Isolate* isolate) const; 298 virtual v8::Maybe
AssignFromObject(v8::Local
context, 299 v8::Local
entries); 300 v8::Maybe
AssignToObject(v8::Isolate* isolate, 301 v8::Local
context, 302 v8::Local
object); 303 304 static std::shared_ptr
CreateMapKVStore(); 305 }; 306 307 // Convenience wrapper around v8::String::NewFromOneByte(). 308 inline v8::Local
OneByteString(v8::Isolate* isolate, 309 const char* data, 310 int length = -1); 311 312 // For the people that compile with -funsigned-char. 313 inline v8::Local
OneByteString(v8::Isolate* isolate, 314 const signed char* data, 315 int length = -1); 316 317 inline v8::Local
OneByteString(v8::Isolate* isolate, 318 const unsigned char* data, 319 int length = -1); 320 321 // Used to be a macro, hence the uppercase name. 322 template
323 inline v8::Local
FIXED_ONE_BYTE_STRING( 324 v8::Isolate* isolate, 325 const char(&data)[N]) { 326 return OneByteString(isolate, data, N - 1); 327 } 328 329 template
330 inline v8::Local
FIXED_ONE_BYTE_STRING( 331 v8::Isolate* isolate, 332 const std::array
& arr) { 333 return OneByteString(isolate, arr.data(), N - 1); 334 } 335 336 337 338 // Swaps bytes in place. nbytes is the number of bytes to swap and must be a 339 // multiple of the word size (checked by function). 340 inline void SwapBytes16(char* data, size_t nbytes); 341 inline void SwapBytes32(char* data, size_t nbytes); 342 inline void SwapBytes64(char* data, size_t nbytes); 343 344 // tolower() is locale-sensitive. Use ToLower() instead. 345 inline char ToLower(char c); 346 inline std::string ToLower(const std::string& in); 347 348 // toupper() is locale-sensitive. Use ToUpper() instead. 349 inline char ToUpper(char c); 350 inline std::string ToUpper(const std::string& in); 351 352 // strcasecmp() is locale-sensitive. Use StringEqualNoCase() instead. 353 inline bool StringEqualNoCase(const char* a, const char* b); 354 355 // strncasecmp() is locale-sensitive. Use StringEqualNoCaseN() instead. 356 inline bool StringEqualNoCaseN(const char* a, const char* b, size_t length); 357 358 template
359 constexpr size_t arraysize(const T (&)[N]) { 360 return N; 361 } 362 363 template
364 constexpr size_t strsize(const T (&)[N]) { 365 return N - 1; 366 } 367 368 // Allocates an array of member type T. For up to kStackStorageSize items, 369 // the stack is used, otherwise malloc(). 370 template
371 class MaybeStackBuffer { 372 public: 373 const T* out() const { 374 return buf_; 375 } 376 377 T* out() { 378 return buf_; 379 } 380 381 // operator* for compatibility with `v8::String::(Utf8)Value` 382 T* operator*() { 383 return buf_; 384 } 385 386 const T* operator*() const { 387 return buf_; 388 } 389 390 T& operator[](size_t index) { 391 CHECK_LT(index, length()); 392 return buf_[index]; 393 } 394 395 const T& operator[](size_t index) const { 396 CHECK_LT(index, length()); 397 return buf_[index]; 398 } 399 400 size_t length() const { 401 return length_; 402 } 403 404 // Current maximum capacity of the buffer with which SetLength() can be used 405 // without first calling AllocateSufficientStorage(). 406 size_t capacity() const { 407 return capacity_; 408 } 409 410 // Make sure enough space for `storage` entries is available. 411 // This method can be called multiple times throughout the lifetime of the 412 // buffer, but once this has been called Invalidate() cannot be used. 413 // Content of the buffer in the range [0, length()) is preserved. 414 void AllocateSufficientStorage(size_t storage); 415 416 void SetLength(size_t length) { 417 // capacity() returns how much memory is actually available. 418 CHECK_LE(length, capacity()); 419 length_ = length; 420 } 421 422 void SetLengthAndZeroTerminate(size_t length) { 423 // capacity() returns how much memory is actually available. 424 CHECK_LE(length + 1, capacity()); 425 SetLength(length); 426 427 // T() is 0 for integer types, nullptr for pointers, etc. 428 buf_[length] = T(); 429 } 430 431 // Make dereferencing this object return nullptr. 432 // This method can be called multiple times throughout the lifetime of the 433 // buffer, but once this has been called AllocateSufficientStorage() cannot 434 // be used. 435 void Invalidate() { 436 CHECK(!IsAllocated()); 437 capacity_ = 0; 438 length_ = 0; 439 buf_ = nullptr; 440 } 441 442 // If the buffer is stored in the heap rather than on the stack. 443 bool IsAllocated() const { 444 return !IsInvalidated() && buf_ != buf_st_; 445 } 446 447 // If Invalidate() has been called. 448 bool IsInvalidated() const { 449 return buf_ == nullptr; 450 } 451 452 // Release ownership of the malloc'd buffer. 453 // Note: This does not free the buffer. 454 void Release() { 455 CHECK(IsAllocated()); 456 buf_ = buf_st_; 457 length_ = 0; 458 capacity_ = arraysize(buf_st_); 459 } 460 461 MaybeStackBuffer() 462 : length_(0), capacity_(arraysize(buf_st_)), buf_(buf_st_) { 463 // Default to a zero-length, null-terminated buffer. 464 buf_[0] = T(); 465 } 466 467 explicit MaybeStackBuffer(size_t storage) : MaybeStackBuffer() { 468 AllocateSufficientStorage(storage); 469 } 470 471 ~MaybeStackBuffer() { 472 if (IsAllocated()) 473 free(buf_); 474 } 475 476 inline std::basic_string
ToString() const { return {out(), length()}; } 477 inline std::basic_string_view
ToStringView() const { 478 return {out(), length()}; 479 } 480 481 private: 482 size_t length_; 483 // capacity of the malloc'ed buf_ 484 size_t capacity_; 485 T* buf_; 486 T buf_st_[kStackStorageSize]; 487 }; 488 489 // Provides access to an ArrayBufferView's storage, either the original, 490 // or for small data, a copy of it. This object's lifetime is bound to the 491 // original ArrayBufferView's lifetime. 492 template
493 class ArrayBufferViewContents { 494 public: 495 ArrayBufferViewContents() = default; 496 497 ArrayBufferViewContents(const ArrayBufferViewContents&) = delete; 498 void operator=(const ArrayBufferViewContents&) = delete; 499 500 explicit inline ArrayBufferViewContents(v8::Local
value); 501 explicit inline ArrayBufferViewContents(v8::Local
value); 502 explicit inline ArrayBufferViewContents(v8::Local
abv); 503 inline void Read(v8::Local
abv); 504 inline void ReadValue(v8::Local
buf); 505 506 inline bool WasDetached() const { return was_detached_; } 507 inline const T* data() const { return data_; } 508 inline size_t length() const { return length_; } 509 510 private: 511 // Declaring operator new and delete as deleted is not spec compliant. 512 // Therefore, declare them private instead to disable dynamic alloc. 513 void* operator new(size_t size); 514 void* operator new[](size_t size); 515 void operator delete(void*, size_t); 516 void operator delete[](void*, size_t); 517 518 T stack_storage_[kStackStorageSize]; 519 T* data_ = nullptr; 520 size_t length_ = 0; 521 bool was_detached_ = false; 522 }; 523 524 class Utf8Value : public MaybeStackBuffer
{ 525 public: 526 explicit Utf8Value(v8::Isolate* isolate, v8::Local
value); 527 528 inline bool operator==(const char* a) const { return strcmp(out(), a) == 0; } 529 inline bool operator!=(const char* a) const { return !(*this == a); } 530 }; 531 532 class TwoByteValue : public MaybeStackBuffer
{ 533 public: 534 explicit TwoByteValue(v8::Isolate* isolate, v8::Local
value); 535 }; 536 537 class BufferValue : public MaybeStackBuffer
{ 538 public: 539 explicit BufferValue(v8::Isolate* isolate, v8::Local
value); 540 541 inline std::string ToString() const { return std::string(out(), length()); } 542 }; 543 544 #define SPREAD_BUFFER_ARG(val, name) \ 545 CHECK((val)->IsArrayBufferView()); \ 546 v8::Local
name = (val).As
(); \ 547 const size_t name##_offset = name->ByteOffset(); \ 548 const size_t name##_length = name->ByteLength(); \ 549 char* const name##_data = \ 550 static_cast
(name->Buffer()->Data()) + name##_offset; \ 551 if (name##_length > 0) CHECK_NE(name##_data, nullptr); 552 553 // Use this when a variable or parameter is unused in order to explicitly 554 // silence a compiler warning about that. 555 template
inline void USE(T&&) {} 556 557 template
558 struct OnScopeLeaveImpl { 559 Fn fn_; 560 bool active_; 561 562 explicit OnScopeLeaveImpl(Fn&& fn) : fn_(std::move(fn)), active_(true) {} 563 ~OnScopeLeaveImpl() { if (active_) fn_(); } 564 565 OnScopeLeaveImpl(const OnScopeLeaveImpl& other) = delete; 566 OnScopeLeaveImpl& operator=(const OnScopeLeaveImpl& other) = delete; 567 OnScopeLeaveImpl(OnScopeLeaveImpl&& other) 568 : fn_(std::move(other.fn_)), active_(other.active_) { 569 other.active_ = false; 570 } 571 }; 572 573 // Run a function when exiting the current scope. Used like this: 574 // auto on_scope_leave = OnScopeLeave([&] { 575 // // ... run some code ... 576 // }); 577 template
578 inline MUST_USE_RESULT OnScopeLeaveImpl
OnScopeLeave(Fn&& fn) { 579 return OnScopeLeaveImpl
{std::move(fn)}; 580 } 581 582 // Simple RAII wrapper for contiguous data that uses malloc()/free(). 583 template
584 struct MallocedBuffer { 585 T* data; 586 size_t size; 587 588 T* release() { 589 T* ret = data; 590 data = nullptr; 591 return ret; 592 } 593 594 void Truncate(size_t new_size) { 595 CHECK_LE(new_size, size); 596 size = new_size; 597 } 598 599 void Realloc(size_t new_size) { 600 Truncate(new_size); 601 data = UncheckedRealloc(data, new_size); 602 } 603 604 bool is_empty() const { return data == nullptr; } 605 606 MallocedBuffer() : data(nullptr), size(0) {} 607 explicit MallocedBuffer(size_t size) : data(Malloc
(size)), size(size) {} 608 MallocedBuffer(T* data, size_t size) : data(data), size(size) {} 609 MallocedBuffer(MallocedBuffer&& other) : data(other.data), size(other.size) { 610 other.data = nullptr; 611 } 612 MallocedBuffer& operator=(MallocedBuffer&& other) { 613 this->~MallocedBuffer(); 614 return *new(this) MallocedBuffer(std::move(other)); 615 } 616 ~MallocedBuffer() { 617 free(data); 618 } 619 MallocedBuffer(const MallocedBuffer&) = delete; 620 MallocedBuffer& operator=(const MallocedBuffer&) = delete; 621 }; 622 623 template
624 class NonCopyableMaybe { 625 public: 626 NonCopyableMaybe() : empty_(true) {} 627 explicit NonCopyableMaybe(T&& value) 628 : empty_(false), 629 value_(std::move(value)) {} 630 631 bool IsEmpty() const { 632 return empty_; 633 } 634 635 const T* get() const { 636 return empty_ ? nullptr : &value_; 637 } 638 639 const T* operator->() const { 640 CHECK(!empty_); 641 return &value_; 642 } 643 644 T&& Release() { 645 CHECK_EQ(empty_, false); 646 empty_ = true; 647 return std::move(value_); 648 } 649 650 private: 651 bool empty_; 652 T value_; 653 }; 654 655 // Test whether some value can be called with (). 656 template
657 struct is_callable : std::is_function
{ }; 658 659 template
660 struct is_callable
::value 662 >::type> : std::true_type { }; 663 664 template
665 struct FunctionDeleter { 666 void operator()(T* pointer) const { function(pointer); } 667 typedef std::unique_ptr
Pointer; 668 }; 669 670 template
671 using DeleteFnPtr = typename FunctionDeleter
::Pointer; 672 673 std::vector
SplitString(const std::string_view in, 674 const std::string_view delim); 675 676 inline v8::MaybeLocal
ToV8Value(v8::Local
context, 677 std::string_view str, 678 v8::Isolate* isolate = nullptr); 679 template
::is_specialized, bool>::type> 681 inline v8::MaybeLocal
ToV8Value(v8::Local
context, 682 const T& number, 683 v8::Isolate* isolate = nullptr); 684 template
685 inline v8::MaybeLocal
ToV8Value(v8::Local
context, 686 const std::vector
& vec, 687 v8::Isolate* isolate = nullptr); 688 template
689 inline v8::MaybeLocal
ToV8Value(v8::Local
context, 690 const std::set
& set, 691 v8::Isolate* isolate = nullptr); 692 template
693 inline v8::MaybeLocal
ToV8Value(v8::Local
context, 694 const std::unordered_map
& map, 695 v8::Isolate* isolate = nullptr); 696 697 // These macros expects a `Isolate* isolate` and a `Local
context` 698 // to be in the scope. 699 #define READONLY_PROPERTY(obj, name, value) \ 700 do { \ 701 obj->DefineOwnProperty( \ 702 context, FIXED_ONE_BYTE_STRING(isolate, name), value, v8::ReadOnly) \ 703 .Check(); \ 704 } while (0) 705 706 #define READONLY_DONT_ENUM_PROPERTY(obj, name, var) \ 707 do { \ 708 obj->DefineOwnProperty( \ 709 context, \ 710 OneByteString(isolate, name), \ 711 var, \ 712 static_cast
(v8::ReadOnly | v8::DontEnum)) \ 713 .Check(); \ 714 } while (0) 715 716 #define READONLY_FALSE_PROPERTY(obj, name) \ 717 READONLY_PROPERTY(obj, name, v8::False(isolate)) 718 719 #define READONLY_TRUE_PROPERTY(obj, name) \ 720 READONLY_PROPERTY(obj, name, v8::True(isolate)) 721 722 #define READONLY_STRING_PROPERTY(obj, name, str) \ 723 READONLY_PROPERTY(obj, name, ToV8Value(context, str).ToLocalChecked()) 724 725 // Variation on NODE_DEFINE_CONSTANT that sets a String value. 726 #define NODE_DEFINE_STRING_CONSTANT(target, name, constant) \ 727 do { \ 728 v8::Isolate* isolate = target->GetIsolate(); \ 729 v8::Local
constant_name = \ 730 v8::String::NewFromUtf8(isolate, name).ToLocalChecked(); \ 731 v8::Local
constant_value = \ 732 v8::String::NewFromUtf8(isolate, constant).ToLocalChecked(); \ 733 v8::PropertyAttribute constant_attributes = \ 734 static_cast
(v8::ReadOnly | v8::DontDelete); \ 735 target \ 736 ->DefineOwnProperty(isolate->GetCurrentContext(), \ 737 constant_name, \ 738 constant_value, \ 739 constant_attributes) \ 740 .Check(); \ 741 } while (0) 742 743 enum class Endianness { LITTLE, BIG }; 744 745 inline Endianness GetEndianness() { 746 // Constant-folded by the compiler. 747 const union { 748 uint8_t u8[2]; 749 uint16_t u16; 750 } u = {{1, 0}}; 751 return u.u16 == 1 ? Endianness::LITTLE : Endianness::BIG; 752 } 753 754 inline bool IsLittleEndian() { 755 return GetEndianness() == Endianness::LITTLE; 756 } 757 758 inline bool IsBigEndian() { 759 return GetEndianness() == Endianness::BIG; 760 } 761 762 // Round up a to the next highest multiple of b. 763 template
764 constexpr T RoundUp(T a, T b) { 765 return a % b != 0 ? a + b - (a % b) : a; 766 } 767 768 // Align ptr to an `alignment`-bytes boundary. 769 template
770 constexpr T* AlignUp(T* ptr, U alignment) { 771 return reinterpret_cast
( 772 RoundUp(reinterpret_cast
(ptr), alignment)); 773 } 774 775 class SlicedArguments : public MaybeStackBuffer
> { 776 public: 777 inline explicit SlicedArguments( 778 const v8::FunctionCallbackInfo
& args, size_t start = 0); 779 }; 780 781 // Convert a v8::PersistentBase, e.g. v8::Global, to a Local, with an extra 782 // optimization for strong persistent handles. 783 class PersistentToLocal { 784 public: 785 // If persistent.IsWeak() == false, then do not call persistent.Reset() 786 // while the returned Local
is still in scope, it will destroy the 787 // reference to the object. 788 template
789 static inline v8::Local
Default( 790 v8::Isolate* isolate, 791 const v8::PersistentBase
& persistent) { 792 if (persistent.IsWeak()) { 793 return PersistentToLocal::Weak(isolate, persistent); 794 } else { 795 return PersistentToLocal::Strong(persistent); 796 } 797 } 798 799 // Unchecked conversion from a non-weak Persistent
to Local
, 800 // use with care! 801 // 802 // Do not call persistent.Reset() while the returned Local
is still in 803 // scope, it will destroy the reference to the object. 804 template
805 static inline v8::Local
Strong( 806 const v8::PersistentBase
& persistent) { 807 DCHECK(!persistent.IsWeak()); 808 return *reinterpret_cast
*>( 809 const_cast
*>(&persistent)); 810 } 811 812 template
813 static inline v8::Local
Weak( 814 v8::Isolate* isolate, 815 const v8::PersistentBase
& persistent) { 816 return v8::Local
::New(isolate, persistent); 817 } 818 }; 819 820 // Can be used as a key for std::unordered_map when lookup performance is more 821 // important than size and the keys are statically used to avoid redundant hash 822 // computations. 823 class FastStringKey { 824 public: 825 constexpr explicit FastStringKey(std::string_view name); 826 827 struct Hash { 828 constexpr size_t operator()(const FastStringKey& key) const; 829 }; 830 constexpr bool operator==(const FastStringKey& other) const; 831 832 constexpr std::string_view as_string_view() const; 833 834 private: 835 static constexpr size_t HashImpl(std::string_view str); 836 837 const std::string_view name_; 838 const size_t cached_hash_; 839 }; 840 841 // Like std::static_pointer_cast but for unique_ptr with the default deleter. 842 template
843 std::unique_ptr
static_unique_pointer_cast(std::unique_ptr
&& ptr) { 844 return std::unique_ptr
(static_cast
(ptr.release())); 845 } 846 847 #define MAYBE_FIELD_PTR(ptr, field) ptr == nullptr ? nullptr : &(ptr->field) 848 849 // Returns a non-zero code if it fails to open or read the file, 850 // aborts if it fails to close the file. 851 int ReadFileSync(std::string* result, const char* path); 852 853 v8::Local
NewFunctionTemplate( 854 v8::Isolate* isolate, 855 v8::FunctionCallback callback, 856 v8::Local
signature = v8::Local
(), 857 v8::ConstructorBehavior behavior = v8::ConstructorBehavior::kAllow, 858 v8::SideEffectType side_effect = v8::SideEffectType::kHasSideEffect, 859 const v8::CFunction* c_function = nullptr); 860 861 // Convenience methods for NewFunctionTemplate(). 862 void SetMethod(v8::Local
context, 863 v8::Local
that, 864 const char* name, 865 v8::FunctionCallback callback); 866 // Similar to SetProtoMethod but without receiver signature checks. 867 void SetMethod(v8::Isolate* isolate, 868 v8::Local
that, 869 const char* name, 870 v8::FunctionCallback callback); 871 872 void SetFastMethod(v8::Local
context, 873 v8::Local
that, 874 const char* name, 875 v8::FunctionCallback slow_callback, 876 const v8::CFunction* c_function); 877 void SetFastMethodNoSideEffect(v8::Local
context, 878 v8::Local
that, 879 const char* name, 880 v8::FunctionCallback slow_callback, 881 const v8::CFunction* c_function); 882 883 void SetProtoMethod(v8::Isolate* isolate, 884 v8::Local
that, 885 const char* name, 886 v8::FunctionCallback callback); 887 888 void SetInstanceMethod(v8::Isolate* isolate, 889 v8::Local
that, 890 const char* name, 891 v8::FunctionCallback callback); 892 893 // Safe variants denote the function has no side effects. 894 void SetMethodNoSideEffect(v8::Local
context, 895 v8::Local
that, 896 const char* name, 897 v8::FunctionCallback callback); 898 void SetProtoMethodNoSideEffect(v8::Isolate* isolate, 899 v8::Local
that, 900 const char* name, 901 v8::FunctionCallback callback); 902 903 enum class SetConstructorFunctionFlag { 904 NONE, 905 SET_CLASS_NAME, 906 }; 907 908 void SetConstructorFunction(v8::Local
context, 909 v8::Local
that, 910 const char* name, 911 v8::Local
tmpl, 912 SetConstructorFunctionFlag flag = 913 SetConstructorFunctionFlag::SET_CLASS_NAME); 914 915 void SetConstructorFunction(v8::Local
context, 916 v8::Local
that, 917 v8::Local
name, 918 v8::Local
tmpl, 919 SetConstructorFunctionFlag flag = 920 SetConstructorFunctionFlag::SET_CLASS_NAME); 921 922 } // namespace node 923 924 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 925 926 #endif // SRC_UTIL_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™