GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/node.h Lines: 12 14 85.7 %
Date: 2017-12-18 Branches: 1 2 50.0 %

Line Branch Exec Source
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
22
#ifndef SRC_NODE_H_
23
#define SRC_NODE_H_
24
25
#ifdef _WIN32
26
# ifndef BUILDING_NODE_EXTENSION
27
#   define NODE_EXTERN __declspec(dllexport)
28
# else
29
#   define NODE_EXTERN __declspec(dllimport)
30
# endif
31
#else
32
# define NODE_EXTERN /* nothing */
33
#endif
34
35
#ifdef BUILDING_NODE_EXTENSION
36
# undef BUILDING_V8_SHARED
37
# undef BUILDING_UV_SHARED
38
# define USING_V8_SHARED 1
39
# define USING_UV_SHARED 1
40
#endif
41
42
// This should be defined in make system.
43
// See issue https://github.com/nodejs/node-v0.x-archive/issues/1236
44
#if defined(__MINGW32__) || defined(_MSC_VER)
45
#ifndef _WIN32_WINNT
46
# define _WIN32_WINNT   0x0600  // Windows Server 2008
47
#endif
48
49
#ifndef NOMINMAX
50
# define NOMINMAX
51
#endif
52
53
#endif
54
55
#if defined(_MSC_VER)
56
#define PATH_MAX MAX_PATH
57
#endif
58
59
#ifdef _WIN32
60
# define SIGKILL         9
61
#endif
62
63
#include "v8.h"  // NOLINT(build/include_order)
64
#include "v8-platform.h"  // NOLINT(build/include_order)
65
#include "node_version.h"  // NODE_MODULE_VERSION
66
67
#define NODE_MAKE_VERSION(major, minor, patch)                                \
68
  ((major) * 0x1000 + (minor) * 0x100 + (patch))
69
70
#ifdef __clang__
71
# define NODE_CLANG_AT_LEAST(major, minor, patch)                             \
72
  (NODE_MAKE_VERSION(major, minor, patch) <=                                  \
73
      NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__))
74
#else
75
# define NODE_CLANG_AT_LEAST(major, minor, patch) (0)
76
#endif
77
78
#ifdef __GNUC__
79
# define NODE_GNUC_AT_LEAST(major, minor, patch)                              \
80
  (NODE_MAKE_VERSION(major, minor, patch) <=                                  \
81
      NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__))
82
#else
83
# define NODE_GNUC_AT_LEAST(major, minor, patch) (0)
84
#endif
85
86
#if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0)
87
# define NODE_DEPRECATED(message, declarator)                                 \
88
    __attribute__((deprecated(message))) declarator
89
#elif defined(_MSC_VER)
90
# define NODE_DEPRECATED(message, declarator)                                 \
91
    __declspec(deprecated) declarator
92
#else
93
# define NODE_DEPRECATED(message, declarator)                                 \
94
    declarator
95
#endif
96
97
// Forward-declare libuv loop
98
struct uv_loop_s;
99
100
// Forward-declare TracingController, used by CreatePlatform.
101
namespace v8 {
102
class TracingController;
103
}
104
105
// Forward-declare these functions now to stop MSVS from becoming
106
// terminally confused when it's done in node_internals.h
107
namespace node {
108
109
NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
110
                                                int errorno,
111
                                                const char* syscall = nullptr,
112
                                                const char* message = nullptr,
113
                                                const char* path = nullptr);
114
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
115
                                             int errorno,
116
                                             const char* syscall = nullptr,
117
                                             const char* message = nullptr,
118
                                             const char* path = nullptr);
119
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
120
                                             int errorno,
121
                                             const char* syscall,
122
                                             const char* message,
123
                                             const char* path,
124
                                             const char* dest);
