napi.h 113 KB

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