1#ifndef SRC_NODE_EXTERNAL_REFERENCE_H_
2#define SRC_NODE_EXTERNAL_REFERENCE_H_
3
4#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6#include <cinttypes>
7#include <vector>
8#include "v8-fast-api-calls.h"
9#include "v8.h"
10
11namespace node {
12
13using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
14
15// This class manages the external references from the V8 heap
16// to the C++ addresses in Node.js.
17class ExternalReferenceRegistry {
18 public:
19  ExternalReferenceRegistry();
20
21#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V)                                    \
22  V(CFunctionCallback)                                                         \
23  V(const v8::CFunctionInfo*)                                                  \
24  V(v8::FunctionCallback)                                                      \
25  V(v8::AccessorGetterCallback)                                                \
26  V(v8::AccessorSetterCallback)                                                \
27  V(v8::AccessorNameGetterCallback)                                            \
28  V(v8::AccessorNameSetterCallback)                                            \
29  V(v8::GenericNamedPropertyDefinerCallback)                                   \
30  V(v8::GenericNamedPropertyDeleterCallback)                                   \
31  V(v8::GenericNamedPropertyEnumeratorCallback)                                \
32  V(v8::GenericNamedPropertyQueryCallback)                                     \
33  V(v8::GenericNamedPropertySetterCallback)                                    \
34  V(v8::IndexedPropertySetterCallback)                                         \
35  V(v8::IndexedPropertyDefinerCallback)                                        \
36  V(v8::IndexedPropertyDeleterCallback)                                        \
37  V(v8::IndexedPropertyQueryCallback)                                          \
38  V(v8::IndexedPropertyDescriptorCallback)
39
40#define V(ExternalReferenceType)                                               \
41  void Register(ExternalReferenceType addr) { RegisterT(addr); }
42  ALLOWED_EXTERNAL_REFERENCE_TYPES(V)
43#undef V
44
45  // This can be called only once.
46  const std::vector<intptr_t>& external_references();
47
48  bool is_empty() { return external_references_.empty(); }
49
50 private:
51  template <typename T>
52  void RegisterT(T* address) {
53    external_references_.push_back(reinterpret_cast<intptr_t>(address));
54  }
55  bool is_finalized_ = false;
56  std::vector<intptr_t> external_references_;
57};
58
59#define EXTERNAL_REFERENCE_BINDING_LIST_BASE(V)                                \
60  V(async_wrap)                                                                \
61  V(binding)                                                                   \
62  V(blob)                                                                      \
63  V(buffer)                                                                    \
64  V(builtins)                                                                  \
65  V(cares_wrap)                                                                \
66  V(contextify)                                                                \
67  V(credentials)                                                               \
68  V(env_var)                                                                   \
69  V(errors)                                                                    \
70  V(fs)                                                                        \
71  V(fs_dir)                                                                    \
72  V(fs_event_wrap)                                                             \
73  V(handle_wrap)                                                               \
74  V(heap_utils)                                                                \
75  V(messaging)                                                                 \
76  V(mksnapshot)                                                                \
77  V(module_wrap)                                                               \
78  V(options)                                                                   \
79  V(os)                                                                        \
80  V(performance)                                                               \
81  V(process_methods)                                                           \
82  V(process_object)                                                            \
83  V(report)                                                                    \
84  V(task_queue)                                                                \
85  V(tcp_wrap)                                                                  \
86  V(tty_wrap)                                                                  \
87  V(url)                                                                       \
88  V(util)                                                                      \
89  V(pipe_wrap)                                                                 \
90  V(sea)                                                                       \
91  V(serdes)                                                                    \
92  V(string_decoder)                                                            \
93  V(stream_wrap)                                                               \
94  V(signal_wrap)                                                               \
95  V(trace_events)                                                              \
96  V(timers)                                                                    \
97  V(types)                                                                     \
98  V(uv)                                                                        \
99  V(v8)                                                                        \
100  V(zlib)                                                                      \
101  V(wasm_web_api)                                                              \
102  V(worker)
103
104#if NODE_HAVE_I18N_SUPPORT
105#define EXTERNAL_REFERENCE_BINDING_LIST_I18N(V) V(icu)
106#else
107#define EXTERNAL_REFERENCE_BINDING_LIST_I18N(V)
108#endif  // NODE_HAVE_I18N_SUPPORT
109
110#if HAVE_INSPECTOR
111#define EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V)                           \
112  V(inspector)                                                                 \
113  V(profiler)
114#else
115#define EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V)
116#endif  // HAVE_INSPECTOR
117
118#if HAVE_DTRACE || HAVE_ETW
119#define EXTERNAL_REFERENCE_BINDING_LIST_DTRACE(V) V(dtrace)
120#else
121#define EXTERNAL_REFERENCE_BINDING_LIST_DTRACE(V)
122#endif
123
124#if HAVE_OPENSSL
125#define EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V) V(crypto) V(tls_wrap)
126#else
127#define EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V)
128#endif  // HAVE_OPENSSL
129
130#define EXTERNAL_REFERENCE_BINDING_LIST(V)                                     \
131  EXTERNAL_REFERENCE_BINDING_LIST_BASE(V)                                      \
132  EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V)                                 \
133  EXTERNAL_REFERENCE_BINDING_LIST_I18N(V)                                      \
134  EXTERNAL_REFERENCE_BINDING_LIST_DTRACE(V)                                    \
135  EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V)
136
137}  // namespace node
138
139// Declare all the external reference registration functions here,
140// and define them later with #NODE_BINDING_EXTERNAL_REFERENCE(modname, func);
141#define V(modname)                                                             \
142  void _register_external_reference_##modname(                                 \
143      node::ExternalReferenceRegistry* registry);
144EXTERNAL_REFERENCE_BINDING_LIST(V)
145#undef V
146
147#define NODE_BINDING_EXTERNAL_REFERENCE(modname, func)                         \
148  void _register_external_reference_##modname(                                 \
149      node::ExternalReferenceRegistry* registry) {                             \
150    func(registry);                                                            \
151  }
152#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
153#endif  // SRC_NODE_EXTERNAL_REFERENCE_H_
154