125
126
NODE_DEPRECATED("Use ErrnoException(isolate, ...)",
127
                inline v8::Local<v8::Value> ErrnoException(
128
      int errorno,
129
      const char* syscall = nullptr,
130
      const char* message = nullptr,
131
      const char* path = nullptr) {
132
  return ErrnoException(v8::Isolate::GetCurrent(),
133
                        errorno,
134
                        syscall,
135
                        message,
136
                        path);
137
})
138
139
inline v8::Local<v8::Value> UVException(int errorno,
140
                                        const char* syscall = nullptr,
141
                                        const char* message = nullptr,
142
                                        const char* path = nullptr) {
143
  return UVException(v8::Isolate::GetCurrent(),
144
                     errorno,
145
                     syscall,
146
                     message,
147
                     path);
148
}
149
150
/*
151
 * These methods need to be called in a HandleScope.
152
 *
153
 * It is preferred that you use the `MakeCallback` overloads taking
154
 * `async_id` arguments.
155
 */
156
157
NODE_EXTERN v8::Local<v8::Value> MakeCallback(
158
    v8::Isolate* isolate,
159
    v8::Local<v8::Object> recv,
160
    const char* method,
161
    int argc,
162
    v8::Local<v8::Value>* argv);
163
NODE_EXTERN v8::Local<v8::Value> MakeCallback(
164
    v8::Isolate* isolate,
165
    v8::Local<v8::Object> recv,
166
    v8::Local<v8::String> symbol,
167
    int argc,
168
    v8::Local<v8::Value>* argv);
169
NODE_EXTERN v8::Local<v8::Value> MakeCallback(
170
    v8::Isolate* isolate,
171
    v8::Local<v8::Object> recv,
172
    v8::Local<v8::Function> callback,
173
    int argc,
174
    v8::Local<v8::Value>* argv);
175
176
}  // namespace node
177
178
#include <assert.h>
179
#include <stdint.h>
180
181
#ifndef NODE_STRINGIFY
182
#define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
183
#define NODE_STRINGIFY_HELPER(n) #n
184
#endif
185
186
#ifdef _WIN32
187
// TODO(tjfontaine) consider changing the usage of ssize_t to ptrdiff_t
188
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
189
typedef intptr_t ssize_t;
190
# define _SSIZE_T_
191
# define _SSIZE_T_DEFINED
192
#endif
193
#else  // !_WIN32
194
# include <sys/types.h>  // size_t, ssize_t
195
#endif  // _WIN32
196
197
198
namespace node {
199
200
NODE_EXTERN extern bool no_deprecation;
201
#if HAVE_OPENSSL
202
NODE_EXTERN extern bool ssl_openssl_cert_store;
203
# if NODE_FIPS_MODE
204
NODE_EXTERN extern bool enable_fips_crypto;
205
NODE_EXTERN extern bool force_fips_crypto;
206
# endif
207
#endif
208
209
NODE_EXTERN int Start(int argc, char *argv[]);
210
NODE_EXTERN void Init(int* argc,
211
                      const char** argv,
212
                      int* exec_argc,
213
                      const char*** exec_argv);
214
215
class IsolateData;
216
class Environment;
217
218
3363
class MultiIsolatePlatform : public v8::Platform {
219
 public:
220
3018
  virtual ~MultiIsolatePlatform() { }
221
  virtual void DrainBackgroundTasks(v8::Isolate* isolate) = 0;
222
  virtual void CancelPendingDelayedTasks(v8::Isolate* isolate) = 0;
223
224
  // These will be called by the `IsolateData` creation/destruction functions.
225
  virtual void RegisterIsolate(IsolateData* isolate_data,
226
                               struct uv_loop_s* loop) = 0;
227
  virtual void UnregisterIsolate(IsolateData* isolate_data) = 0;
228
};
229
230
// If `platform` is passed, it will be used to register new Worker instances.
231
// It can be `nullptr`, in which case creating new Workers inside of
232
// Environments that use this `IsolateData` will not work.
233
NODE_EXTERN IsolateData* CreateIsolateData(
234
    v8::Isolate* isolate,
235
    struct uv_loop_s* loop);
236
NODE_EXTERN IsolateData* CreateIsolateData(
237
    v8::Isolate* isolate,
238
    struct uv_loop_s* loop,
239
    MultiIsolatePlatform* platform);
240
NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data);
241
242
NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data,
243
                                           v8::Local<v8::Context> context,
