napi.h 116 KB

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