Turn audio into a shareable video. forked from nypublicradio/audiogram

node.h 34KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. // Copyright Joyent, Inc. and other Node contributors.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a
  4. // copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to permit
  8. // persons to whom the Software is furnished to do so, subject to the
  9. // following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included
  12. // in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  17. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  18. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #ifndef SRC_NODE_H_
  22. #define SRC_NODE_H_
  23. #ifdef _WIN32
  24. # ifndef BUILDING_NODE_EXTENSION
  25. # define NODE_EXTERN __declspec(dllexport)
  26. # else
  27. # define NODE_EXTERN __declspec(dllimport)
  28. # endif
  29. #else
  30. # define NODE_EXTERN __attribute__((visibility("default")))
  31. #endif
  32. #ifdef BUILDING_NODE_EXTENSION
  33. # undef BUILDING_V8_SHARED
  34. # undef BUILDING_UV_SHARED
  35. # define USING_V8_SHARED 1
  36. # define USING_UV_SHARED 1
  37. #endif
  38. // This should be defined in make system.
  39. // See issue https://github.com/nodejs/node-v0.x-archive/issues/1236
  40. #if defined(__MINGW32__) || defined(_MSC_VER)
  41. #ifndef _WIN32_WINNT
  42. # define _WIN32_WINNT 0x0600 // Windows Server 2008
  43. #endif
  44. #ifndef NOMINMAX
  45. # define NOMINMAX
  46. #endif
  47. #endif
  48. #if defined(_MSC_VER)
  49. #define PATH_MAX MAX_PATH
  50. #endif
  51. #ifdef _WIN32
  52. # define SIGKILL 9
  53. #endif
  54. #include "v8.h" // NOLINT(build/include_order)
  55. #include "v8-platform.h" // NOLINT(build/include_order)
  56. #include "node_version.h" // NODE_MODULE_VERSION
  57. #include <memory>
  58. #define NODE_MAKE_VERSION(major, minor, patch) \
  59. ((major) * 0x1000 + (minor) * 0x100 + (patch))
  60. #ifdef __clang__
  61. # define NODE_CLANG_AT_LEAST(major, minor, patch) \
  62. (NODE_MAKE_VERSION(major, minor, patch) <= \
  63. NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__))
  64. #else
  65. # define NODE_CLANG_AT_LEAST(major, minor, patch) (0)
  66. #endif
  67. #ifdef __GNUC__
  68. # define NODE_GNUC_AT_LEAST(major, minor, patch) \
  69. (NODE_MAKE_VERSION(major, minor, patch) <= \
  70. NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__))
  71. #else
  72. # define NODE_GNUC_AT_LEAST(major, minor, patch) (0)
  73. #endif
  74. #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
  75. # define NODE_DEPRECATED(message, declarator) declarator
  76. #else // NODE_WANT_INTERNALS
  77. # if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0)
  78. # define NODE_DEPRECATED(message, declarator) \
  79. __attribute__((deprecated(message))) declarator
  80. # elif defined(_MSC_VER)
  81. # define NODE_DEPRECATED(message, declarator) \
  82. __declspec(deprecated) declarator
  83. # else
  84. # define NODE_DEPRECATED(message, declarator) declarator
  85. # endif
  86. #endif
  87. // Forward-declare libuv loop
  88. struct uv_loop_s;
  89. // Forward-declare these functions now to stop MSVS from becoming
  90. // terminally confused when it's done in node_internals.h
  91. namespace node {
  92. namespace tracing {
  93. class TracingController;
  94. }
  95. NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
  96. int errorno,
  97. const char* syscall = nullptr,
  98. const char* message = nullptr,
  99. const char* path = nullptr);
  100. NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
  101. int errorno,
  102. const char* syscall = nullptr,
  103. const char* message = nullptr,
  104. const char* path = nullptr,
  105. const char* dest = nullptr);
  106. NODE_DEPRECATED("Use ErrnoException(isolate, ...)",
  107. inline v8::Local<v8::Value> ErrnoException(
  108. int errorno,
  109. const char* syscall = nullptr,
  110. const char* message = nullptr,
  111. const char* path = nullptr) {
  112. return ErrnoException(v8::Isolate::GetCurrent(),
  113. errorno,
  114. syscall,
  115. message,
  116. path);
  117. })
  118. NODE_DEPRECATED("Use UVException(isolate, ...)",
  119. inline v8::Local<v8::Value> UVException(int errorno,
  120. const char* syscall = nullptr,
  121. const char* message = nullptr,
  122. const char* path = nullptr) {
  123. return UVException(v8::Isolate::GetCurrent(),
  124. errorno,
  125. syscall,
  126. message,
  127. path);
  128. })
  129. /*
  130. * These methods need to be called in a HandleScope.
  131. *
  132. * It is preferred that you use the `MakeCallback` overloads taking
  133. * `async_context` arguments.
  134. */
  135. NODE_DEPRECATED("Use MakeCallback(..., async_context)",
  136. NODE_EXTERN v8::Local<v8::Value> MakeCallback(
  137. v8::Isolate* isolate,
  138. v8::Local<v8::Object> recv,
  139. const char* method,
  140. int argc,
  141. v8::Local<v8::Value>* argv));
  142. NODE_DEPRECATED("Use MakeCallback(..., async_context)",
  143. NODE_EXTERN v8::Local<v8::Value> MakeCallback(
  144. v8::Isolate* isolate,
  145. v8::Local<v8::Object> recv,
  146. v8::Local<v8::String> symbol,
  147. int argc,
  148. v8::Local<v8::Value>* argv));
  149. NODE_DEPRECATED("Use MakeCallback(..., async_context)",
  150. NODE_EXTERN v8::Local<v8::Value> MakeCallback(
  151. v8::Isolate* isolate,
  152. v8::Local<v8::Object> recv,
  153. v8::Local<v8::Function> callback,
  154. int argc,
  155. v8::Local<v8::Value>* argv));
  156. } // namespace node
  157. #include <cassert>
  158. #include <cstdint>
  159. #ifndef NODE_STRINGIFY
  160. # define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
  161. # define NODE_STRINGIFY_HELPER(n) #n
  162. #endif
  163. #ifdef _WIN32
  164. #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
  165. typedef intptr_t ssize_t;
  166. # define _SSIZE_T_
  167. # define _SSIZE_T_DEFINED
  168. #endif
  169. #else // !_WIN32
  170. # include <sys/types.h> // size_t, ssize_t
  171. #endif // _WIN32
  172. namespace node {
  173. class IsolateData;
  174. class Environment;
  175. // TODO(addaleax): Officially deprecate this and replace it with something
  176. // better suited for a public embedder API.
  177. NODE_EXTERN int Start(int argc, char* argv[]);
  178. // Tear down Node.js while it is running (there are active handles
  179. // in the loop and / or actively executing JavaScript code).
  180. NODE_EXTERN int Stop(Environment* env);
  181. // TODO(addaleax): Officially deprecate this and replace it with something
  182. // better suited for a public embedder API.
  183. NODE_EXTERN void Init(int* argc,
  184. const char** argv,
  185. int* exec_argc,
  186. const char*** exec_argv);
  187. class NodeArrayBufferAllocator;
  188. // An ArrayBuffer::Allocator class with some Node.js-specific tweaks. If you do
  189. // not have to use another allocator, using this class is recommended:
  190. // - It supports Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() with
  191. // uninitialized memory.
  192. // - It supports transferring, rather than copying, ArrayBuffers when using
  193. // MessagePorts.
  194. class NODE_EXTERN ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
  195. public:
  196. // If `always_debug` is true, create an ArrayBuffer::Allocator instance
  197. // that performs additional integrity checks (e.g. make sure that only memory
  198. // that was allocated by the it is also freed by it).
  199. // This can also be set using the --debug-arraybuffer-allocations flag.
  200. static std::unique_ptr<ArrayBufferAllocator> Create(
  201. bool always_debug = false);
  202. private:
  203. virtual NodeArrayBufferAllocator* GetImpl() = 0;
  204. friend class IsolateData;
  205. };
  206. // Legacy equivalents for ArrayBufferAllocator::Create().
  207. NODE_EXTERN ArrayBufferAllocator* CreateArrayBufferAllocator();
  208. NODE_EXTERN void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator);
  209. class NODE_EXTERN MultiIsolatePlatform : public v8::Platform {
  210. public:
  211. ~MultiIsolatePlatform() override = default;
  212. // Returns true if work was dispatched or executed. New tasks that are
  213. // posted during flushing of the queue are postponed until the next
  214. // flushing.
  215. virtual bool FlushForegroundTasks(v8::Isolate* isolate) = 0;
  216. virtual void DrainTasks(v8::Isolate* isolate) = 0;
  217. // TODO(addaleax): Remove this, it is unnecessary.
  218. // This would currently be called before `UnregisterIsolate()` but will be
  219. // folded into it in the future.
  220. virtual void CancelPendingDelayedTasks(v8::Isolate* isolate);
  221. // This needs to be called between the calls to `Isolate::Allocate()` and
  222. // `Isolate::Initialize()`, so that initialization can already start
  223. // using the platform.
  224. // When using `NewIsolate()`, this is taken care of by that function.
  225. // This function may only be called once per `Isolate`.
  226. virtual void RegisterIsolate(v8::Isolate* isolate,
  227. struct uv_loop_s* loop) = 0;
  228. // This function may only be called once per `Isolate`, and discard any
  229. // pending delayed tasks scheduled for that isolate.
  230. virtual void UnregisterIsolate(v8::Isolate* isolate) = 0;
  231. // The platform should call the passed function once all state associated
  232. // with the given isolate has been cleaned up. This can, but does not have to,
  233. // happen asynchronously.
  234. virtual void AddIsolateFinishedCallback(v8::Isolate* isolate,
  235. void (*callback)(void*),
  236. void* data) = 0;
  237. };
  238. // Set a number of callbacks for the `isolate`, in particular the Node.js
  239. // uncaught exception listener.
  240. NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate);
  241. // Creates a new isolate with Node.js-specific settings.
  242. // This is a convenience method equivalent to using SetIsolateCreateParams(),
  243. // Isolate::Allocate(), MultiIsolatePlatform::RegisterIsolate(),
  244. // Isolate::Initialize(), and SetIsolateUpForNode().
  245. NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator,
  246. struct uv_loop_s* event_loop);
  247. NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator,
  248. struct uv_loop_s* event_loop,
  249. MultiIsolatePlatform* platform);
  250. // Creates a new context with Node.js-specific tweaks.
  251. NODE_EXTERN v8::Local<v8::Context> NewContext(
  252. v8::Isolate* isolate,
  253. v8::Local<v8::ObjectTemplate> object_template =
  254. v8::Local<v8::ObjectTemplate>());
  255. // Runs Node.js-specific tweaks on an already constructed context
  256. // Return value indicates success of operation
  257. NODE_EXTERN bool InitializeContext(v8::Local<v8::Context> context);
  258. // If `platform` is passed, it will be used to register new Worker instances.
  259. // It can be `nullptr`, in which case creating new Workers inside of
  260. // Environments that use this `IsolateData` will not work.
  261. NODE_EXTERN IsolateData* CreateIsolateData(
  262. v8::Isolate* isolate,
  263. struct uv_loop_s* loop,
  264. MultiIsolatePlatform* platform = nullptr,
  265. ArrayBufferAllocator* allocator = nullptr);
  266. NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data);
  267. // TODO(addaleax): Add an official variant using STL containers, and move
  268. // per-Environment options parsing here.
  269. // Returns nullptr when the Environment cannot be created e.g. there are
  270. // pending JavaScript exceptions.
  271. NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data,
  272. v8::Local<v8::Context> context,
  273. int argc,
  274. const char* const* argv,
  275. int exec_argc,
  276. const char* const* exec_argv);
  277. NODE_EXTERN void LoadEnvironment(Environment* env);
  278. NODE_EXTERN void FreeEnvironment(Environment* env);
  279. // This may return nullptr if context is not associated with a Node instance.
  280. NODE_EXTERN Environment* GetCurrentEnvironment(v8::Local<v8::Context> context);
  281. // This returns the MultiIsolatePlatform used in the main thread of Node.js.
  282. // If NODE_USE_V8_PLATFORM haven't been defined when Node.js was built,
  283. // it returns nullptr.
  284. NODE_EXTERN MultiIsolatePlatform* GetMainThreadMultiIsolatePlatform();
  285. NODE_EXTERN MultiIsolatePlatform* CreatePlatform(
  286. int thread_pool_size,
  287. node::tracing::TracingController* tracing_controller);
  288. MultiIsolatePlatform* InitializeV8Platform(int thread_pool_size);
  289. NODE_EXTERN void FreePlatform(MultiIsolatePlatform* platform);
  290. NODE_EXTERN void EmitBeforeExit(Environment* env);
  291. NODE_EXTERN int EmitExit(Environment* env);
  292. NODE_EXTERN void RunAtExit(Environment* env);
  293. // This may return nullptr if the current v8::Context is not associated
  294. // with a Node instance.
  295. NODE_EXTERN struct uv_loop_s* GetCurrentEventLoop(v8::Isolate* isolate);
  296. /* Converts a unixtime to V8 Date */
  297. NODE_DEPRECATED("Use v8::Date::New() directly",
  298. inline v8::Local<v8::Value> NODE_UNIXTIME_V8(double time) {
  299. return v8::Date::New(
  300. v8::Isolate::GetCurrent()->GetCurrentContext(),
  301. 1000 * time)
  302. .ToLocalChecked();
  303. })
  304. #define NODE_UNIXTIME_V8 node::NODE_UNIXTIME_V8
  305. NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
  306. inline double NODE_V8_UNIXTIME(v8::Local<v8::Date> date) {
  307. return date->ValueOf() / 1000;
  308. })
  309. #define NODE_V8_UNIXTIME node::NODE_V8_UNIXTIME
  310. #define NODE_DEFINE_CONSTANT(target, constant) \
  311. do { \
  312. v8::Isolate* isolate = target->GetIsolate(); \
  313. v8::Local<v8::Context> context = isolate->GetCurrentContext(); \
  314. v8::Local<v8::String> constant_name = \
  315. v8::String::NewFromUtf8(isolate, #constant, \
  316. v8::NewStringType::kInternalized).ToLocalChecked(); \
  317. v8::Local<v8::Number> constant_value = \
  318. v8::Number::New(isolate, static_cast<double>(constant)); \
  319. v8::PropertyAttribute constant_attributes = \
  320. static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); \
  321. (target)->DefineOwnProperty(context, \
  322. constant_name, \
  323. constant_value, \
  324. constant_attributes).Check(); \
  325. } \
  326. while (0)
  327. #define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \
  328. do { \
  329. v8::Isolate* isolate = target->GetIsolate(); \
  330. v8::Local<v8::Context> context = isolate->GetCurrentContext(); \
  331. v8::Local<v8::String> constant_name = \
  332. v8::String::NewFromUtf8(isolate, #constant, \
  333. v8::NewStringType::kInternalized) \
  334. .ToLocalChecked(); \
  335. v8::Local<v8::Number> constant_value = \
  336. v8::Number::New(isolate, static_cast<double>(constant)); \
  337. v8::PropertyAttribute constant_attributes = \
  338. static_cast<v8::PropertyAttribute>(v8::ReadOnly | \
  339. v8::DontDelete | \
  340. v8::DontEnum); \
  341. (target)->DefineOwnProperty(context, \
  342. constant_name, \
  343. constant_value, \
  344. constant_attributes).Check(); \
  345. } \
  346. while (0)
  347. // Used to be a macro, hence the uppercase name.
  348. inline void NODE_SET_METHOD(v8::Local<v8::Template> recv,
  349. const char* name,
  350. v8::FunctionCallback callback) {
  351. v8::Isolate* isolate = v8::Isolate::GetCurrent();
  352. v8::HandleScope handle_scope(isolate);
  353. v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
  354. callback);
  355. v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name,
  356. v8::NewStringType::kInternalized).ToLocalChecked();
  357. t->SetClassName(fn_name);
  358. recv->Set(fn_name, t);
  359. }
  360. // Used to be a macro, hence the uppercase name.
  361. inline void NODE_SET_METHOD(v8::Local<v8::Object> recv,
  362. const char* name,
  363. v8::FunctionCallback callback) {
  364. v8::Isolate* isolate = v8::Isolate::GetCurrent();
  365. v8::HandleScope handle_scope(isolate);
  366. v8::Local<v8::Context> context = isolate->GetCurrentContext();
  367. v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
  368. callback);
  369. v8::Local<v8::Function> fn = t->GetFunction(context).ToLocalChecked();
  370. v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name,
  371. v8::NewStringType::kInternalized).ToLocalChecked();
  372. fn->SetName(fn_name);
  373. recv->Set(context, fn_name, fn).Check();
  374. }
  375. #define NODE_SET_METHOD node::NODE_SET_METHOD
  376. // Used to be a macro, hence the uppercase name.
  377. // Not a template because it only makes sense for FunctionTemplates.
  378. inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv,
  379. const char* name,
  380. v8::FunctionCallback callback) {
  381. v8::Isolate* isolate = v8::Isolate::GetCurrent();
  382. v8::HandleScope handle_scope(isolate);
  383. v8::Local<v8::Signature> s = v8::Signature::New(isolate, recv);
  384. v8::Local<v8::FunctionTemplate> t =
  385. v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), s);
  386. v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name,
  387. v8::NewStringType::kInternalized).ToLocalChecked();
  388. t->SetClassName(fn_name);
  389. recv->PrototypeTemplate()->Set(fn_name, t);
  390. }
  391. #define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD
  392. // BINARY is a deprecated alias of LATIN1.
  393. enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER, LATIN1 = BINARY};
  394. NODE_EXTERN enum encoding ParseEncoding(
  395. v8::Isolate* isolate,
  396. v8::Local<v8::Value> encoding_v,
  397. enum encoding default_encoding = LATIN1);
  398. NODE_EXTERN void FatalException(v8::Isolate* isolate,
  399. const v8::TryCatch& try_catch);
  400. NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
  401. const char* buf,
  402. size_t len,
  403. enum encoding encoding = LATIN1);
  404. // Warning: This reverses endianness on Big Endian platforms, even though the
  405. // signature using uint16_t implies that it should not.
  406. NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
  407. const uint16_t* buf,
  408. size_t len);
  409. // Returns -1 if the handle was not valid for decoding
  410. NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
  411. v8::Local<v8::Value>,
  412. enum encoding encoding = LATIN1);
  413. // returns bytes written.
  414. NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate,
  415. char* buf,
  416. size_t buflen,
  417. v8::Local<v8::Value>,
  418. enum encoding encoding = LATIN1);
  419. #ifdef _WIN32
  420. NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
  421. v8::Isolate* isolate,
  422. int errorno,
  423. const char* syscall = nullptr,
  424. const char* msg = "",
  425. const char* path = nullptr);
  426. #endif
  427. const char* signo_string(int errorno);
  428. typedef void (*addon_register_func)(
  429. v8::Local<v8::Object> exports,
  430. v8::Local<v8::Value> module,
  431. void* priv);
  432. typedef void (*addon_context_register_func)(
  433. v8::Local<v8::Object> exports,
  434. v8::Local<v8::Value> module,
  435. v8::Local<v8::Context> context,
  436. void* priv);
  437. enum ModuleFlags {
  438. kLinked = 0x02
  439. };
  440. struct node_module {
  441. int nm_version;
  442. unsigned int nm_flags;
  443. void* nm_dso_handle;
  444. const char* nm_filename;
  445. node::addon_register_func nm_register_func;
  446. node::addon_context_register_func nm_context_register_func;
  447. const char* nm_modname;
  448. void* nm_priv;
  449. struct node_module* nm_link;
  450. };
  451. extern "C" NODE_EXTERN void node_module_register(void* mod);
  452. #ifdef _WIN32
  453. # define NODE_MODULE_EXPORT __declspec(dllexport)
  454. #else
  455. # define NODE_MODULE_EXPORT __attribute__((visibility("default")))
  456. #endif
  457. #ifdef NODE_SHARED_MODE
  458. # define NODE_CTOR_PREFIX
  459. #else
  460. # define NODE_CTOR_PREFIX static
  461. #endif
  462. #if defined(_MSC_VER)
  463. #pragma section(".CRT$XCU", read)
  464. #define NODE_C_CTOR(fn) \
  465. NODE_CTOR_PREFIX void __cdecl fn(void); \
  466. __declspec(dllexport, allocate(".CRT$XCU")) \
  467. void (__cdecl*fn ## _)(void) = fn; \
  468. NODE_CTOR_PREFIX void __cdecl fn(void)
  469. #else
  470. #define NODE_C_CTOR(fn) \
  471. NODE_CTOR_PREFIX void fn(void) __attribute__((constructor)); \
  472. NODE_CTOR_PREFIX void fn(void)
  473. #endif
  474. #define NODE_MODULE_X(modname, regfunc, priv, flags) \
  475. extern "C" { \
  476. static node::node_module _module = \
  477. { \
  478. NODE_MODULE_VERSION, \
  479. flags, \
  480. NULL, /* NOLINT (readability/null_usage) */ \
  481. __FILE__, \
  482. (node::addon_register_func) (regfunc), \
  483. NULL, /* NOLINT (readability/null_usage) */ \
  484. NODE_STRINGIFY(modname), \
  485. priv, \
  486. NULL /* NOLINT (readability/null_usage) */ \
  487. }; \
  488. NODE_C_CTOR(_register_ ## modname) { \
  489. node_module_register(&_module); \
  490. } \
  491. }
  492. #define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags) \
  493. extern "C" { \
  494. static node::node_module _module = \
  495. { \
  496. NODE_MODULE_VERSION, \
  497. flags, \
  498. NULL, /* NOLINT (readability/null_usage) */ \
  499. __FILE__, \
  500. NULL, /* NOLINT (readability/null_usage) */ \
  501. (node::addon_context_register_func) (regfunc), \
  502. NODE_STRINGIFY(modname), \
  503. priv, \
  504. NULL /* NOLINT (readability/null_usage) */ \
  505. }; \
  506. NODE_C_CTOR(_register_ ## modname) { \
  507. node_module_register(&_module); \
  508. } \
  509. }
  510. // Usage: `NODE_MODULE(NODE_GYP_MODULE_NAME, InitializerFunction)`
  511. // If no NODE_MODULE is declared, Node.js looks for the well-known
  512. // symbol `node_register_module_v${NODE_MODULE_VERSION}`.
  513. #define NODE_MODULE(modname, regfunc) \
  514. NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage)
  515. #define NODE_MODULE_CONTEXT_AWARE(modname, regfunc) \
  516. /* NOLINTNEXTLINE (readability/null_usage) */ \
  517. NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)
  518. // Embedders can use this type of binding for statically linked native bindings.
  519. // It is used the same way addon bindings are used, except that linked bindings
  520. // can be accessed through `process._linkedBinding(modname)`.
  521. #define NODE_MODULE_LINKED(modname, regfunc) \
  522. /* NOLINTNEXTLINE (readability/null_usage) */ \
  523. NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, \
  524. node::ModuleFlags::kLinked)
  525. /*
  526. * For backward compatibility in add-on modules.
  527. */
  528. #define NODE_MODULE_DECL /* nothing */
  529. #define NODE_MODULE_INITIALIZER_BASE node_register_module_v
  530. #define NODE_MODULE_INITIALIZER_X(base, version) \
  531. NODE_MODULE_INITIALIZER_X_HELPER(base, version)
  532. #define NODE_MODULE_INITIALIZER_X_HELPER(base, version) base##version
  533. #define NODE_MODULE_INITIALIZER \
  534. NODE_MODULE_INITIALIZER_X(NODE_MODULE_INITIALIZER_BASE, \
  535. NODE_MODULE_VERSION)
  536. #define NODE_MODULE_INIT() \
  537. extern "C" NODE_MODULE_EXPORT void \
  538. NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports, \
  539. v8::Local<v8::Value> module, \
  540. v8::Local<v8::Context> context); \
  541. NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, \
  542. NODE_MODULE_INITIALIZER) \
  543. void NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports, \
  544. v8::Local<v8::Value> module, \
  545. v8::Local<v8::Context> context)
  546. /* Called after the event loop exits but before the VM is disposed.
  547. * Callbacks are run in reverse order of registration, i.e. newest first.
  548. */
  549. NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = nullptr);
  550. /* Registers a callback with the passed-in Environment instance. The callback
  551. * is called after the event loop exits, but before the VM is disposed.
  552. * Callbacks are run in reverse order of registration, i.e. newest first.
  553. */
  554. NODE_EXTERN void AtExit(Environment* env,
  555. void (*cb)(void* arg),
  556. void* arg = nullptr);
  557. typedef double async_id;
  558. struct async_context {
  559. ::node::async_id async_id;
  560. ::node::async_id trigger_async_id;
  561. };
  562. /* This is a lot like node::AtExit, except that the hooks added via this
  563. * function are run before the AtExit ones and will always be registered
  564. * for the current Environment instance.
  565. * These functions are safe to use in an addon supporting multiple
  566. * threads/isolates. */
  567. NODE_EXTERN void AddEnvironmentCleanupHook(v8::Isolate* isolate,
  568. void (*fun)(void* arg),
  569. void* arg);
  570. NODE_EXTERN void RemoveEnvironmentCleanupHook(v8::Isolate* isolate,
  571. void (*fun)(void* arg),
  572. void* arg);
  573. /* Returns the id of the current execution context. If the return value is
  574. * zero then no execution has been set. This will happen if the user handles
  575. * I/O from native code. */
  576. NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate);
  577. /* Return same value as async_hooks.triggerAsyncId(); */
  578. NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);
  579. /* If the native API doesn't inherit from the helper class then the callbacks
  580. * must be triggered manually. This triggers the init() callback. The return
  581. * value is the async id assigned to the resource.
  582. *
  583. * The `trigger_async_id` parameter should correspond to the resource which is
  584. * creating the new resource, which will usually be the return value of
  585. * `AsyncHooksGetTriggerAsyncId()`. */
  586. NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
  587. v8::Local<v8::Object> resource,
  588. const char* name,
  589. async_id trigger_async_id = -1);
  590. NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
  591. v8::Local<v8::Object> resource,
  592. v8::Local<v8::String> name,
  593. async_id trigger_async_id = -1);
  594. /* Emit the destroy() callback. The overload taking an `Environment*` argument
  595. * should be used when the Isolate’s current Context is not associated with
  596. * a Node.js Environment, or when there is no current Context, for example
  597. * when calling this function during garbage collection. In that case, the
  598. * `Environment*` value should have been acquired previously, e.g. through
  599. * `GetCurrentEnvironment()`. */
  600. NODE_EXTERN void EmitAsyncDestroy(v8::Isolate* isolate,
  601. async_context asyncContext);
  602. NODE_EXTERN void EmitAsyncDestroy(Environment* env,
  603. async_context asyncContext);
  604. class InternalCallbackScope;
  605. /* This class works like `MakeCallback()` in that it sets up a specific
  606. * asyncContext as the current one and informs the async_hooks and domains
  607. * modules that this context is currently active.
  608. *
  609. * `MakeCallback()` is a wrapper around this class as well as
  610. * `Function::Call()`. Either one of these mechanisms needs to be used for
  611. * top-level calls into JavaScript (i.e. without any existing JS stack).
  612. *
  613. * This object should be stack-allocated to ensure that it is contained in a
  614. * valid HandleScope.
  615. *
  616. * Exceptions happening within this scope will be treated like uncaught
  617. * exceptions. If this behaviour is undesirable, a new `v8::TryCatch` scope
  618. * needs to be created inside of this scope.
  619. */
  620. class NODE_EXTERN CallbackScope {
  621. public:
  622. CallbackScope(v8::Isolate* isolate,
  623. v8::Local<v8::Object> resource,
  624. async_context asyncContext);
  625. ~CallbackScope();
  626. void operator=(const CallbackScope&) = delete;
  627. void operator=(CallbackScope&&) = delete;
  628. CallbackScope(const CallbackScope&) = delete;
  629. CallbackScope(CallbackScope&&) = delete;
  630. private:
  631. InternalCallbackScope* private_;
  632. v8::TryCatch try_catch_;
  633. };
  634. /* An API specific to emit before/after callbacks is unnecessary because
  635. * MakeCallback will automatically call them for you.
  636. *
  637. * These methods may create handles on their own, so run them inside a
  638. * HandleScope.
  639. *
  640. * `asyncId` and `triggerAsyncId` should correspond to the values returned by
  641. * `EmitAsyncInit()` and `AsyncHooksGetTriggerAsyncId()`, respectively, when the
  642. * invoking resource was created. If these values are unknown, 0 can be passed.
  643. * */
  644. NODE_EXTERN
  645. v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
  646. v8::Local<v8::Object> recv,
  647. v8::Local<v8::Function> callback,
  648. int argc,
  649. v8::Local<v8::Value>* argv,
  650. async_context asyncContext);
  651. NODE_EXTERN
  652. v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
  653. v8::Local<v8::Object> recv,
  654. const char* method,
  655. int argc,
  656. v8::Local<v8::Value>* argv,
  657. async_context asyncContext);
  658. NODE_EXTERN
  659. v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
  660. v8::Local<v8::Object> recv,
  661. v8::Local<v8::String> symbol,
  662. int argc,
  663. v8::Local<v8::Value>* argv,
  664. async_context asyncContext);
  665. /* Helper class users can optionally inherit from. If
  666. * `AsyncResource::MakeCallback()` is used, then all four callbacks will be
  667. * called automatically. */
  668. class NODE_EXTERN AsyncResource {
  669. public:
  670. AsyncResource(v8::Isolate* isolate,
  671. v8::Local<v8::Object> resource,
  672. const char* name,
  673. async_id trigger_async_id = -1);
  674. virtual ~AsyncResource();
  675. AsyncResource(const AsyncResource&) = delete;
  676. void operator=(const AsyncResource&) = delete;
  677. v8::MaybeLocal<v8::Value> MakeCallback(
  678. v8::Local<v8::Function> callback,
  679. int argc,
  680. v8::Local<v8::Value>* argv);
  681. v8::MaybeLocal<v8::Value> MakeCallback(
  682. const char* method,
  683. int argc,
  684. v8::Local<v8::Value>* argv);
  685. v8::MaybeLocal<v8::Value> MakeCallback(
  686. v8::Local<v8::String> symbol,
  687. int argc,
  688. v8::Local<v8::Value>* argv);
  689. v8::Local<v8::Object> get_resource();
  690. async_id get_async_id() const;
  691. async_id get_trigger_async_id() const;
  692. protected:
  693. class NODE_EXTERN CallbackScope : public node::CallbackScope {
  694. public:
  695. explicit CallbackScope(AsyncResource* res);
  696. };
  697. private:
  698. Environment* env_;
  699. v8::Persistent<v8::Object> resource_;
  700. async_context async_context_;
  701. };
  702. } // namespace node
  703. #endif // SRC_NODE_H_