napi.h 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053
  1. #ifndef SRC_NAPI_H_
  2. #define SRC_NAPI_H_
  3. #include <node_api.h>
  4. #include <functional>
  5. #include <initializer_list>
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. // VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known good version)
  10. #if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210
  11. #define NAPI_HAS_CONSTEXPR 1
  12. #endif
  13. // VS2013 does not support char16_t literal strings, so we'll work around it using wchar_t strings
  14. // and casting them. This is safe as long as the character sizes are the same.
  15. #if defined(_MSC_VER) && _MSC_VER <= 1800
  16. static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16_t and wchar_t");
  17. #define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L ## x)
  18. #else
  19. #define NAPI_WIDE_TEXT(x) u ## x
  20. #endif
  21. // If C++ exceptions are not explicitly enabled or disabled, enable them
  22. // if exceptions were enabled in the compiler settings.
  23. #if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
  24. #if defined(_CPPUNWIND) || defined (__EXCEPTIONS)
  25. #define NAPI_CPP_EXCEPTIONS
  26. #else
  27. #error Exception support not detected. \
  28. Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS.
  29. #endif
  30. #endif
  31. #ifdef _NOEXCEPT
  32. #define NAPI_NOEXCEPT _NOEXCEPT
  33. #else
  34. #define NAPI_NOEXCEPT noexcept
  35. #endif
  36. #ifdef NAPI_CPP_EXCEPTIONS
  37. // When C++ exceptions are enabled, Errors are thrown directly. There is no need
  38. // to return anything after the throw statements. The variadic parameter is an
  39. // optional return value that is ignored.
  40. // We need _VOID versions of the macros to avoid warnings resulting from
  41. // leaving the NAPI_THROW_* `...` argument empty.
  42. #define NAPI_THROW(e, ...) throw e
  43. #define NAPI_THROW_VOID(e) throw e
  44. #define NAPI_THROW_IF_FAILED(env, status, ...) \
  45. if ((status) != napi_ok) throw Napi::Error::New(env);
  46. #define NAPI_THROW_IF_FAILED_VOID(env, status) \
  47. if ((status) != napi_ok) throw Napi::Error::New(env);
  48. #else // NAPI_CPP_EXCEPTIONS
  49. // When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
  50. // which are pending until the callback returns to JS. The variadic parameter
  51. // is an optional return value; usually it is an empty result.
  52. // We need _VOID versions of the macros to avoid warnings resulting from
  53. // leaving the NAPI_THROW_* `...` argument empty.
  54. #define NAPI_THROW(e, ...) \
  55. do { \
  56. (e).ThrowAsJavaScriptException(); \
  57. return __VA_ARGS__; \
  58. } while (0)
  59. #define NAPI_THROW_VOID(e) \
  60. do { \
  61. (e).ThrowAsJavaScriptException(); \
  62. return; \
  63. } while (0)
  64. #define NAPI_THROW_IF_FAILED(env, status, ...) \
  65. if ((status) != napi_ok) { \
  66. Napi::Error::New(env).ThrowAsJavaScriptException(); \
  67. return __VA_ARGS__; \
  68. }
  69. #define NAPI_THROW_IF_FAILED_VOID(env, status) \
  70. if ((status) != napi_ok) { \
  71. Napi::Error::New(env).ThrowAsJavaScriptException(); \
  72. return; \
  73. }
  74. #endif // NAPI_CPP_EXCEPTIONS
  75. #define NAPI_FATAL_IF_FAILED(status, location, message) \
  76. do { \
  77. if ((status) != napi_ok) { \
  78. Napi::Error::Fatal((location), (message)); \
  79. } \
  80. } while (0)
  81. ////////////////////////////////////////////////////////////////////////////////
  82. /// N-API C++ Wrapper Classes
  83. ///
  84. /// These classes wrap the "N-API" ABI-stable C APIs for Node.js, providing a
  85. /// C++ object model and C++ exception-handling semantics with low overhead.
  86. /// The wrappers are all header-only so that they do not affect the ABI.
  87. ////////////////////////////////////////////////////////////////////////////////
  88. namespace Napi {
  89. // Forward declarations
  90. class Env;
  91. class Value;
  92. class Boolean;
  93. class Number;
  94. // currently experimental guard with version of NAPI_VERSION that it is
  95. // released in once it is no longer experimental
  96. #if (NAPI_VERSION > 2147483646)
  97. class BigInt;
  98. #endif // NAPI_EXPERIMENTAL
  99. class String;
  100. class Object;
  101. class Array;
  102. class Function;
  103. template <typename T> class Buffer;
  104. class Error;
  105. class PropertyDescriptor;
  106. class CallbackInfo;
  107. template <typename T> class Reference;
  108. class TypedArray;
  109. template <typename T> class TypedArrayOf;
  110. typedef TypedArrayOf<int8_t> Int8Array; ///< Typed-array of signed 8-bit integers
  111. typedef TypedArrayOf<uint8_t> Uint8Array; ///< Typed-array of unsigned 8-bit integers
  112. typedef TypedArrayOf<int16_t> Int16Array; ///< Typed-array of signed 16-bit integers
  113. typedef TypedArrayOf<uint16_t> Uint16Array; ///< Typed-array of unsigned 16-bit integers
  114. typedef TypedArrayOf<int32_t> Int32Array; ///< Typed-array of signed 32-bit integers
  115. typedef TypedArrayOf<uint32_t> Uint32Array; ///< Typed-array of unsigned 32-bit integers
  116. typedef TypedArrayOf<float> Float32Array; ///< Typed-array of 32-bit floating-point values
  117. typedef TypedArrayOf<double> Float64Array; ///< Typed-array of 64-bit floating-point values
  118. // currently experimental guard with version of NAPI_VERSION that it is
  119. // released in once it is no longer experimental
  120. #if (NAPI_VERSION > 2147483646)
  121. typedef TypedArrayOf<int64_t> BigInt64Array; ///< Typed array of signed 64-bit integers
  122. typedef TypedArrayOf<uint64_t> BigUint64Array; ///< Typed array of unsigned 64-bit integers
  123. #endif // NAPI_EXPERIMENTAL
  124. /// Defines the signature of a N-API C++ module's registration callback (init) function.
  125. typedef Object (*ModuleRegisterCallback)(Env env, Object exports);
  126. class MemoryManagement;
  127. /// Environment for N-API values and operations.
  128. ///
  129. /// All N-API values and operations must be associated with an environment. An environment
  130. /// instance is always provided to callback functions; that environment must then be used for any
  131. /// creation of N-API values or other N-API operations within the callback. (Many methods infer
  132. /// the environment from the `this` instance that the method is called on.)
  133. ///
  134. /// In the future, multiple environments per process may be supported, although current
  135. /// implementations only support one environment per process.
  136. ///
  137. /// In the V8 JavaScript engine, a N-API environment approximately corresponds to an Isolate.
  138. class Env {
  139. public:
  140. Env(napi_env env);
  141. operator napi_env() const;
  142. Object Global() const;
  143. Value Undefined() const;
  144. Value Null() const;
  145. bool IsExceptionPending() const;
  146. Error GetAndClearPendingException();
  147. private:
  148. napi_env _env;
  149. };
  150. /// A JavaScript value of unknown type.
  151. ///
  152. /// For type-specific operations, convert to one of the Value subclasses using a `To*` or `As()`
  153. /// method. The `To*` methods do type coercion; the `As()` method does not.
  154. ///
  155. /// Napi::Value value = ...
  156. /// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid arg...");
  157. /// Napi::String str = value.As<Napi::String>(); // Cast to a string value
  158. ///
  159. /// Napi::Value anotherValue = ...
  160. /// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value
  161. class Value {
  162. public:
  163. Value(); ///< Creates a new _empty_ Value instance.
  164. Value(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  165. /// Creates a JS value from a C++ primitive.
  166. ///
  167. /// `value` may be any of:
  168. /// - bool
  169. /// - Any integer type
  170. /// - Any floating point type
  171. /// - const char* (encoded using UTF-8, null-terminated)
  172. /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
  173. /// - std::string (encoded using UTF-8)
  174. /// - std::u16string
  175. /// - napi::Value
  176. /// - napi_value
  177. template <typename T>
  178. static Value From(napi_env env, const T& value);
  179. /// Converts to a N-API value primitive.
  180. ///
  181. /// If the instance is _empty_, this returns `nullptr`.
  182. operator napi_value() const;
  183. /// Tests if this value strictly equals another value.
  184. bool operator ==(const Value& other) const;
  185. /// Tests if this value does not strictly equal another value.
  186. bool operator !=(const Value& other) const;
  187. /// Tests if this value strictly equals another value.
  188. bool StrictEquals(const Value& other) const;
  189. /// Gets the environment the value is associated with.
  190. Napi::Env Env() const;
  191. /// Checks if the value is empty (uninitialized).
  192. ///
  193. /// An empty value is invalid, and most attempts to perform an operation on an empty value
  194. /// will result in an exception. Note an empty value is distinct from JavaScript `null` or
  195. /// `undefined`, which are valid values.
  196. ///
  197. /// When C++ exceptions are disabled at compile time, a method with a `Value` return type may
  198. /// return an empty value to indicate a pending exception. So when not using C++ exceptions,
  199. /// callers should check whether the value is empty before attempting to use it.
  200. bool IsEmpty() const;
  201. napi_valuetype Type() const; ///< Gets the type of the value.
  202. bool IsUndefined() const; ///< Tests if a value is an undefined JavaScript value.
  203. bool IsNull() const; ///< Tests if a value is a null JavaScript value.
  204. bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean.
  205. bool IsNumber() const; ///< Tests if a value is a JavaScript number.
  206. // currently experimental guard with version of NAPI_VERSION that it is
  207. // released in once it is no longer experimental
  208. #if (NAPI_VERSION > 2147483646)
  209. bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint.
  210. #endif // NAPI_EXPERIMENTAL
  211. bool IsString() const; ///< Tests if a value is a JavaScript string.
  212. bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol.
  213. bool IsArray() const; ///< Tests if a value is a JavaScript array.
  214. bool IsArrayBuffer() const; ///< Tests if a value is a JavaScript array buffer.
  215. bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array.
  216. bool IsObject() const; ///< Tests if a value is a JavaScript object.
  217. bool IsFunction() const; ///< Tests if a value is a JavaScript function.
  218. bool IsPromise() const; ///< Tests if a value is a JavaScript promise.
  219. bool IsDataView() const; ///< Tests if a value is a JavaScript data view.
  220. bool IsBuffer() const; ///< Tests if a value is a Node buffer.
  221. bool IsExternal() const; ///< Tests if a value is a pointer to external data.
  222. /// Casts to another type of `Napi::Value`, when the actual type is known or assumed.
  223. ///
  224. /// This conversion does NOT coerce the type. Calling any methods inappropriate for the actual
  225. /// value type will throw `Napi::Error`.
  226. template <typename T> T As() const;
  227. Boolean ToBoolean() const; ///< Coerces a value to a JavaScript boolean.
  228. Number ToNumber() const; ///< Coerces a value to a JavaScript number.
  229. String ToString() const; ///< Coerces a value to a JavaScript string.
  230. Object ToObject() const; ///< Coerces a value to a JavaScript object.
  231. protected:
  232. /// !cond INTERNAL
  233. napi_env _env;
  234. napi_value _value;
  235. /// !endcond
  236. };
  237. /// A JavaScript boolean value.
  238. class Boolean : public Value {
  239. public:
  240. static Boolean New(
  241. napi_env env, ///< N-API environment
  242. bool value ///< Boolean value
  243. );
  244. Boolean(); ///< Creates a new _empty_ Boolean instance.
  245. Boolean(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  246. operator bool() const; ///< Converts a Boolean value to a boolean primitive.
  247. bool Value() const; ///< Converts a Boolean value to a boolean primitive.
  248. };
  249. /// A JavaScript number value.
  250. class Number : public Value {
  251. public:
  252. static Number New(
  253. napi_env env, ///< N-API environment
  254. double value ///< Number value
  255. );
  256. Number(); ///< Creates a new _empty_ Number instance.
  257. Number(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  258. operator int32_t() const; ///< Converts a Number value to a 32-bit signed integer value.
  259. operator uint32_t() const; ///< Converts a Number value to a 32-bit unsigned integer value.
  260. operator int64_t() const; ///< Converts a Number value to a 64-bit signed integer value.
  261. operator float() const; ///< Converts a Number value to a 32-bit floating-point value.
  262. operator double() const; ///< Converts a Number value to a 64-bit floating-point value.
  263. int32_t Int32Value() const; ///< Converts a Number value to a 32-bit signed integer value.
  264. uint32_t Uint32Value() const; ///< Converts a Number value to a 32-bit unsigned integer value.
  265. int64_t Int64Value() const; ///< Converts a Number value to a 64-bit signed integer value.
  266. float FloatValue() const; ///< Converts a Number value to a 32-bit floating-point value.
  267. double DoubleValue() const; ///< Converts a Number value to a 64-bit floating-point value.
  268. };
  269. // currently experimental guard with version of NAPI_VERSION that it is
  270. // released in once it is no longer experimental
  271. #if (NAPI_VERSION > 2147483646)
  272. /// A JavaScript bigint value.
  273. class BigInt : public Value {
  274. public:
  275. static BigInt New(
  276. napi_env env, ///< N-API environment
  277. int64_t value ///< Number value
  278. );
  279. static BigInt New(
  280. napi_env env, ///< N-API environment
  281. uint64_t value ///< Number value
  282. );
  283. /// Creates a new BigInt object using a specified sign bit and a
  284. /// specified list of digits/words.
  285. /// The resulting number is calculated as:
  286. /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
  287. static BigInt New(
  288. napi_env env, ///< N-API environment
  289. int sign_bit, ///< Sign bit. 1 if negative.
  290. size_t word_count, ///< Number of words in array
  291. const uint64_t* words ///< Array of words
  292. );
  293. BigInt(); ///< Creates a new _empty_ BigInt instance.
  294. BigInt(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  295. int64_t Int64Value(bool* lossless) const; ///< Converts a BigInt value to a 64-bit signed integer value.
  296. uint64_t Uint64Value(bool* lossless) const; ///< Converts a BigInt value to a 64-bit unsigned integer value.
  297. size_t WordCount() const; ///< The number of 64-bit words needed to store the result of ToWords().
  298. /// Writes the contents of this BigInt to a specified memory location.
  299. /// `sign_bit` must be provided and will be set to 1 if this BigInt is negative.
  300. /// `*word_count` has to be initialized to the length of the `words` array.
  301. /// Upon return, it will be set to the actual number of words that would
  302. /// be needed to store this BigInt (i.e. the return value of `WordCount()`).
  303. void ToWords(int* sign_bit, size_t* word_count, uint64_t* words);
  304. };
  305. #endif // NAPI_EXPERIMENTAL
  306. /// A JavaScript string or symbol value (that can be used as a property name).
  307. class Name : public Value {
  308. public:
  309. Name(); ///< Creates a new _empty_ Name instance.
  310. Name(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  311. };
  312. /// A JavaScript string value.
  313. class String : public Name {
  314. public:
  315. /// Creates a new String value from a UTF-8 encoded C++ string.
  316. static String New(
  317. napi_env env, ///< N-API environment
  318. const std::string& value ///< UTF-8 encoded C++ string
  319. );
  320. /// Creates a new String value from a UTF-16 encoded C++ string.
  321. static String New(
  322. napi_env env, ///< N-API environment
  323. const std::u16string& value ///< UTF-16 encoded C++ string
  324. );
  325. /// Creates a new String value from a UTF-8 encoded C string.
  326. static String New(
  327. napi_env env, ///< N-API environment
  328. const char* value ///< UTF-8 encoded null-terminated C string
  329. );
  330. /// Creates a new String value from a UTF-16 encoded C string.
  331. static String New(
  332. napi_env env, ///< N-API environment
  333. const char16_t* value ///< UTF-16 encoded null-terminated C string
  334. );
  335. /// Creates a new String value from a UTF-8 encoded C string with specified length.
  336. static String New(
  337. napi_env env, ///< N-API environment
  338. const char* value, ///< UTF-8 encoded C string (not necessarily null-terminated)
  339. size_t length ///< length of the string in bytes
  340. );
  341. /// Creates a new String value from a UTF-16 encoded C string with specified length.
  342. static String New(
  343. napi_env env, ///< N-API environment
  344. const char16_t* value, ///< UTF-16 encoded C string (not necessarily null-terminated)
  345. size_t length ///< Length of the string in 2-byte code units
  346. );
  347. /// Creates a new String based on the original object's type.
  348. ///
  349. /// `value` may be any of:
  350. /// - const char* (encoded using UTF-8, null-terminated)
  351. /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
  352. /// - std::string (encoded using UTF-8)
  353. /// - std::u16string
  354. template <typename T>
  355. static String From(napi_env env, const T& value);
  356. String(); ///< Creates a new _empty_ String instance.
  357. String(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  358. operator std::string() const; ///< Converts a String value to a UTF-8 encoded C++ string.
  359. operator std::u16string() const; ///< Converts a String value to a UTF-16 encoded C++ string.
  360. std::string Utf8Value() const; ///< Converts a String value to a UTF-8 encoded C++ string.
  361. std::u16string Utf16Value() const; ///< Converts a String value to a UTF-16 encoded C++ string.
  362. };
  363. /// A JavaScript symbol value.
  364. class Symbol : public Name {
  365. public:
  366. /// Creates a new Symbol value with an optional description.
  367. static Symbol New(
  368. napi_env env, ///< N-API environment
  369. const char* description = nullptr ///< Optional UTF-8 encoded null-terminated C string
  370. /// describing the symbol
  371. );
  372. /// Creates a new Symbol value with a description.
  373. static Symbol New(
  374. napi_env env, ///< N-API environment
  375. const std::string& description ///< UTF-8 encoded C++ string describing the symbol
  376. );
  377. /// Creates a new Symbol value with a description.
  378. static Symbol New(
  379. napi_env env, ///< N-API environment
  380. String description ///< String value describing the symbol
  381. );
  382. /// Creates a new Symbol value with a description.
  383. static Symbol New(
  384. napi_env env, ///< N-API environment
  385. napi_value description ///< String value describing the symbol
  386. );
  387. /// Get a public Symbol (e.g. Symbol.iterator).
  388. static Symbol WellKnown(napi_env, const std::string& name);
  389. Symbol(); ///< Creates a new _empty_ Symbol instance.
  390. Symbol(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  391. };
  392. /// A JavaScript object value.
  393. class Object : public Value {
  394. public:
  395. /// Enables property and element assignments using indexing syntax.
  396. ///
  397. /// Example:
  398. ///
  399. /// Napi::Value propertyValue = object1['A'];
  400. /// object2['A'] = propertyValue;
  401. /// Napi::Value elementValue = array[0];
  402. /// array[1] = elementValue;
  403. template <typename Key>
  404. class PropertyLValue {
  405. public:
  406. /// Converts an L-value to a value.
  407. operator Value() const;
  408. /// Assigns a value to the property. The type of value can be
  409. /// anything supported by `Object::Set`.
  410. template <typename ValueType>
  411. PropertyLValue& operator =(ValueType value);
  412. private:
  413. PropertyLValue() = delete;
  414. PropertyLValue(Object object, Key key);
  415. napi_env _env;
  416. napi_value _object;
  417. Key _key;
  418. friend class Napi::Object;
  419. };
  420. /// Creates a new Object value.
  421. static Object New(
  422. napi_env env ///< N-API environment
  423. );
  424. Object(); ///< Creates a new _empty_ Object instance.
  425. Object(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  426. /// Gets or sets a named property.
  427. PropertyLValue<std::string> operator [](
  428. const char* utf8name ///< UTF-8 encoded null-terminated property name
  429. );
  430. /// Gets or sets a named property.
  431. PropertyLValue<std::string> operator [](
  432. const std::string& utf8name ///< UTF-8 encoded property name
  433. );
  434. /// Gets or sets an indexed property or array element.
  435. PropertyLValue<uint32_t> operator [](
  436. uint32_t index /// Property / element index
  437. );
  438. /// Gets a named property.
  439. Value operator [](
  440. const char* utf8name ///< UTF-8 encoded null-terminated property name
  441. ) const;
  442. /// Gets a named property.
  443. Value operator [](
  444. const std::string& utf8name ///< UTF-8 encoded property name
  445. ) const;
  446. /// Gets an indexed property or array element.
  447. Value operator [](
  448. uint32_t index ///< Property / element index
  449. ) const;
  450. /// Checks whether a property is present.
  451. bool Has(
  452. napi_value key ///< Property key primitive
  453. ) const;
  454. /// Checks whether a property is present.
  455. bool Has(
  456. Value key ///< Property key
  457. ) const;
  458. /// Checks whether a named property is present.
  459. bool Has(
  460. const char* utf8name ///< UTF-8 encoded null-terminated property name
  461. ) const;
  462. /// Checks whether a named property is present.
  463. bool Has(
  464. const std::string& utf8name ///< UTF-8 encoded property name
  465. ) const;
  466. /// Checks whether a own property is present.
  467. bool HasOwnProperty(
  468. napi_value key ///< Property key primitive
  469. ) const;
  470. /// Checks whether a own property is present.
  471. bool HasOwnProperty(
  472. Value key ///< Property key
  473. ) const;
  474. /// Checks whether a own property is present.
  475. bool HasOwnProperty(
  476. const char* utf8name ///< UTF-8 encoded null-terminated property name
  477. ) const;
  478. /// Checks whether a own property is present.
  479. bool HasOwnProperty(
  480. const std::string& utf8name ///< UTF-8 encoded property name
  481. ) const;
  482. /// Gets a property.
  483. Value Get(
  484. napi_value key ///< Property key primitive
  485. ) const;
  486. /// Gets a property.
  487. Value Get(
  488. Value key ///< Property key
  489. ) const;
  490. /// Gets a named property.
  491. Value Get(
  492. const char* utf8name ///< UTF-8 encoded null-terminated property name
  493. ) const;
  494. /// Gets a named property.
  495. Value Get(
  496. const std::string& utf8name ///< UTF-8 encoded property name
  497. ) const;
  498. /// Sets a property.
  499. template <typename ValueType>
  500. void Set(
  501. napi_value key, ///< Property key primitive
  502. const ValueType& value ///< Property value primitive
  503. );
  504. /// Sets a property.
  505. template <typename ValueType>
  506. void Set(
  507. Value key, ///< Property key
  508. const ValueType& value ///< Property value
  509. );
  510. /// Sets a named property.
  511. template <typename ValueType>
  512. void Set(
  513. const char* utf8name, ///< UTF-8 encoded null-terminated property name
  514. const ValueType& value
  515. );
  516. /// Sets a named property.
  517. template <typename ValueType>
  518. void Set(
  519. const std::string& utf8name, ///< UTF-8 encoded property name
  520. const ValueType& value ///< Property value primitive
  521. );
  522. /// Delete property.
  523. bool Delete(
  524. napi_value key ///< Property key primitive
  525. );
  526. /// Delete property.
  527. bool Delete(
  528. Value key ///< Property key
  529. );
  530. /// Delete property.
  531. bool Delete(
  532. const char* utf8name ///< UTF-8 encoded null-terminated property name
  533. );
  534. /// Delete property.
  535. bool Delete(
  536. const std::string& utf8name ///< UTF-8 encoded property name
  537. );
  538. /// Checks whether an indexed property is present.
  539. bool Has(
  540. uint32_t index ///< Property / element index
  541. ) const;
  542. /// Gets an indexed property or array element.
  543. Value Get(
  544. uint32_t index ///< Property / element index
  545. ) const;
  546. /// Sets an indexed property or array element.
  547. template <typename ValueType>
  548. void Set(
  549. uint32_t index, ///< Property / element index
  550. const ValueType& value ///< Property value primitive
  551. );
  552. /// Deletes an indexed property or array element.
  553. bool Delete(
  554. uint32_t index ///< Property / element index
  555. );
  556. Array GetPropertyNames() const; ///< Get all property names
  557. /// Defines a property on the object.
  558. void DefineProperty(
  559. const PropertyDescriptor& property ///< Descriptor for the property to be defined
  560. );
  561. /// Defines properties on the object.
  562. void DefineProperties(
  563. const std::initializer_list<PropertyDescriptor>& properties
  564. ///< List of descriptors for the properties to be defined
  565. );
  566. /// Defines properties on the object.
  567. void DefineProperties(
  568. const std::vector<PropertyDescriptor>& properties
  569. ///< Vector of descriptors for the properties to be defined
  570. );
  571. /// Checks if an object is an instance created by a constructor function.
  572. ///
  573. /// This is equivalent to the JavaScript `instanceof` operator.
  574. bool InstanceOf(
  575. const Function& constructor ///< Constructor function
  576. ) const;
  577. };
  578. template <typename T>
  579. class External : public Value {
  580. public:
  581. static External New(napi_env env, T* data);
  582. // Finalizer must implement `void operator()(Env env, T* data)`.
  583. template <typename Finalizer>
  584. static External New(napi_env env,
  585. T* data,
  586. Finalizer finalizeCallback);
  587. // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
  588. template <typename Finalizer, typename Hint>
  589. static External New(napi_env env,
  590. T* data,
  591. Finalizer finalizeCallback,
  592. Hint* finalizeHint);
  593. External();
  594. External(napi_env env, napi_value value);
  595. T* Data() const;
  596. };
  597. class Array : public Object {
  598. public:
  599. static Array New(napi_env env);
  600. static Array New(napi_env env, size_t length);
  601. Array();
  602. Array(napi_env env, napi_value value);
  603. uint32_t Length() const;
  604. };
  605. /// A JavaScript array buffer value.
  606. class ArrayBuffer : public Object {
  607. public:
  608. /// Creates a new ArrayBuffer instance over a new automatically-allocated buffer.
  609. static ArrayBuffer New(
  610. napi_env env, ///< N-API environment
  611. size_t byteLength ///< Length of the buffer to be allocated, in bytes
  612. );
  613. /// Creates a new ArrayBuffer instance, using an external buffer with specified byte length.
  614. static ArrayBuffer New(
  615. napi_env env, ///< N-API environment
  616. void* externalData, ///< Pointer to the external buffer to be used by the array
  617. size_t byteLength ///< Length of the external buffer to be used by the array, in bytes
  618. );
  619. /// Creates a new ArrayBuffer instance, using an external buffer with specified byte length.
  620. template <typename Finalizer>
  621. static ArrayBuffer New(
  622. napi_env env, ///< N-API environment
  623. void* externalData, ///< Pointer to the external buffer to be used by the array
  624. size_t byteLength, ///< Length of the external buffer to be used by the array,
  625. /// in bytes
  626. Finalizer finalizeCallback ///< Function to be called when the array buffer is destroyed;
  627. /// must implement `void operator()(Env env, void* externalData)`
  628. );
  629. /// Creates a new ArrayBuffer instance, using an external buffer with specified byte length.
  630. template <typename Finalizer, typename Hint>
  631. static ArrayBuffer New(
  632. napi_env env, ///< N-API environment
  633. void* externalData, ///< Pointer to the external buffer to be used by the array
  634. size_t byteLength, ///< Length of the external buffer to be used by the array,
  635. /// in bytes
  636. Finalizer finalizeCallback, ///< Function to be called when the array buffer is destroyed;
  637. /// must implement `void operator()(Env env, void* externalData, Hint* hint)`
  638. Hint* finalizeHint ///< Hint (second parameter) to be passed to the finalize callback
  639. );
  640. ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance.
  641. ArrayBuffer(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  642. void* Data(); ///< Gets a pointer to the data buffer.
  643. size_t ByteLength(); ///< Gets the length of the array buffer in bytes.
  644. private:
  645. mutable void* _data;
  646. mutable size_t _length;
  647. ArrayBuffer(napi_env env, napi_value value, void* data, size_t length);
  648. void EnsureInfo() const;
  649. };
  650. /// A JavaScript typed-array value with unknown array type.
  651. ///
  652. /// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the `As()`
  653. /// method:
  654. ///
  655. /// Napi::TypedArray array = ...
  656. /// if (t.TypedArrayType() == napi_int32_array) {
  657. /// Napi::Int32Array int32Array = t.As<Napi::Int32Array>();
  658. /// }
  659. class TypedArray : public Object {
  660. public:
  661. TypedArray(); ///< Creates a new _empty_ TypedArray instance.
  662. TypedArray(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  663. napi_typedarray_type TypedArrayType() const; ///< Gets the type of this typed-array.
  664. Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
  665. uint8_t ElementSize() const; ///< Gets the size in bytes of one element in the array.
  666. size_t ElementLength() const; ///< Gets the number of elements in the array.
  667. size_t ByteOffset() const; ///< Gets the offset into the buffer where the array starts.
  668. size_t ByteLength() const; ///< Gets the length of the array in bytes.
  669. protected:
  670. /// !cond INTERNAL
  671. napi_typedarray_type _type;
  672. size_t _length;
  673. TypedArray(napi_env env, napi_value value, napi_typedarray_type type, size_t length);
  674. static const napi_typedarray_type unknown_array_type = static_cast<napi_typedarray_type>(-1);
  675. template <typename T>
  676. static
  677. #if defined(NAPI_HAS_CONSTEXPR)
  678. constexpr
  679. #endif
  680. napi_typedarray_type TypedArrayTypeForPrimitiveType() {
  681. return std::is_same<T, int8_t>::value ? napi_int8_array
  682. : std::is_same<T, uint8_t>::value ? napi_uint8_array
  683. : std::is_same<T, int16_t>::value ? napi_int16_array
  684. : std::is_same<T, uint16_t>::value ? napi_uint16_array
  685. : std::is_same<T, int32_t>::value ? napi_int32_array
  686. : std::is_same<T, uint32_t>::value ? napi_uint32_array
  687. : std::is_same<T, float>::value ? napi_float32_array
  688. : std::is_same<T, double>::value ? napi_float64_array
  689. // currently experimental guard with version of NAPI_VERSION that it is
  690. // released in once it is no longer experimental
  691. #if (NAPI_VERSION > 2147483646)
  692. : std::is_same<T, int64_t>::value ? napi_bigint64_array
  693. : std::is_same<T, uint64_t>::value ? napi_biguint64_array
  694. #endif // NAPI_EXPERIMENTAL
  695. : unknown_array_type;
  696. }
  697. /// !endcond
  698. };
  699. /// A JavaScript typed-array value with known array type.
  700. ///
  701. /// Note while it is possible to create and access Uint8 "clamped" arrays using this class,
  702. /// the _clamping_ behavior is only applied in JavaScript.
  703. template <typename T>
  704. class TypedArrayOf : public TypedArray {
  705. public:
  706. /// Creates a new TypedArray instance over a new automatically-allocated array buffer.
  707. ///
  708. /// The array type parameter can normally be omitted (because it is inferred from the template
  709. /// parameter T), except when creating a "clamped" array:
  710. ///
  711. /// Uint8Array::New(env, length, napi_uint8_clamped_array)
  712. static TypedArrayOf New(
  713. napi_env env, ///< N-API environment
  714. size_t elementLength, ///< Length of the created array, as a number of elements
  715. #if defined(NAPI_HAS_CONSTEXPR)
  716. napi_typedarray_type type = TypedArray::TypedArrayTypeForPrimitiveType<T>()
  717. #else
  718. napi_typedarray_type type
  719. #endif
  720. ///< Type of array, if different from the default array type for the template parameter T.
  721. );
  722. /// Creates a new TypedArray instance over a provided array buffer.
  723. ///
  724. /// The array type parameter can normally be omitted (because it is inferred from the template
  725. /// parameter T), except when creating a "clamped" array:
  726. ///
  727. /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array)
  728. static TypedArrayOf New(
  729. napi_env env, ///< N-API environment
  730. size_t elementLength, ///< Length of the created array, as a number of elements
  731. Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use
  732. size_t bufferOffset, ///< Offset into the array buffer where the typed-array starts
  733. #if defined(NAPI_HAS_CONSTEXPR)
  734. napi_typedarray_type type = TypedArray::TypedArrayTypeForPrimitiveType<T>()
  735. #else
  736. napi_typedarray_type type
  737. #endif
  738. ///< Type of array, if different from the default array type for the template parameter T.
  739. );
  740. TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance.
  741. TypedArrayOf(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  742. T& operator [](size_t index); ///< Gets or sets an element in the array.
  743. const T& operator [](size_t index) const; ///< Gets an element in the array.
  744. /// Gets a pointer to the array's backing buffer.
  745. ///
  746. /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, because the
  747. /// typed-array may have a non-zero `ByteOffset()` into the `ArrayBuffer`.
  748. T* Data();
  749. /// Gets a pointer to the array's backing buffer.
  750. ///
  751. /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, because the
  752. /// typed-array may have a non-zero `ByteOffset()` into the `ArrayBuffer`.
  753. const T* Data() const;
  754. private:
  755. T* _data;
  756. TypedArrayOf(napi_env env,
  757. napi_value value,
  758. napi_typedarray_type type,
  759. size_t length,
  760. T* data);
  761. };
  762. /// The DataView provides a low-level interface for reading/writing multiple
  763. /// number types in an ArrayBuffer irrespective of the platform's endianness.
  764. class DataView : public Object {
  765. public:
  766. static DataView New(napi_env env,
  767. Napi::ArrayBuffer arrayBuffer);
  768. static DataView New(napi_env env,
  769. Napi::ArrayBuffer arrayBuffer,
  770. size_t byteOffset);
  771. static DataView New(napi_env env,
  772. Napi::ArrayBuffer arrayBuffer,
  773. size_t byteOffset,
  774. size_t byteLength);
  775. DataView(); ///< Creates a new _empty_ DataView instance.
  776. DataView(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
  777. Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
  778. size_t ByteOffset() const; ///< Gets the offset into the buffer where the array starts.
  779. size_t ByteLength() const; ///< Gets the length of the array in bytes.
  780. void* Data() const;
  781. float GetFloat32(size_t byteOffset) const;
  782. double GetFloat64(size_t byteOffset) const;
  783. int8_t GetInt8(size_t byteOffset) const;
  784. int16_t GetInt16(size_t byteOffset) const;
  785. int32_t GetInt32(size_t byteOffset) const;
  786. uint8_t GetUint8(size_t byteOffset) const;
  787. uint16_t GetUint16(size_t byteOffset) const;
  788. uint32_t GetUint32(size_t byteOffset) const;
  789. void SetFloat32(size_t byteOffset, float value) const;
  790. void SetFloat64(size_t byteOffset, double value) const;
  791. void SetInt8(size_t byteOffset, int8_t value) const;
  792. void SetInt16(size_t byteOffset, int16_t value) const;
  793. void SetInt32(size_t byteOffset, int32_t value) const;
  794. void SetUint8(size_t byteOffset, uint8_t value) const;
  795. void SetUint16(size_t byteOffset, uint16_t value) const;
  796. void SetUint32(size_t byteOffset, uint32_t value) const;
  797. private:
  798. template <typename T>
  799. T ReadData(size_t byteOffset) const;
  800. template <typename T>
  801. void WriteData(size_t byteOffset, T value) const;
  802. void* _data;
  803. size_t _length;
  804. };
  805. class Function : public Object {
  806. public:
  807. /// Callable must implement operator() accepting a const CallbackInfo&
  808. /// and return either void or Value.
  809. template <typename Callable>
  810. static Function New(napi_env env,
  811. Callable cb,
  812. const char* utf8name = nullptr,
  813. void* data = nullptr);
  814. /// Callable must implement operator() accepting a const CallbackInfo&
  815. /// and return either void or Value.
  816. template <typename Callable>
  817. static Function New(napi_env env,
  818. Callable cb,
  819. const std::string& utf8name,
  820. void* data = nullptr);
  821. Function();
  822. Function(napi_env env, napi_value value);
  823. Value operator ()(const std::initializer_list<napi_value>& args) const;
  824. Value Call(const std::initializer_list<napi_value>& args) const;
  825. Value Call(const std::vector<napi_value>& args) const;
  826. Value Call(size_t argc, const napi_value* args) const;
  827. Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
  828. Value Call(napi_value recv, const std::vector<napi_value>& args) const;
  829. Value Call(napi_value recv, size_t argc, const napi_value* args) const;
  830. Value MakeCallback(napi_value recv,
  831. const std::initializer_list<napi_value>& args,
  832. napi_async_context context = nullptr) const;
  833. Value MakeCallback(napi_value recv,
  834. const std::vector<napi_value>& args,
  835. napi_async_context context = nullptr) const;
  836. Value MakeCallback(napi_value recv,
  837. size_t argc,
  838. const napi_value* args,
  839. napi_async_context context = nullptr) const;
  840. Object New(const std::initializer_list<napi_value>& args) const;
  841. Object New(const std::vector<napi_value>& args) const;
  842. Object New(size_t argc, const napi_value* args) const;
  843. };
  844. class Promise : public Object {
  845. public:
  846. class Deferred {
  847. public:
  848. static Deferred New(napi_env env);
  849. Deferred(napi_env env);
  850. Napi::Promise Promise() const;
  851. Napi::Env Env() const;
  852. void Resolve(napi_value value) const;
  853. void Reject(napi_value value) const;
  854. private:
  855. napi_env _env;
  856. napi_deferred _deferred;
  857. napi_value _promise;
  858. };
  859. Promise(napi_env env, napi_value value);
  860. };
  861. template <typename T>
  862. class Buffer : public Uint8Array {
  863. public:
  864. static Buffer<T> New(napi_env env, size_t length);
  865. static Buffer<T> New(napi_env env, T* data, size_t length);
  866. // Finalizer must implement `void operator()(Env env, T* data)`.
  867. template <typename Finalizer>
  868. static Buffer<T> New(napi_env env, T* data,
  869. size_t length,
  870. Finalizer finalizeCallback);
  871. // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
  872. template <typename Finalizer, typename Hint>
  873. static Buffer<T> New(napi_env env, T* data,
  874. size_t length,
  875. Finalizer finalizeCallback,
  876. Hint* finalizeHint);
  877. static Buffer<T> Copy(napi_env env, const T* data, size_t length);
  878. Buffer();
  879. Buffer(napi_env env, napi_value value);
  880. size_t Length() const;
  881. T* Data() const;
  882. private:
  883. mutable size_t _length;
  884. mutable T* _data;
  885. Buffer(napi_env env, napi_value value, size_t length, T* data);
  886. void EnsureInfo() const;
  887. };
  888. /// Holds a counted reference to a value; initially a weak reference unless otherwise specified,
  889. /// may be changed to/from a strong reference by adjusting the refcount.
  890. ///
  891. /// The referenced value is not immediately destroyed when the reference count is zero; it is
  892. /// merely then eligible for garbage-collection if there are no other references to the value.
  893. template <typename T>
  894. class Reference {
  895. public:
  896. static Reference<T> New(const T& value, uint32_t initialRefcount = 0);
  897. Reference();
  898. Reference(napi_env env, napi_ref ref);
  899. ~Reference();
  900. // A reference can be moved but cannot be copied.
  901. Reference(Reference<T>&& other);
  902. Reference<T>& operator =(Reference<T>&& other);
  903. Reference<T>& operator =(Reference<T>&) = delete;
  904. operator napi_ref() const;
  905. bool operator ==(const Reference<T> &other) const;
  906. bool operator !=(const Reference<T> &other) const;
  907. Napi::Env Env() const;
  908. bool IsEmpty() const;
  909. // Note when getting the value of a Reference it is usually correct to do so
  910. // within a HandleScope so that the value handle gets cleaned up efficiently.
  911. T Value() const;
  912. uint32_t Ref();
  913. uint32_t Unref();
  914. void Reset();
  915. void Reset(const T& value, uint32_t refcount = 0);
  916. // Call this on a reference that is declared as static data, to prevent its destructor
  917. // from running at program shutdown time, which would attempt to reset the reference when
  918. // the environment is no longer valid.
  919. void SuppressDestruct();
  920. protected:
  921. Reference(const Reference<T>&);
  922. /// !cond INTERNAL
  923. napi_env _env;
  924. napi_ref _ref;
  925. /// !endcond
  926. private:
  927. bool _suppressDestruct;
  928. };
  929. class ObjectReference: public Reference<Object> {
  930. public:
  931. ObjectReference();
  932. ObjectReference(napi_env env, napi_ref ref);
  933. // A reference can be moved but cannot be copied.
  934. ObjectReference(Reference<Object>&& other);
  935. ObjectReference& operator =(Reference<Object>&& other);
  936. ObjectReference(ObjectReference&& other);
  937. ObjectReference& operator =(ObjectReference&& other);
  938. ObjectReference& operator =(ObjectReference&) = delete;
  939. Napi::Value Get(const char* utf8name) const;
  940. Napi::Value Get(const std::string& utf8name) const;
  941. void Set(const char* utf8name, napi_value value);
  942. void Set(const char* utf8name, Napi::Value value);
  943. void Set(const char* utf8name, const char* utf8value);
  944. void Set(const char* utf8name, bool boolValue);
  945. void Set(const char* utf8name, double numberValue);
  946. void Set(const std::string& utf8name, napi_value value);
  947. void Set(const std::string& utf8name, Napi::Value value);
  948. void Set(const std::string& utf8name, std::string& utf8value);
  949. void Set(const std::string& utf8name, bool boolValue);
  950. void Set(const std::string& utf8name, double numberValue);
  951. Napi::Value Get(uint32_t index) const;
  952. void Set(uint32_t index, const napi_value value);
  953. void Set(uint32_t index, const Napi::Value value);
  954. void Set(uint32_t index, const char* utf8value);
  955. void Set(uint32_t index, const std::string& utf8value);
  956. void Set(uint32_t index, bool boolValue);
  957. void Set(uint32_t index, double numberValue);
  958. protected:
  959. ObjectReference(const ObjectReference&);
  960. };
  961. class FunctionReference: public Reference<Function> {
  962. public:
  963. FunctionReference();
  964. FunctionReference(napi_env env, napi_ref ref);
  965. // A reference can be moved but cannot be copied.
  966. FunctionReference(Reference<Function>&& other);
  967. FunctionReference& operator =(Reference<Function>&& other);
  968. FunctionReference(FunctionReference&& other);
  969. FunctionReference& operator =(FunctionReference&& other);
  970. FunctionReference(const FunctionReference&) = delete;
  971. FunctionReference& operator =(FunctionReference&) = delete;
  972. Napi::Value operator ()(const std::initializer_list<napi_value>& args) const;
  973. Napi::Value Call(const std::initializer_list<napi_value>& args) const;
  974. Napi::Value Call(const std::vector<napi_value>& args) const;
  975. Napi::Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
  976. Napi::Value Call(napi_value recv, const std::vector<napi_value>& args) const;
  977. Napi::Value Call(napi_value recv, size_t argc, const napi_value* args) const;
  978. Napi::Value MakeCallback(napi_value recv,
  979. const std::initializer_list<napi_value>& args,
  980. napi_async_context context = nullptr) const;
  981. Napi::Value MakeCallback(napi_value recv,
  982. const std::vector<napi_value>& args,
  983. napi_async_context context = nullptr) const;
  984. Napi::Value MakeCallback(napi_value recv,
  985. size_t argc,
  986. const napi_value* args,
  987. napi_async_context context = nullptr) const;
  988. Object New(const std::initializer_list<napi_value>& args) const;
  989. Object New(const std::vector<napi_value>& args) const;
  990. };
  991. // Shortcuts to creating a new reference with inferred type and refcount = 0.
  992. template <typename T> Reference<T> Weak(T value);
  993. ObjectReference Weak(Object value);
  994. FunctionReference Weak(Function value);
  995. // Shortcuts to creating a new reference with inferred type and refcount = 1.
  996. template <typename T> Reference<T> Persistent(T value);
  997. ObjectReference Persistent(Object value);
  998. FunctionReference Persistent(Function value);
  999. /// A persistent reference to a JavaScript error object. Use of this class depends somewhat
  1000. /// on whether C++ exceptions are enabled at compile time.
  1001. ///
  1002. /// ### Handling Errors With C++ Exceptions
  1003. ///
  1004. /// If C++ exceptions are enabled, then the `Error` class extends `std::exception` and enables
  1005. /// integrated error-handling for C++ exceptions and JavaScript exceptions.
  1006. ///
  1007. /// If a N-API call fails without executing any JavaScript code (for example due to an invalid
  1008. /// argument), then the N-API wrapper automatically converts and throws the error as a C++
  1009. /// exception of type `Napi::Error`. Or if a JavaScript function called by C++ code via N-API
  1010. /// throws a JavaScript exception, then the N-API wrapper automatically converts and throws it as
  1011. /// a C++ exception of type `Napi::Error`.
  1012. ///
  1013. /// If a C++ exception of type `Napi::Error` escapes from a N-API C++ callback, then the N-API
  1014. /// wrapper automatically converts and throws it as a JavaScript exception. Therefore, catching
  1015. /// a C++ exception of type `Napi::Error` prevents a JavaScript exception from being thrown.
  1016. ///
  1017. /// #### Example 1A - Throwing a C++ exception:
  1018. ///
  1019. /// Napi::Env env = ...
  1020. /// throw Napi::Error::New(env, "Example exception");
  1021. ///
  1022. /// Following C++ statements will not be executed. The exception will bubble up as a C++
  1023. /// exception of type `Napi::Error`, until it is either caught while still in C++, or else
  1024. /// automatically propataged as a JavaScript exception when the callback returns to JavaScript.
  1025. ///
  1026. /// #### Example 2A - Propagating a N-API C++ exception:
  1027. ///
  1028. /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
  1029. /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
  1030. ///
  1031. /// Following C++ statements will not be executed. The exception will bubble up as a C++
  1032. /// exception of type `Napi::Error`, until it is either caught while still in C++, or else
  1033. /// automatically propagated as a JavaScript exception when the callback returns to JavaScript.
  1034. ///
  1035. /// #### Example 3A - Handling a N-API C++ exception:
  1036. ///
  1037. /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
  1038. /// Napi::Value result;
  1039. /// try {
  1040. /// result = jsFunctionThatThrows({ arg1, arg2 });
  1041. /// } catch (const Napi::Error& e) {
  1042. /// cerr << "Caught JavaScript exception: " + e.what();
  1043. /// }
  1044. ///
  1045. /// Since the exception was caught here, it will not be propagated as a JavaScript exception.
  1046. ///
  1047. /// ### Handling Errors Without C++ Exceptions
  1048. ///
  1049. /// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`) then this class
  1050. /// does not extend `std::exception`, and APIs in the `Napi` namespace do not throw C++
  1051. /// exceptions when they fail. Instead, they raise _pending_ JavaScript exceptions and
  1052. /// return _empty_ `Value`s. Calling code should check `Value::IsEmpty()` before attempting
  1053. /// to use a returned value, and may use methods on the `Env` class to check for, get, and
  1054. /// clear a pending JavaScript exception. If the pending exception is not cleared, it will
  1055. /// be thrown when the native callback returns to JavaScript.
  1056. ///
  1057. /// #### Example 1B - Throwing a JS exception
  1058. ///
  1059. /// Napi::Env env = ...
  1060. /// Napi::Error::New(env, "Example exception").ThrowAsJavaScriptException();
  1061. /// return;
  1062. ///
  1063. /// After throwing a JS exception, the code should generally return immediately from the native
  1064. /// callback, after performing any necessary cleanup.
  1065. ///
  1066. /// #### Example 2B - Propagating a N-API JS exception:
  1067. ///
  1068. /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
  1069. /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
  1070. /// if (result.IsEmpty()) return;
  1071. ///
  1072. /// An empty value result from a N-API call indicates an error occurred, and a JavaScript
  1073. /// exception is pending. To let the exception propagate, the code should generally return
  1074. /// immediately from the native callback, after performing any necessary cleanup.
  1075. ///
  1076. /// #### Example 3B - Handling a N-API JS exception:
  1077. ///
  1078. /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
  1079. /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
  1080. /// if (result.IsEmpty()) {
  1081. /// Napi::Error e = env.GetAndClearPendingException();
  1082. /// cerr << "Caught JavaScript exception: " + e.Message();
  1083. /// }
  1084. ///
  1085. /// Since the exception was cleared here, it will not be propagated as a JavaScript exception
  1086. /// after the native callback returns.
  1087. class Error : public ObjectReference
  1088. #ifdef NAPI_CPP_EXCEPTIONS
  1089. , public std::exception
  1090. #endif // NAPI_CPP_EXCEPTIONS
  1091. {
  1092. public:
  1093. static Error New(napi_env env);
  1094. static Error New(napi_env env, const char* message);
  1095. static Error New(napi_env env, const std::string& message);
  1096. static NAPI_NO_RETURN void Fatal(const char* location, const char* message);
  1097. Error();
  1098. Error(napi_env env, napi_value value);
  1099. // An error can be moved or copied.
  1100. Error(Error&& other);
  1101. Error& operator =(Error&& other);
  1102. Error(const Error&);
  1103. Error& operator =(Error&);
  1104. const std::string& Message() const NAPI_NOEXCEPT;
  1105. void ThrowAsJavaScriptException() const;
  1106. #ifdef NAPI_CPP_EXCEPTIONS
  1107. const char* what() const NAPI_NOEXCEPT override;
  1108. #endif // NAPI_CPP_EXCEPTIONS
  1109. protected:
  1110. /// !cond INTERNAL
  1111. typedef napi_status (*create_error_fn)(napi_env envb, napi_value code, napi_value msg, napi_value* result);
  1112. template <typename TError>
  1113. static TError New(napi_env env,
  1114. const char* message,
  1115. size_t length,
  1116. create_error_fn create_error);
  1117. /// !endcond
  1118. private:
  1119. mutable std::string _message;
  1120. };
  1121. class TypeError : public Error {
  1122. public:
  1123. static TypeError New(napi_env env, const char* message);
  1124. static TypeError New(napi_env env, const std::string& message);
  1125. TypeError();
  1126. TypeError(napi_env env, napi_value value);
  1127. };
  1128. class RangeError : public Error {
  1129. public:
  1130. static RangeError New(napi_env env, const char* message);
  1131. static RangeError New(napi_env env, const std::string& message);
  1132. RangeError();
  1133. RangeError(napi_env env, napi_value value);
  1134. };
  1135. class CallbackInfo {
  1136. public:
  1137. CallbackInfo(napi_env env, napi_callback_info info);
  1138. ~CallbackInfo();
  1139. // Disallow copying to prevent multiple free of _dynamicArgs
  1140. CallbackInfo(CallbackInfo const &) = delete;
  1141. void operator=(CallbackInfo const &) = delete;
  1142. Napi::Env Env() const;
  1143. Value NewTarget() const;
  1144. bool IsConstructCall() const;
  1145. size_t Length() const;
  1146. const Value operator [](size_t index) const;
  1147. Value This() const;
  1148. void* Data() const;
  1149. void SetData(void* data);
  1150. private:
  1151. const size_t _staticArgCount = 6;
  1152. napi_env _env;
  1153. napi_callback_info _info;
  1154. napi_value _this;
  1155. size_t _argc;
  1156. napi_value* _argv;
  1157. napi_value _staticArgs[6];
  1158. napi_value* _dynamicArgs;
  1159. void* _data;
  1160. };
  1161. class PropertyDescriptor {
  1162. public:
  1163. #ifndef NODE_ADDON_API_DISABLE_DEPRECATED
  1164. template <typename Getter>
  1165. static PropertyDescriptor Accessor(const char* utf8name,
  1166. Getter getter,
  1167. napi_property_attributes attributes = napi_default,
  1168. void* data = nullptr);
  1169. template <typename Getter>
  1170. static PropertyDescriptor Accessor(const std::string& utf8name,
  1171. Getter getter,
  1172. napi_property_attributes attributes = napi_default,
  1173. void* data = nullptr);
  1174. template <typename Getter>
  1175. static PropertyDescriptor Accessor(napi_value name,
  1176. Getter getter,
  1177. napi_property_attributes attributes = napi_default,
  1178. void* data = nullptr);
  1179. template <typename Getter>
  1180. static PropertyDescriptor Accessor(Name name,
  1181. Getter getter,
  1182. napi_property_attributes attributes = napi_default,
  1183. void* data = nullptr);
  1184. template <typename Getter, typename Setter>
  1185. static PropertyDescriptor Accessor(const char* utf8name,
  1186. Getter getter,
  1187. Setter setter,
  1188. napi_property_attributes attributes = napi_default,
  1189. void* data = nullptr);
  1190. template <typename Getter, typename Setter>
  1191. static PropertyDescriptor Accessor(const std::string& utf8name,
  1192. Getter getter,
  1193. Setter setter,
  1194. napi_property_attributes attributes = napi_default,
  1195. void* data = nullptr);
  1196. template <typename Getter, typename Setter>
  1197. static PropertyDescriptor Accessor(napi_value name,
  1198. Getter getter,
  1199. Setter setter,
  1200. napi_property_attributes attributes = napi_default,
  1201. void* data = nullptr);
  1202. template <typename Getter, typename Setter>
  1203. static PropertyDescriptor Accessor(Name name,
  1204. Getter getter,
  1205. Setter setter,
  1206. napi_property_attributes attributes = napi_default,
  1207. void* data = nullptr);
  1208. template <typename Callable>
  1209. static PropertyDescriptor Function(const char* utf8name,
  1210. Callable cb,
  1211. napi_property_attributes attributes = napi_default,
  1212. void* data = nullptr);
  1213. template <typename Callable>
  1214. static PropertyDescriptor Function(const std::string& utf8name,
  1215. Callable cb,
  1216. napi_property_attributes attributes = napi_default,
  1217. void* data = nullptr);
  1218. template <typename Callable>
  1219. static PropertyDescriptor Function(napi_value name,
  1220. Callable cb,
  1221. napi_property_attributes attributes = napi_default,
  1222. void* data = nullptr);
  1223. template <typename Callable>
  1224. static PropertyDescriptor Function(Name name,
  1225. Callable cb,
  1226. napi_property_attributes attributes = napi_default,
  1227. void* data = nullptr);
  1228. #endif // !NODE_ADDON_API_DISABLE_DEPRECATED
  1229. template <typename Getter>
  1230. static PropertyDescriptor Accessor(Napi::Env env,
  1231. Napi::Object object,
  1232. const char* utf8name,
  1233. Getter getter,
  1234. napi_property_attributes attributes = napi_default,
  1235. void* data = nullptr);
  1236. template <typename Getter>
  1237. static PropertyDescriptor Accessor(Napi::Env env,
  1238. Napi::Object object,
  1239. const std::string& utf8name,
  1240. Getter getter,
  1241. napi_property_attributes attributes = napi_default,
  1242. void* data = nullptr);
  1243. template <typename Getter>
  1244. static PropertyDescriptor Accessor(Napi::Env env,
  1245. Napi::Object object,
  1246. Name name,
  1247. Getter getter,
  1248. napi_property_attributes attributes = napi_default,
  1249. void* data = nullptr);
  1250. template <typename Getter, typename Setter>
  1251. static PropertyDescriptor Accessor(Napi::Env env,
  1252. Napi::Object object,
  1253. const char* utf8name,
  1254. Getter getter,
  1255. Setter setter,
  1256. napi_property_attributes attributes = napi_default,
  1257. void* data = nullptr);
  1258. template <typename Getter, typename Setter>
  1259. static PropertyDescriptor Accessor(Napi::Env env,
  1260. Napi::Object object,
  1261. const std::string& utf8name,
  1262. Getter getter,
  1263. Setter setter,
  1264. napi_property_attributes attributes = napi_default,
  1265. void* data = nullptr);
  1266. template <typename Getter, typename Setter>
  1267. static PropertyDescriptor Accessor(Napi::Env env,
  1268. Napi::Object object,
  1269. Name name,
  1270. Getter getter,
  1271. Setter setter,
  1272. napi_property_attributes attributes = napi_default,
  1273. void* data = nullptr);
  1274. template <typename Callable>
  1275. static PropertyDescriptor Function(Napi::Env env,
  1276. Napi::Object object,
  1277. const char* utf8name,
  1278. Callable cb,
  1279. napi_property_attributes attributes = napi_default,
  1280. void* data = nullptr);
  1281. template <typename Callable>
  1282. static PropertyDescriptor Function(Napi::Env env,
  1283. Napi::Object object,
  1284. const std::string& utf8name,
  1285. Callable cb,
  1286. napi_property_attributes attributes = napi_default,
  1287. void* data = nullptr);
  1288. template <typename Callable>
  1289. static PropertyDescriptor Function(Napi::Env env,
  1290. Napi::Object object,
  1291. Name name,
  1292. Callable cb,
  1293. napi_property_attributes attributes = napi_default,
  1294. void* data = nullptr);
  1295. static PropertyDescriptor Value(const char* utf8name,
  1296. napi_value value,
  1297. napi_property_attributes attributes = napi_default);
  1298. static PropertyDescriptor Value(const std::string& utf8name,
  1299. napi_value value,
  1300. napi_property_attributes attributes = napi_default);
  1301. static PropertyDescriptor Value(napi_value name,
  1302. napi_value value,
  1303. napi_property_attributes attributes = napi_default);
  1304. static PropertyDescriptor Value(Name name,
  1305. Napi::Value value,
  1306. napi_property_attributes attributes = napi_default);
  1307. PropertyDescriptor(napi_property_descriptor desc);
  1308. operator napi_property_descriptor&();
  1309. operator const napi_property_descriptor&() const;
  1310. private:
  1311. napi_property_descriptor _desc;
  1312. };
  1313. /// Property descriptor for use with `ObjectWrap::DefineClass()`.
  1314. ///
  1315. /// This is different from the standalone `PropertyDescriptor` because it is specific to each
  1316. /// `ObjectWrap<T>` subclass. This prevents using descriptors from a different class when
  1317. /// defining a new class (preventing the callbacks from having incorrect `this` pointers).
  1318. template <typename T>
  1319. class ClassPropertyDescriptor {
  1320. public:
  1321. ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {}
  1322. operator napi_property_descriptor&() { return _desc; }
  1323. operator const napi_property_descriptor&() const { return _desc; }
  1324. private:
  1325. napi_property_descriptor _desc;
  1326. };
  1327. /// Base class to be extended by C++ classes exposed to JavaScript; each C++ class instance gets
  1328. /// "wrapped" by a JavaScript object that is managed by this class.
  1329. ///
  1330. /// At initialization time, the `DefineClass()` method must be used to
  1331. /// hook up the accessor and method callbacks. It takes a list of
  1332. /// property descriptors, which can be constructed via the various
  1333. /// static methods on the base class.
  1334. ///
  1335. /// #### Example:
  1336. ///
  1337. /// class Example: public Napi::ObjectWrap<Example> {
  1338. /// public:
  1339. /// static void Initialize(Napi::Env& env, Napi::Object& target) {
  1340. /// Napi::Function constructor = DefineClass(env, "Example", {
  1341. /// InstanceAccessor("value", &Example::GetSomething, &Example::SetSomething),
  1342. /// InstanceMethod("doSomething", &Example::DoSomething),
  1343. /// });
  1344. /// target.Set("Example", constructor);
  1345. /// }
  1346. ///
  1347. /// Example(const Napi::CallbackInfo& info); // Constructor
  1348. /// Napi::Value GetSomething(const Napi::CallbackInfo& info);
  1349. /// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value& value);
  1350. /// Napi::Value DoSomething(const Napi::CallbackInfo& info);
  1351. /// }
  1352. template <typename T>
  1353. class ObjectWrap : public Reference<Object> {
  1354. public:
  1355. ObjectWrap(const CallbackInfo& callbackInfo);
  1356. static T* Unwrap(Object wrapper);
  1357. // Methods exposed to JavaScript must conform to one of these callback signatures.
  1358. typedef void (*StaticVoidMethodCallback)(const CallbackInfo& info);
  1359. typedef Napi::Value (*StaticMethodCallback)(const CallbackInfo& info);
  1360. typedef Napi::Value (*StaticGetterCallback)(const CallbackInfo& info);
  1361. typedef void (*StaticSetterCallback)(const CallbackInfo& info, const Napi::Value& value);
  1362. typedef void (T::*InstanceVoidMethodCallback)(const CallbackInfo& info);
  1363. typedef Napi::Value (T::*InstanceMethodCallback)(const CallbackInfo& info);
  1364. typedef Napi::Value (T::*InstanceGetterCallback)(const CallbackInfo& info);
  1365. typedef void (T::*InstanceSetterCallback)(const CallbackInfo& info, const Napi::Value& value);
  1366. typedef ClassPropertyDescriptor<T> PropertyDescriptor;
  1367. static Function DefineClass(Napi::Env env,
  1368. const char* utf8name,
  1369. const std::initializer_list<PropertyDescriptor>& properties,
  1370. void* data = nullptr);
  1371. static Function DefineClass(Napi::Env env,
  1372. const char* utf8name,
  1373. const std::vector<PropertyDescriptor>& properties,
  1374. void* data = nullptr);
  1375. static PropertyDescriptor StaticMethod(const char* utf8name,
  1376. StaticVoidMethodCallback method,
  1377. napi_property_attributes attributes = napi_default,
  1378. void* data = nullptr);
  1379. static PropertyDescriptor StaticMethod(const char* utf8name,
  1380. StaticMethodCallback method,
  1381. napi_property_attributes attributes = napi_default,
  1382. void* data = nullptr);
  1383. static PropertyDescriptor StaticMethod(Symbol name,
  1384. StaticVoidMethodCallback method,
  1385. napi_property_attributes attributes = napi_default,
  1386. void* data = nullptr);
  1387. static PropertyDescriptor StaticMethod(Symbol name,
  1388. StaticMethodCallback method,
  1389. napi_property_attributes attributes = napi_default,
  1390. void* data = nullptr);
  1391. static PropertyDescriptor StaticAccessor(const char* utf8name,
  1392. StaticGetterCallback getter,
  1393. StaticSetterCallback setter,
  1394. napi_property_attributes attributes = napi_default,
  1395. void* data = nullptr);
  1396. static PropertyDescriptor StaticAccessor(Symbol name,
  1397. StaticGetterCallback getter,
  1398. StaticSetterCallback setter,
  1399. napi_property_attributes attributes = napi_default,
  1400. void* data = nullptr);
  1401. static PropertyDescriptor InstanceMethod(const char* utf8name,
  1402. InstanceVoidMethodCallback method,
  1403. napi_property_attributes attributes = napi_default,
  1404. void* data = nullptr);
  1405. static PropertyDescriptor InstanceMethod(const char* utf8name,
  1406. InstanceMethodCallback method,
  1407. napi_property_attributes attributes = napi_default,
  1408. void* data = nullptr);
  1409. static PropertyDescriptor InstanceMethod(Symbol name,
  1410. InstanceVoidMethodCallback method,
  1411. napi_property_attributes attributes = napi_default,
  1412. void* data = nullptr);
  1413. static PropertyDescriptor InstanceMethod(Symbol name,
  1414. InstanceMethodCallback method,
  1415. napi_property_attributes attributes = napi_default,
  1416. void* data = nullptr);
  1417. static PropertyDescriptor InstanceAccessor(const char* utf8name,
  1418. InstanceGetterCallback getter,
  1419. InstanceSetterCallback setter,
  1420. napi_property_attributes attributes = napi_default,
  1421. void* data = nullptr);
  1422. static PropertyDescriptor InstanceAccessor(Symbol name,
  1423. InstanceGetterCallback getter,
  1424. InstanceSetterCallback setter,
  1425. napi_property_attributes attributes = napi_default,
  1426. void* data = nullptr);
  1427. static PropertyDescriptor StaticValue(const char* utf8name,
  1428. Napi::Value value,
  1429. napi_property_attributes attributes = napi_default);
  1430. static PropertyDescriptor StaticValue(Symbol name,
  1431. Napi::Value value,
  1432. napi_property_attributes attributes = napi_default);
  1433. static PropertyDescriptor InstanceValue(const char* utf8name,
  1434. Napi::Value value,
  1435. napi_property_attributes attributes = napi_default);
  1436. static PropertyDescriptor InstanceValue(Symbol name,
  1437. Napi::Value value,
  1438. napi_property_attributes attributes = napi_default);
  1439. private:
  1440. static napi_value ConstructorCallbackWrapper(napi_env env, napi_callback_info info);
  1441. static napi_value StaticVoidMethodCallbackWrapper(napi_env env, napi_callback_info info);
  1442. static napi_value StaticMethodCallbackWrapper(napi_env env, napi_callback_info info);
  1443. static napi_value StaticGetterCallbackWrapper(napi_env env, napi_callback_info info);
  1444. static napi_value StaticSetterCallbackWrapper(napi_env env, napi_callback_info info);
  1445. static napi_value InstanceVoidMethodCallbackWrapper(napi_env env, napi_callback_info info);
  1446. static napi_value InstanceMethodCallbackWrapper(napi_env env, napi_callback_info info);
  1447. static napi_value InstanceGetterCallbackWrapper(napi_env env, napi_callback_info info);
  1448. static napi_value InstanceSetterCallbackWrapper(napi_env env, napi_callback_info info);
  1449. static void FinalizeCallback(napi_env env, void* data, void* hint);
  1450. static Function DefineClass(Napi::Env env,
  1451. const char* utf8name,
  1452. const size_t props_count,
  1453. const napi_property_descriptor* props,
  1454. void* data = nullptr);
  1455. template <typename TCallback>
  1456. struct MethodCallbackData {
  1457. TCallback callback;
  1458. void* data;
  1459. };
  1460. typedef MethodCallbackData<StaticVoidMethodCallback> StaticVoidMethodCallbackData;
  1461. typedef MethodCallbackData<StaticMethodCallback> StaticMethodCallbackData;
  1462. typedef MethodCallbackData<InstanceVoidMethodCallback> InstanceVoidMethodCallbackData;
  1463. typedef MethodCallbackData<InstanceMethodCallback> InstanceMethodCallbackData;
  1464. template <typename TGetterCallback, typename TSetterCallback>
  1465. struct AccessorCallbackData {
  1466. TGetterCallback getterCallback;
  1467. TSetterCallback setterCallback;
  1468. void* data;
  1469. };
  1470. typedef AccessorCallbackData<StaticGetterCallback, StaticSetterCallback>
  1471. StaticAccessorCallbackData;
  1472. typedef AccessorCallbackData<InstanceGetterCallback, InstanceSetterCallback>
  1473. InstanceAccessorCallbackData;
  1474. };
  1475. class HandleScope {
  1476. public:
  1477. HandleScope(napi_env env, napi_handle_scope scope);
  1478. explicit HandleScope(Napi::Env env);
  1479. ~HandleScope();
  1480. operator napi_handle_scope() const;
  1481. Napi::Env Env() const;
  1482. private:
  1483. napi_env _env;
  1484. napi_handle_scope _scope;
  1485. };
  1486. class EscapableHandleScope {
  1487. public:
  1488. EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope);
  1489. explicit EscapableHandleScope(Napi::Env env);
  1490. ~EscapableHandleScope();
  1491. operator napi_escapable_handle_scope() const;
  1492. Napi::Env Env() const;
  1493. Value Escape(napi_value escapee);
  1494. private:
  1495. napi_env _env;
  1496. napi_escapable_handle_scope _scope;
  1497. };
  1498. #if (NAPI_VERSION > 2)
  1499. class CallbackScope {
  1500. public:
  1501. CallbackScope(napi_env env, napi_callback_scope scope);
  1502. CallbackScope(napi_env env, napi_async_context context);
  1503. virtual ~CallbackScope();
  1504. operator napi_callback_scope() const;
  1505. Napi::Env Env() const;
  1506. private:
  1507. napi_env _env;
  1508. napi_callback_scope _scope;
  1509. };
  1510. #endif
  1511. class AsyncContext {
  1512. public:
  1513. explicit AsyncContext(napi_env env, const char* resource_name);
  1514. explicit AsyncContext(napi_env env, const char* resource_name, const Object& resource);
  1515. virtual ~AsyncContext();
  1516. AsyncContext(AsyncContext&& other);
  1517. AsyncContext& operator =(AsyncContext&& other);
  1518. AsyncContext(const AsyncContext&) = delete;
  1519. AsyncContext& operator =(AsyncContext&) = delete;
  1520. operator napi_async_context() const;
  1521. private:
  1522. napi_env _env;
  1523. napi_async_context _context;
  1524. };
  1525. class AsyncWorker {
  1526. public:
  1527. virtual ~AsyncWorker();
  1528. // An async worker can be moved but cannot be copied.
  1529. AsyncWorker(AsyncWorker&& other);
  1530. AsyncWorker& operator =(AsyncWorker&& other);
  1531. AsyncWorker(const AsyncWorker&) = delete;
  1532. AsyncWorker& operator =(AsyncWorker&) = delete;
  1533. operator napi_async_work() const;
  1534. Napi::Env Env() const;
  1535. void Queue();
  1536. void Cancel();
  1537. void SuppressDestruct();
  1538. ObjectReference& Receiver();
  1539. FunctionReference& Callback();
  1540. protected:
  1541. explicit AsyncWorker(const Function& callback);
  1542. explicit AsyncWorker(const Function& callback,
  1543. const char* resource_name);
  1544. explicit AsyncWorker(const Function& callback,
  1545. const char* resource_name,
  1546. const Object& resource);
  1547. explicit AsyncWorker(const Object& receiver,
  1548. const Function& callback);
  1549. explicit AsyncWorker(const Object& receiver,
  1550. const Function& callback,
  1551. const char* resource_name);
  1552. explicit AsyncWorker(const Object& receiver,
  1553. const Function& callback,
  1554. const char* resource_name,
  1555. const Object& resource);
  1556. explicit AsyncWorker(Napi::Env env);
  1557. explicit AsyncWorker(Napi::Env env,
  1558. const char* resource_name);
  1559. explicit AsyncWorker(Napi::Env env,
  1560. const char* resource_name,
  1561. const Object& resource);
  1562. virtual void Execute() = 0;
  1563. virtual void OnOK();
  1564. virtual void OnError(const Error& e);
  1565. virtual void Destroy();
  1566. virtual std::vector<napi_value> GetResult(Napi::Env env);
  1567. void SetError(const std::string& error);
  1568. private:
  1569. static void OnExecute(napi_env env, void* this_pointer);
  1570. static void OnWorkComplete(napi_env env,
  1571. napi_status status,
  1572. void* this_pointer);
  1573. napi_env _env;
  1574. napi_async_work _work;
  1575. ObjectReference _receiver;
  1576. FunctionReference _callback;
  1577. std::string _error;
  1578. bool _suppress_destruct;
  1579. };
  1580. #if (NAPI_VERSION > 3)
  1581. class ThreadSafeFunction {
  1582. public:
  1583. // This API may only be called from the main thread.
  1584. template <typename ResourceString>
  1585. static ThreadSafeFunction New(napi_env env,
  1586. const Function& callback,
  1587. ResourceString resourceName,
  1588. size_t maxQueueSize,
  1589. size_t initialThreadCount);
  1590. // This API may only be called from the main thread.
  1591. template <typename ResourceString, typename ContextType>
  1592. static ThreadSafeFunction New(napi_env env,
  1593. const Function& callback,
  1594. ResourceString resourceName,
  1595. size_t maxQueueSize,
  1596. size_t initialThreadCount,
  1597. ContextType* context);
  1598. // This API may only be called from the main thread.
  1599. template <typename ResourceString, typename Finalizer>
  1600. static ThreadSafeFunction New(napi_env env,
  1601. const Function& callback,
  1602. ResourceString resourceName,
  1603. size_t maxQueueSize,
  1604. size_t initialThreadCount,
  1605. Finalizer finalizeCallback);
  1606. // This API may only be called from the main thread.
  1607. template <typename ResourceString, typename Finalizer,
  1608. typename FinalizerDataType>
  1609. static ThreadSafeFunction New(napi_env env,
  1610. const Function& callback,
  1611. ResourceString resourceName,
  1612. size_t maxQueueSize,
  1613. size_t initialThreadCount,
  1614. Finalizer finalizeCallback,
  1615. FinalizerDataType* data);
  1616. // This API may only be called from the main thread.
  1617. template <typename ResourceString, typename ContextType, typename Finalizer>
  1618. static ThreadSafeFunction New(napi_env env,
  1619. const Function& callback,
  1620. ResourceString resourceName,
  1621. size_t maxQueueSize,
  1622. size_t initialThreadCount,
  1623. ContextType* context,
  1624. Finalizer finalizeCallback);
  1625. // This API may only be called from the main thread.
  1626. template <typename ResourceString, typename ContextType,
  1627. typename Finalizer, typename FinalizerDataType>
  1628. static ThreadSafeFunction New(napi_env env,
  1629. const Function& callback,
  1630. ResourceString resourceName,
  1631. size_t maxQueueSize,
  1632. size_t initialThreadCount,
  1633. ContextType* context,
  1634. Finalizer finalizeCallback,
  1635. FinalizerDataType* data);
  1636. // This API may only be called from the main thread.
  1637. template <typename ResourceString>
  1638. static ThreadSafeFunction New(napi_env env,
  1639. const Function& callback,
  1640. const Object& resource,
  1641. ResourceString resourceName,
  1642. size_t maxQueueSize,
  1643. size_t initialThreadCount);
  1644. // This API may only be called from the main thread.
  1645. template <typename ResourceString, typename ContextType>
  1646. static ThreadSafeFunction New(napi_env env,
  1647. const Function& callback,
  1648. const Object& resource,
  1649. ResourceString resourceName,
  1650. size_t maxQueueSize,
  1651. size_t initialThreadCount,
  1652. ContextType* context);
  1653. // This API may only be called from the main thread.
  1654. template <typename ResourceString, typename Finalizer>
  1655. static ThreadSafeFunction New(napi_env env,
  1656. const Function& callback,
  1657. const Object& resource,
  1658. ResourceString resourceName,
  1659. size_t maxQueueSize,
  1660. size_t initialThreadCount,
  1661. Finalizer finalizeCallback);
  1662. // This API may only be called from the main thread.
  1663. template <typename ResourceString, typename Finalizer,
  1664. typename FinalizerDataType>
  1665. static ThreadSafeFunction New(napi_env env,
  1666. const Function& callback,
  1667. const Object& resource,
  1668. ResourceString resourceName,
  1669. size_t maxQueueSize,
  1670. size_t initialThreadCount,
  1671. Finalizer finalizeCallback,
  1672. FinalizerDataType* data);
  1673. // This API may only be called from the main thread.
  1674. template <typename ResourceString, typename ContextType, typename Finalizer>
  1675. static ThreadSafeFunction New(napi_env env,
  1676. const Function& callback,
  1677. const Object& resource,
  1678. ResourceString resourceName,
  1679. size_t maxQueueSize,
  1680. size_t initialThreadCount,
  1681. ContextType* context,
  1682. Finalizer finalizeCallback);
  1683. // This API may only be called from the main thread.
  1684. template <typename ResourceString, typename ContextType,
  1685. typename Finalizer, typename FinalizerDataType>
  1686. static ThreadSafeFunction New(napi_env env,
  1687. const Function& callback,
  1688. const Object& resource,
  1689. ResourceString resourceName,
  1690. size_t maxQueueSize,
  1691. size_t initialThreadCount,
  1692. ContextType* context,
  1693. Finalizer finalizeCallback,
  1694. FinalizerDataType* data);
  1695. ThreadSafeFunction();
  1696. ThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
  1697. ThreadSafeFunction(ThreadSafeFunction&& other);
  1698. ThreadSafeFunction& operator=(ThreadSafeFunction&& other);
  1699. // This API may be called from any thread.
  1700. napi_status BlockingCall() const;
  1701. // This API may be called from any thread.
  1702. template <typename Callback>
  1703. napi_status BlockingCall(Callback callback) const;
  1704. // This API may be called from any thread.
  1705. template <typename DataType, typename Callback>
  1706. napi_status BlockingCall(DataType* data, Callback callback) const;
  1707. // This API may be called from any thread.
  1708. napi_status NonBlockingCall() const;
  1709. // This API may be called from any thread.
  1710. template <typename Callback>
  1711. napi_status NonBlockingCall(Callback callback) const;
  1712. // This API may be called from any thread.
  1713. template <typename DataType, typename Callback>
  1714. napi_status NonBlockingCall(DataType* data, Callback callback) const;
  1715. // This API may be called from any thread.
  1716. napi_status Acquire() const;
  1717. // This API may be called from any thread.
  1718. napi_status Release();
  1719. // This API may be called from any thread.
  1720. napi_status Abort();
  1721. struct ConvertibleContext
  1722. {
  1723. template <class T>
  1724. operator T*() { return static_cast<T*>(context); }
  1725. void* context;
  1726. };
  1727. // This API may be called from any thread.
  1728. ConvertibleContext GetContext() const;
  1729. private:
  1730. using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>;
  1731. template <typename ResourceString, typename ContextType,
  1732. typename Finalizer, typename FinalizerDataType>
  1733. static ThreadSafeFunction New(napi_env env,
  1734. const Function& callback,
  1735. const Object& resource,
  1736. ResourceString resourceName,
  1737. size_t maxQueueSize,
  1738. size_t initialThreadCount,
  1739. ContextType* context,
  1740. Finalizer finalizeCallback,
  1741. FinalizerDataType* data,
  1742. napi_finalize wrapper);
  1743. napi_status CallInternal(CallbackWrapper* callbackWrapper,
  1744. napi_threadsafe_function_call_mode mode) const;
  1745. static void CallJS(napi_env env,
  1746. napi_value jsCallback,
  1747. void* context,
  1748. void* data);
  1749. std::unique_ptr<napi_threadsafe_function> _tsfn;
  1750. };
  1751. #endif
  1752. // Memory management.
  1753. class MemoryManagement {
  1754. public:
  1755. static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
  1756. };
  1757. // Version management
  1758. class VersionManagement {
  1759. public:
  1760. static uint32_t GetNapiVersion(Env env);
  1761. static const napi_node_version* GetNodeVersion(Env env);
  1762. };
  1763. } // namespace Napi
  1764. // Inline implementations of all the above class methods are included here.
  1765. #include "napi-inl.h"
  1766. #endif // SRC_NAPI_H_