244
                                           int argc,
245
                                           const char* const* argv,
246
                                           int exec_argc,
247
                                           const char* const* exec_argv);
248
249
NODE_EXTERN void LoadEnvironment(Environment* env);
250
NODE_EXTERN void FreeEnvironment(Environment* env);
251
252
NODE_EXTERN MultiIsolatePlatform* CreatePlatform(
253
    int thread_pool_size,
254
    v8::TracingController* tracing_controller);
255
NODE_EXTERN void FreePlatform(MultiIsolatePlatform* platform);
256
257
NODE_EXTERN void EmitBeforeExit(Environment* env);
258
NODE_EXTERN int EmitExit(Environment* env);
259
NODE_EXTERN void RunAtExit(Environment* env);
260
261
// This may return nullptr if the current v8::Context is not associated
262
// with a Node instance.
263
NODE_EXTERN struct uv_loop_s* GetCurrentEventLoop(v8::Isolate* isolate);
264
265
/* Converts a unixtime to V8 Date */
266
#define NODE_UNIXTIME_V8(t) v8::Date::New(v8::Isolate::GetCurrent(),          \
267
    1000 * static_cast<double>(t))
268
#define NODE_V8_UNIXTIME(v) (static_cast<double>((v)->NumberValue())/1000.0);
269
270
#define NODE_DEFINE_CONSTANT(target, constant)                                \
271
  do {                                                                        \
272
    v8::Isolate* isolate = target->GetIsolate();                              \
273
    v8::Local<v8::Context> context = isolate->GetCurrentContext();            \
274
    v8::Local<v8::String> constant_name =                                     \
275
        v8::String::NewFromUtf8(isolate, #constant);                          \
276
    v8::Local<v8::Number> constant_value =                                    \
277
        v8::Number::New(isolate, static_cast<double>(constant));              \
278
    v8::PropertyAttribute constant_attributes =                               \
279
        static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);    \
280
    (target)->DefineOwnProperty(context,                                      \
281
                                constant_name,                                \
282
                                constant_value,                               \
283
                                constant_attributes).FromJust();              \
284
  }                                                                           \
285
  while (0)
286
287
#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant)                         \
288
  do {                                                                        \
289
    v8::Isolate* isolate = target->GetIsolate();                              \
290
    v8::Local<v8::Context> context = isolate->GetCurrentContext();            \
291
    v8::Local<v8::String> constant_name =                                     \
292
        v8::String::NewFromUtf8(isolate, #constant,                           \
293
                                v8::NewStringType::kInternalized)             \
294
                                  .ToLocalChecked();                          \
295
    v8::Local<v8::Number> constant_value =                                    \
296
        v8::Number::New(isolate, static_cast<double>(constant));              \
297
    v8::PropertyAttribute constant_attributes =                               \
298
        static_cast<v8::PropertyAttribute>(v8::ReadOnly |                     \
299
                                           v8::DontDelete |                   \
300
                                           v8::DontEnum);                     \
301
    (target)->DefineOwnProperty(context,                                      \
302
                                constant_name,                                \
303
                                constant_value,                               \
304
                                constant_attributes).FromJust();              \
305
  }                                                                           \
306
  while (0)
307
308
// Used to be a macro, hence the uppercase name.
309
inline void NODE_SET_METHOD(v8::Local<v8::Template> recv,
310
                            const char* name,
311
                            v8::FunctionCallback callback) {
312
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
313
  v8::HandleScope handle_scope(isolate);
314
  v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
315
                                                                callback);
316
  v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name);
317
  t->SetClassName(fn_name);
318
  recv->Set(fn_name, t);
319
}
320
321
// Used to be a macro, hence the uppercase name.
322
inline void NODE_SET_METHOD(v8::Local<v8::Object> recv,
323
                            const char* name,
324
                            v8::FunctionCallback callback) {
325
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
326
  v8::HandleScope handle_scope(isolate);
327
  v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
328
                                                                callback);
329
  v8::Local<v8::Function> fn = t->GetFunction();
330
  v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name);
