OR-1 dataflow CPU sketch
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_