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