331
  fn->SetName(fn_name);
332
  recv->Set(fn_name, fn);
333
}
334
#define NODE_SET_METHOD node::NODE_SET_METHOD
335
336
// Used to be a macro, hence the uppercase name.
337
// Not a template because it only makes sense for FunctionTemplates.
338
inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv,
339
                                      const char* name,
340
                                      v8::FunctionCallback callback) {
341
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
342
  v8::HandleScope handle_scope(isolate);
343
  v8::Local<v8::Signature> s = v8::Signature::New(isolate, recv);
344
  v8::Local<v8::FunctionTemplate> t =
345
      v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), s);
346
  v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name);
347
  t->SetClassName(fn_name);
348
  recv->PrototypeTemplate()->Set(fn_name, t);
349
}
350
#define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD
351
352
// BINARY is a deprecated alias of LATIN1.
353
enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER, LATIN1 = BINARY};
354
355
NODE_EXTERN enum encoding ParseEncoding(
356
    v8::Isolate* isolate,
357
    v8::Local<v8::Value> encoding_v,
358
    enum encoding default_encoding = LATIN1);
359
NODE_DEPRECATED("Use ParseEncoding(isolate, ...)",
360
                inline enum encoding ParseEncoding(
361
      v8::Local<v8::Value> encoding_v,
362
      enum encoding default_encoding = LATIN1) {
363
  return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, default_encoding);
364
})
365
366
NODE_EXTERN void FatalException(v8::Isolate* isolate,
367
                                const v8::TryCatch& try_catch);
368
369
NODE_DEPRECATED("Use FatalException(isolate, ...)",
370
                inline void FatalException(const v8::TryCatch& try_catch) {
371
  return FatalException(v8::Isolate::GetCurrent(), try_catch);
372
})
373
374
// Don't call with encoding=UCS2.
375
NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
376
                                        const char* buf,
377
                                        size_t len,
378
                                        enum encoding encoding = LATIN1);
379
380
// The input buffer should be in host endianness.
381
NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
382
                                        const uint16_t* buf,
383
                                        size_t len);
384
385
NODE_DEPRECATED("Use Encode(isolate, ...)",
386
                inline v8::Local<v8::Value> Encode(
387
    const void* buf,
388
    size_t len,
389
    enum encoding encoding = LATIN1) {
390
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
391
  if (encoding == UCS2) {
392
    assert(reinterpret_cast<uintptr_t>(buf) % sizeof(uint16_t) == 0 &&
393
           "UCS2 buffer must be aligned on two-byte boundary.");
394
    const uint16_t* that = static_cast<const uint16_t*>(buf);
395
    return Encode(isolate, that, len / sizeof(*that));
396
  }
397
  return Encode(isolate, static_cast<const char*>(buf), len, encoding);
398
})
399
400
// Returns -1 if the handle was not valid for decoding
401
NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
402
                                v8::Local<v8::Value>,
403
                                enum encoding encoding = LATIN1);
404
NODE_DEPRECATED("Use DecodeBytes(isolate, ...)",
405
                inline ssize_t DecodeBytes(
406
    v8::Local<v8::Value> val,
407
    enum encoding encoding = LATIN1) {
408
  return DecodeBytes(v8::Isolate::GetCurrent(), val, encoding);
409
})
410
411
// returns bytes written.
412
NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate,
413
                                char* buf,
414
                                size_t buflen,
415
                                v8::Local<v8::Value>,
416
                                enum encoding encoding = LATIN1);
417
NODE_DEPRECATED("Use DecodeWrite(isolate, ...)",
418
                inline ssize_t DecodeWrite(char* buf,
419
                                           size_t buflen,
420
                                           v8::Local<v8::Value> val,
421
                                           enum encoding encoding = LATIN1) {
422
  return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding);
423
})
424
425
#ifdef _WIN32
426
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
427
    v8::Isolate* isolate,
428
    int errorno,
429
    const char *syscall = nullptr,
430
    const char *msg = "",
431
    const char *path = nullptr);
