napi.h 110 KB

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