napi.h 112 KB

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