432
433
NODE_DEPRECATED("Use WinapiErrnoException(isolate, ...)",
434
                inline v8::Local<v8::Value> WinapiErrnoException(int errorno,
435
    const char *syscall = nullptr,  const char *msg = "",
436
    const char *path = nullptr) {
437
  return WinapiErrnoException(v8::Isolate::GetCurrent(),
438
                              errorno,
439
                              syscall,
440
                              msg,
441
                              path);
442
})
443
#endif
444
445
const char *signo_string(int errorno);
446
447
448
typedef void (*addon_register_func)(
449
    v8::Local<v8::Object> exports,
450
    v8::Local<v8::Value> module,
451
    void* priv);
452
453
typedef void (*addon_context_register_func)(
454
    v8::Local<v8::Object> exports,
455
    v8::Local<v8::Value> module,
456
    v8::Local<v8::Context> context,
457
    void* priv);
458
459
struct node_module {
460
  int nm_version;
461
  unsigned int nm_flags;
462
  void* nm_dso_handle;
463
  const char* nm_filename;
464
  node::addon_register_func nm_register_func;
465
  node::addon_context_register_func nm_context_register_func;
466
  const char* nm_modname;
467
  void* nm_priv;
468
  struct node_module* nm_link;
469
};
470
471
extern "C" NODE_EXTERN void node_module_register(void* mod);
472
473
#ifdef _WIN32
474
# define NODE_MODULE_EXPORT __declspec(dllexport)
475
#else
476
# define NODE_MODULE_EXPORT __attribute__((visibility("default")))
477
#endif
478
479
#ifdef NODE_SHARED_MODE
480
# define NODE_CTOR_PREFIX
481
#else
482
# define NODE_CTOR_PREFIX static
483
#endif
484
485
#if defined(_MSC_VER)
486
#pragma section(".CRT$XCU", read)
487
#define NODE_C_CTOR(fn)                                               \
488
  NODE_CTOR_PREFIX void __cdecl fn(void);                             \
489
  __declspec(dllexport, allocate(".CRT$XCU"))                         \
490
      void (__cdecl*fn ## _)(void) = fn;                              \
491
  NODE_CTOR_PREFIX void __cdecl fn(void)
492
#else
493
#define NODE_C_CTOR(fn)                                               \
494
  NODE_CTOR_PREFIX void fn(void) __attribute__((constructor));        \
495
  NODE_CTOR_PREFIX void fn(void)
496
#endif
497
498
#define NODE_MODULE_X(modname, regfunc, priv, flags)                  \
499
  extern "C" {                                                        \
500
    static node::node_module _module =                                \
501
    {                                                                 \
502
      NODE_MODULE_VERSION,                                            \
503
      flags,                                                          \
504
      NULL,  /* NOLINT (readability/null_usage) */                    \
505
      __FILE__,                                                       \
506
      (node::addon_register_func) (regfunc),                          \
507
      NULL,  /* NOLINT (readability/null_usage) */                    \
508
      NODE_STRINGIFY(modname),                                        \
509
      priv,                                                           \
510
      NULL   /* NOLINT (readability/null_usage) */                    \
511
    };                                                                \
512
    NODE_C_CTOR(_register_ ## modname) {                              \
513
      node_module_register(&_module);                                 \
514
    }                                                                 \
515
  }
516
517
#define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags)    \
518
  extern "C" {                                                        \
519
    static node::node_module _module =                                \
520
    {                                                                 \
521
      NODE_MODULE_VERSION,                                            \
522
      flags,                                                          \
523
      NULL,  /* NOLINT (readability/null_usage) */                    \
524
      __FILE__,                                                       \
525
      NULL,  /* NOLINT (readability/null_usage) */                    \
526
      (node::addon_context_register_func) (regfunc),                  \
527
      NODE_STRINGIFY(modname),                                        \
528
      priv,                                                           \
529
      NULL  /* NOLINT (readability/null_usage) */                     \
530
    };                                                                \
531
    NODE_C_CTOR(_register_ ## modname) {                              \
532
      node_module_register(&_module);                                 \
533
    }                                                                 \
534
  }
535
536
#define NODE_MODULE(modname, regfunc)                                 \
537
  NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
538
539
#define NODE_MODULE_CONTEXT_AWARE(modname, regfunc)                   \
540
  /* NOLINTNEXTLINE (readability/null_usage) */                       \
541
  NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)
