OR-1 dataflow CPU sketch
at main 3309 lines 120 kB view raw
1#ifndef SRC_NAPI_H_ 2#define SRC_NAPI_H_ 3 4#ifndef NAPI_HAS_THREADS 5#if !defined(__wasm__) || (defined(__EMSCRIPTEN_PTHREADS__) || \ 6 (defined(__wasi__) && defined(_REENTRANT))) 7#define NAPI_HAS_THREADS 1 8#else 9#define NAPI_HAS_THREADS 0 10#endif 11#endif 12 13#include <node_api.h> 14#include <functional> 15#include <initializer_list> 16#include <memory> 17#if NAPI_HAS_THREADS 18#include <mutex> 19#endif // NAPI_HAS_THREADS 20#include <string> 21#include <vector> 22 23// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known 24// good version) 25#if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210 26#define NAPI_HAS_CONSTEXPR 1 27#endif 28 29// VS2013 does not support char16_t literal strings, so we'll work around it 30// using wchar_t strings and casting them. This is safe as long as the character 31// sizes are the same. 32#if defined(_MSC_VER) && _MSC_VER <= 1800 33static_assert(sizeof(char16_t) == sizeof(wchar_t), 34 "Size mismatch between char16_t and wchar_t"); 35#define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L##x) 36#else 37#define NAPI_WIDE_TEXT(x) u##x 38#endif 39 40// Backwards-compatibility to handle the rename of this macro definition, in 41// case they are used within userland code. 42#ifdef NAPI_CPP_EXCEPTIONS 43#define NODE_ADDON_API_CPP_EXCEPTIONS 44#endif 45#if defined(NODE_ADDON_API_CPP_EXCEPTIONS) && !defined(NAPI_CPP_EXCEPTIONS) 46#define NAPI_CPP_EXCEPTIONS 47#endif 48#ifdef NAPI_DISABLE_CPP_EXCEPTIONS 49#define NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS 50#endif 51#if defined(NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS) && \ 52 !defined(NAPI_DISABLE_CPP_EXCEPTIONS) 53#define NAPI_DISABLE_CPP_EXCEPTIONS 54#endif 55 56// If C++ exceptions are not explicitly enabled or disabled, enable them 57// if exceptions were enabled in the compiler settings. 58#if !defined(NODE_ADDON_API_CPP_EXCEPTIONS) && \ 59 !defined(NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS) 60#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) 61#define NODE_ADDON_API_CPP_EXCEPTIONS 62#else 63#error Exception support not detected. \ 64 Define either NODE_ADDON_API_CPP_EXCEPTIONS or NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS. 65#endif 66#endif 67 68// If C++ NODE_ADDON_API_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE 69// should not be set 70#if defined(NODE_ADDON_API_CPP_EXCEPTIONS) && \ 71 defined(NODE_ADDON_API_ENABLE_MAYBE) 72#error NODE_ADDON_API_ENABLE_MAYBE should not be set when \ 73 NODE_ADDON_API_CPP_EXCEPTIONS is defined. 74#endif 75 76#ifdef _NOEXCEPT 77#define NAPI_NOEXCEPT _NOEXCEPT 78#else 79#define NAPI_NOEXCEPT noexcept 80#endif 81 82#ifdef NODE_ADDON_API_CPP_EXCEPTIONS 83 84// When C++ exceptions are enabled, Errors are thrown directly. There is no need 85// to return anything after the throw statements. The variadic parameter is an 86// optional return value that is ignored. 87// We need _VOID versions of the macros to avoid warnings resulting from 88// leaving the NAPI_THROW_* `...` argument empty. 89 90#define NAPI_THROW(e, ...) throw e 91#define NAPI_THROW_VOID(e) throw e 92 93#define NAPI_THROW_IF_FAILED(env, status, ...) \ 94 if ((status) != napi_ok) throw Napi::Error::New(env); 95 96#define NAPI_THROW_IF_FAILED_VOID(env, status) \ 97 if ((status) != napi_ok) throw Napi::Error::New(env); 98 99#else // NODE_ADDON_API_CPP_EXCEPTIONS 100 101// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions, 102// which are pending until the callback returns to JS. The variadic parameter 103// is an optional return value; usually it is an empty result. 104// We need _VOID versions of the macros to avoid warnings resulting from 105// leaving the NAPI_THROW_* `...` argument empty. 106 107#define NAPI_THROW(e, ...) \ 108 do { \ 109 (e).ThrowAsJavaScriptException(); \ 110 return __VA_ARGS__; \ 111 } while (0) 112 113#define NAPI_THROW_VOID(e) \ 114 do { \ 115 (e).ThrowAsJavaScriptException(); \ 116 return; \ 117 } while (0) 118 119#define NAPI_THROW_IF_FAILED(env, status, ...) \ 120 if ((status) != napi_ok) { \ 121 Napi::Error::New(env).ThrowAsJavaScriptException(); \ 122 return __VA_ARGS__; \ 123 } 124 125#define NAPI_THROW_IF_FAILED_VOID(env, status) \ 126 if ((status) != napi_ok) { \ 127 Napi::Error::New(env).ThrowAsJavaScriptException(); \ 128 return; \ 129 } 130 131#endif // NODE_ADDON_API_CPP_EXCEPTIONS 132 133#ifdef NODE_ADDON_API_ENABLE_MAYBE 134#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \ 135 NAPI_THROW_IF_FAILED(env, status, Napi::Nothing<type>()) 136 137#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \ 138 NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \ 139 return Napi::Just<type>(result); 140#else 141#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \ 142 NAPI_THROW_IF_FAILED(env, status, type()) 143 144#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \ 145 NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \ 146 return result; 147#endif 148 149#define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete; 150#define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete; 151 152#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \ 153 NAPI_DISALLOW_ASSIGN(CLASS) \ 154 NAPI_DISALLOW_COPY(CLASS) 155 156#define NAPI_CHECK(condition, location, message) \ 157 do { \ 158 if (!(condition)) { \ 159 Napi::Error::Fatal((location), (message)); \ 160 } \ 161 } while (0) 162 163// Internal check helper. Be careful that the formatted message length should be 164// max 255 size and null terminated. 165#define NAPI_INTERNAL_CHECK(expr, location, ...) \ 166 do { \ 167 if (!(expr)) { \ 168 std::string msg = Napi::details::StringFormat(__VA_ARGS__); \ 169 Napi::Error::Fatal(location, msg.c_str()); \ 170 } \ 171 } while (0) 172 173#define NAPI_INTERNAL_CHECK_EQ(actual, expected, value_format, location) \ 174 do { \ 175 auto actual_value = (actual); \ 176 NAPI_INTERNAL_CHECK(actual_value == (expected), \ 177 location, \ 178 "Expected " #actual " to be equal to " #expected \ 179 ", but got " value_format ".", \ 180 actual_value); \ 181 } while (0) 182 183#define NAPI_FATAL_IF_FAILED(status, location, message) \ 184 NAPI_CHECK((status) == napi_ok, location, message) 185 186//////////////////////////////////////////////////////////////////////////////// 187/// Node-API C++ Wrapper Classes 188/// 189/// These classes wrap the "Node-API" ABI-stable C APIs for Node.js, providing a 190/// C++ object model and C++ exception-handling semantics with low overhead. 191/// The wrappers are all header-only so that they do not affect the ABI. 192//////////////////////////////////////////////////////////////////////////////// 193namespace Napi { 194 195#ifdef NAPI_CPP_CUSTOM_NAMESPACE 196// NAPI_CPP_CUSTOM_NAMESPACE can be #define'd per-addon to avoid symbol 197// conflicts between different instances of node-addon-api 198 199// First dummy definition of the namespace to make sure that Napi::(name) still 200// refers to the right things inside this file. 201namespace NAPI_CPP_CUSTOM_NAMESPACE {} 202using namespace NAPI_CPP_CUSTOM_NAMESPACE; 203 204namespace NAPI_CPP_CUSTOM_NAMESPACE { 205#endif 206 207// Forward declarations 208class Env; 209class Value; 210class Boolean; 211class Number; 212#if NAPI_VERSION > 5 213class BigInt; 214#endif // NAPI_VERSION > 5 215#if (NAPI_VERSION > 4) 216class Date; 217#endif 218class String; 219class Object; 220class Array; 221class ArrayBuffer; 222class Function; 223class Error; 224class PropertyDescriptor; 225class CallbackInfo; 226class TypedArray; 227template <typename T> 228class TypedArrayOf; 229 230using Int8Array = 231 TypedArrayOf<int8_t>; ///< Typed-array of signed 8-bit integers 232using Uint8Array = 233 TypedArrayOf<uint8_t>; ///< Typed-array of unsigned 8-bit integers 234using Int16Array = 235 TypedArrayOf<int16_t>; ///< Typed-array of signed 16-bit integers 236using Uint16Array = 237 TypedArrayOf<uint16_t>; ///< Typed-array of unsigned 16-bit integers 238using Int32Array = 239 TypedArrayOf<int32_t>; ///< Typed-array of signed 32-bit integers 240using Uint32Array = 241 TypedArrayOf<uint32_t>; ///< Typed-array of unsigned 32-bit integers 242using Float32Array = 243 TypedArrayOf<float>; ///< Typed-array of 32-bit floating-point values 244using Float64Array = 245 TypedArrayOf<double>; ///< Typed-array of 64-bit floating-point values 246#if NAPI_VERSION > 5 247using BigInt64Array = 248 TypedArrayOf<int64_t>; ///< Typed array of signed 64-bit integers 249using BigUint64Array = 250 TypedArrayOf<uint64_t>; ///< Typed array of unsigned 64-bit integers 251#endif // NAPI_VERSION > 5 252 253/// Defines the signature of a Node-API C++ module's registration callback 254/// (init) function. 255using ModuleRegisterCallback = Object (*)(Env env, Object exports); 256 257class MemoryManagement; 258 259/// A simple Maybe type, representing an object which may or may not have a 260/// value. 261/// 262/// If an API method returns a Maybe<>, the API method can potentially fail 263/// either because an exception is thrown, or because an exception is pending, 264/// e.g. because a previous API call threw an exception that hasn't been 265/// caught yet. In that case, a "Nothing" value is returned. 266template <class T> 267class Maybe { 268 public: 269 bool IsNothing() const; 270 bool IsJust() const; 271 272 /// Short-hand for Unwrap(), which doesn't return a value. Could be used 273 /// where the actual value of the Maybe is not needed like Object::Set. 274 /// If this Maybe is nothing (empty), node-addon-api will crash the 275 /// process. 276 void Check() const; 277 278 /// Return the value of type T contained in the Maybe. If this Maybe is 279 /// nothing (empty), node-addon-api will crash the process. 280 T Unwrap() const; 281 282 /// Return the value of type T contained in the Maybe, or using a default 283 /// value if this Maybe is nothing (empty). 284 T UnwrapOr(const T& default_value) const; 285 286 /// Converts this Maybe to a value of type T in the out. If this Maybe is 287 /// nothing (empty), `false` is returned and `out` is left untouched. 288 bool UnwrapTo(T* out) const; 289 290 bool operator==(const Maybe& other) const; 291 bool operator!=(const Maybe& other) const; 292 293 private: 294 Maybe(); 295 explicit Maybe(const T& t); 296 297 bool _has_value; 298 T _value; 299 300 template <class U> 301 friend Maybe<U> Nothing(); 302 template <class U> 303 friend Maybe<U> Just(const U& u); 304}; 305 306template <class T> 307inline Maybe<T> Nothing(); 308 309template <class T> 310inline Maybe<T> Just(const T& t); 311 312#if defined(NODE_ADDON_API_ENABLE_MAYBE) 313template <typename T> 314using MaybeOrValue = Maybe<T>; 315#else 316template <typename T> 317using MaybeOrValue = T; 318#endif 319 320#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER 321using node_addon_api_basic_env = node_api_nogc_env; 322using node_addon_api_basic_finalize = node_api_nogc_finalize; 323#else 324using node_addon_api_basic_env = napi_env; 325using node_addon_api_basic_finalize = napi_finalize; 326#endif 327 328/// Environment for Node-API values and operations. 329/// 330/// All Node-API values and operations must be associated with an environment. 331/// An environment instance is always provided to callback functions; that 332/// environment must then be used for any creation of Node-API values or other 333/// Node-API operations within the callback. (Many methods infer the 334/// environment from the `this` instance that the method is called on.) 335/// 336/// Multiple environments may co-exist in a single process or a thread. 337/// 338/// In the V8 JavaScript engine, a Node-API environment approximately 339/// corresponds to an Isolate. 340class BasicEnv { 341 private: 342 node_addon_api_basic_env _env; 343#if NAPI_VERSION > 5 344 template <typename T> 345 static void DefaultFini(Env, T* data); 346 template <typename DataType, typename HintType> 347 static void DefaultFiniWithHint(Env, DataType* data, HintType* hint); 348#endif // NAPI_VERSION > 5 349 public: 350 BasicEnv(node_addon_api_basic_env env); 351 352 operator node_addon_api_basic_env() const; 353 354 // Without these operator overloads, the error: 355 // 356 // Use of overloaded operator '==' is ambiguous (with operand types 357 // 'Napi::Env' and 'Napi::Env') 358 // 359 // ... occurs when comparing foo.Env() == bar.Env() or foo.Env() == nullptr 360 bool operator==(const BasicEnv& other) const { 361 return _env == other._env; 362 }; 363 bool operator==(std::nullptr_t /*other*/) const { 364 return _env == nullptr; 365 }; 366 367#if NAPI_VERSION > 2 368 template <typename Hook, typename Arg = void> 369 class CleanupHook; 370 371 template <typename Hook> 372 CleanupHook<Hook> AddCleanupHook(Hook hook); 373 374 template <typename Hook, typename Arg> 375 CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg); 376#endif // NAPI_VERSION > 2 377 378#if NAPI_VERSION > 5 379 template <typename T> 380 T* GetInstanceData() const; 381 382 template <typename T> 383 using Finalizer = void (*)(Env, T*); 384 template <typename T, Finalizer<T> fini = BasicEnv::DefaultFini<T>> 385 void SetInstanceData(T* data) const; 386 387 template <typename DataType, typename HintType> 388 using FinalizerWithHint = void (*)(Env, DataType*, HintType*); 389 template <typename DataType, 390 typename HintType, 391 FinalizerWithHint<DataType, HintType> fini = 392 BasicEnv::DefaultFiniWithHint<DataType, HintType>> 393 void SetInstanceData(DataType* data, HintType* hint) const; 394#endif // NAPI_VERSION > 5 395 396#if NAPI_VERSION > 2 397 template <typename Hook, typename Arg> 398 class CleanupHook { 399 public: 400 CleanupHook(); 401 CleanupHook(BasicEnv env, Hook hook, Arg* arg); 402 CleanupHook(BasicEnv env, Hook hook); 403 bool Remove(BasicEnv env); 404 bool IsEmpty() const; 405 406 private: 407 static inline void Wrapper(void* data) NAPI_NOEXCEPT; 408 static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT; 409 410 void (*wrapper)(void* arg); 411 struct CleanupData { 412 Hook hook; 413 Arg* arg; 414 } * data; 415 }; 416#endif // NAPI_VERSION > 2 417 418#if NAPI_VERSION > 8 419 const char* GetModuleFileName() const; 420#endif // NAPI_VERSION > 8 421 422#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER 423 template <typename FinalizerType> 424 inline void PostFinalizer(FinalizerType finalizeCallback) const; 425 426 template <typename FinalizerType, typename T> 427 inline void PostFinalizer(FinalizerType finalizeCallback, T* data) const; 428 429 template <typename FinalizerType, typename T, typename Hint> 430 inline void PostFinalizer(FinalizerType finalizeCallback, 431 T* data, 432 Hint* finalizeHint) const; 433#endif // NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER 434 435 friend class Env; 436}; 437 438class Env : public BasicEnv { 439 public: 440 Env(napi_env env); 441 442 operator napi_env() const; 443 444 Object Global() const; 445 Value Undefined() const; 446 Value Null() const; 447 448 bool IsExceptionPending() const; 449 Error GetAndClearPendingException() const; 450 451 MaybeOrValue<Value> RunScript(const char* utf8script) const; 452 MaybeOrValue<Value> RunScript(const std::string& utf8script) const; 453 MaybeOrValue<Value> RunScript(String script) const; 454}; 455 456/// A JavaScript value of unknown type. 457/// 458/// For type-specific operations, convert to one of the Value subclasses using a 459/// `To*` or `As()` method. The `To*` methods do type coercion; the `As()` 460/// method does not. 461/// 462/// Napi::Value value = ... 463/// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid 464/// arg..."); Napi::String str = value.As<Napi::String>(); // Cast to a 465/// string value 466/// 467/// Napi::Value anotherValue = ... 468/// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value 469class Value { 470 public: 471 Value(); ///< Creates a new _empty_ Value instance. 472 Value(napi_env env, 473 napi_value value); ///< Wraps a Node-API value primitive. 474 475 /// Creates a JS value from a C++ primitive. 476 /// 477 /// `value` may be any of: 478 /// - bool 479 /// - Any integer type 480 /// - Any floating point type 481 /// - const char* (encoded using UTF-8, null-terminated) 482 /// - const char16_t* (encoded using UTF-16-LE, null-terminated) 483 /// - std::string (encoded using UTF-8) 484 /// - std::u16string 485 /// - napi::Value 486 /// - napi_value 487 template <typename T> 488 static Value From(napi_env env, const T& value); 489 490 static void CheckCast(napi_env env, napi_value value); 491 492 /// Converts to a Node-API value primitive. 493 /// 494 /// If the instance is _empty_, this returns `nullptr`. 495 operator napi_value() const; 496 497 /// Tests if this value strictly equals another value. 498 bool operator==(const Value& other) const; 499 500 /// Tests if this value does not strictly equal another value. 501 bool operator!=(const Value& other) const; 502 503 /// Tests if this value strictly equals another value. 504 bool StrictEquals(const Value& other) const; 505 506 /// Gets the environment the value is associated with. 507 Napi::Env Env() const; 508 509 /// Checks if the value is empty (uninitialized). 510 /// 511 /// An empty value is invalid, and most attempts to perform an operation on an 512 /// empty value will result in an exception. Note an empty value is distinct 513 /// from JavaScript `null` or `undefined`, which are valid values. 514 /// 515 /// When C++ exceptions are disabled at compile time, a method with a `Value` 516 /// return type may return an empty value to indicate a pending exception. So 517 /// when not using C++ exceptions, callers should check whether the value is 518 /// empty before attempting to use it. 519 bool IsEmpty() const; 520 521 napi_valuetype Type() const; ///< Gets the type of the value. 522 523 bool IsUndefined() 524 const; ///< Tests if a value is an undefined JavaScript value. 525 bool IsNull() const; ///< Tests if a value is a null JavaScript value. 526 bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean. 527 bool IsNumber() const; ///< Tests if a value is a JavaScript number. 528#if NAPI_VERSION > 5 529 bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint. 530#endif // NAPI_VERSION > 5 531#if (NAPI_VERSION > 4) 532 bool IsDate() const; ///< Tests if a value is a JavaScript date. 533#endif 534 bool IsString() const; ///< Tests if a value is a JavaScript string. 535 bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol. 536 bool IsArray() const; ///< Tests if a value is a JavaScript array. 537 bool IsArrayBuffer() 538 const; ///< Tests if a value is a JavaScript array buffer. 539 bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array. 540 bool IsObject() const; ///< Tests if a value is a JavaScript object. 541 bool IsFunction() const; ///< Tests if a value is a JavaScript function. 542 bool IsPromise() const; ///< Tests if a value is a JavaScript promise. 543 bool IsDataView() const; ///< Tests if a value is a JavaScript data view. 544 bool IsBuffer() const; ///< Tests if a value is a Node buffer. 545 bool IsExternal() const; ///< Tests if a value is a pointer to external data. 546 547 /// Casts to another type of `Napi::Value`, when the actual type is known or 548 /// assumed. 549 /// 550 /// This conversion does NOT coerce the type. Calling any methods 551 /// inappropriate for the actual value type will throw `Napi::Error`. 552 /// 553 /// If `NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS` is defined, this method 554 /// asserts that the actual type is the expected type. 555 template <typename T> 556 T As() const; 557 558 // Unsafe Value::As(), should be avoided. 559 template <typename T> 560 T UnsafeAs() const; 561 562 MaybeOrValue<Boolean> ToBoolean() 563 const; ///< Coerces a value to a JavaScript boolean. 564 MaybeOrValue<Number> ToNumber() 565 const; ///< Coerces a value to a JavaScript number. 566 MaybeOrValue<String> ToString() 567 const; ///< Coerces a value to a JavaScript string. 568 MaybeOrValue<Object> ToObject() 569 const; ///< Coerces a value to a JavaScript object. 570 571 protected: 572 /// !cond INTERNAL 573 napi_env _env; 574 napi_value _value; 575 /// !endcond 576}; 577 578/// A JavaScript boolean value. 579class Boolean : public Value { 580 public: 581 static Boolean New(napi_env env, ///< Node-API environment 582 bool value ///< Boolean value 583 ); 584 585 static void CheckCast(napi_env env, napi_value value); 586 587 Boolean(); ///< Creates a new _empty_ Boolean instance. 588 Boolean(napi_env env, 589 napi_value value); ///< Wraps a Node-API value primitive. 590 591 operator bool() const; ///< Converts a Boolean value to a boolean primitive. 592 bool Value() const; ///< Converts a Boolean value to a boolean primitive. 593}; 594 595/// A JavaScript number value. 596class Number : public Value { 597 public: 598 static Number New(napi_env env, ///< Node-API environment 599 double value ///< Number value 600 ); 601 602 static void CheckCast(napi_env env, napi_value value); 603 604 Number(); ///< Creates a new _empty_ Number instance. 605 Number(napi_env env, 606 napi_value value); ///< Wraps a Node-API value primitive. 607 608 operator int32_t() 609 const; ///< Converts a Number value to a 32-bit signed integer value. 610 operator uint32_t() 611 const; ///< Converts a Number value to a 32-bit unsigned integer value. 612 operator int64_t() 613 const; ///< Converts a Number value to a 64-bit signed integer value. 614 operator float() 615 const; ///< Converts a Number value to a 32-bit floating-point value. 616 operator double() 617 const; ///< Converts a Number value to a 64-bit floating-point value. 618 619 int32_t Int32Value() 620 const; ///< Converts a Number value to a 32-bit signed integer value. 621 uint32_t Uint32Value() 622 const; ///< Converts a Number value to a 32-bit unsigned integer value. 623 int64_t Int64Value() 624 const; ///< Converts a Number value to a 64-bit signed integer value. 625 float FloatValue() 626 const; ///< Converts a Number value to a 32-bit floating-point value. 627 double DoubleValue() 628 const; ///< Converts a Number value to a 64-bit floating-point value. 629}; 630 631#if NAPI_VERSION > 5 632/// A JavaScript bigint value. 633class BigInt : public Value { 634 public: 635 static BigInt New(napi_env env, ///< Node-API environment 636 int64_t value ///< Number value 637 ); 638 static BigInt New(napi_env env, ///< Node-API environment 639 uint64_t value ///< Number value 640 ); 641 642 /// Creates a new BigInt object using a specified sign bit and a 643 /// specified list of digits/words. 644 /// The resulting number is calculated as: 645 /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...) 646 static BigInt New(napi_env env, ///< Node-API environment 647 int sign_bit, ///< Sign bit. 1 if negative. 648 size_t word_count, ///< Number of words in array 649 const uint64_t* words ///< Array of words 650 ); 651 652 static void CheckCast(napi_env env, napi_value value); 653 654 BigInt(); ///< Creates a new _empty_ BigInt instance. 655 BigInt(napi_env env, 656 napi_value value); ///< Wraps a Node-API value primitive. 657 658 int64_t Int64Value(bool* lossless) 659 const; ///< Converts a BigInt value to a 64-bit signed integer value. 660 uint64_t Uint64Value(bool* lossless) 661 const; ///< Converts a BigInt value to a 64-bit unsigned integer value. 662 663 size_t WordCount() const; ///< The number of 64-bit words needed to store 664 ///< the result of ToWords(). 665 666 /// Writes the contents of this BigInt to a specified memory location. 667 /// `sign_bit` must be provided and will be set to 1 if this BigInt is 668 /// negative. 669 /// `*word_count` has to be initialized to the length of the `words` array. 670 /// Upon return, it will be set to the actual number of words that would 671 /// be needed to store this BigInt (i.e. the return value of `WordCount()`). 672 void ToWords(int* sign_bit, size_t* word_count, uint64_t* words); 673}; 674#endif // NAPI_VERSION > 5 675 676#if (NAPI_VERSION > 4) 677/// A JavaScript date value. 678class Date : public Value { 679 public: 680 /// Creates a new Date value from a double primitive. 681 static Date New(napi_env env, ///< Node-API environment 682 double value ///< Number value 683 ); 684 685 static void CheckCast(napi_env env, napi_value value); 686 687 Date(); ///< Creates a new _empty_ Date instance. 688 Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. 689 operator double() const; ///< Converts a Date value to double primitive 690 691 double ValueOf() const; ///< Converts a Date value to a double primitive. 692}; 693#endif 694 695/// A JavaScript string or symbol value (that can be used as a property name). 696class Name : public Value { 697 public: 698 static void CheckCast(napi_env env, napi_value value); 699 700 Name(); ///< Creates a new _empty_ Name instance. 701 Name(napi_env env, 702 napi_value value); ///< Wraps a Node-API value primitive. 703}; 704 705/// A JavaScript string value. 706class String : public Name { 707 public: 708 /// Creates a new String value from a UTF-8 encoded C++ string. 709 static String New(napi_env env, ///< Node-API environment 710 const std::string& value ///< UTF-8 encoded C++ string 711 ); 712 713 /// Creates a new String value from a UTF-16 encoded C++ string. 714 static String New(napi_env env, ///< Node-API environment 715 const std::u16string& value ///< UTF-16 encoded C++ string 716 ); 717 718 /// Creates a new String value from a UTF-8 encoded C string. 719 static String New( 720 napi_env env, ///< Node-API environment 721 const char* value ///< UTF-8 encoded null-terminated C string 722 ); 723 724 /// Creates a new String value from a UTF-16 encoded C string. 725 static String New( 726 napi_env env, ///< Node-API environment 727 const char16_t* value ///< UTF-16 encoded null-terminated C string 728 ); 729 730 /// Creates a new String value from a UTF-8 encoded C string with specified 731 /// length. 732 static String New(napi_env env, ///< Node-API environment 733 const char* value, ///< UTF-8 encoded C string (not 734 ///< necessarily null-terminated) 735 size_t length ///< length of the string in bytes 736 ); 737 738 /// Creates a new String value from a UTF-16 encoded C string with specified 739 /// length. 740 static String New( 741 napi_env env, ///< Node-API environment 742 const char16_t* value, ///< UTF-16 encoded C string (not necessarily 743 ///< null-terminated) 744 size_t length ///< Length of the string in 2-byte code units 745 ); 746 747 /// Creates a new String based on the original object's type. 748 /// 749 /// `value` may be any of: 750 /// - const char* (encoded using UTF-8, null-terminated) 751 /// - const char16_t* (encoded using UTF-16-LE, null-terminated) 752 /// - std::string (encoded using UTF-8) 753 /// - std::u16string 754 template <typename T> 755 static String From(napi_env env, const T& value); 756 757 static void CheckCast(napi_env env, napi_value value); 758 759 String(); ///< Creates a new _empty_ String instance. 760 String(napi_env env, 761 napi_value value); ///< Wraps a Node-API value primitive. 762 763 operator std::string() 764 const; ///< Converts a String value to a UTF-8 encoded C++ string. 765 operator std::u16string() 766 const; ///< Converts a String value to a UTF-16 encoded C++ string. 767 std::string Utf8Value() 768 const; ///< Converts a String value to a UTF-8 encoded C++ string. 769 std::u16string Utf16Value() 770 const; ///< Converts a String value to a UTF-16 encoded C++ string. 771}; 772 773/// A JavaScript symbol value. 774class Symbol : public Name { 775 public: 776 /// Creates a new Symbol value with an optional description. 777 static Symbol New( 778 napi_env env, ///< Node-API environment 779 const char* description = 780 nullptr ///< Optional UTF-8 encoded null-terminated C string 781 /// describing the symbol 782 ); 783 784 /// Creates a new Symbol value with a description. 785 static Symbol New( 786 napi_env env, ///< Node-API environment 787 const std::string& 788 description ///< UTF-8 encoded C++ string describing the symbol 789 ); 790 791 /// Creates a new Symbol value with a description. 792 static Symbol New(napi_env env, ///< Node-API environment 793 String description ///< String value describing the symbol 794 ); 795 796 /// Creates a new Symbol value with a description. 797 static Symbol New( 798 napi_env env, ///< Node-API environment 799 napi_value description ///< String value describing the symbol 800 ); 801 802 /// Get a public Symbol (e.g. Symbol.iterator). 803 static MaybeOrValue<Symbol> WellKnown(napi_env, const std::string& name); 804 805 // Create a symbol in the global registry, UTF-8 Encoded cpp string 806 static MaybeOrValue<Symbol> For(napi_env env, const std::string& description); 807 808 // Create a symbol in the global registry, C style string (null terminated) 809 static MaybeOrValue<Symbol> For(napi_env env, const char* description); 810 811 // Create a symbol in the global registry, String value describing the symbol 812 static MaybeOrValue<Symbol> For(napi_env env, String description); 813 814 // Create a symbol in the global registry, napi_value describing the symbol 815 static MaybeOrValue<Symbol> For(napi_env env, napi_value description); 816 817 static void CheckCast(napi_env env, napi_value value); 818 819 Symbol(); ///< Creates a new _empty_ Symbol instance. 820 Symbol(napi_env env, 821 napi_value value); ///< Wraps a Node-API value primitive. 822}; 823 824class TypeTaggable : public Value { 825 public: 826#if NAPI_VERSION >= 8 827 void TypeTag(const napi_type_tag* type_tag) const; 828 bool CheckTypeTag(const napi_type_tag* type_tag) const; 829#endif // NAPI_VERSION >= 8 830 protected: 831 TypeTaggable(); 832 TypeTaggable(napi_env env, napi_value value); 833}; 834 835/// A JavaScript object value. 836class Object : public TypeTaggable { 837 public: 838 /// Enables property and element assignments using indexing syntax. 839 /// 840 /// This is a convenient helper to get and set object properties. As 841 /// getting and setting object properties may throw with JavaScript 842 /// exceptions, it is notable that these operations may fail. 843 /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort 844 /// on JavaScript exceptions. 845 /// 846 /// Example: 847 /// 848 /// Napi::Value propertyValue = object1['A']; 849 /// object2['A'] = propertyValue; 850 /// Napi::Value elementValue = array[0]; 851 /// array[1] = elementValue; 852 template <typename Key> 853 class PropertyLValue { 854 public: 855 /// Converts an L-value to a value. 856 operator Value() const; 857 858 /// Assigns a value to the property. The type of value can be 859 /// anything supported by `Object::Set`. 860 template <typename ValueType> 861 PropertyLValue& operator=(ValueType value); 862 863 /// Converts an L-value to a value. For convenience. 864 Value AsValue() const; 865 866 private: 867 PropertyLValue() = delete; 868 PropertyLValue(Object object, Key key); 869 napi_env _env; 870 napi_value _object; 871 Key _key; 872 873 friend class Napi::Object; 874 }; 875 876 /// Creates a new Object value. 877 static Object New(napi_env env ///< Node-API environment 878 ); 879 880 static void CheckCast(napi_env env, napi_value value); 881 882 Object(); ///< Creates a new _empty_ Object instance. 883 Object(napi_env env, 884 napi_value value); ///< Wraps a Node-API value primitive. 885 886 /// Gets or sets a named property. 887 PropertyLValue<std::string> operator[]( 888 const char* utf8name ///< UTF-8 encoded null-terminated property name 889 ); 890 891 /// Gets or sets a named property. 892 PropertyLValue<std::string> operator[]( 893 const std::string& utf8name ///< UTF-8 encoded property name 894 ); 895 896 /// Gets or sets an indexed property or array element. 897 PropertyLValue<uint32_t> operator[]( 898 uint32_t index /// Property / element index 899 ); 900 901 /// Gets or sets an indexed property or array element. 902 PropertyLValue<Value> operator[](Value index /// Property / element index 903 ) const; 904 905 /// Gets a named property. 906 MaybeOrValue<Value> operator[]( 907 const char* utf8name ///< UTF-8 encoded null-terminated property name 908 ) const; 909 910 /// Gets a named property. 911 MaybeOrValue<Value> operator[]( 912 const std::string& utf8name ///< UTF-8 encoded property name 913 ) const; 914 915 /// Gets an indexed property or array element. 916 MaybeOrValue<Value> operator[](uint32_t index ///< Property / element index 917 ) const; 918 919 /// Checks whether a property is present. 920 MaybeOrValue<bool> Has(napi_value key ///< Property key primitive 921 ) const; 922 923 /// Checks whether a property is present. 924 MaybeOrValue<bool> Has(Value key ///< Property key 925 ) const; 926 927 /// Checks whether a named property is present. 928 MaybeOrValue<bool> Has( 929 const char* utf8name ///< UTF-8 encoded null-terminated property name 930 ) const; 931 932 /// Checks whether a named property is present. 933 MaybeOrValue<bool> Has( 934 const std::string& utf8name ///< UTF-8 encoded property name 935 ) const; 936 937 /// Checks whether a own property is present. 938 MaybeOrValue<bool> HasOwnProperty(napi_value key ///< Property key primitive 939 ) const; 940 941 /// Checks whether a own property is present. 942 MaybeOrValue<bool> HasOwnProperty(Value key ///< Property key 943 ) const; 944 945 /// Checks whether a own property is present. 946 MaybeOrValue<bool> HasOwnProperty( 947 const char* utf8name ///< UTF-8 encoded null-terminated property name 948 ) const; 949 950 /// Checks whether a own property is present. 951 MaybeOrValue<bool> HasOwnProperty( 952 const std::string& utf8name ///< UTF-8 encoded property name 953 ) const; 954 955 /// Gets a property. 956 MaybeOrValue<Value> Get(napi_value key ///< Property key primitive 957 ) const; 958 959 /// Gets a property. 960 MaybeOrValue<Value> Get(Value key ///< Property key 961 ) const; 962 963 /// Gets a named property. 964 MaybeOrValue<Value> Get( 965 const char* utf8name ///< UTF-8 encoded null-terminated property name 966 ) const; 967 968 /// Gets a named property. 969 MaybeOrValue<Value> Get( 970 const std::string& utf8name ///< UTF-8 encoded property name 971 ) const; 972 973 /// Sets a property. 974 template <typename ValueType> 975 MaybeOrValue<bool> Set(napi_value key, ///< Property key primitive 976 const ValueType& value ///< Property value primitive 977 ) const; 978 979 /// Sets a property. 980 template <typename ValueType> 981 MaybeOrValue<bool> Set(Value key, ///< Property key 982 const ValueType& value ///< Property value 983 ) const; 984 985 /// Sets a named property. 986 template <typename ValueType> 987 MaybeOrValue<bool> Set( 988 const char* utf8name, ///< UTF-8 encoded null-terminated property name 989 const ValueType& value) const; 990 991 /// Sets a named property. 992 template <typename ValueType> 993 MaybeOrValue<bool> Set( 994 const std::string& utf8name, ///< UTF-8 encoded property name 995 const ValueType& value ///< Property value primitive 996 ) const; 997 998 /// Delete property. 999 MaybeOrValue<bool> Delete(napi_value key ///< Property key primitive 1000 ) const; 1001 1002 /// Delete property. 1003 MaybeOrValue<bool> Delete(Value key ///< Property key 1004 ) const; 1005 1006 /// Delete property. 1007 MaybeOrValue<bool> Delete( 1008 const char* utf8name ///< UTF-8 encoded null-terminated property name 1009 ) const; 1010 1011 /// Delete property. 1012 MaybeOrValue<bool> Delete( 1013 const std::string& utf8name ///< UTF-8 encoded property name 1014 ) const; 1015 1016 /// Checks whether an indexed property is present. 1017 MaybeOrValue<bool> Has(uint32_t index ///< Property / element index 1018 ) const; 1019 1020 /// Gets an indexed property or array element. 1021 MaybeOrValue<Value> Get(uint32_t index ///< Property / element index 1022 ) const; 1023 1024 /// Sets an indexed property or array element. 1025 template <typename ValueType> 1026 MaybeOrValue<bool> Set(uint32_t index, ///< Property / element index 1027 const ValueType& value ///< Property value primitive 1028 ) const; 1029 1030 /// Deletes an indexed property or array element. 1031 MaybeOrValue<bool> Delete(uint32_t index ///< Property / element index 1032 ) const; 1033 1034 /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and 1035 /// Proxy.[[GetOwnProperty]] calling into JavaScript. See: 1036 /// - 1037 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys 1038 /// - 1039 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p 1040 MaybeOrValue<Array> GetPropertyNames() const; ///< Get all property names 1041 1042 /// Defines a property on the object. 1043 /// 1044 /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling 1045 /// into JavaScript. See 1046 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc 1047 MaybeOrValue<bool> DefineProperty( 1048 const PropertyDescriptor& 1049 property ///< Descriptor for the property to be defined 1050 ) const; 1051 1052 /// Defines properties on the object. 1053 /// 1054 /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling 1055 /// into JavaScript. See 1056 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc 1057 MaybeOrValue<bool> DefineProperties( 1058 const std::initializer_list<PropertyDescriptor>& properties 1059 ///< List of descriptors for the properties to be defined 1060 ) const; 1061 1062 /// Defines properties on the object. 1063 /// 1064 /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling 1065 /// into JavaScript. See 1066 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc 1067 MaybeOrValue<bool> DefineProperties( 1068 const std::vector<PropertyDescriptor>& properties 1069 ///< Vector of descriptors for the properties to be defined 1070 ) const; 1071 1072 /// Checks if an object is an instance created by a constructor function. 1073 /// 1074 /// This is equivalent to the JavaScript `instanceof` operator. 1075 /// 1076 /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into 1077 /// JavaScript. 1078 /// See 1079 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof 1080 MaybeOrValue<bool> InstanceOf( 1081 const Function& constructor ///< Constructor function 1082 ) const; 1083 1084 template <typename Finalizer, typename T> 1085 inline void AddFinalizer(Finalizer finalizeCallback, T* data) const; 1086 1087 template <typename Finalizer, typename T, typename Hint> 1088 inline void AddFinalizer(Finalizer finalizeCallback, 1089 T* data, 1090 Hint* finalizeHint) const; 1091 1092#ifdef NODE_ADDON_API_CPP_EXCEPTIONS 1093 class const_iterator; 1094 1095 inline const_iterator begin() const; 1096 1097 inline const_iterator end() const; 1098 1099 class iterator; 1100 1101 inline iterator begin(); 1102 1103 inline iterator end(); 1104#endif // NODE_ADDON_API_CPP_EXCEPTIONS 1105 1106#if NAPI_VERSION >= 8 1107 /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into 1108 /// JavaScript. 1109 /// See 1110 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof 1111 MaybeOrValue<bool> Freeze() const; 1112 /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into 1113 /// JavaScript. 1114 /// See 1115 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof 1116 MaybeOrValue<bool> Seal() const; 1117#endif // NAPI_VERSION >= 8 1118}; 1119 1120template <typename T> 1121class External : public TypeTaggable { 1122 public: 1123 static External New(napi_env env, T* data); 1124 1125 // Finalizer must implement `void operator()(Env env, T* data)`. 1126 template <typename Finalizer> 1127 static External New(napi_env env, T* data, Finalizer finalizeCallback); 1128 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. 1129 template <typename Finalizer, typename Hint> 1130 static External New(napi_env env, 1131 T* data, 1132 Finalizer finalizeCallback, 1133 Hint* finalizeHint); 1134 1135 static void CheckCast(napi_env env, napi_value value); 1136 1137 External(); 1138 External(napi_env env, napi_value value); 1139 1140 T* Data() const; 1141}; 1142 1143class Array : public Object { 1144 public: 1145 static Array New(napi_env env); 1146 static Array New(napi_env env, size_t length); 1147 1148 static void CheckCast(napi_env env, napi_value value); 1149 1150 Array(); 1151 Array(napi_env env, napi_value value); 1152 1153 uint32_t Length() const; 1154}; 1155 1156#ifdef NODE_ADDON_API_CPP_EXCEPTIONS 1157class Object::const_iterator { 1158 private: 1159 enum class Type { BEGIN, END }; 1160 1161 inline const_iterator(const Object* object, const Type type); 1162 1163 public: 1164 inline const_iterator& operator++(); 1165 1166 inline bool operator==(const const_iterator& other) const; 1167 1168 inline bool operator!=(const const_iterator& other) const; 1169 1170 inline const std::pair<Value, Object::PropertyLValue<Value>> operator*() 1171 const; 1172 1173 private: 1174 const Napi::Object* _object; 1175 Array _keys; 1176 uint32_t _index; 1177 1178 friend class Object; 1179}; 1180 1181class Object::iterator { 1182 private: 1183 enum class Type { BEGIN, END }; 1184 1185 inline iterator(Object* object, const Type type); 1186 1187 public: 1188 inline iterator& operator++(); 1189 1190 inline bool operator==(const iterator& other) const; 1191 1192 inline bool operator!=(const iterator& other) const; 1193 1194 inline std::pair<Value, Object::PropertyLValue<Value>> operator*(); 1195 1196 private: 1197 Napi::Object* _object; 1198 Array _keys; 1199 uint32_t _index; 1200 1201 friend class Object; 1202}; 1203#endif // NODE_ADDON_API_CPP_EXCEPTIONS 1204 1205/// A JavaScript array buffer value. 1206class ArrayBuffer : public Object { 1207 public: 1208 /// Creates a new ArrayBuffer instance over a new automatically-allocated 1209 /// buffer. 1210 static ArrayBuffer New( 1211 napi_env env, ///< Node-API environment 1212 size_t byteLength ///< Length of the buffer to be allocated, in bytes 1213 ); 1214 1215#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED 1216 /// Creates a new ArrayBuffer instance, using an external buffer with 1217 /// specified byte length. 1218 static ArrayBuffer New( 1219 napi_env env, ///< Node-API environment 1220 void* externalData, ///< Pointer to the external buffer to be used by 1221 ///< the array 1222 size_t byteLength ///< Length of the external buffer to be used by the 1223 ///< array, in bytes 1224 ); 1225 1226 /// Creates a new ArrayBuffer instance, using an external buffer with 1227 /// specified byte length. 1228 template <typename Finalizer> 1229 static ArrayBuffer New( 1230 napi_env env, ///< Node-API environment 1231 void* externalData, ///< Pointer to the external buffer to be used by 1232 ///< the array 1233 size_t byteLength, ///< Length of the external buffer to be used by the 1234 ///< array, 1235 /// in bytes 1236 Finalizer finalizeCallback ///< Function to be called when the array 1237 ///< buffer is destroyed; 1238 /// must implement `void operator()(Env env, 1239 /// void* externalData)` 1240 ); 1241 1242 /// Creates a new ArrayBuffer instance, using an external buffer with 1243 /// specified byte length. 1244 template <typename Finalizer, typename Hint> 1245 static ArrayBuffer New( 1246 napi_env env, ///< Node-API environment 1247 void* externalData, ///< Pointer to the external buffer to be used by 1248 ///< the array 1249 size_t byteLength, ///< Length of the external buffer to be used by the 1250 ///< array, 1251 /// in bytes 1252 Finalizer finalizeCallback, ///< Function to be called when the array 1253 ///< buffer is destroyed; 1254 /// must implement `void operator()(Env 1255 /// env, void* externalData, Hint* hint)` 1256 Hint* finalizeHint ///< Hint (second parameter) to be passed to the 1257 ///< finalize callback 1258 ); 1259#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED 1260 1261 static void CheckCast(napi_env env, napi_value value); 1262 1263 ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance. 1264 ArrayBuffer(napi_env env, 1265 napi_value value); ///< Wraps a Node-API value primitive. 1266 1267 void* Data(); ///< Gets a pointer to the data buffer. 1268 size_t ByteLength(); ///< Gets the length of the array buffer in bytes. 1269 1270#if NAPI_VERSION >= 7 1271 bool IsDetached() const; 1272 void Detach(); 1273#endif // NAPI_VERSION >= 7 1274}; 1275 1276/// A JavaScript typed-array value with unknown array type. 1277/// 1278/// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the 1279/// `As()` method: 1280/// 1281/// Napi::TypedArray array = ... 1282/// if (t.TypedArrayType() == napi_int32_array) { 1283/// Napi::Int32Array int32Array = t.As<Napi::Int32Array>(); 1284/// } 1285class TypedArray : public Object { 1286 public: 1287 static void CheckCast(napi_env env, napi_value value); 1288 1289 TypedArray(); ///< Creates a new _empty_ TypedArray instance. 1290 TypedArray(napi_env env, 1291 napi_value value); ///< Wraps a Node-API value primitive. 1292 1293 napi_typedarray_type TypedArrayType() 1294 const; ///< Gets the type of this typed-array. 1295 Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. 1296 1297 uint8_t ElementSize() 1298 const; ///< Gets the size in bytes of one element in the array. 1299 size_t ElementLength() const; ///< Gets the number of elements in the array. 1300 size_t ByteOffset() 1301 const; ///< Gets the offset into the buffer where the array starts. 1302 size_t ByteLength() const; ///< Gets the length of the array in bytes. 1303 1304 protected: 1305 /// !cond INTERNAL 1306 napi_typedarray_type _type; 1307 size_t _length; 1308 1309 TypedArray(napi_env env, 1310 napi_value value, 1311 napi_typedarray_type type, 1312 size_t length); 1313 1314 template <typename T> 1315 static 1316#if defined(NAPI_HAS_CONSTEXPR) 1317 constexpr 1318#endif 1319 napi_typedarray_type 1320 TypedArrayTypeForPrimitiveType() { 1321 return std::is_same<T, int8_t>::value ? napi_int8_array 1322 : std::is_same<T, uint8_t>::value ? napi_uint8_array 1323 : std::is_same<T, int16_t>::value ? napi_int16_array 1324 : std::is_same<T, uint16_t>::value ? napi_uint16_array 1325 : std::is_same<T, int32_t>::value ? napi_int32_array 1326 : std::is_same<T, uint32_t>::value ? napi_uint32_array 1327 : std::is_same<T, float>::value ? napi_float32_array 1328 : std::is_same<T, double>::value ? napi_float64_array 1329#if NAPI_VERSION > 5 1330 : std::is_same<T, int64_t>::value ? napi_bigint64_array 1331 : std::is_same<T, uint64_t>::value ? napi_biguint64_array 1332#endif // NAPI_VERSION > 5 1333 : napi_int8_array; 1334 } 1335 /// !endcond 1336}; 1337 1338/// A JavaScript typed-array value with known array type. 1339/// 1340/// Note while it is possible to create and access Uint8 "clamped" arrays using 1341/// this class, the _clamping_ behavior is only applied in JavaScript. 1342template <typename T> 1343class TypedArrayOf : public TypedArray { 1344 public: 1345 /// Creates a new TypedArray instance over a new automatically-allocated array 1346 /// buffer. 1347 /// 1348 /// The array type parameter can normally be omitted (because it is inferred 1349 /// from the template parameter T), except when creating a "clamped" array: 1350 /// 1351 /// Uint8Array::New(env, length, napi_uint8_clamped_array) 1352 static TypedArrayOf New( 1353 napi_env env, ///< Node-API environment 1354 size_t elementLength, ///< Length of the created array, as a number of 1355 ///< elements 1356#if defined(NAPI_HAS_CONSTEXPR) 1357 napi_typedarray_type type = 1358 TypedArray::TypedArrayTypeForPrimitiveType<T>() 1359#else 1360 napi_typedarray_type type 1361#endif 1362 ///< Type of array, if different from the default array type for the 1363 ///< template parameter T. 1364 ); 1365 1366 /// Creates a new TypedArray instance over a provided array buffer. 1367 /// 1368 /// The array type parameter can normally be omitted (because it is inferred 1369 /// from the template parameter T), except when creating a "clamped" array: 1370 /// 1371 /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array) 1372 static TypedArrayOf New( 1373 napi_env env, ///< Node-API environment 1374 size_t elementLength, ///< Length of the created array, as a number of 1375 ///< elements 1376 Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use 1377 size_t bufferOffset, ///< Offset into the array buffer where the 1378 ///< typed-array starts 1379#if defined(NAPI_HAS_CONSTEXPR) 1380 napi_typedarray_type type = 1381 TypedArray::TypedArrayTypeForPrimitiveType<T>() 1382#else 1383 napi_typedarray_type type 1384#endif 1385 ///< Type of array, if different from the default array type for the 1386 ///< template parameter T. 1387 ); 1388 1389 static void CheckCast(napi_env env, napi_value value); 1390 1391 TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance. 1392 TypedArrayOf(napi_env env, 1393 napi_value value); ///< Wraps a Node-API value primitive. 1394 1395 T& operator[](size_t index); ///< Gets or sets an element in the array. 1396 const T& operator[](size_t index) const; ///< Gets an element in the array. 1397 1398 /// Gets a pointer to the array's backing buffer. 1399 /// 1400 /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, 1401 /// because the typed-array may have a non-zero `ByteOffset()` into the 1402 /// `ArrayBuffer`. 1403 T* Data(); 1404 1405 /// Gets a pointer to the array's backing buffer. 1406 /// 1407 /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, 1408 /// because the typed-array may have a non-zero `ByteOffset()` into the 1409 /// `ArrayBuffer`. 1410 const T* Data() const; 1411 1412 private: 1413 T* _data; 1414 1415 TypedArrayOf(napi_env env, 1416 napi_value value, 1417 napi_typedarray_type type, 1418 size_t length, 1419 T* data); 1420}; 1421 1422/// The DataView provides a low-level interface for reading/writing multiple 1423/// number types in an ArrayBuffer irrespective of the platform's endianness. 1424class DataView : public Object { 1425 public: 1426 static DataView New(napi_env env, Napi::ArrayBuffer arrayBuffer); 1427 static DataView New(napi_env env, 1428 Napi::ArrayBuffer arrayBuffer, 1429 size_t byteOffset); 1430 static DataView New(napi_env env, 1431 Napi::ArrayBuffer arrayBuffer, 1432 size_t byteOffset, 1433 size_t byteLength); 1434 1435 static void CheckCast(napi_env env, napi_value value); 1436 1437 DataView(); ///< Creates a new _empty_ DataView instance. 1438 DataView(napi_env env, 1439 napi_value value); ///< Wraps a Node-API value primitive. 1440 1441 Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. 1442 size_t ByteOffset() 1443 const; ///< Gets the offset into the buffer where the array starts. 1444 size_t ByteLength() const; ///< Gets the length of the array in bytes. 1445 1446 void* Data() const; 1447 1448 float GetFloat32(size_t byteOffset) const; 1449 double GetFloat64(size_t byteOffset) const; 1450 int8_t GetInt8(size_t byteOffset) const; 1451 int16_t GetInt16(size_t byteOffset) const; 1452 int32_t GetInt32(size_t byteOffset) const; 1453 uint8_t GetUint8(size_t byteOffset) const; 1454 uint16_t GetUint16(size_t byteOffset) const; 1455 uint32_t GetUint32(size_t byteOffset) const; 1456 1457 void SetFloat32(size_t byteOffset, float value) const; 1458 void SetFloat64(size_t byteOffset, double value) const; 1459 void SetInt8(size_t byteOffset, int8_t value) const; 1460 void SetInt16(size_t byteOffset, int16_t value) const; 1461 void SetInt32(size_t byteOffset, int32_t value) const; 1462 void SetUint8(size_t byteOffset, uint8_t value) const; 1463 void SetUint16(size_t byteOffset, uint16_t value) const; 1464 void SetUint32(size_t byteOffset, uint32_t value) const; 1465 1466 private: 1467 template <typename T> 1468 T ReadData(size_t byteOffset) const; 1469 1470 template <typename T> 1471 void WriteData(size_t byteOffset, T value) const; 1472 1473 void* _data{}; 1474 size_t _length{}; 1475}; 1476 1477class Function : public Object { 1478 public: 1479 using VoidCallback = void (*)(const CallbackInfo& info); 1480 using Callback = Value (*)(const CallbackInfo& info); 1481 1482 template <VoidCallback cb> 1483 static Function New(napi_env env, 1484 const char* utf8name = nullptr, 1485 void* data = nullptr); 1486 1487 template <Callback cb> 1488 static Function New(napi_env env, 1489 const char* utf8name = nullptr, 1490 void* data = nullptr); 1491 1492 template <VoidCallback cb> 1493 static Function New(napi_env env, 1494 const std::string& utf8name, 1495 void* data = nullptr); 1496 1497 template <Callback cb> 1498 static Function New(napi_env env, 1499 const std::string& utf8name, 1500 void* data = nullptr); 1501 1502 /// Callable must implement operator() accepting a const CallbackInfo& 1503 /// and return either void or Value. 1504 template <typename Callable> 1505 static Function New(napi_env env, 1506 Callable cb, 1507 const char* utf8name = nullptr, 1508 void* data = nullptr); 1509 /// Callable must implement operator() accepting a const CallbackInfo& 1510 /// and return either void or Value. 1511 template <typename Callable> 1512 static Function New(napi_env env, 1513 Callable cb, 1514 const std::string& utf8name, 1515 void* data = nullptr); 1516 1517 static void CheckCast(napi_env env, napi_value value); 1518 1519 Function(); 1520 Function(napi_env env, napi_value value); 1521 1522 MaybeOrValue<Value> operator()( 1523 const std::initializer_list<napi_value>& args) const; 1524 1525 MaybeOrValue<Value> Call(const std::initializer_list<napi_value>& args) const; 1526 MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const; 1527 MaybeOrValue<Value> Call(const std::vector<Value>& args) const; 1528 MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const; 1529 MaybeOrValue<Value> Call(napi_value recv, 1530 const std::initializer_list<napi_value>& args) const; 1531 MaybeOrValue<Value> Call(napi_value recv, 1532 const std::vector<napi_value>& args) const; 1533 MaybeOrValue<Value> Call(napi_value recv, 1534 const std::vector<Value>& args) const; 1535 MaybeOrValue<Value> Call(napi_value recv, 1536 size_t argc, 1537 const napi_value* args) const; 1538 1539 MaybeOrValue<Value> MakeCallback( 1540 napi_value recv, 1541 const std::initializer_list<napi_value>& args, 1542 napi_async_context context = nullptr) const; 1543 MaybeOrValue<Value> MakeCallback(napi_value recv, 1544 const std::vector<napi_value>& args, 1545 napi_async_context context = nullptr) const; 1546 MaybeOrValue<Value> MakeCallback(napi_value recv, 1547 size_t argc, 1548 const napi_value* args, 1549 napi_async_context context = nullptr) const; 1550 1551 MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const; 1552 MaybeOrValue<Object> New(const std::vector<napi_value>& args) const; 1553 MaybeOrValue<Object> New(size_t argc, const napi_value* args) const; 1554}; 1555 1556class Promise : public Object { 1557 public: 1558 class Deferred { 1559 public: 1560 static Deferred New(napi_env env); 1561 Deferred(napi_env env); 1562 1563 Napi::Promise Promise() const; 1564 Napi::Env Env() const; 1565 1566 void Resolve(napi_value value) const; 1567 void Reject(napi_value value) const; 1568 1569 private: 1570 napi_env _env; 1571 napi_deferred _deferred; 1572 napi_value _promise; 1573 }; 1574 1575 static void CheckCast(napi_env env, napi_value value); 1576 1577 Promise(); 1578 Promise(napi_env env, napi_value value); 1579 1580 MaybeOrValue<Promise> Then(napi_value onFulfilled) const; 1581 MaybeOrValue<Promise> Then(napi_value onFulfilled, 1582 napi_value onRejected) const; 1583 MaybeOrValue<Promise> Catch(napi_value onRejected) const; 1584 1585 MaybeOrValue<Promise> Then(const Function& onFulfilled) const; 1586 MaybeOrValue<Promise> Then(const Function& onFulfilled, 1587 const Function& onRejected) const; 1588 MaybeOrValue<Promise> Catch(const Function& onRejected) const; 1589}; 1590 1591template <typename T> 1592class Buffer : public Uint8Array { 1593 public: 1594 static Buffer<T> New(napi_env env, size_t length); 1595#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED 1596 static Buffer<T> New(napi_env env, T* data, size_t length); 1597 1598 // Finalizer must implement `void operator()(Env env, T* data)`. 1599 template <typename Finalizer> 1600 static Buffer<T> New(napi_env env, 1601 T* data, 1602 size_t length, 1603 Finalizer finalizeCallback); 1604 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. 1605 template <typename Finalizer, typename Hint> 1606 static Buffer<T> New(napi_env env, 1607 T* data, 1608 size_t length, 1609 Finalizer finalizeCallback, 1610 Hint* finalizeHint); 1611#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED 1612 1613 static Buffer<T> NewOrCopy(napi_env env, T* data, size_t length); 1614 // Finalizer must implement `void operator()(Env env, T* data)`. 1615 template <typename Finalizer> 1616 static Buffer<T> NewOrCopy(napi_env env, 1617 T* data, 1618 size_t length, 1619 Finalizer finalizeCallback); 1620 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. 1621 template <typename Finalizer, typename Hint> 1622 static Buffer<T> NewOrCopy(napi_env env, 1623 T* data, 1624 size_t length, 1625 Finalizer finalizeCallback, 1626 Hint* finalizeHint); 1627 1628 static Buffer<T> Copy(napi_env env, const T* data, size_t length); 1629 1630 static void CheckCast(napi_env env, napi_value value); 1631 1632 Buffer(); 1633 Buffer(napi_env env, napi_value value); 1634 size_t Length() const; 1635 T* Data() const; 1636 1637 private: 1638}; 1639 1640/// Holds a counted reference to a value; initially a weak reference unless 1641/// otherwise specified, may be changed to/from a strong reference by adjusting 1642/// the refcount. 1643/// 1644/// The referenced value is not immediately destroyed when the reference count 1645/// is zero; it is merely then eligible for garbage-collection if there are no 1646/// other references to the value. 1647template <typename T> 1648class Reference { 1649 public: 1650 static Reference<T> New(const T& value, uint32_t initialRefcount = 0); 1651 1652 Reference(); 1653 Reference(napi_env env, napi_ref ref); 1654 ~Reference(); 1655 1656 // A reference can be moved but cannot be copied. 1657 Reference(Reference<T>&& other); 1658 Reference<T>& operator=(Reference<T>&& other); 1659 NAPI_DISALLOW_ASSIGN(Reference<T>) 1660 1661 operator napi_ref() const; 1662 bool operator==(const Reference<T>& other) const; 1663 bool operator!=(const Reference<T>& other) const; 1664 1665 Napi::Env Env() const; 1666 bool IsEmpty() const; 1667 1668 // Note when getting the value of a Reference it is usually correct to do so 1669 // within a HandleScope so that the value handle gets cleaned up efficiently. 1670 T Value() const; 1671 1672 uint32_t Ref() const; 1673 uint32_t Unref() const; 1674 void Reset(); 1675 void Reset(const T& value, uint32_t refcount = 0); 1676 1677 // Call this on a reference that is declared as static data, to prevent its 1678 // destructor from running at program shutdown time, which would attempt to 1679 // reset the reference when the environment is no longer valid. Avoid using 1680 // this if at all possible. If you do need to use static data, MAKE SURE to 1681 // warn your users that your addon is NOT threadsafe. 1682 void SuppressDestruct(); 1683 1684 protected: 1685 Reference(const Reference<T>&); 1686 1687 /// !cond INTERNAL 1688 napi_env _env; 1689 napi_ref _ref; 1690 /// !endcond 1691 1692 private: 1693 bool _suppressDestruct; 1694}; 1695 1696class ObjectReference : public Reference<Object> { 1697 public: 1698 ObjectReference(); 1699 ObjectReference(napi_env env, napi_ref ref); 1700 1701 // A reference can be moved but cannot be copied. 1702 ObjectReference(Reference<Object>&& other); 1703 ObjectReference& operator=(Reference<Object>&& other); 1704 ObjectReference(ObjectReference&& other); 1705 ObjectReference& operator=(ObjectReference&& other); 1706 NAPI_DISALLOW_ASSIGN(ObjectReference) 1707 1708 MaybeOrValue<Napi::Value> Get(const char* utf8name) const; 1709 MaybeOrValue<Napi::Value> Get(const std::string& utf8name) const; 1710 MaybeOrValue<bool> Set(const char* utf8name, napi_value value) const; 1711 MaybeOrValue<bool> Set(const char* utf8name, Napi::Value value) const; 1712 MaybeOrValue<bool> Set(const char* utf8name, const char* utf8value) const; 1713 MaybeOrValue<bool> Set(const char* utf8name, bool boolValue) const; 1714 MaybeOrValue<bool> Set(const char* utf8name, double numberValue) const; 1715 MaybeOrValue<bool> Set(const std::string& utf8name, napi_value value) const; 1716 MaybeOrValue<bool> Set(const std::string& utf8name, Napi::Value value) const; 1717 MaybeOrValue<bool> Set(const std::string& utf8name, 1718 std::string& utf8value) const; 1719 MaybeOrValue<bool> Set(const std::string& utf8name, bool boolValue) const; 1720 MaybeOrValue<bool> Set(const std::string& utf8name, double numberValue) const; 1721 1722 MaybeOrValue<Napi::Value> Get(uint32_t index) const; 1723 MaybeOrValue<bool> Set(uint32_t index, const napi_value value) const; 1724 MaybeOrValue<bool> Set(uint32_t index, const Napi::Value value) const; 1725 MaybeOrValue<bool> Set(uint32_t index, const char* utf8value) const; 1726 MaybeOrValue<bool> Set(uint32_t index, const std::string& utf8value) const; 1727 MaybeOrValue<bool> Set(uint32_t index, bool boolValue) const; 1728 MaybeOrValue<bool> Set(uint32_t index, double numberValue) const; 1729 1730 protected: 1731 ObjectReference(const ObjectReference&); 1732}; 1733 1734class FunctionReference : public Reference<Function> { 1735 public: 1736 FunctionReference(); 1737 FunctionReference(napi_env env, napi_ref ref); 1738 1739 // A reference can be moved but cannot be copied. 1740 FunctionReference(Reference<Function>&& other); 1741 FunctionReference& operator=(Reference<Function>&& other); 1742 FunctionReference(FunctionReference&& other); 1743 FunctionReference& operator=(FunctionReference&& other); 1744 NAPI_DISALLOW_ASSIGN_COPY(FunctionReference) 1745 1746 MaybeOrValue<Napi::Value> operator()( 1747 const std::initializer_list<napi_value>& args) const; 1748 1749 MaybeOrValue<Napi::Value> Call( 1750 const std::initializer_list<napi_value>& args) const; 1751 MaybeOrValue<Napi::Value> Call(const std::vector<napi_value>& args) const; 1752 MaybeOrValue<Napi::Value> Call( 1753 napi_value recv, const std::initializer_list<napi_value>& args) const; 1754 MaybeOrValue<Napi::Value> Call(napi_value recv, 1755 const std::vector<napi_value>& args) const; 1756 MaybeOrValue<Napi::Value> Call(napi_value recv, 1757 size_t argc, 1758 const napi_value* args) const; 1759 1760 MaybeOrValue<Napi::Value> MakeCallback( 1761 napi_value recv, 1762 const std::initializer_list<napi_value>& args, 1763 napi_async_context context = nullptr) const; 1764 MaybeOrValue<Napi::Value> MakeCallback( 1765 napi_value recv, 1766 const std::vector<napi_value>& args, 1767 napi_async_context context = nullptr) const; 1768 MaybeOrValue<Napi::Value> MakeCallback( 1769 napi_value recv, 1770 size_t argc, 1771 const napi_value* args, 1772 napi_async_context context = nullptr) const; 1773 1774 MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const; 1775 MaybeOrValue<Object> New(const std::vector<napi_value>& args) const; 1776}; 1777 1778// Shortcuts to creating a new reference with inferred type and refcount = 0. 1779template <typename T> 1780Reference<T> Weak(T value); 1781ObjectReference Weak(Object value); 1782FunctionReference Weak(Function value); 1783 1784// Shortcuts to creating a new reference with inferred type and refcount = 1. 1785template <typename T> 1786Reference<T> Persistent(T value); 1787ObjectReference Persistent(Object value); 1788FunctionReference Persistent(Function value); 1789 1790/// A persistent reference to a JavaScript error object. Use of this class 1791/// depends somewhat on whether C++ exceptions are enabled at compile time. 1792/// 1793/// ### Handling Errors With C++ Exceptions 1794/// 1795/// If C++ exceptions are enabled, then the `Error` class extends 1796/// `std::exception` and enables integrated error-handling for C++ exceptions 1797/// and JavaScript exceptions. 1798/// 1799/// If a Node-API call fails without executing any JavaScript code (for 1800/// example due to an invalid argument), then the Node-API wrapper 1801/// automatically converts and throws the error as a C++ exception of type 1802/// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API 1803/// throws a JavaScript exception, then the Node-API wrapper automatically 1804/// converts and throws it as a C++ exception of type `Napi::Error`. 1805/// 1806/// If a C++ exception of type `Napi::Error` escapes from a Node-API C++ 1807/// callback, then the Node-API wrapper automatically converts and throws it 1808/// as a JavaScript exception. Therefore, catching a C++ exception of type 1809/// `Napi::Error` prevents a JavaScript exception from being thrown. 1810/// 1811/// #### Example 1A - Throwing a C++ exception: 1812/// 1813/// Napi::Env env = ... 1814/// throw Napi::Error::New(env, "Example exception"); 1815/// 1816/// Following C++ statements will not be executed. The exception will bubble 1817/// up as a C++ exception of type `Napi::Error`, until it is either caught 1818/// while still in C++, or else automatically propagated as a JavaScript 1819/// exception when the callback returns to JavaScript. 1820/// 1821/// #### Example 2A - Propagating a Node-API C++ exception: 1822/// 1823/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); 1824/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); 1825/// 1826/// Following C++ statements will not be executed. The exception will bubble 1827/// up as a C++ exception of type `Napi::Error`, until it is either caught 1828/// while still in C++, or else automatically propagated as a JavaScript 1829/// exception when the callback returns to JavaScript. 1830/// 1831/// #### Example 3A - Handling a Node-API C++ exception: 1832/// 1833/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); 1834/// Napi::Value result; 1835/// try { 1836/// result = jsFunctionThatThrows({ arg1, arg2 }); 1837/// } catch (const Napi::Error& e) { 1838/// cerr << "Caught JavaScript exception: " + e.what(); 1839/// } 1840/// 1841/// Since the exception was caught here, it will not be propagated as a 1842/// JavaScript exception. 1843/// 1844/// ### Handling Errors Without C++ Exceptions 1845/// 1846/// If C++ exceptions are disabled (by defining 1847/// `NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS`) then this class does not extend 1848/// `std::exception`, and APIs in the `Napi` namespace do not throw C++ 1849/// exceptions when they fail. Instead, they raise _pending_ JavaScript 1850/// exceptions and return _empty_ `Value`s. Calling code should check 1851/// `Value::IsEmpty()` before attempting to use a returned value, and may use 1852/// methods on the `Env` class to check for, get, and clear a pending JavaScript 1853/// exception. If the pending exception is not cleared, it will be thrown when 1854/// the native callback returns to JavaScript. 1855/// 1856/// #### Example 1B - Throwing a JS exception 1857/// 1858/// Napi::Env env = ... 1859/// Napi::Error::New(env, "Example 1860/// exception").ThrowAsJavaScriptException(); return; 1861/// 1862/// After throwing a JS exception, the code should generally return 1863/// immediately from the native callback, after performing any necessary 1864/// cleanup. 1865/// 1866/// #### Example 2B - Propagating a Node-API JS exception: 1867/// 1868/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); 1869/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); 1870/// if (result.IsEmpty()) return; 1871/// 1872/// An empty value result from a Node-API call indicates an error occurred, 1873/// and a JavaScript exception is pending. To let the exception propagate, the 1874/// code should generally return immediately from the native callback, after 1875/// performing any necessary cleanup. 1876/// 1877/// #### Example 3B - Handling a Node-API JS exception: 1878/// 1879/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); 1880/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); 1881/// if (result.IsEmpty()) { 1882/// Napi::Error e = env.GetAndClearPendingException(); 1883/// cerr << "Caught JavaScript exception: " + e.Message(); 1884/// } 1885/// 1886/// Since the exception was cleared here, it will not be propagated as a 1887/// JavaScript exception after the native callback returns. 1888class Error : public ObjectReference 1889#ifdef NODE_ADDON_API_CPP_EXCEPTIONS 1890 , 1891 public std::exception 1892#endif // NODE_ADDON_API_CPP_EXCEPTIONS 1893{ 1894 public: 1895 static Error New(napi_env env); 1896 static Error New(napi_env env, const char* message); 1897 static Error New(napi_env env, const std::string& message); 1898 1899 static NAPI_NO_RETURN void Fatal(const char* location, const char* message); 1900 1901 Error(); 1902 Error(napi_env env, napi_value value); 1903 1904 // An error can be moved or copied. 1905 Error(Error&& other); 1906 Error& operator=(Error&& other); 1907 Error(const Error&); 1908 Error& operator=(const Error&); 1909 1910 const std::string& Message() const NAPI_NOEXCEPT; 1911 void ThrowAsJavaScriptException() const; 1912 1913 Object Value() const; 1914 1915#ifdef NODE_ADDON_API_CPP_EXCEPTIONS 1916 const char* what() const NAPI_NOEXCEPT override; 1917#endif // NODE_ADDON_API_CPP_EXCEPTIONS 1918 1919 protected: 1920 /// !cond INTERNAL 1921 using create_error_fn = napi_status (*)(napi_env envb, 1922 napi_value code, 1923 napi_value msg, 1924 napi_value* result); 1925 1926 template <typename TError> 1927 static TError New(napi_env env, 1928 const char* message, 1929 size_t length, 1930 create_error_fn create_error); 1931 /// !endcond 1932 1933 private: 1934 static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT; 1935 mutable std::string _message; 1936}; 1937 1938class TypeError : public Error { 1939 public: 1940 static TypeError New(napi_env env, const char* message); 1941 static TypeError New(napi_env env, const std::string& message); 1942 1943 TypeError(); 1944 TypeError(napi_env env, napi_value value); 1945}; 1946 1947class RangeError : public Error { 1948 public: 1949 static RangeError New(napi_env env, const char* message); 1950 static RangeError New(napi_env env, const std::string& message); 1951 1952 RangeError(); 1953 RangeError(napi_env env, napi_value value); 1954}; 1955 1956#if NAPI_VERSION > 8 1957class SyntaxError : public Error { 1958 public: 1959 static SyntaxError New(napi_env env, const char* message); 1960 static SyntaxError New(napi_env env, const std::string& message); 1961 1962 SyntaxError(); 1963 SyntaxError(napi_env env, napi_value value); 1964}; 1965#endif // NAPI_VERSION > 8 1966 1967class CallbackInfo { 1968 public: 1969 CallbackInfo(napi_env env, napi_callback_info info); 1970 ~CallbackInfo(); 1971 1972 // Disallow copying to prevent multiple free of _dynamicArgs 1973 NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo) 1974 1975 Napi::Env Env() const; 1976 Value NewTarget() const; 1977 bool IsConstructCall() const; 1978 size_t Length() const; 1979 const Value operator[](size_t index) const; 1980 Value This() const; 1981 void* Data() const; 1982 void SetData(void* data); 1983 explicit operator napi_callback_info() const; 1984 1985 private: 1986 const size_t _staticArgCount = 6; 1987 napi_env _env; 1988 napi_callback_info _info; 1989 napi_value _this; 1990 size_t _argc; 1991 napi_value* _argv; 1992 napi_value _staticArgs[6]{}; 1993 napi_value* _dynamicArgs; 1994 void* _data; 1995}; 1996 1997class PropertyDescriptor { 1998 public: 1999 using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info); 2000 using SetterCallback = void (*)(const Napi::CallbackInfo& info); 2001 2002#ifndef NODE_ADDON_API_DISABLE_DEPRECATED 2003 template <typename Getter> 2004 static PropertyDescriptor Accessor( 2005 const char* utf8name, 2006 Getter getter, 2007 napi_property_attributes attributes = napi_default, 2008 void* data = nullptr); 2009 template <typename Getter> 2010 static PropertyDescriptor Accessor( 2011 const std::string& utf8name, 2012 Getter getter, 2013 napi_property_attributes attributes = napi_default, 2014 void* data = nullptr); 2015 template <typename Getter> 2016 static PropertyDescriptor Accessor( 2017 napi_value name, 2018 Getter getter, 2019 napi_property_attributes attributes = napi_default, 2020 void* data = nullptr); 2021 template <typename Getter> 2022 static PropertyDescriptor Accessor( 2023 Name name, 2024 Getter getter, 2025 napi_property_attributes attributes = napi_default, 2026 void* data = nullptr); 2027 template <typename Getter, typename Setter> 2028 static PropertyDescriptor Accessor( 2029 const char* utf8name, 2030 Getter getter, 2031 Setter setter, 2032 napi_property_attributes attributes = napi_default, 2033 void* data = nullptr); 2034 template <typename Getter, typename Setter> 2035 static PropertyDescriptor Accessor( 2036 const std::string& utf8name, 2037 Getter getter, 2038 Setter setter, 2039 napi_property_attributes attributes = napi_default, 2040 void* data = nullptr); 2041 template <typename Getter, typename Setter> 2042 static PropertyDescriptor Accessor( 2043 napi_value name, 2044 Getter getter, 2045 Setter setter, 2046 napi_property_attributes attributes = napi_default, 2047 void* data = nullptr); 2048 template <typename Getter, typename Setter> 2049 static PropertyDescriptor Accessor( 2050 Name name, 2051 Getter getter, 2052 Setter setter, 2053 napi_property_attributes attributes = napi_default, 2054 void* data = nullptr); 2055 template <typename Callable> 2056 static PropertyDescriptor Function( 2057 const char* utf8name, 2058 Callable cb, 2059 napi_property_attributes attributes = napi_default, 2060 void* data = nullptr); 2061 template <typename Callable> 2062 static PropertyDescriptor Function( 2063 const std::string& utf8name, 2064 Callable cb, 2065 napi_property_attributes attributes = napi_default, 2066 void* data = nullptr); 2067 template <typename Callable> 2068 static PropertyDescriptor Function( 2069 napi_value name, 2070 Callable cb, 2071 napi_property_attributes attributes = napi_default, 2072 void* data = nullptr); 2073 template <typename Callable> 2074 static PropertyDescriptor Function( 2075 Name name, 2076 Callable cb, 2077 napi_property_attributes attributes = napi_default, 2078 void* data = nullptr); 2079#endif // !NODE_ADDON_API_DISABLE_DEPRECATED 2080 2081 template <GetterCallback Getter> 2082 static PropertyDescriptor Accessor( 2083 const char* utf8name, 2084 napi_property_attributes attributes = napi_default, 2085 void* data = nullptr); 2086 2087 template <GetterCallback Getter> 2088 static PropertyDescriptor Accessor( 2089 const std::string& utf8name, 2090 napi_property_attributes attributes = napi_default, 2091 void* data = nullptr); 2092 2093 template <GetterCallback Getter> 2094 static PropertyDescriptor Accessor( 2095 Name name, 2096 napi_property_attributes attributes = napi_default, 2097 void* data = nullptr); 2098 2099 template <GetterCallback Getter, SetterCallback Setter> 2100 static PropertyDescriptor Accessor( 2101 const char* utf8name, 2102 napi_property_attributes attributes = napi_default, 2103 void* data = nullptr); 2104 2105 template <GetterCallback Getter, SetterCallback Setter> 2106 static PropertyDescriptor Accessor( 2107 const std::string& utf8name, 2108 napi_property_attributes attributes = napi_default, 2109 void* data = nullptr); 2110 2111 template <GetterCallback Getter, SetterCallback Setter> 2112 static PropertyDescriptor Accessor( 2113 Name name, 2114 napi_property_attributes attributes = napi_default, 2115 void* data = nullptr); 2116 2117 template <typename Getter> 2118 static PropertyDescriptor Accessor( 2119 Napi::Env env, 2120 Napi::Object object, 2121 const char* utf8name, 2122 Getter getter, 2123 napi_property_attributes attributes = napi_default, 2124 void* data = nullptr); 2125 template <typename Getter> 2126 static PropertyDescriptor Accessor( 2127 Napi::Env env, 2128 Napi::Object object, 2129 const std::string& utf8name, 2130 Getter getter, 2131 napi_property_attributes attributes = napi_default, 2132 void* data = nullptr); 2133 template <typename Getter> 2134 static PropertyDescriptor Accessor( 2135 Napi::Env env, 2136 Napi::Object object, 2137 Name name, 2138 Getter getter, 2139 napi_property_attributes attributes = napi_default, 2140 void* data = nullptr); 2141 template <typename Getter, typename Setter> 2142 static PropertyDescriptor Accessor( 2143 Napi::Env env, 2144 Napi::Object object, 2145 const char* utf8name, 2146 Getter getter, 2147 Setter setter, 2148 napi_property_attributes attributes = napi_default, 2149 void* data = nullptr); 2150 template <typename Getter, typename Setter> 2151 static PropertyDescriptor Accessor( 2152 Napi::Env env, 2153 Napi::Object object, 2154 const std::string& utf8name, 2155 Getter getter, 2156 Setter setter, 2157 napi_property_attributes attributes = napi_default, 2158 void* data = nullptr); 2159 template <typename Getter, typename Setter> 2160 static PropertyDescriptor Accessor( 2161 Napi::Env env, 2162 Napi::Object object, 2163 Name name, 2164 Getter getter, 2165 Setter setter, 2166 napi_property_attributes attributes = napi_default, 2167 void* data = nullptr); 2168 template <typename Callable> 2169 static PropertyDescriptor Function( 2170 Napi::Env env, 2171 Napi::Object object, 2172 const char* utf8name, 2173 Callable cb, 2174 napi_property_attributes attributes = napi_default, 2175 void* data = nullptr); 2176 template <typename Callable> 2177 static PropertyDescriptor Function( 2178 Napi::Env env, 2179 Napi::Object object, 2180 const std::string& utf8name, 2181 Callable cb, 2182 napi_property_attributes attributes = napi_default, 2183 void* data = nullptr); 2184 template <typename Callable> 2185 static PropertyDescriptor Function( 2186 Napi::Env env, 2187 Napi::Object object, 2188 Name name, 2189 Callable cb, 2190 napi_property_attributes attributes = napi_default, 2191 void* data = nullptr); 2192 static PropertyDescriptor Value( 2193 const char* utf8name, 2194 napi_value value, 2195 napi_property_attributes attributes = napi_default); 2196 static PropertyDescriptor Value( 2197 const std::string& utf8name, 2198 napi_value value, 2199 napi_property_attributes attributes = napi_default); 2200 static PropertyDescriptor Value( 2201 napi_value name, 2202 napi_value value, 2203 napi_property_attributes attributes = napi_default); 2204 static PropertyDescriptor Value( 2205 Name name, 2206 Napi::Value value, 2207 napi_property_attributes attributes = napi_default); 2208 2209 PropertyDescriptor(napi_property_descriptor desc); 2210 2211 operator napi_property_descriptor&(); 2212 operator const napi_property_descriptor&() const; 2213 2214 private: 2215 napi_property_descriptor _desc; 2216}; 2217 2218/// Property descriptor for use with `ObjectWrap::DefineClass()`. 2219/// 2220/// This is different from the standalone `PropertyDescriptor` because it is 2221/// specific to each `ObjectWrap<T>` subclass. This prevents using descriptors 2222/// from a different class when defining a new class (preventing the callbacks 2223/// from having incorrect `this` pointers). 2224template <typename T> 2225class ClassPropertyDescriptor { 2226 public: 2227 ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} 2228 2229 operator napi_property_descriptor&() { return _desc; } 2230 operator const napi_property_descriptor&() const { return _desc; } 2231 2232 private: 2233 napi_property_descriptor _desc; 2234}; 2235 2236template <typename T, typename TCallback> 2237struct MethodCallbackData { 2238 TCallback callback; 2239 void* data; 2240}; 2241 2242template <typename T, typename TGetterCallback, typename TSetterCallback> 2243struct AccessorCallbackData { 2244 TGetterCallback getterCallback; 2245 TSetterCallback setterCallback; 2246 void* data; 2247}; 2248 2249template <typename T> 2250class InstanceWrap { 2251 public: 2252 using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info); 2253 using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info); 2254 using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info); 2255 using InstanceSetterCallback = void (T::*)(const CallbackInfo& info, 2256 const Napi::Value& value); 2257 2258 using PropertyDescriptor = ClassPropertyDescriptor<T>; 2259 2260 static PropertyDescriptor InstanceMethod( 2261 const char* utf8name, 2262 InstanceVoidMethodCallback method, 2263 napi_property_attributes attributes = napi_default, 2264 void* data = nullptr); 2265 static PropertyDescriptor InstanceMethod( 2266 const char* utf8name, 2267 InstanceMethodCallback method, 2268 napi_property_attributes attributes = napi_default, 2269 void* data = nullptr); 2270 static PropertyDescriptor InstanceMethod( 2271 Symbol name, 2272 InstanceVoidMethodCallback method, 2273 napi_property_attributes attributes = napi_default, 2274 void* data = nullptr); 2275 static PropertyDescriptor InstanceMethod( 2276 Symbol name, 2277 InstanceMethodCallback method, 2278 napi_property_attributes attributes = napi_default, 2279 void* data = nullptr); 2280 template <InstanceVoidMethodCallback method> 2281 static PropertyDescriptor InstanceMethod( 2282 const char* utf8name, 2283 napi_property_attributes attributes = napi_default, 2284 void* data = nullptr); 2285 template <InstanceMethodCallback method> 2286 static PropertyDescriptor InstanceMethod( 2287 const char* utf8name, 2288 napi_property_attributes attributes = napi_default, 2289 void* data = nullptr); 2290 template <InstanceVoidMethodCallback method> 2291 static PropertyDescriptor InstanceMethod( 2292 Symbol name, 2293 napi_property_attributes attributes = napi_default, 2294 void* data = nullptr); 2295 template <InstanceMethodCallback method> 2296 static PropertyDescriptor InstanceMethod( 2297 Symbol name, 2298 napi_property_attributes attributes = napi_default, 2299 void* data = nullptr); 2300 static PropertyDescriptor InstanceAccessor( 2301 const char* utf8name, 2302 InstanceGetterCallback getter, 2303 InstanceSetterCallback setter, 2304 napi_property_attributes attributes = napi_default, 2305 void* data = nullptr); 2306 static PropertyDescriptor InstanceAccessor( 2307 Symbol name, 2308 InstanceGetterCallback getter, 2309 InstanceSetterCallback setter, 2310 napi_property_attributes attributes = napi_default, 2311 void* data = nullptr); 2312 template <InstanceGetterCallback getter, 2313 InstanceSetterCallback setter = nullptr> 2314 static PropertyDescriptor InstanceAccessor( 2315 const char* utf8name, 2316 napi_property_attributes attributes = napi_default, 2317 void* data = nullptr); 2318 template <InstanceGetterCallback getter, 2319 InstanceSetterCallback setter = nullptr> 2320 static PropertyDescriptor InstanceAccessor( 2321 Symbol name, 2322 napi_property_attributes attributes = napi_default, 2323 void* data = nullptr); 2324 static PropertyDescriptor InstanceValue( 2325 const char* utf8name, 2326 Napi::Value value, 2327 napi_property_attributes attributes = napi_default); 2328 static PropertyDescriptor InstanceValue( 2329 Symbol name, 2330 Napi::Value value, 2331 napi_property_attributes attributes = napi_default); 2332 2333 protected: 2334 static void AttachPropData(napi_env env, 2335 napi_value value, 2336 const napi_property_descriptor* prop); 2337 2338 private: 2339 using This = InstanceWrap<T>; 2340 2341 using InstanceVoidMethodCallbackData = 2342 MethodCallbackData<T, InstanceVoidMethodCallback>; 2343 using InstanceMethodCallbackData = 2344 MethodCallbackData<T, InstanceMethodCallback>; 2345 using InstanceAccessorCallbackData = 2346 AccessorCallbackData<T, InstanceGetterCallback, InstanceSetterCallback>; 2347 2348 static napi_value InstanceVoidMethodCallbackWrapper(napi_env env, 2349 napi_callback_info info); 2350 static napi_value InstanceMethodCallbackWrapper(napi_env env, 2351 napi_callback_info info); 2352 static napi_value InstanceGetterCallbackWrapper(napi_env env, 2353 napi_callback_info info); 2354 static napi_value InstanceSetterCallbackWrapper(napi_env env, 2355 napi_callback_info info); 2356 2357 template <InstanceSetterCallback method> 2358 static napi_value WrappedMethod(napi_env env, 2359 napi_callback_info info) NAPI_NOEXCEPT; 2360 2361 template <InstanceSetterCallback setter> 2362 struct SetterTag {}; 2363 2364 template <InstanceSetterCallback setter> 2365 static napi_callback WrapSetter(SetterTag<setter>) NAPI_NOEXCEPT { 2366 return &This::WrappedMethod<setter>; 2367 } 2368 static napi_callback WrapSetter(SetterTag<nullptr>) NAPI_NOEXCEPT { 2369 return nullptr; 2370 } 2371}; 2372 2373/// Base class to be extended by C++ classes exposed to JavaScript; each C++ 2374/// class instance gets "wrapped" by a JavaScript object that is managed by this 2375/// class. 2376/// 2377/// At initialization time, the `DefineClass()` method must be used to 2378/// hook up the accessor and method callbacks. It takes a list of 2379/// property descriptors, which can be constructed via the various 2380/// static methods on the base class. 2381/// 2382/// #### Example: 2383/// 2384/// class Example: public Napi::ObjectWrap<Example> { 2385/// public: 2386/// static void Initialize(Napi::Env& env, Napi::Object& target) { 2387/// Napi::Function constructor = DefineClass(env, "Example", { 2388/// InstanceAccessor<&Example::GetSomething, 2389/// &Example::SetSomething>("value"), 2390/// InstanceMethod<&Example::DoSomething>("doSomething"), 2391/// }); 2392/// target.Set("Example", constructor); 2393/// } 2394/// 2395/// Example(const Napi::CallbackInfo& info); // Constructor 2396/// Napi::Value GetSomething(const Napi::CallbackInfo& info); 2397/// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value& 2398/// value); Napi::Value DoSomething(const Napi::CallbackInfo& info); 2399/// } 2400template <typename T> 2401class ObjectWrap : public InstanceWrap<T>, public Reference<Object> { 2402 public: 2403 ObjectWrap(const CallbackInfo& callbackInfo); 2404 virtual ~ObjectWrap(); 2405 2406 static T* Unwrap(Object wrapper); 2407 2408 // Methods exposed to JavaScript must conform to one of these callback 2409 // signatures. 2410 using StaticVoidMethodCallback = void (*)(const CallbackInfo& info); 2411 using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info); 2412 using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info); 2413 using StaticSetterCallback = void (*)(const CallbackInfo& info, 2414 const Napi::Value& value); 2415 2416 using PropertyDescriptor = ClassPropertyDescriptor<T>; 2417 2418 static Function DefineClass( 2419 Napi::Env env, 2420 const char* utf8name, 2421 const std::initializer_list<PropertyDescriptor>& properties, 2422 void* data = nullptr); 2423 static Function DefineClass(Napi::Env env, 2424 const char* utf8name, 2425 const std::vector<PropertyDescriptor>& properties, 2426 void* data = nullptr); 2427 static PropertyDescriptor StaticMethod( 2428 const char* utf8name, 2429 StaticVoidMethodCallback method, 2430 napi_property_attributes attributes = napi_default, 2431 void* data = nullptr); 2432 static PropertyDescriptor StaticMethod( 2433 const char* utf8name, 2434 StaticMethodCallback method, 2435 napi_property_attributes attributes = napi_default, 2436 void* data = nullptr); 2437 static PropertyDescriptor StaticMethod( 2438 Symbol name, 2439 StaticVoidMethodCallback method, 2440 napi_property_attributes attributes = napi_default, 2441 void* data = nullptr); 2442 static PropertyDescriptor StaticMethod( 2443 Symbol name, 2444 StaticMethodCallback method, 2445 napi_property_attributes attributes = napi_default, 2446 void* data = nullptr); 2447 template <StaticVoidMethodCallback method> 2448 static PropertyDescriptor StaticMethod( 2449 const char* utf8name, 2450 napi_property_attributes attributes = napi_default, 2451 void* data = nullptr); 2452 template <StaticVoidMethodCallback method> 2453 static PropertyDescriptor StaticMethod( 2454 Symbol name, 2455 napi_property_attributes attributes = napi_default, 2456 void* data = nullptr); 2457 template <StaticMethodCallback method> 2458 static PropertyDescriptor StaticMethod( 2459 const char* utf8name, 2460 napi_property_attributes attributes = napi_default, 2461 void* data = nullptr); 2462 template <StaticMethodCallback method> 2463 static PropertyDescriptor StaticMethod( 2464 Symbol name, 2465 napi_property_attributes attributes = napi_default, 2466 void* data = nullptr); 2467 static PropertyDescriptor StaticAccessor( 2468 const char* utf8name, 2469 StaticGetterCallback getter, 2470 StaticSetterCallback setter, 2471 napi_property_attributes attributes = napi_default, 2472 void* data = nullptr); 2473 static PropertyDescriptor StaticAccessor( 2474 Symbol name, 2475 StaticGetterCallback getter, 2476 StaticSetterCallback setter, 2477 napi_property_attributes attributes = napi_default, 2478 void* data = nullptr); 2479 template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr> 2480 static PropertyDescriptor StaticAccessor( 2481 const char* utf8name, 2482 napi_property_attributes attributes = napi_default, 2483 void* data = nullptr); 2484 template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr> 2485 static PropertyDescriptor StaticAccessor( 2486 Symbol name, 2487 napi_property_attributes attributes = napi_default, 2488 void* data = nullptr); 2489 static PropertyDescriptor StaticValue( 2490 const char* utf8name, 2491 Napi::Value value, 2492 napi_property_attributes attributes = napi_default); 2493 static PropertyDescriptor StaticValue( 2494 Symbol name, 2495 Napi::Value value, 2496 napi_property_attributes attributes = napi_default); 2497 static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo); 2498 virtual void Finalize(Napi::Env env); 2499 virtual void Finalize(BasicEnv env); 2500 2501 private: 2502 using This = ObjectWrap<T>; 2503 2504 static napi_value ConstructorCallbackWrapper(napi_env env, 2505 napi_callback_info info); 2506 static napi_value StaticVoidMethodCallbackWrapper(napi_env env, 2507 napi_callback_info info); 2508 static napi_value StaticMethodCallbackWrapper(napi_env env, 2509 napi_callback_info info); 2510 static napi_value StaticGetterCallbackWrapper(napi_env env, 2511 napi_callback_info info); 2512 static napi_value StaticSetterCallbackWrapper(napi_env env, 2513 napi_callback_info info); 2514 static void FinalizeCallback(node_addon_api_basic_env env, 2515 void* data, 2516 void* hint); 2517 2518 static void PostFinalizeCallback(napi_env env, void* data, void* hint); 2519 2520 static Function DefineClass(Napi::Env env, 2521 const char* utf8name, 2522 const size_t props_count, 2523 const napi_property_descriptor* props, 2524 void* data = nullptr); 2525 2526 using StaticVoidMethodCallbackData = 2527 MethodCallbackData<T, StaticVoidMethodCallback>; 2528 using StaticMethodCallbackData = MethodCallbackData<T, StaticMethodCallback>; 2529 2530 using StaticAccessorCallbackData = 2531 AccessorCallbackData<T, StaticGetterCallback, StaticSetterCallback>; 2532 2533 template <StaticSetterCallback method> 2534 static napi_value WrappedMethod(napi_env env, 2535 napi_callback_info info) NAPI_NOEXCEPT; 2536 2537 template <StaticSetterCallback setter> 2538 struct StaticSetterTag {}; 2539 2540 template <StaticSetterCallback setter> 2541 static napi_callback WrapStaticSetter(StaticSetterTag<setter>) NAPI_NOEXCEPT { 2542 return &This::WrappedMethod<setter>; 2543 } 2544 static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>) 2545 NAPI_NOEXCEPT { 2546 return nullptr; 2547 } 2548 2549 bool _construction_failed = true; 2550 bool _finalized = false; 2551}; 2552 2553class HandleScope { 2554 public: 2555 HandleScope(napi_env env, napi_handle_scope scope); 2556 explicit HandleScope(Napi::Env env); 2557 ~HandleScope(); 2558 2559 // Disallow copying to prevent double close of napi_handle_scope 2560 NAPI_DISALLOW_ASSIGN_COPY(HandleScope) 2561 2562 operator napi_handle_scope() const; 2563 2564 Napi::Env Env() const; 2565 2566 private: 2567 napi_env _env; 2568 napi_handle_scope _scope; 2569}; 2570 2571class EscapableHandleScope { 2572 public: 2573 EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope); 2574 explicit EscapableHandleScope(Napi::Env env); 2575 ~EscapableHandleScope(); 2576 2577 // Disallow copying to prevent double close of napi_escapable_handle_scope 2578 NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope) 2579 2580 operator napi_escapable_handle_scope() const; 2581 2582 Napi::Env Env() const; 2583 Value Escape(napi_value escapee); 2584 2585 private: 2586 napi_env _env; 2587 napi_escapable_handle_scope _scope; 2588}; 2589 2590#if (NAPI_VERSION > 2) 2591class CallbackScope { 2592 public: 2593 CallbackScope(napi_env env, napi_callback_scope scope); 2594 CallbackScope(napi_env env, napi_async_context context); 2595 virtual ~CallbackScope(); 2596 2597 // Disallow copying to prevent double close of napi_callback_scope 2598 NAPI_DISALLOW_ASSIGN_COPY(CallbackScope) 2599 2600 operator napi_callback_scope() const; 2601 2602 Napi::Env Env() const; 2603 2604 private: 2605 napi_env _env; 2606 napi_callback_scope _scope; 2607}; 2608#endif 2609 2610class AsyncContext { 2611 public: 2612 explicit AsyncContext(napi_env env, const char* resource_name); 2613 explicit AsyncContext(napi_env env, 2614 const char* resource_name, 2615 const Object& resource); 2616 virtual ~AsyncContext(); 2617 2618 AsyncContext(AsyncContext&& other); 2619 AsyncContext& operator=(AsyncContext&& other); 2620 NAPI_DISALLOW_ASSIGN_COPY(AsyncContext) 2621 2622 operator napi_async_context() const; 2623 2624 Napi::Env Env() const; 2625 2626 private: 2627 napi_env _env; 2628 napi_async_context _context; 2629}; 2630 2631#if NAPI_HAS_THREADS 2632class AsyncWorker { 2633 public: 2634 virtual ~AsyncWorker(); 2635 2636 NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker) 2637 2638 operator napi_async_work() const; 2639 2640 Napi::Env Env() const; 2641 2642 void Queue(); 2643 void Cancel(); 2644 void SuppressDestruct(); 2645 2646 ObjectReference& Receiver(); 2647 FunctionReference& Callback(); 2648 2649 virtual void OnExecute(Napi::Env env); 2650 virtual void OnWorkComplete(Napi::Env env, napi_status status); 2651 2652 protected: 2653 explicit AsyncWorker(const Function& callback); 2654 explicit AsyncWorker(const Function& callback, const char* resource_name); 2655 explicit AsyncWorker(const Function& callback, 2656 const char* resource_name, 2657 const Object& resource); 2658 explicit AsyncWorker(const Object& receiver, const Function& callback); 2659 explicit AsyncWorker(const Object& receiver, 2660 const Function& callback, 2661 const char* resource_name); 2662 explicit AsyncWorker(const Object& receiver, 2663 const Function& callback, 2664 const char* resource_name, 2665 const Object& resource); 2666 2667 explicit AsyncWorker(Napi::Env env); 2668 explicit AsyncWorker(Napi::Env env, const char* resource_name); 2669 explicit AsyncWorker(Napi::Env env, 2670 const char* resource_name, 2671 const Object& resource); 2672 2673 virtual void Execute() = 0; 2674 virtual void OnOK(); 2675 virtual void OnError(const Error& e); 2676 virtual void Destroy(); 2677 virtual std::vector<napi_value> GetResult(Napi::Env env); 2678 2679 void SetError(const std::string& error); 2680 2681 private: 2682 static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker); 2683 static inline void OnAsyncWorkComplete(napi_env env, 2684 napi_status status, 2685 void* asyncworker); 2686 2687 napi_env _env; 2688 napi_async_work _work; 2689 ObjectReference _receiver; 2690 FunctionReference _callback; 2691 std::string _error; 2692 bool _suppress_destruct; 2693}; 2694#endif // NAPI_HAS_THREADS 2695 2696#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS) 2697class ThreadSafeFunction { 2698 public: 2699 // This API may only be called from the main thread. 2700 template <typename ResourceString> 2701 static ThreadSafeFunction New(napi_env env, 2702 const Function& callback, 2703 ResourceString resourceName, 2704 size_t maxQueueSize, 2705 size_t initialThreadCount); 2706 2707 // This API may only be called from the main thread. 2708 template <typename ResourceString, typename ContextType> 2709 static ThreadSafeFunction New(napi_env env, 2710 const Function& callback, 2711 ResourceString resourceName, 2712 size_t maxQueueSize, 2713 size_t initialThreadCount, 2714 ContextType* context); 2715 2716 // This API may only be called from the main thread. 2717 template <typename ResourceString, typename Finalizer> 2718 static ThreadSafeFunction New(napi_env env, 2719 const Function& callback, 2720 ResourceString resourceName, 2721 size_t maxQueueSize, 2722 size_t initialThreadCount, 2723 Finalizer finalizeCallback); 2724 2725 // This API may only be called from the main thread. 2726 template <typename ResourceString, 2727 typename Finalizer, 2728 typename FinalizerDataType> 2729 static ThreadSafeFunction New(napi_env env, 2730 const Function& callback, 2731 ResourceString resourceName, 2732 size_t maxQueueSize, 2733 size_t initialThreadCount, 2734 Finalizer finalizeCallback, 2735 FinalizerDataType* data); 2736 2737 // This API may only be called from the main thread. 2738 template <typename ResourceString, typename ContextType, typename Finalizer> 2739 static ThreadSafeFunction New(napi_env env, 2740 const Function& callback, 2741 ResourceString resourceName, 2742 size_t maxQueueSize, 2743 size_t initialThreadCount, 2744 ContextType* context, 2745 Finalizer finalizeCallback); 2746 2747 // This API may only be called from the main thread. 2748 template <typename ResourceString, 2749 typename ContextType, 2750 typename Finalizer, 2751 typename FinalizerDataType> 2752 static ThreadSafeFunction New(napi_env env, 2753 const Function& callback, 2754 ResourceString resourceName, 2755 size_t maxQueueSize, 2756 size_t initialThreadCount, 2757 ContextType* context, 2758 Finalizer finalizeCallback, 2759 FinalizerDataType* data); 2760 2761 // This API may only be called from the main thread. 2762 template <typename ResourceString> 2763 static ThreadSafeFunction New(napi_env env, 2764 const Function& callback, 2765 const Object& resource, 2766 ResourceString resourceName, 2767 size_t maxQueueSize, 2768 size_t initialThreadCount); 2769 2770 // This API may only be called from the main thread. 2771 template <typename ResourceString, typename ContextType> 2772 static ThreadSafeFunction New(napi_env env, 2773 const Function& callback, 2774 const Object& resource, 2775 ResourceString resourceName, 2776 size_t maxQueueSize, 2777 size_t initialThreadCount, 2778 ContextType* context); 2779 2780 // This API may only be called from the main thread. 2781 template <typename ResourceString, typename Finalizer> 2782 static ThreadSafeFunction New(napi_env env, 2783 const Function& callback, 2784 const Object& resource, 2785 ResourceString resourceName, 2786 size_t maxQueueSize, 2787 size_t initialThreadCount, 2788 Finalizer finalizeCallback); 2789 2790 // This API may only be called from the main thread. 2791 template <typename ResourceString, 2792 typename Finalizer, 2793 typename FinalizerDataType> 2794 static ThreadSafeFunction New(napi_env env, 2795 const Function& callback, 2796 const Object& resource, 2797 ResourceString resourceName, 2798 size_t maxQueueSize, 2799 size_t initialThreadCount, 2800 Finalizer finalizeCallback, 2801 FinalizerDataType* data); 2802 2803 // This API may only be called from the main thread. 2804 template <typename ResourceString, typename ContextType, typename Finalizer> 2805 static ThreadSafeFunction New(napi_env env, 2806 const Function& callback, 2807 const Object& resource, 2808 ResourceString resourceName, 2809 size_t maxQueueSize, 2810 size_t initialThreadCount, 2811 ContextType* context, 2812 Finalizer finalizeCallback); 2813 2814 // This API may only be called from the main thread. 2815 template <typename ResourceString, 2816 typename ContextType, 2817 typename Finalizer, 2818 typename FinalizerDataType> 2819 static ThreadSafeFunction New(napi_env env, 2820 const Function& callback, 2821 const Object& resource, 2822 ResourceString resourceName, 2823 size_t maxQueueSize, 2824 size_t initialThreadCount, 2825 ContextType* context, 2826 Finalizer finalizeCallback, 2827 FinalizerDataType* data); 2828 2829 ThreadSafeFunction(); 2830 ThreadSafeFunction(napi_threadsafe_function tsFunctionValue); 2831 2832 operator napi_threadsafe_function() const; 2833 2834 // This API may be called from any thread. 2835 napi_status BlockingCall() const; 2836 2837 // This API may be called from any thread. 2838 template <typename Callback> 2839 napi_status BlockingCall(Callback callback) const; 2840 2841 // This API may be called from any thread. 2842 template <typename DataType, typename Callback> 2843 napi_status BlockingCall(DataType* data, Callback callback) const; 2844 2845 // This API may be called from any thread. 2846 napi_status NonBlockingCall() const; 2847 2848 // This API may be called from any thread. 2849 template <typename Callback> 2850 napi_status NonBlockingCall(Callback callback) const; 2851 2852 // This API may be called from any thread. 2853 template <typename DataType, typename Callback> 2854 napi_status NonBlockingCall(DataType* data, Callback callback) const; 2855 2856 // This API may only be called from the main thread. 2857 void Ref(napi_env env) const; 2858 2859 // This API may only be called from the main thread. 2860 void Unref(napi_env env) const; 2861 2862 // This API may be called from any thread. 2863 napi_status Acquire() const; 2864 2865 // This API may be called from any thread. 2866 napi_status Release() const; 2867 2868 // This API may be called from any thread. 2869 napi_status Abort() const; 2870 2871 struct ConvertibleContext { 2872 template <class T> 2873 operator T*() { 2874 return static_cast<T*>(context); 2875 } 2876 void* context; 2877 }; 2878 2879 // This API may be called from any thread. 2880 ConvertibleContext GetContext() const; 2881 2882 private: 2883 using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>; 2884 2885 template <typename ResourceString, 2886 typename ContextType, 2887 typename Finalizer, 2888 typename FinalizerDataType> 2889 static ThreadSafeFunction New(napi_env env, 2890 const Function& callback, 2891 const Object& resource, 2892 ResourceString resourceName, 2893 size_t maxQueueSize, 2894 size_t initialThreadCount, 2895 ContextType* context, 2896 Finalizer finalizeCallback, 2897 FinalizerDataType* data, 2898 napi_finalize wrapper); 2899 2900 napi_status CallInternal(CallbackWrapper* callbackWrapper, 2901 napi_threadsafe_function_call_mode mode) const; 2902 2903 static void CallJS(napi_env env, 2904 napi_value jsCallback, 2905 void* context, 2906 void* data); 2907 2908 napi_threadsafe_function _tsfn; 2909}; 2910 2911// A TypedThreadSafeFunction by default has no context (nullptr) and can 2912// accept any type (void) to its CallJs. 2913template <typename ContextType = std::nullptr_t, 2914 typename DataType = void, 2915 void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) = 2916 nullptr> 2917class TypedThreadSafeFunction { 2918 public: 2919 // This API may only be called from the main thread. 2920 // Helper function that returns nullptr if running Node-API 5+, otherwise a 2921 // non-empty, no-op Function. This provides the ability to specify at 2922 // compile-time a callback parameter to `New` that safely does no action 2923 // when targeting _any_ Node-API version. 2924#if NAPI_VERSION > 4 2925 static std::nullptr_t EmptyFunctionFactory(Napi::Env env); 2926#else 2927 static Napi::Function EmptyFunctionFactory(Napi::Env env); 2928#endif 2929 static Napi::Function FunctionOrEmpty(Napi::Env env, 2930 Napi::Function& callback); 2931 2932#if NAPI_VERSION > 4 2933 // This API may only be called from the main thread. 2934 // Creates a new threadsafe function with: 2935 // Callback [missing] Resource [missing] Finalizer [missing] 2936 template <typename ResourceString> 2937 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 2938 napi_env env, 2939 ResourceString resourceName, 2940 size_t maxQueueSize, 2941 size_t initialThreadCount, 2942 ContextType* context = nullptr); 2943 2944 // This API may only be called from the main thread. 2945 // Creates a new threadsafe function with: 2946 // Callback [missing] Resource [passed] Finalizer [missing] 2947 template <typename ResourceString> 2948 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 2949 napi_env env, 2950 const Object& resource, 2951 ResourceString resourceName, 2952 size_t maxQueueSize, 2953 size_t initialThreadCount, 2954 ContextType* context = nullptr); 2955 2956 // This API may only be called from the main thread. 2957 // Creates a new threadsafe function with: 2958 // Callback [missing] Resource [missing] Finalizer [passed] 2959 template <typename ResourceString, 2960 typename Finalizer, 2961 typename FinalizerDataType = void> 2962 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 2963 napi_env env, 2964 ResourceString resourceName, 2965 size_t maxQueueSize, 2966 size_t initialThreadCount, 2967 ContextType* context, 2968 Finalizer finalizeCallback, 2969 FinalizerDataType* data = nullptr); 2970 2971 // This API may only be called from the main thread. 2972 // Creates a new threadsafe function with: 2973 // Callback [missing] Resource [passed] Finalizer [passed] 2974 template <typename ResourceString, 2975 typename Finalizer, 2976 typename FinalizerDataType = void> 2977 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 2978 napi_env env, 2979 const Object& resource, 2980 ResourceString resourceName, 2981 size_t maxQueueSize, 2982 size_t initialThreadCount, 2983 ContextType* context, 2984 Finalizer finalizeCallback, 2985 FinalizerDataType* data = nullptr); 2986#endif 2987 2988 // This API may only be called from the main thread. 2989 // Creates a new threadsafe function with: 2990 // Callback [passed] Resource [missing] Finalizer [missing] 2991 template <typename ResourceString> 2992 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 2993 napi_env env, 2994 const Function& callback, 2995 ResourceString resourceName, 2996 size_t maxQueueSize, 2997 size_t initialThreadCount, 2998 ContextType* context = nullptr); 2999 3000 // This API may only be called from the main thread. 3001 // Creates a new threadsafe function with: 3002 // Callback [passed] Resource [passed] Finalizer [missing] 3003 template <typename ResourceString> 3004 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 3005 napi_env env, 3006 const Function& callback, 3007 const Object& resource, 3008 ResourceString resourceName, 3009 size_t maxQueueSize, 3010 size_t initialThreadCount, 3011 ContextType* context = nullptr); 3012 3013 // This API may only be called from the main thread. 3014 // Creates a new threadsafe function with: 3015 // Callback [passed] Resource [missing] Finalizer [passed] 3016 template <typename ResourceString, 3017 typename Finalizer, 3018 typename FinalizerDataType = void> 3019 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 3020 napi_env env, 3021 const Function& callback, 3022 ResourceString resourceName, 3023 size_t maxQueueSize, 3024 size_t initialThreadCount, 3025 ContextType* context, 3026 Finalizer finalizeCallback, 3027 FinalizerDataType* data = nullptr); 3028 3029 // This API may only be called from the main thread. 3030 // Creates a new threadsafe function with: 3031 // Callback [passed] Resource [passed] Finalizer [passed] 3032 template <typename CallbackType, 3033 typename ResourceString, 3034 typename Finalizer, 3035 typename FinalizerDataType> 3036 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 3037 napi_env env, 3038 CallbackType callback, 3039 const Object& resource, 3040 ResourceString resourceName, 3041 size_t maxQueueSize, 3042 size_t initialThreadCount, 3043 ContextType* context, 3044 Finalizer finalizeCallback, 3045 FinalizerDataType* data = nullptr); 3046 3047 TypedThreadSafeFunction(); 3048 TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue); 3049 3050 operator napi_threadsafe_function() const; 3051 3052 // This API may be called from any thread. 3053 napi_status BlockingCall(DataType* data = nullptr) const; 3054 3055 // This API may be called from any thread. 3056 napi_status NonBlockingCall(DataType* data = nullptr) const; 3057 3058 // This API may only be called from the main thread. 3059 void Ref(napi_env env) const; 3060 3061 // This API may only be called from the main thread. 3062 void Unref(napi_env env) const; 3063 3064 // This API may be called from any thread. 3065 napi_status Acquire() const; 3066 3067 // This API may be called from any thread. 3068 napi_status Release() const; 3069 3070 // This API may be called from any thread. 3071 napi_status Abort() const; 3072 3073 // This API may be called from any thread. 3074 ContextType* GetContext() const; 3075 3076 private: 3077 template <typename ResourceString, 3078 typename Finalizer, 3079 typename FinalizerDataType> 3080 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( 3081 napi_env env, 3082 const Function& callback, 3083 const Object& resource, 3084 ResourceString resourceName, 3085 size_t maxQueueSize, 3086 size_t initialThreadCount, 3087 ContextType* context, 3088 Finalizer finalizeCallback, 3089 FinalizerDataType* data, 3090 napi_finalize wrapper); 3091 3092 static void CallJsInternal(napi_env env, 3093 napi_value jsCallback, 3094 void* context, 3095 void* data); 3096 3097 protected: 3098 napi_threadsafe_function _tsfn; 3099}; 3100template <typename DataType> 3101class AsyncProgressWorkerBase : public AsyncWorker { 3102 public: 3103 virtual void OnWorkProgress(DataType* data) = 0; 3104 class ThreadSafeData { 3105 public: 3106 ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data) 3107 : _asyncprogressworker(asyncprogressworker), _data(data) {} 3108 3109 AsyncProgressWorkerBase* asyncprogressworker() { 3110 return _asyncprogressworker; 3111 }; 3112 DataType* data() { return _data; }; 3113 3114 private: 3115 AsyncProgressWorkerBase* _asyncprogressworker; 3116 DataType* _data; 3117 }; 3118 void OnWorkComplete(Napi::Env env, napi_status status) override; 3119 3120 protected: 3121 explicit AsyncProgressWorkerBase(const Object& receiver, 3122 const Function& callback, 3123 const char* resource_name, 3124 const Object& resource, 3125 size_t queue_size = 1); 3126 virtual ~AsyncProgressWorkerBase(); 3127 3128// Optional callback of Napi::ThreadSafeFunction only available after 3129// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 3130#if NAPI_VERSION > 4 3131 explicit AsyncProgressWorkerBase(Napi::Env env, 3132 const char* resource_name, 3133 const Object& resource, 3134 size_t queue_size = 1); 3135#endif 3136 3137 static inline void OnAsyncWorkProgress(Napi::Env env, 3138 Napi::Function jsCallback, 3139 void* data); 3140 3141 napi_status NonBlockingCall(DataType* data); 3142 3143 private: 3144 ThreadSafeFunction _tsfn; 3145 bool _work_completed = false; 3146 napi_status _complete_status; 3147 static inline void OnThreadSafeFunctionFinalize( 3148 Napi::Env env, void* data, AsyncProgressWorkerBase* context); 3149}; 3150 3151template <class T> 3152class AsyncProgressWorker : public AsyncProgressWorkerBase<void> { 3153 public: 3154 virtual ~AsyncProgressWorker(); 3155 3156 class ExecutionProgress { 3157 friend class AsyncProgressWorker; 3158 3159 public: 3160 void Signal() const; 3161 void Send(const T* data, size_t count) const; 3162 3163 private: 3164 explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {} 3165 AsyncProgressWorker* const _worker; 3166 }; 3167 3168 void OnWorkProgress(void*) override; 3169 3170 protected: 3171 explicit AsyncProgressWorker(const Function& callback); 3172 explicit AsyncProgressWorker(const Function& callback, 3173 const char* resource_name); 3174 explicit AsyncProgressWorker(const Function& callback, 3175 const char* resource_name, 3176 const Object& resource); 3177 explicit AsyncProgressWorker(const Object& receiver, 3178 const Function& callback); 3179 explicit AsyncProgressWorker(const Object& receiver, 3180 const Function& callback, 3181 const char* resource_name); 3182 explicit AsyncProgressWorker(const Object& receiver, 3183 const Function& callback, 3184 const char* resource_name, 3185 const Object& resource); 3186 3187// Optional callback of Napi::ThreadSafeFunction only available after 3188// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 3189#if NAPI_VERSION > 4 3190 explicit AsyncProgressWorker(Napi::Env env); 3191 explicit AsyncProgressWorker(Napi::Env env, const char* resource_name); 3192 explicit AsyncProgressWorker(Napi::Env env, 3193 const char* resource_name, 3194 const Object& resource); 3195#endif 3196 virtual void Execute(const ExecutionProgress& progress) = 0; 3197 virtual void OnProgress(const T* data, size_t count) = 0; 3198 3199 private: 3200 void Execute() override; 3201 void Signal(); 3202 void SendProgress_(const T* data, size_t count); 3203 3204 std::mutex _mutex; 3205 T* _asyncdata; 3206 size_t _asyncsize; 3207 bool _signaled; 3208}; 3209 3210template <class T> 3211class AsyncProgressQueueWorker 3212 : public AsyncProgressWorkerBase<std::pair<T*, size_t>> { 3213 public: 3214 virtual ~AsyncProgressQueueWorker(){}; 3215 3216 class ExecutionProgress { 3217 friend class AsyncProgressQueueWorker; 3218 3219 public: 3220 void Signal() const; 3221 void Send(const T* data, size_t count) const; 3222 3223 private: 3224 explicit ExecutionProgress(AsyncProgressQueueWorker* worker) 3225 : _worker(worker) {} 3226 AsyncProgressQueueWorker* const _worker; 3227 }; 3228 3229 void OnWorkComplete(Napi::Env env, napi_status status) override; 3230 void OnWorkProgress(std::pair<T*, size_t>*) override; 3231 3232 protected: 3233 explicit AsyncProgressQueueWorker(const Function& callback); 3234 explicit AsyncProgressQueueWorker(const Function& callback, 3235 const char* resource_name); 3236 explicit AsyncProgressQueueWorker(const Function& callback, 3237 const char* resource_name, 3238 const Object& resource); 3239 explicit AsyncProgressQueueWorker(const Object& receiver, 3240 const Function& callback); 3241 explicit AsyncProgressQueueWorker(const Object& receiver, 3242 const Function& callback, 3243 const char* resource_name); 3244 explicit AsyncProgressQueueWorker(const Object& receiver, 3245 const Function& callback, 3246 const char* resource_name, 3247 const Object& resource); 3248 3249// Optional callback of Napi::ThreadSafeFunction only available after 3250// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 3251#if NAPI_VERSION > 4 3252 explicit AsyncProgressQueueWorker(Napi::Env env); 3253 explicit AsyncProgressQueueWorker(Napi::Env env, const char* resource_name); 3254 explicit AsyncProgressQueueWorker(Napi::Env env, 3255 const char* resource_name, 3256 const Object& resource); 3257#endif 3258 virtual void Execute(const ExecutionProgress& progress) = 0; 3259 virtual void OnProgress(const T* data, size_t count) = 0; 3260 3261 private: 3262 void Execute() override; 3263 void Signal() const; 3264 void SendProgress_(const T* data, size_t count); 3265}; 3266#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS 3267 3268// Memory management. 3269class MemoryManagement { 3270 public: 3271 static int64_t AdjustExternalMemory(BasicEnv env, int64_t change_in_bytes); 3272}; 3273 3274// Version management 3275class VersionManagement { 3276 public: 3277 static uint32_t GetNapiVersion(BasicEnv env); 3278 static const napi_node_version* GetNodeVersion(BasicEnv env); 3279}; 3280 3281#if NAPI_VERSION > 5 3282template <typename T> 3283class Addon : public InstanceWrap<T> { 3284 public: 3285 static inline Object Init(Env env, Object exports); 3286 static T* Unwrap(Object wrapper); 3287 3288 protected: 3289 using AddonProp = ClassPropertyDescriptor<T>; 3290 void DefineAddon(Object exports, 3291 const std::initializer_list<AddonProp>& props); 3292 Napi::Object DefineProperties(Object object, 3293 const std::initializer_list<AddonProp>& props); 3294 3295 private: 3296 Object entry_point_; 3297}; 3298#endif // NAPI_VERSION > 5 3299 3300#ifdef NAPI_CPP_CUSTOM_NAMESPACE 3301} // namespace NAPI_CPP_CUSTOM_NAMESPACE 3302#endif 3303 3304} // namespace Napi 3305 3306// Inline implementations of all the above class methods are included here. 3307#include "napi-inl.h" 3308 3309#endif // SRC_NAPI_H_