542
543
/*
544
 * For backward compatibility in add-on modules.
545
 */
546
#define NODE_MODULE_DECL /* nothing */
547
548
/* Called after the event loop exits but before the VM is disposed.
549
 * Callbacks are run in reverse order of registration, i.e. newest first.
550
 */
551
NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = 0);
552
553
/* Registers a callback with the passed-in Environment instance. The callback
554
 * is called after the event loop exits, but before the VM is disposed.
555
 * Callbacks are run in reverse order of registration, i.e. newest first.
556
 */
557
NODE_EXTERN void AtExit(Environment* env, void (*cb)(void* arg), void* arg = 0);
558
559
typedef void (*promise_hook_func) (v8::PromiseHookType type,
560
                                   v8::Local<v8::Promise> promise,
561
                                   v8::Local<v8::Value> parent,
562
                                   void* arg);
563
564
typedef double async_id;
565
struct async_context {
566
  ::node::async_id async_id;
567
  ::node::async_id trigger_async_id;
568
};
569
570
/* Registers an additional v8::PromiseHook wrapper. This API exists because V8
571
 * itself supports only a single PromiseHook. */
572
NODE_EXTERN void AddPromiseHook(v8::Isolate* isolate,
573
                                promise_hook_func fn,
574
                                void* arg);
575
576
/* Returns the id of the current execution context. If the return value is
577
 * zero then no execution has been set. This will happen if the user handles
578
 * I/O from native code. */
579
NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate);
580
581
/* Return same value as async_hooks.triggerAsyncId(); */
582
NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);
583
584
/* If the native API doesn't inherit from the helper class then the callbacks
585
 * must be triggered manually. This triggers the init() callback. The return
586
 * value is the async id assigned to the resource.
587
 *
588
 * The `trigger_async_id` parameter should correspond to the resource which is
589
 * creating the new resource, which will usually be the return value of
590
 * `AsyncHooksGetTriggerAsyncId()`. */
591
NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
592
                                        v8::Local<v8::Object> resource,
593
                                        const char* name,
594
                                        async_id trigger_async_id = -1);
595
596
NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
597
                                        v8::Local<v8::Object> resource,
598
                                        v8::Local<v8::String> name,
599
                                        async_id trigger_async_id = -1);
600
601
/* Emit the destroy() callback. */
602
NODE_EXTERN void EmitAsyncDestroy(v8::Isolate* isolate,
603
                                  async_context asyncContext);
604
605
class InternalCallbackScope;
606
607
/* This class works like `MakeCallback()` in that it sets up a specific
608
 * asyncContext as the current one and informs the async_hooks and domains
609
 * modules that this context is currently active.
610
 *
611
 * `MakeCallback()` is a wrapper around this class as well as
612
 * `Function::Call()`. Either one of these mechanisms needs to be used for
613
 * top-level calls into JavaScript (i.e. without any existing JS stack).
614
 *
615
 * This object should be stack-allocated to ensure that it is contained in a
616
 * valid HandleScope.
617
 */
618
class NODE_EXTERN CallbackScope {
619
 public:
620
  CallbackScope(v8::Isolate* isolate,
621
                v8::Local<v8::Object> resource,
622
                async_context asyncContext);
623
  ~CallbackScope();
624
625
 private:
626
  InternalCallbackScope* private_;
627
  v8::TryCatch try_catch_;
628
629
  void operator=(const CallbackScope&) = delete;
630
  void operator=(CallbackScope&&) = delete;
631
  CallbackScope(const CallbackScope&) = delete;
632
  CallbackScope(CallbackScope&&) = delete;
633
};
634
635
/* An API specific to emit before/after callbacks is unnecessary because
636
 * MakeCallback will automatically call them for you.
637
 *
638
 * These methods may create handles on their own, so run them inside a
639
 * HandleScope.
640
 *
641
 * `asyncId` and `triggerAsyncId` should correspond to the values returned by
642
 * `EmitAsyncInit()` and `AsyncHooksGetTriggerAsyncId()`, respectively, when the
643
 * invoking resource was created. If these values are unknown, 0 can be passed.
644
 * */
645
NODE_EXTERN
646
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
647
                                       v8::Local<v8::Object> recv,
648
                                       v8::Local<v8::Function> callback,
649
                                       int argc,
650
                                       v8::Local<v8::Value>* argv,
651
                                       async_context asyncContext);
652
NODE_EXTERN
653
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
654
                                       v8::Local<v8::Object> recv,
655
                                       const char* method,
656
                                       int argc,
657
                                       v8::Local<v8::Value>* argv,
658
                                       async_context asyncContext);
659
NODE_EXTERN
660
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
661
                                       v8::Local<v8::Object> recv,
662
                                       v8::Local<v8::String> symbol,
663
                                       int argc,
664
                                       v8::Local<v8::Value>* argv,
665
                                       async_context asyncContext);
666
667
/* Helper class users can optionally inherit from. If
668
 * `AsyncResource::MakeCallback()` is used, then all four callbacks will be
669
 * called automatically. */
670
class AsyncResource {
671
  public:
672
9
    AsyncResource(v8::Isolate* isolate,
673
                  v8::Local<v8::Object> resource,
674
                  const char* name,
675
                  async_id trigger_async_id = -1)
676
        : isolate_(isolate),
677
9
          resource_(isolate, resource) {
678
      async_context_ = EmitAsyncInit(isolate, resource, name,
679
9
                                     trigger_async_id);
680
9
    }
681
682
    AsyncResource(v8::Isolate* isolate,
683
                  v8::Local<v8::Object> resource,
684
                  v8::Local<v8::String> name,
685
                  async_id trigger_async_id = -1)
686
        : isolate_(isolate),
687
          resource_(isolate, resource) {
688
      async_context_ = EmitAsyncInit(isolate, resource, name,
689
                                     trigger_async_id);
690
    }
691
692
16
    ~AsyncResource() {
693
8
      EmitAsyncDestroy(isolate_, async_context_);
694
8
    }
695
696
    v8::MaybeLocal<v8::Value> MakeCallback(
697
        v8::Local<v8::Function> callback,
698
        int argc,
699
        v8::Local<v8::Value>* argv) {
700
      return node::MakeCallback(isolate_, get_resource(),
701
                                callback, argc, argv,
702
                                async_context_);
703
    }
704
705
    v8::MaybeLocal<v8::Value> MakeCallback(
706
        const char* method,
707
        int argc,
708
        v8::Local<v8::Value>* argv) {
709
      return node::MakeCallback(isolate_, get_resource(),
710
                                method, argc, argv,
711
                                async_context_);
712
    }
713
714
    v8::MaybeLocal<v8::Value> MakeCallback(
715
        v8::Local<v8::String> symbol,
716
        int argc,
717
        v8::Local<v8::Value>* argv) {
718
      return node::MakeCallback(isolate_, get_resource(),
719
                                symbol, argc, argv,
720
                                async_context_);
721
    }
722
723
    v8::Local<v8::Object> get_resource() {
724
      return resource_.Get(isolate_);
725
    }
726
727
    async_id get_async_id() const {
728
      return async_context_.async_id;
729
    }
730
731
    async_id get_trigger_async_id() const {
732
      return async_context_.trigger_async_id;
733
    }
734
735
  protected:
736
8
    class CallbackScope : public node::CallbackScope {
737
     public:
738
9
      explicit CallbackScope(AsyncResource* res)
739
        : node::CallbackScope(res->isolate_,
740
                              res->resource_.Get(res->isolate_),
741
18
                              res->async_context_) {}
742
    };
743
744
  private:
745
    v8::Isolate* isolate_;
746
    v8::Persistent<v8::Object> resource_;
747
    async_context async_context_;
748
};
749
750
}  // namespace node
751
752
#endif  // SRC_NODE_H_