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 __attribute__((visibility("default"))) |
33 |
|
|
#endif |
34 |
|
|
|
35 |
|
|
// Declarations annotated with NODE_EXTERN_PRIVATE do not form part of |
36 |
|
|
// the public API. They are implementation details that can and will |
37 |
|
|
// change between releases, even in semver patch releases. Do not use |
38 |
|
|
// any such symbol in external code. |
39 |
|
|
#ifdef NODE_SHARED_MODE |
40 |
|
|
#define NODE_EXTERN_PRIVATE NODE_EXTERN |
41 |
|
|
#else |
42 |
|
|
#define NODE_EXTERN_PRIVATE |
43 |
|
|
#endif |
44 |
|
|
|
45 |
|
|
#ifdef BUILDING_NODE_EXTENSION |
46 |
|
|
# undef BUILDING_V8_SHARED |
47 |
|
|
# undef BUILDING_UV_SHARED |
48 |
|
|
# define USING_V8_SHARED 1 |
49 |
|
|
# define USING_UV_SHARED 1 |
50 |
|
|
#endif |
51 |
|
|
|
52 |
|
|
// This should be defined in make system. |
53 |
|
|
// See issue https://github.com/nodejs/node-v0.x-archive/issues/1236 |
54 |
|
|
#if defined(__MINGW32__) || defined(_MSC_VER) |
55 |
|
|
#ifndef _WIN32_WINNT |
56 |
|
|
# define _WIN32_WINNT 0x0600 // Windows Server 2008 |
57 |
|
|
#endif |
58 |
|
|
|
59 |
|
|
#ifndef NOMINMAX |
60 |
|
|
# define NOMINMAX |
61 |
|
|
#endif |
62 |
|
|
|
63 |
|
|
#endif |
64 |
|
|
|
65 |
|
|
#if defined(_MSC_VER) |
66 |
|
|
#define PATH_MAX MAX_PATH |
67 |
|
|
#endif |
68 |
|
|
|
69 |
|
|
#ifdef _WIN32 |
70 |
|
|
# define SIGKILL 9 |
71 |
|
|
#endif |
72 |
|
|
|
73 |
|
|
#include "v8.h" // NOLINT(build/include_order) |
74 |
|
|
|
75 |
|
|
#include "v8-platform.h" // NOLINT(build/include_order) |
76 |
|
|
#include "node_version.h" // NODE_MODULE_VERSION |
77 |
|
|
|
78 |
|
|
#include <functional> |
79 |
|
|
#include <memory> |
80 |
|
|
#include <ostream> |
81 |
|
|
|
82 |
|
|
// We cannot use __POSIX__ in this header because that's only defined when |
83 |
|
|
// building Node.js. |
84 |
|
|
#ifndef _WIN32 |
85 |
|
|
#include <signal.h> |
86 |
|
|
#endif // _WIN32 |
87 |
|
|
|
88 |
|
|
#define NODE_MAKE_VERSION(major, minor, patch) \ |
89 |
|
|
((major) * 0x1000 + (minor) * 0x100 + (patch)) |
90 |
|
|
|
91 |
|
|
#ifdef __clang__ |
92 |
|
|
# define NODE_CLANG_AT_LEAST(major, minor, patch) \ |
93 |
|
|
(NODE_MAKE_VERSION(major, minor, patch) <= \ |
94 |
|
|
NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)) |
95 |
|
|
#else |
96 |
|
|
# define NODE_CLANG_AT_LEAST(major, minor, patch) (0) |
97 |
|
|
#endif |
98 |
|
|
|
99 |
|
|
#ifdef __GNUC__ |
100 |
|
|
# define NODE_GNUC_AT_LEAST(major, minor, patch) \ |
101 |
|
|
(NODE_MAKE_VERSION(major, minor, patch) <= \ |
102 |
|
|
NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)) |
103 |
|
|
#else |
104 |
|
|
# define NODE_GNUC_AT_LEAST(major, minor, patch) (0) |
105 |
|
|
#endif |
106 |
|
|
|
107 |
|
|
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
108 |
|
|
# define NODE_DEPRECATED(message, declarator) declarator |
109 |
|
|
#else // NODE_WANT_INTERNALS |
110 |
|
|
# if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0) |
111 |
|
|
# define NODE_DEPRECATED(message, declarator) \ |
112 |
|
|
__attribute__((deprecated(message))) declarator |
113 |
|
|
# elif defined(_MSC_VER) |
114 |
|
|
# define NODE_DEPRECATED(message, declarator) \ |
115 |
|
|
__declspec(deprecated) declarator |
116 |
|
|
# else |
117 |
|
|
# define NODE_DEPRECATED(message, declarator) declarator |
118 |
|
|
# endif |
119 |
|
|
#endif |
120 |
|
|
|
121 |
|
|
// Forward-declare libuv loop |
122 |
|
|
struct uv_loop_s; |
123 |
|
|
|
124 |
|
|
struct napi_module; |
125 |
|
|
|
126 |
|
|
// Forward-declare these functions now to stop MSVS from becoming |
127 |
|
|
// terminally confused when it's done in node_internals.h |
128 |
|
|
namespace node { |
129 |
|
|
|
130 |
|
|
namespace tracing { |
131 |
|
|
|
132 |
|
|
class TracingController; |
133 |
|
|
|
134 |
|
|
} |
135 |
|
|
|
136 |
|
|
NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate, |
137 |
|
|
int errorno, |
138 |
|
|
const char* syscall = nullptr, |
139 |
|
|
const char* message = nullptr, |
140 |
|
|
const char* path = nullptr); |
141 |
|
|
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate, |
142 |
|
|
int errorno, |
143 |
|
|
const char* syscall = nullptr, |
144 |
|
|
const char* message = nullptr, |
145 |
|
|
const char* path = nullptr, |
146 |
|
|
const char* dest = nullptr); |
147 |
|
|
|
148 |
|
|
NODE_DEPRECATED("Use ErrnoException(isolate, ...)", |
149 |
|
|
inline v8::Local<v8::Value> ErrnoException( |
150 |
|
|
int errorno, |
151 |
|
|
const char* syscall = nullptr, |
152 |
|
|
const char* message = nullptr, |
153 |
|
|
const char* path = nullptr) { |
154 |
|
|
return ErrnoException(v8::Isolate::GetCurrent(), |
155 |
|
|
errorno, |
156 |
|
|
syscall, |
157 |
|
|
message, |
158 |
|
|
path); |
159 |
|
|
}) |
160 |
|
|
|
161 |
|
|
NODE_DEPRECATED("Use UVException(isolate, ...)", |
162 |
|
|
inline v8::Local<v8::Value> UVException(int errorno, |
163 |
|
|
const char* syscall = nullptr, |
164 |
|
|
const char* message = nullptr, |
165 |
|
|
const char* path = nullptr) { |
166 |
|
|
return UVException(v8::Isolate::GetCurrent(), |
167 |
|
|
errorno, |
168 |
|
|
syscall, |
169 |
|
|
message, |
170 |
|
|
path); |
171 |
|
|
}) |
172 |
|
|
|
173 |
|
|
/* |
174 |
|
|
* These methods need to be called in a HandleScope. |
175 |
|
|
* |
176 |
|
|
* It is preferred that you use the `MakeCallback` overloads taking |
177 |
|
|
* `async_context` arguments. |
178 |
|
|
*/ |
179 |
|
|
|
180 |
|
|
NODE_DEPRECATED("Use MakeCallback(..., async_context)", |
181 |
|
|
NODE_EXTERN v8::Local<v8::Value> MakeCallback( |
182 |
|
|
v8::Isolate* isolate, |
183 |
|
|
v8::Local<v8::Object> recv, |
184 |
|
|
const char* method, |
185 |
|
|
int argc, |
186 |
|
|
v8::Local<v8::Value>* argv)); |
187 |
|
|
NODE_DEPRECATED("Use MakeCallback(..., async_context)", |
188 |
|
|
NODE_EXTERN v8::Local<v8::Value> MakeCallback( |
189 |
|
|
v8::Isolate* isolate, |
190 |
|
|
v8::Local<v8::Object> recv, |
191 |
|
|
v8::Local<v8::String> symbol, |
192 |
|
|
int argc, |
193 |
|
|
v8::Local<v8::Value>* argv)); |
194 |
|
|
NODE_DEPRECATED("Use MakeCallback(..., async_context)", |
195 |
|
|
NODE_EXTERN v8::Local<v8::Value> MakeCallback( |
196 |
|
|
v8::Isolate* isolate, |
197 |
|
|
v8::Local<v8::Object> recv, |
198 |
|
|
v8::Local<v8::Function> callback, |
199 |
|
|
int argc, |
200 |
|
|
v8::Local<v8::Value>* argv)); |
201 |
|
|
|
202 |
|
|
} // namespace node |
203 |
|
|
|
204 |
|
|
#include <cassert> |
205 |
|
|
#include <cstdint> |
206 |
|
|
|
207 |
|
|
#ifndef NODE_STRINGIFY |
208 |
|
|
# define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) |
209 |
|
|
# define NODE_STRINGIFY_HELPER(n) #n |
210 |
|
|
#endif |
211 |
|
|
|
212 |
|
|
#ifdef _WIN32 |
213 |
|
|
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) |
214 |
|
|
typedef intptr_t ssize_t; |
215 |
|
|
# define _SSIZE_T_ |
216 |
|
|
# define _SSIZE_T_DEFINED |
217 |
|
|
#endif |
218 |
|
|
#else // !_WIN32 |
219 |
|
|
# include <sys/types.h> // size_t, ssize_t |
220 |
|
|
#endif // _WIN32 |
221 |
|
|
|
222 |
|
|
|
223 |
|
|
namespace node { |
224 |
|
|
|
225 |
|
|
class IsolateData; |
226 |
|
|
class Environment; |
227 |
|
|
class MultiIsolatePlatform; |
228 |
|
|
class InitializationResultImpl; |
229 |
|
|
|
230 |
|
|
namespace ProcessFlags { |
231 |
|
|
enum Flags : uint64_t { |
232 |
|
|
kNoFlags = 0, |
233 |
|
|
// Enable stdio inheritance, which is disabled by default. |
234 |
|
|
// This flag is also implied by kNoStdioInitialization. |
235 |
|
|
kEnableStdioInheritance = 1 << 0, |
236 |
|
|
// Disable reading the NODE_OPTIONS environment variable. |
237 |
|
|
kDisableNodeOptionsEnv = 1 << 1, |
238 |
|
|
// Do not parse CLI options. |
239 |
|
|
kDisableCLIOptions = 1 << 2, |
240 |
|
|
// Do not initialize ICU. |
241 |
|
|
kNoICU = 1 << 3, |
242 |
|
|
// Do not modify stdio file descriptor or TTY state. |
243 |
|
|
kNoStdioInitialization = 1 << 4, |
244 |
|
|
// Do not register Node.js-specific signal handlers |
245 |
|
|
// and reset other signal handlers to default state. |
246 |
|
|
kNoDefaultSignalHandling = 1 << 5, |
247 |
|
|
// Do not perform V8 initialization. |
248 |
|
|
kNoInitializeV8 = 1 << 6, |
249 |
|
|
// Do not initialize a default Node.js-provided V8 platform instance. |
250 |
|
|
kNoInitializeNodeV8Platform = 1 << 7, |
251 |
|
|
// Do not initialize OpenSSL config. |
252 |
|
|
kNoInitOpenSSL = 1 << 8, |
253 |
|
|
// Do not initialize Node.js debugging based on environment variables. |
254 |
|
|
kNoParseGlobalDebugVariables = 1 << 9, |
255 |
|
|
// Do not adjust OS resource limits for this process. |
256 |
|
|
kNoAdjustResourceLimits = 1 << 10, |
257 |
|
|
// Do not map code segments into large pages for this process. |
258 |
|
|
kNoUseLargePages = 1 << 11, |
259 |
|
|
// Skip printing output for --help, --version, --v8-options. |
260 |
|
|
kNoPrintHelpOrVersionOutput = 1 << 12, |
261 |
|
|
|
262 |
|
|
// Emulate the behavior of InitializeNodeWithArgs() when passing |
263 |
|
|
// a flags argument to the InitializeOncePerProcess() replacement |
264 |
|
|
// function. |
265 |
|
|
kLegacyInitializeNodeWithArgsBehavior = |
266 |
|
|
kNoStdioInitialization | kNoDefaultSignalHandling | kNoInitializeV8 | |
267 |
|
|
kNoInitializeNodeV8Platform | kNoInitOpenSSL | |
268 |
|
|
kNoParseGlobalDebugVariables | kNoAdjustResourceLimits | |
269 |
|
|
kNoUseLargePages | kNoPrintHelpOrVersionOutput, |
270 |
|
|
}; |
271 |
|
|
} // namespace ProcessFlags |
272 |
|
|
// TODO(addaleax): Make this the canonical name, as it is more descriptive. |
273 |
|
|
namespace ProcessInitializationFlags = ProcessFlags; |
274 |
|
|
|
275 |
|
|
class NODE_EXTERN InitializationResult { |
276 |
|
|
public: |
277 |
|
|
virtual ~InitializationResult(); |
278 |
|
|
|
279 |
|
|
// Returns a suggested process exit code. |
280 |
|
|
virtual int exit_code() const = 0; |
281 |
|
|
|
282 |
|
|
// Returns 'true' if initialization was aborted early due to errors. |
283 |
|
|
virtual bool early_return() const = 0; |
284 |
|
|
|
285 |
|
|
// Returns the parsed list of non-Node.js arguments. |
286 |
|
|
virtual const std::vector<std::string>& args() const = 0; |
287 |
|
|
|
288 |
|
|
// Returns the parsed list of Node.js arguments. |
289 |
|
|
virtual const std::vector<std::string>& exec_args() const = 0; |
290 |
|
|
|
291 |
|
|
// Returns an array of errors. Note that these may be warnings |
292 |
|
|
// whose existence does not imply a non-zero exit code. |
293 |
|
|
virtual const std::vector<std::string>& errors() const = 0; |
294 |
|
|
|
295 |
|
|
// If kNoInitializeNodeV8Platform was not specified, the global Node.js |
296 |
|
|
// platform instance. |
297 |
|
|
virtual MultiIsolatePlatform* platform() const = 0; |
298 |
|
|
|
299 |
|
|
private: |
300 |
|
5596 |
InitializationResult() = default; |
301 |
|
|
friend class InitializationResultImpl; |
302 |
|
|
}; |
303 |
|
|
|
304 |
|
|
// TODO(addaleax): Officially deprecate this and replace it with something |
305 |
|
|
// better suited for a public embedder API. |
306 |
|
|
NODE_EXTERN int Start(int argc, char* argv[]); |
307 |
|
|
|
308 |
|
|
// Tear down Node.js while it is running (there are active handles |
309 |
|
|
// in the loop and / or actively executing JavaScript code). |
310 |
|
|
NODE_EXTERN int Stop(Environment* env); |
311 |
|
|
|
312 |
|
|
// Set up per-process state needed to run Node.js. This will consume arguments |
313 |
|
|
// from argv, fill exec_argv, and possibly add errors resulting from parsing |
314 |
|
|
// the arguments to `errors`. The return value is a suggested exit code for the |
315 |
|
|
// program; If it is 0, then initializing Node.js succeeded. |
316 |
|
|
// This runs a subset of the initialization performed by |
317 |
|
|
// InitializeOncePerProcess(), which supersedes this function. |
318 |
|
|
// The subset is roughly equivalent to the one given by |
319 |
|
|
// `ProcessInitializationFlags::kLegacyInitializeNodeWithArgsBehavior`. |
320 |
|
|
NODE_DEPRECATED("Use InitializeOncePerProcess() instead", |
321 |
|
|
NODE_EXTERN int InitializeNodeWithArgs( |
322 |
|
|
std::vector<std::string>* argv, |
323 |
|
|
std::vector<std::string>* exec_argv, |
324 |
|
|
std::vector<std::string>* errors, |
325 |
|
|
ProcessInitializationFlags::Flags flags = |
326 |
|
|
ProcessInitializationFlags::kNoFlags)); |
327 |
|
|
|
328 |
|
|
// Set up per-process state needed to run Node.js. This will consume arguments |
329 |
|
|
// from args, and return information about the initialization success, |
330 |
|
|
// including the arguments split into argv/exec_argv, a list of potential |
331 |
|
|
// errors encountered during initialization, and a potential suggested |
332 |
|
|
// exit code. |
333 |
|
|
NODE_EXTERN std::unique_ptr<InitializationResult> InitializeOncePerProcess( |
334 |
|
|
const std::vector<std::string>& args, |
335 |
|
|
ProcessInitializationFlags::Flags flags = |
336 |
|
|
ProcessInitializationFlags::kNoFlags); |
337 |
|
|
// Undoes the initialization performed by InitializeOncePerProcess(), |
338 |
|
|
// where cleanup is necessary. |
339 |
|
|
NODE_EXTERN void TearDownOncePerProcess(); |
340 |
|
|
// Convenience overload for specifying multiple flags without having |
341 |
|
|
// to worry about casts. |
342 |
|
7 |
inline std::unique_ptr<InitializationResult> InitializeOncePerProcess( |
343 |
|
|
const std::vector<std::string>& args, |
344 |
|
|
std::initializer_list<ProcessInitializationFlags::Flags> list) { |
345 |
|
7 |
uint64_t flags_accum = ProcessInitializationFlags::kNoFlags; |
346 |
✓✓ |
21 |
for (const auto flag : list) flags_accum |= static_cast<uint64_t>(flag); |
347 |
|
|
return InitializeOncePerProcess( |
348 |
|
7 |
args, static_cast<ProcessInitializationFlags::Flags>(flags_accum)); |
349 |
|
|
} |
350 |
|
|
|
351 |
|
|
enum OptionEnvvarSettings { |
352 |
|
|
kAllowedInEnvironment, |
353 |
|
|
kDisallowedInEnvironment |
354 |
|
|
}; |
355 |
|
|
|
356 |
|
|
NODE_EXTERN int ProcessGlobalArgs(std::vector<std::string>* args, |
357 |
|
|
std::vector<std::string>* exec_args, |
358 |
|
|
std::vector<std::string>* errors, |
359 |
|
|
OptionEnvvarSettings settings); |
360 |
|
|
|
361 |
|
|
class NodeArrayBufferAllocator; |
362 |
|
|
|
363 |
|
|
// An ArrayBuffer::Allocator class with some Node.js-specific tweaks. If you do |
364 |
|
|
// not have to use another allocator, using this class is recommended: |
365 |
|
|
// - It supports Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() with |
366 |
|
|
// uninitialized memory. |
367 |
|
|
// - It supports transferring, rather than copying, ArrayBuffers when using |
368 |
|
|
// MessagePorts. |
369 |
|
|
class NODE_EXTERN ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { |
370 |
|
|
public: |
371 |
|
|
// If `always_debug` is true, create an ArrayBuffer::Allocator instance |
372 |
|
|
// that performs additional integrity checks (e.g. make sure that only memory |
373 |
|
|
// that was allocated by the it is also freed by it). |
374 |
|
|
// This can also be set using the --debug-arraybuffer-allocations flag. |
375 |
|
|
static std::unique_ptr<ArrayBufferAllocator> Create( |
376 |
|
|
bool always_debug = false); |
377 |
|
|
|
378 |
|
|
private: |
379 |
|
|
virtual NodeArrayBufferAllocator* GetImpl() = 0; |
380 |
|
|
|
381 |
|
|
friend class IsolateData; |
382 |
|
|
}; |
383 |
|
|
|
384 |
|
|
// Legacy equivalents for ArrayBufferAllocator::Create(). |
385 |
|
|
NODE_EXTERN ArrayBufferAllocator* CreateArrayBufferAllocator(); |
386 |
|
|
NODE_EXTERN void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator); |
387 |
|
|
|
388 |
|
|
class NODE_EXTERN IsolatePlatformDelegate { |
389 |
|
|
public: |
390 |
|
|
virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner() = 0; |
391 |
|
|
virtual bool IdleTasksEnabled() = 0; |
392 |
|
|
}; |
393 |
|
|
|
394 |
|
|
class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { |
395 |
|
|
public: |
396 |
|
11064 |
~MultiIsolatePlatform() override = default; |
397 |
|
|
// Returns true if work was dispatched or executed. New tasks that are |
398 |
|
|
// posted during flushing of the queue are postponed until the next |
399 |
|
|
// flushing. |
400 |
|
|
virtual bool FlushForegroundTasks(v8::Isolate* isolate) = 0; |
401 |
|
|
virtual void DrainTasks(v8::Isolate* isolate) = 0; |
402 |
|
|
|
403 |
|
|
// This needs to be called between the calls to `Isolate::Allocate()` and |
404 |
|
|
// `Isolate::Initialize()`, so that initialization can already start |
405 |
|
|
// using the platform. |
406 |
|
|
// When using `NewIsolate()`, this is taken care of by that function. |
407 |
|
|
// This function may only be called once per `Isolate`. |
408 |
|
|
virtual void RegisterIsolate(v8::Isolate* isolate, |
409 |
|
|
struct uv_loop_s* loop) = 0; |
410 |
|
|
// This method can be used when an application handles task scheduling on its |
411 |
|
|
// own through `IsolatePlatformDelegate`. Upon registering an isolate with |
412 |
|
|
// this overload any other method in this class with the exception of |
413 |
|
|
// `UnregisterIsolate` *must not* be used on that isolate. |
414 |
|
|
virtual void RegisterIsolate(v8::Isolate* isolate, |
415 |
|
|
IsolatePlatformDelegate* delegate) = 0; |
416 |
|
|
|
417 |
|
|
// This function may only be called once per `Isolate`, and discard any |
418 |
|
|
// pending delayed tasks scheduled for that isolate. |
419 |
|
|
// This needs to be called right before calling `Isolate::Dispose()`. |
420 |
|
|
virtual void UnregisterIsolate(v8::Isolate* isolate) = 0; |
421 |
|
|
|
422 |
|
|
// The platform should call the passed function once all state associated |
423 |
|
|
// with the given isolate has been cleaned up. This can, but does not have to, |
424 |
|
|
// happen asynchronously. |
425 |
|
|
virtual void AddIsolateFinishedCallback(v8::Isolate* isolate, |
426 |
|
|
void (*callback)(void*), |
427 |
|
|
void* data) = 0; |
428 |
|
|
|
429 |
|
|
static std::unique_ptr<MultiIsolatePlatform> Create( |
430 |
|
|
int thread_pool_size, |
431 |
|
|
v8::TracingController* tracing_controller = nullptr, |
432 |
|
|
v8::PageAllocator* page_allocator = nullptr); |
433 |
|
|
}; |
434 |
|
|
|
435 |
|
|
enum IsolateSettingsFlags { |
436 |
|
|
MESSAGE_LISTENER_WITH_ERROR_LEVEL = 1 << 0, |
437 |
|
|
DETAILED_SOURCE_POSITIONS_FOR_PROFILING = 1 << 1, |
438 |
|
|
SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK = 1 << 2, |
439 |
|
|
SHOULD_NOT_SET_PREPARE_STACK_TRACE_CALLBACK = 1 << 3 |
440 |
|
|
}; |
441 |
|
|
|
442 |
|
|
struct IsolateSettings { |
443 |
|
|
uint64_t flags = MESSAGE_LISTENER_WITH_ERROR_LEVEL | |
444 |
|
|
DETAILED_SOURCE_POSITIONS_FOR_PROFILING; |
445 |
|
|
v8::MicrotasksPolicy policy = v8::MicrotasksPolicy::kExplicit; |
446 |
|
|
|
447 |
|
|
// Error handling callbacks |
448 |
|
|
v8::Isolate::AbortOnUncaughtExceptionCallback |
449 |
|
|
should_abort_on_uncaught_exception_callback = nullptr; |
450 |
|
|
v8::FatalErrorCallback fatal_error_callback = nullptr; |
451 |
|
|
v8::PrepareStackTraceCallback prepare_stack_trace_callback = nullptr; |
452 |
|
|
|
453 |
|
|
// Miscellaneous callbacks |
454 |
|
|
v8::PromiseRejectCallback promise_reject_callback = nullptr; |
455 |
|
|
v8::AllowWasmCodeGenerationCallback |
456 |
|
|
allow_wasm_code_generation_callback = nullptr; |
457 |
|
|
}; |
458 |
|
|
|
459 |
|
|
// Overriding IsolateSettings may produce unexpected behavior |
460 |
|
|
// in Node.js core functionality, so proceed at your own risk. |
461 |
|
|
NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate, |
462 |
|
|
const IsolateSettings& settings); |
463 |
|
|
|
464 |
|
|
// Set a number of callbacks for the `isolate`, in particular the Node.js |
465 |
|
|
// uncaught exception listener. |
466 |
|
|
NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate); |
467 |
|
|
|
468 |
|
|
// Creates a new isolate with Node.js-specific settings. |
469 |
|
|
// This is a convenience method equivalent to using SetIsolateCreateParams(), |
470 |
|
|
// Isolate::Allocate(), MultiIsolatePlatform::RegisterIsolate(), |
471 |
|
|
// Isolate::Initialize(), and SetIsolateUpForNode(). |
472 |
|
|
NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator, |
473 |
|
|
struct uv_loop_s* event_loop, |
474 |
|
|
MultiIsolatePlatform* platform = nullptr); |
475 |
|
|
NODE_EXTERN v8::Isolate* NewIsolate( |
476 |
|
|
std::shared_ptr<ArrayBufferAllocator> allocator, |
477 |
|
|
struct uv_loop_s* event_loop, |
478 |
|
|
MultiIsolatePlatform* platform); |
479 |
|
|
|
480 |
|
|
// Creates a new context with Node.js-specific tweaks. |
481 |
|
|
NODE_EXTERN v8::Local<v8::Context> NewContext( |
482 |
|
|
v8::Isolate* isolate, |
483 |
|
|
v8::Local<v8::ObjectTemplate> object_template = |
484 |
|
|
v8::Local<v8::ObjectTemplate>()); |
485 |
|
|
|
486 |
|
|
// Runs Node.js-specific tweaks on an already constructed context |
487 |
|
|
// Return value indicates success of operation |
488 |
|
|
NODE_EXTERN v8::Maybe<bool> InitializeContext(v8::Local<v8::Context> context); |
489 |
|
|
|
490 |
|
|
// If `platform` is passed, it will be used to register new Worker instances. |
491 |
|
|
// It can be `nullptr`, in which case creating new Workers inside of |
492 |
|
|
// Environments that use this `IsolateData` will not work. |
493 |
|
|
NODE_EXTERN IsolateData* CreateIsolateData( |
494 |
|
|
v8::Isolate* isolate, |
495 |
|
|
struct uv_loop_s* loop, |
496 |
|
|
MultiIsolatePlatform* platform = nullptr, |
497 |
|
|
ArrayBufferAllocator* allocator = nullptr); |
498 |
|
|
NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data); |
499 |
|
|
|
500 |
|
|
struct ThreadId { |
501 |
|
|
uint64_t id = static_cast<uint64_t>(-1); |
502 |
|
|
}; |
503 |
|
|
NODE_EXTERN ThreadId AllocateEnvironmentThreadId(); |
504 |
|
|
|
505 |
|
|
namespace EnvironmentFlags { |
506 |
|
|
enum Flags : uint64_t { |
507 |
|
|
kNoFlags = 0, |
508 |
|
|
// Use the default behaviour for Node.js instances. |
509 |
|
|
kDefaultFlags = 1 << 0, |
510 |
|
|
// Controls whether this Environment is allowed to affect per-process state |
511 |
|
|
// (e.g. cwd, process title, uid, etc.). |
512 |
|
|
// This is set when using kDefaultFlags. |
513 |
|
|
kOwnsProcessState = 1 << 1, |
514 |
|
|
// Set if this Environment instance is associated with the global inspector |
515 |
|
|
// handling code (i.e. listening on SIGUSR1). |
516 |
|
|
// This is set when using kDefaultFlags. |
517 |
|
|
kOwnsInspector = 1 << 2, |
518 |
|
|
// Set if Node.js should not run its own esm loader. This is needed by some |
519 |
|
|
// embedders, because it's possible for the Node.js esm loader to conflict |
520 |
|
|
// with another one in an embedder environment, e.g. Blink's in Chromium. |
521 |
|
|
kNoRegisterESMLoader = 1 << 3, |
522 |
|
|
// Set this flag to make Node.js track "raw" file descriptors, i.e. managed |
523 |
|
|
// by fs.open() and fs.close(), and close them during FreeEnvironment(). |
524 |
|
|
kTrackUnmanagedFds = 1 << 4, |
525 |
|
|
// Set this flag to force hiding console windows when spawning child |
526 |
|
|
// processes. This is usually used when embedding Node.js in GUI programs on |
527 |
|
|
// Windows. |
528 |
|
|
kHideConsoleWindows = 1 << 5, |
529 |
|
|
// Set this flag to disable loading native addons via `process.dlopen`. |
530 |
|
|
// This environment flag is especially important for worker threads |
531 |
|
|
// so that a worker thread can't load a native addon even if `execArgv` |
532 |
|
|
// is overwritten and `--no-addons` is not specified but was specified |
533 |
|
|
// for this Environment instance. |
534 |
|
|
kNoNativeAddons = 1 << 6, |
535 |
|
|
// Set this flag to disable searching modules from global paths like |
536 |
|
|
// $HOME/.node_modules and $NODE_PATH. This is used by standalone apps that |
537 |
|
|
// do not expect to have their behaviors changed because of globally |
538 |
|
|
// installed modules. |
539 |
|
|
kNoGlobalSearchPaths = 1 << 7, |
540 |
|
|
// Do not export browser globals like setTimeout, console, etc. |
541 |
|
|
kNoBrowserGlobals = 1 << 8, |
542 |
|
|
// Controls whether or not the Environment should call V8Inspector::create(). |
543 |
|
|
// This control is needed by embedders who may not want to initialize the V8 |
544 |
|
|
// inspector in situations where one has already been created, |
545 |
|
|
// e.g. Blink's in Chromium. |
546 |
|
|
kNoCreateInspector = 1 << 9 |
547 |
|
|
}; |
548 |
|
|
} // namespace EnvironmentFlags |
549 |
|
|
|
550 |
|
|
struct InspectorParentHandle { |
551 |
|
|
virtual ~InspectorParentHandle(); |
552 |
|
|
}; |
553 |
|
|
|
554 |
|
|
// TODO(addaleax): Maybe move per-Environment options parsing here. |
555 |
|
|
// Returns nullptr when the Environment cannot be created e.g. there are |
556 |
|
|
// pending JavaScript exceptions. |
557 |
|
|
NODE_EXTERN Environment* CreateEnvironment( |
558 |
|
|
IsolateData* isolate_data, |
559 |
|
|
v8::Local<v8::Context> context, |
560 |
|
|
const std::vector<std::string>& args, |
561 |
|
|
const std::vector<std::string>& exec_args, |
562 |
|
|
EnvironmentFlags::Flags flags = EnvironmentFlags::kDefaultFlags, |
563 |
|
|
ThreadId thread_id = {} /* allocates a thread id automatically */, |
564 |
|
|
std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {}); |
565 |
|
|
|
566 |
|
|
// Returns a handle that can be passed to `LoadEnvironment()`, making the |
567 |
|
|
// child Environment accessible to the inspector as if it were a Node.js Worker. |
568 |
|
|
// `child_thread_id` can be created using `AllocateEnvironmentThreadId()` |
569 |
|
|
// and then later passed on to `CreateEnvironment()` to create the child |
570 |
|
|
// Environment, together with the inspector handle. |
571 |
|
|
// This method should not be called while the parent Environment is active |
572 |
|
|
// on another thread. |
573 |
|
|
NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle( |
574 |
|
|
Environment* parent_env, |
575 |
|
|
ThreadId child_thread_id, |
576 |
|
|
const char* child_url); |
577 |
|
|
|
578 |
|
|
struct StartExecutionCallbackInfo { |
579 |
|
|
v8::Local<v8::Object> process_object; |
580 |
|
|
v8::Local<v8::Function> native_require; |
581 |
|
|
}; |
582 |
|
|
|
583 |
|
|
using StartExecutionCallback = |
584 |
|
|
std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>; |
585 |
|
|
|
586 |
|
|
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment( |
587 |
|
|
Environment* env, |
588 |
|
|
StartExecutionCallback cb); |
589 |
|
|
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment( |
590 |
|
|
Environment* env, |
591 |
|
|
const char* main_script_source_utf8); |
592 |
|
|
NODE_EXTERN void FreeEnvironment(Environment* env); |
593 |
|
|
|
594 |
|
|
// Set a callback that is called when process.exit() is called from JS, |
595 |
|
|
// overriding the default handler. |
596 |
|
|
// It receives the Environment* instance and the exit code as arguments. |
597 |
|
|
// This could e.g. call Stop(env); in order to terminate execution and stop |
598 |
|
|
// the event loop. |
599 |
|
|
// The default handler disposes of the global V8 platform instance, if one is |
600 |
|
|
// being used, and calls exit(). |
601 |
|
|
NODE_EXTERN void SetProcessExitHandler( |
602 |
|
|
Environment* env, |
603 |
|
|
std::function<void(Environment*, int)>&& handler); |
604 |
|
|
NODE_EXTERN void DefaultProcessExitHandler(Environment* env, int exit_code); |
605 |
|
|
|
606 |
|
|
// This may return nullptr if context is not associated with a Node instance. |
607 |
|
|
NODE_EXTERN Environment* GetCurrentEnvironment(v8::Local<v8::Context> context); |
608 |
|
|
NODE_EXTERN IsolateData* GetEnvironmentIsolateData(Environment* env); |
609 |
|
|
NODE_EXTERN ArrayBufferAllocator* GetArrayBufferAllocator(IsolateData* data); |
610 |
|
|
|
611 |
|
|
NODE_EXTERN void OnFatalError(const char* location, const char* message); |
612 |
|
|
NODE_EXTERN void PromiseRejectCallback(v8::PromiseRejectMessage message); |
613 |
|
|
NODE_EXTERN bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context, |
614 |
|
|
v8::Local<v8::String>); |
615 |
|
|
NODE_EXTERN bool ShouldAbortOnUncaughtException(v8::Isolate* isolate); |
616 |
|
|
NODE_EXTERN v8::MaybeLocal<v8::Value> PrepareStackTraceCallback( |
617 |
|
|
v8::Local<v8::Context> context, |
618 |
|
|
v8::Local<v8::Value> exception, |
619 |
|
|
v8::Local<v8::Array> trace); |
620 |
|
|
|
621 |
|
|
// Writes a diagnostic report to a file. If filename is not provided, the |
622 |
|
|
// default filename includes the date, time, PID, and a sequence number. |
623 |
|
|
// The report's JavaScript stack trace is taken from err, if present. |
624 |
|
|
// If isolate is nullptr, no information about the JavaScript environment |
625 |
|
|
// is included in the report. |
626 |
|
|
// Returns the filename of the written report. |
627 |
|
|
NODE_EXTERN std::string TriggerNodeReport(v8::Isolate* isolate, |
628 |
|
|
const char* message, |
629 |
|
|
const char* trigger, |
630 |
|
|
const std::string& filename, |
631 |
|
|
v8::Local<v8::Value> error); |
632 |
|
|
NODE_EXTERN std::string TriggerNodeReport(Environment* env, |
633 |
|
|
const char* message, |
634 |
|
|
const char* trigger, |
635 |
|
|
const std::string& filename, |
636 |
|
|
v8::Local<v8::Value> error); |
637 |
|
|
NODE_EXTERN void GetNodeReport(v8::Isolate* isolate, |
638 |
|
|
const char* message, |
639 |
|
|
const char* trigger, |
640 |
|
|
v8::Local<v8::Value> error, |
641 |
|
|
std::ostream& out); |
642 |
|
|
NODE_EXTERN void GetNodeReport(Environment* env, |
643 |
|
|
const char* message, |
644 |
|
|
const char* trigger, |
645 |
|
|
v8::Local<v8::Value> error, |
646 |
|
|
std::ostream& out); |
647 |
|
|
|
648 |
|
|
// This returns the MultiIsolatePlatform used for an Environment or IsolateData |
649 |
|
|
// instance, if one exists. |
650 |
|
|
NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(Environment* env); |
651 |
|
|
NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env); |
652 |
|
|
|
653 |
|
|
NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead", |
654 |
|
|
NODE_EXTERN MultiIsolatePlatform* CreatePlatform( |
655 |
|
|
int thread_pool_size, |
656 |
|
|
v8::TracingController* tracing_controller)); |
657 |
|
|
NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead", |
658 |
|
|
NODE_EXTERN void FreePlatform(MultiIsolatePlatform* platform)); |
659 |
|
|
|
660 |
|
|
// Get/set the currently active tracing controller. Using CreatePlatform() |
661 |
|
|
// will implicitly set this by default. This is global and should be initialized |
662 |
|
|
// along with the v8::Platform instance that is being used. `controller` |
663 |
|
|
// is allowed to be `nullptr`. |
664 |
|
|
// This is used for tracing events from Node.js itself. V8 uses the tracing |
665 |
|
|
// controller returned from the active `v8::Platform` instance. |
666 |
|
|
NODE_EXTERN v8::TracingController* GetTracingController(); |
667 |
|
|
NODE_EXTERN void SetTracingController(v8::TracingController* controller); |
668 |
|
|
|
669 |
|
|
// Run `process.emit('beforeExit')` as it would usually happen when Node.js is |
670 |
|
|
// run in standalone mode. |
671 |
|
|
NODE_EXTERN v8::Maybe<bool> EmitProcessBeforeExit(Environment* env); |
672 |
|
|
NODE_DEPRECATED("Use Maybe version (EmitProcessBeforeExit) instead", |
673 |
|
|
NODE_EXTERN void EmitBeforeExit(Environment* env)); |
674 |
|
|
// Run `process.emit('exit')` as it would usually happen when Node.js is run |
675 |
|
|
// in standalone mode. The return value corresponds to the exit code. |
676 |
|
|
NODE_EXTERN v8::Maybe<int> EmitProcessExit(Environment* env); |
677 |
|
|
NODE_DEPRECATED("Use Maybe version (EmitProcessExit) instead", |
678 |
|
|
NODE_EXTERN int EmitExit(Environment* env)); |
679 |
|
|
|
680 |
|
|
// Runs hooks added through `AtExit()`. This is part of `FreeEnvironment()`, |
681 |
|
|
// so calling it manually is typically not necessary. |
682 |
|
|
NODE_EXTERN void RunAtExit(Environment* env); |
683 |
|
|
|
684 |
|
|
// This may return nullptr if the current v8::Context is not associated |
685 |
|
|
// with a Node instance. |
686 |
|
|
NODE_EXTERN struct uv_loop_s* GetCurrentEventLoop(v8::Isolate* isolate); |
687 |
|
|
|
688 |
|
|
// Runs the main loop for a given Environment. This roughly performs the |
689 |
|
|
// following steps: |
690 |
|
|
// 1. Call uv_run() on the event loop until it is drained. |
691 |
|
|
// 2. Call platform->DrainTasks() on the associated platform/isolate. |
692 |
|
|
// 3. If the event loop is alive again, go to Step 1. |
693 |
|
|
// 4. Call EmitProcessBeforeExit(). |
694 |
|
|
// 5. If the event loop is alive again, go to Step 1. |
695 |
|
|
// 6. Call EmitProcessExit() and forward the return value. |
696 |
|
|
// If at any point node::Stop() is called, the function will attempt to return |
697 |
|
|
// as soon as possible, returning an empty `Maybe`. |
698 |
|
|
// This function only works if `env` has an associated `MultiIsolatePlatform`. |
699 |
|
|
NODE_EXTERN v8::Maybe<int> SpinEventLoop(Environment* env); |
700 |
|
|
|
701 |
|
|
class NODE_EXTERN CommonEnvironmentSetup { |
702 |
|
|
public: |
703 |
|
|
~CommonEnvironmentSetup(); |
704 |
|
|
|
705 |
|
|
// Create a new CommonEnvironmentSetup, that is, a group of objects that |
706 |
|
|
// together form the typical setup for a single Node.js Environment instance. |
707 |
|
|
// If any error occurs, `*errors` will be populated and the returned pointer |
708 |
|
|
// will be empty. |
709 |
|
|
// env_args will be passed through as arguments to CreateEnvironment(), after |
710 |
|
|
// `isolate_data` and `context`. |
711 |
|
|
template <typename... EnvironmentArgs> |
712 |
|
|
static std::unique_ptr<CommonEnvironmentSetup> Create( |
713 |
|
|
MultiIsolatePlatform* platform, |
714 |
|
|
std::vector<std::string>* errors, |
715 |
|
|
EnvironmentArgs&&... env_args); |
716 |
|
|
|
717 |
|
|
struct uv_loop_s* event_loop() const; |
718 |
|
|
std::shared_ptr<ArrayBufferAllocator> array_buffer_allocator() const; |
719 |
|
|
v8::Isolate* isolate() const; |
720 |
|
|
IsolateData* isolate_data() const; |
721 |
|
|
Environment* env() const; |
722 |
|
|
v8::Local<v8::Context> context() const; |
723 |
|
|
|
724 |
|
|
CommonEnvironmentSetup(const CommonEnvironmentSetup&) = delete; |
725 |
|
|
CommonEnvironmentSetup& operator=(const CommonEnvironmentSetup&) = delete; |
726 |
|
|
CommonEnvironmentSetup(CommonEnvironmentSetup&&) = delete; |
727 |
|
|
CommonEnvironmentSetup& operator=(CommonEnvironmentSetup&&) = delete; |
728 |
|
|
|
729 |
|
|
private: |
730 |
|
|
struct Impl; |
731 |
|
|
Impl* impl_; |
732 |
|
|
CommonEnvironmentSetup( |
733 |
|
|
MultiIsolatePlatform*, |
734 |
|
|
std::vector<std::string>*, |
735 |
|
|
std::function<Environment*(const CommonEnvironmentSetup*)>); |
736 |
|
|
}; |
737 |
|
|
|
738 |
|
|
// Implementation for CommonEnvironmentSetup::Create |
739 |
|
|
template <typename... EnvironmentArgs> |
740 |
|
7 |
std::unique_ptr<CommonEnvironmentSetup> CommonEnvironmentSetup::Create( |
741 |
|
|
MultiIsolatePlatform* platform, |
742 |
|
|
std::vector<std::string>* errors, |
743 |
|
|
EnvironmentArgs&&... env_args) { |
744 |
|
7 |
auto ret = std::unique_ptr<CommonEnvironmentSetup>(new CommonEnvironmentSetup( |
745 |
|
|
platform, errors, |
746 |
|
7 |
[&](const CommonEnvironmentSetup* setup) -> Environment* { |
747 |
|
21 |
return CreateEnvironment( |
748 |
|
|
setup->isolate_data(), setup->context(), |
749 |
|
14 |
std::forward<EnvironmentArgs>(env_args)...); |
750 |
|
|
})); |
751 |
✗✓ |
7 |
if (!errors->empty()) ret.reset(); |
752 |
|
7 |
return ret; |
753 |
|
|
} |
754 |
|
|
|
755 |
|
|
/* Converts a unixtime to V8 Date */ |
756 |
|
|
NODE_DEPRECATED("Use v8::Date::New() directly", |
757 |
|
|
inline v8::Local<v8::Value> NODE_UNIXTIME_V8(double time) { |
758 |
|
|
return v8::Date::New( |
759 |
|
|
v8::Isolate::GetCurrent()->GetCurrentContext(), |
760 |
|
|
1000 * time) |
761 |
|
|
.ToLocalChecked(); |
762 |
|
|
}) |
763 |
|
|
#define NODE_UNIXTIME_V8 node::NODE_UNIXTIME_V8 |
764 |
|
|
NODE_DEPRECATED("Use v8::Date::ValueOf() directly", |
765 |
|
|
inline double NODE_V8_UNIXTIME(v8::Local<v8::Date> date) { |
766 |
|
|
return date->ValueOf() / 1000; |
767 |
|
|
}) |
768 |
|
|
#define NODE_V8_UNIXTIME node::NODE_V8_UNIXTIME |
769 |
|
|
|
770 |
|
|
#define NODE_DEFINE_CONSTANT(target, constant) \ |
771 |
|
|
do { \ |
772 |
|
|
v8::Isolate* isolate = target->GetIsolate(); \ |
773 |
|
|
v8::Local<v8::Context> context = isolate->GetCurrentContext(); \ |
774 |
|
|
v8::Local<v8::String> constant_name = \ |
775 |
|
|
v8::String::NewFromUtf8(isolate, #constant, \ |
776 |
|
|
v8::NewStringType::kInternalized).ToLocalChecked(); \ |
777 |
|
|
v8::Local<v8::Number> constant_value = \ |
778 |
|
|
v8::Number::New(isolate, static_cast<double>(constant)); \ |
779 |
|
|
v8::PropertyAttribute constant_attributes = \ |
780 |
|
|
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); \ |
781 |
|
|
(target)->DefineOwnProperty(context, \ |
782 |
|
|
constant_name, \ |
783 |
|
|
constant_value, \ |
784 |
|
|
constant_attributes).Check(); \ |
785 |
|
|
} \ |
786 |
|
|
while (0) |
787 |
|
|
|
788 |
|
|
#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \ |
789 |
|
|
do { \ |
790 |
|
|
v8::Isolate* isolate = target->GetIsolate(); \ |
791 |
|
|
v8::Local<v8::Context> context = isolate->GetCurrentContext(); \ |
792 |
|
|
v8::Local<v8::String> constant_name = \ |
793 |
|
|
v8::String::NewFromUtf8(isolate, #constant, \ |
794 |
|
|
v8::NewStringType::kInternalized) \ |
795 |
|
|
.ToLocalChecked(); \ |
796 |
|
|
v8::Local<v8::Number> constant_value = \ |
797 |
|
|
v8::Number::New(isolate, static_cast<double>(constant)); \ |
798 |
|
|
v8::PropertyAttribute constant_attributes = \ |
799 |
|
|
static_cast<v8::PropertyAttribute>(v8::ReadOnly | \ |
800 |
|
|
v8::DontDelete | \ |
801 |
|
|
v8::DontEnum); \ |
802 |
|
|
(target)->DefineOwnProperty(context, \ |
803 |
|
|
constant_name, \ |
804 |
|
|
constant_value, \ |
805 |
|
|
constant_attributes).Check(); \ |
806 |
|
|
} \ |
807 |
|
|
while (0) |
808 |
|
|
|
809 |
|
|
// Used to be a macro, hence the uppercase name. |
810 |
|
|
inline void NODE_SET_METHOD(v8::Local<v8::Template> recv, |
811 |
|
|
const char* name, |
812 |
|
|
v8::FunctionCallback callback) { |
813 |
|
|
v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
814 |
|
|
v8::HandleScope handle_scope(isolate); |
815 |
|
|
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate, |
816 |
|
|
callback); |
817 |
|
|
v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name, |
818 |
|
|
v8::NewStringType::kInternalized).ToLocalChecked(); |
819 |
|
|
t->SetClassName(fn_name); |
820 |
|
|
recv->Set(fn_name, t); |
821 |
|
|
} |
822 |
|
|
|
823 |
|
|
// Used to be a macro, hence the uppercase name. |
824 |
|
|
inline void NODE_SET_METHOD(v8::Local<v8::Object> recv, |
825 |
|
|
const char* name, |
826 |
|
|
v8::FunctionCallback callback) { |
827 |
|
|
v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
828 |
|
|
v8::HandleScope handle_scope(isolate); |
829 |
|
|
v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
830 |
|
|
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate, |
831 |
|
|
callback); |
832 |
|
|
v8::Local<v8::Function> fn = t->GetFunction(context).ToLocalChecked(); |
833 |
|
|
v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name, |
834 |
|
|
v8::NewStringType::kInternalized).ToLocalChecked(); |
835 |
|
|
fn->SetName(fn_name); |
836 |
|
|
recv->Set(context, fn_name, fn).Check(); |
837 |
|
|
} |
838 |
|
|
#define NODE_SET_METHOD node::NODE_SET_METHOD |
839 |
|
|
|
840 |
|
|
// Used to be a macro, hence the uppercase name. |
841 |
|
|
// Not a template because it only makes sense for FunctionTemplates. |
842 |
|
|
inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv, |
843 |
|
|
const char* name, |
844 |
|
|
v8::FunctionCallback callback) { |
845 |
|
|
v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
846 |
|
|
v8::HandleScope handle_scope(isolate); |
847 |
|
|
v8::Local<v8::Signature> s = v8::Signature::New(isolate, recv); |
848 |
|
|
v8::Local<v8::FunctionTemplate> t = |
849 |
|
|
v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), s); |
850 |
|
|
v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name, |
851 |
|
|
v8::NewStringType::kInternalized).ToLocalChecked(); |
852 |
|
|
t->SetClassName(fn_name); |
853 |
|
|
recv->PrototypeTemplate()->Set(fn_name, t); |
854 |
|
|
} |
855 |
|
|
#define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD |
856 |
|
|
|
857 |
|
|
// BINARY is a deprecated alias of LATIN1. |
858 |
|
|
// BASE64URL is not currently exposed to the JavaScript side. |
859 |
|
|
enum encoding { |
860 |
|
|
ASCII, |
861 |
|
|
UTF8, |
862 |
|
|
BASE64, |
863 |
|
|
UCS2, |
864 |
|
|
BINARY, |
865 |
|
|
HEX, |
866 |
|
|
BUFFER, |
867 |
|
|
BASE64URL, |
868 |
|
|
LATIN1 = BINARY |
869 |
|
|
}; |
870 |
|
|
|
871 |
|
|
NODE_EXTERN enum encoding ParseEncoding( |
872 |
|
|
v8::Isolate* isolate, |
873 |
|
|
v8::Local<v8::Value> encoding_v, |
874 |
|
|
enum encoding default_encoding = LATIN1); |
875 |
|
|
|
876 |
|
|
NODE_EXTERN void FatalException(v8::Isolate* isolate, |
877 |
|
|
const v8::TryCatch& try_catch); |
878 |
|
|
|
879 |
|
|
NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate, |
880 |
|
|
const char* buf, |
881 |
|
|
size_t len, |
882 |
|
|
enum encoding encoding = LATIN1); |
883 |
|
|
|
884 |
|
|
// Warning: This reverses endianness on Big Endian platforms, even though the |
885 |
|
|
// signature using uint16_t implies that it should not. |
886 |
|
|
NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate, |
887 |
|
|
const uint16_t* buf, |
888 |
|
|
size_t len); |
889 |
|
|
|
890 |
|
|
// Returns -1 if the handle was not valid for decoding |
891 |
|
|
NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate, |
892 |
|
|
v8::Local<v8::Value>, |
893 |
|
|
enum encoding encoding = LATIN1); |
894 |
|
|
// returns bytes written. |
895 |
|
|
NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate, |
896 |
|
|
char* buf, |
897 |
|
|
size_t buflen, |
898 |
|
|
v8::Local<v8::Value>, |
899 |
|
|
enum encoding encoding = LATIN1); |
900 |
|
|
#ifdef _WIN32 |
901 |
|
|
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException( |
902 |
|
|
v8::Isolate* isolate, |
903 |
|
|
int errorno, |
904 |
|
|
const char* syscall = nullptr, |
905 |
|
|
const char* msg = "", |
906 |
|
|
const char* path = nullptr); |
907 |
|
|
#endif |
908 |
|
|
|
909 |
|
|
const char* signo_string(int errorno); |
910 |
|
|
|
911 |
|
|
|
912 |
|
|
typedef void (*addon_register_func)( |
913 |
|
|
v8::Local<v8::Object> exports, |
914 |
|
|
v8::Local<v8::Value> module, |
915 |
|
|
void* priv); |
916 |
|
|
|
917 |
|
|
typedef void (*addon_context_register_func)( |
918 |
|
|
v8::Local<v8::Object> exports, |
919 |
|
|
v8::Local<v8::Value> module, |
920 |
|
|
v8::Local<v8::Context> context, |
921 |
|
|
void* priv); |
922 |
|
|
|
923 |
|
|
enum ModuleFlags { |
924 |
|
|
kLinked = 0x02 |
925 |
|
|
}; |
926 |
|
|
|
927 |
|
|
struct node_module { |
928 |
|
|
int nm_version; |
929 |
|
|
unsigned int nm_flags; |
930 |
|
|
void* nm_dso_handle; |
931 |
|
|
const char* nm_filename; |
932 |
|
|
node::addon_register_func nm_register_func; |
933 |
|
|
node::addon_context_register_func nm_context_register_func; |
934 |
|
|
const char* nm_modname; |
935 |
|
|
void* nm_priv; |
936 |
|
|
struct node_module* nm_link; |
937 |
|
|
}; |
938 |
|
|
|
939 |
|
|
extern "C" NODE_EXTERN void node_module_register(void* mod); |
940 |
|
|
|
941 |
|
|
#ifdef _WIN32 |
942 |
|
|
# define NODE_MODULE_EXPORT __declspec(dllexport) |
943 |
|
|
#else |
944 |
|
|
# define NODE_MODULE_EXPORT __attribute__((visibility("default"))) |
945 |
|
|
#endif |
946 |
|
|
|
947 |
|
|
#ifdef NODE_SHARED_MODE |
948 |
|
|
# define NODE_CTOR_PREFIX |
949 |
|
|
#else |
950 |
|
|
# define NODE_CTOR_PREFIX static |
951 |
|
|
#endif |
952 |
|
|
|
953 |
|
|
#if defined(_MSC_VER) |
954 |
|
|
#define NODE_C_CTOR(fn) \ |
955 |
|
|
NODE_CTOR_PREFIX void __cdecl fn(void); \ |
956 |
|
|
namespace { \ |
957 |
|
|
struct fn##_ { \ |
958 |
|
|
fn##_() { fn(); }; \ |
959 |
|
|
} fn##_v_; \ |
960 |
|
|
} \ |
961 |
|
|
NODE_CTOR_PREFIX void __cdecl fn(void) |
962 |
|
|
#else |
963 |
|
|
#define NODE_C_CTOR(fn) \ |
964 |
|
|
NODE_CTOR_PREFIX void fn(void) __attribute__((constructor)); \ |
965 |
|
|
NODE_CTOR_PREFIX void fn(void) |
966 |
|
|
#endif |
967 |
|
|
|
968 |
|
|
#define NODE_MODULE_X(modname, regfunc, priv, flags) \ |
969 |
|
|
extern "C" { \ |
970 |
|
|
static node::node_module _module = \ |
971 |
|
|
{ \ |
972 |
|
|
NODE_MODULE_VERSION, \ |
973 |
|
|
flags, \ |
974 |
|
|
NULL, /* NOLINT (readability/null_usage) */ \ |
975 |
|
|
__FILE__, \ |
976 |
|
|
(node::addon_register_func) (regfunc), \ |
977 |
|
|
NULL, /* NOLINT (readability/null_usage) */ \ |
978 |
|
|
NODE_STRINGIFY(modname), \ |
979 |
|
|
priv, \ |
980 |
|
|
NULL /* NOLINT (readability/null_usage) */ \ |
981 |
|
|
}; \ |
982 |
|
|
NODE_C_CTOR(_register_ ## modname) { \ |
983 |
|
|
node_module_register(&_module); \ |
984 |
|
|
} \ |
985 |
|
|
} |
986 |
|
|
|
987 |
|
|
#define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags) \ |
988 |
|
|
extern "C" { \ |
989 |
|
|
static node::node_module _module = \ |
990 |
|
|
{ \ |
991 |
|
|
NODE_MODULE_VERSION, \ |
992 |
|
|
flags, \ |
993 |
|
|
NULL, /* NOLINT (readability/null_usage) */ \ |
994 |
|
|
__FILE__, \ |
995 |
|
|
NULL, /* NOLINT (readability/null_usage) */ \ |
996 |
|
|
(node::addon_context_register_func) (regfunc), \ |
997 |
|
|
NODE_STRINGIFY(modname), \ |
998 |
|
|
priv, \ |
999 |
|
|
NULL /* NOLINT (readability/null_usage) */ \ |
1000 |
|
|
}; \ |
1001 |
|
|
NODE_C_CTOR(_register_ ## modname) { \ |
1002 |
|
|
node_module_register(&_module); \ |
1003 |
|
|
} \ |
1004 |
|
|
} |
1005 |
|
|
|
1006 |
|
|
// Usage: `NODE_MODULE(NODE_GYP_MODULE_NAME, InitializerFunction)` |
1007 |
|
|
// If no NODE_MODULE is declared, Node.js looks for the well-known |
1008 |
|
|
// symbol `node_register_module_v${NODE_MODULE_VERSION}`. |
1009 |
|
|
#define NODE_MODULE(modname, regfunc) \ |
1010 |
|
|
NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage) |
1011 |
|
|
|
1012 |
|
|
#define NODE_MODULE_CONTEXT_AWARE(modname, regfunc) \ |
1013 |
|
|
/* NOLINTNEXTLINE (readability/null_usage) */ \ |
1014 |
|
|
NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0) |
1015 |
|
|
|
1016 |
|
|
// Embedders can use this type of binding for statically linked native bindings. |
1017 |
|
|
// It is used the same way addon bindings are used, except that linked bindings |
1018 |
|
|
// can be accessed through `process._linkedBinding(modname)`. |
1019 |
|
|
#define NODE_MODULE_LINKED(modname, regfunc) \ |
1020 |
|
|
/* NOLINTNEXTLINE (readability/null_usage) */ \ |
1021 |
|
|
NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, \ |
1022 |
|
|
node::ModuleFlags::kLinked) |
1023 |
|
|
|
1024 |
|
|
/* |
1025 |
|
|
* For backward compatibility in add-on modules. |
1026 |
|
|
*/ |
1027 |
|
|
#define NODE_MODULE_DECL /* nothing */ |
1028 |
|
|
|
1029 |
|
|
#define NODE_MODULE_INITIALIZER_BASE node_register_module_v |
1030 |
|
|
|
1031 |
|
|
#define NODE_MODULE_INITIALIZER_X(base, version) \ |
1032 |
|
|
NODE_MODULE_INITIALIZER_X_HELPER(base, version) |
1033 |
|
|
|
1034 |
|
|
#define NODE_MODULE_INITIALIZER_X_HELPER(base, version) base##version |
1035 |
|
|
|
1036 |
|
|
#define NODE_MODULE_INITIALIZER \ |
1037 |
|
|
NODE_MODULE_INITIALIZER_X(NODE_MODULE_INITIALIZER_BASE, \ |
1038 |
|
|
NODE_MODULE_VERSION) |
1039 |
|
|
|
1040 |
|
|
#define NODE_MODULE_INIT() \ |
1041 |
|
|
extern "C" NODE_MODULE_EXPORT void \ |
1042 |
|
|
NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports, \ |
1043 |
|
|
v8::Local<v8::Value> module, \ |
1044 |
|
|
v8::Local<v8::Context> context); \ |
1045 |
|
|
NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, \ |
1046 |
|
|
NODE_MODULE_INITIALIZER) \ |
1047 |
|
|
void NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports, \ |
1048 |
|
|
v8::Local<v8::Value> module, \ |
1049 |
|
|
v8::Local<v8::Context> context) |
1050 |
|
|
|
1051 |
|
|
// Allows embedders to add a binding to the current Environment* that can be |
1052 |
|
|
// accessed through process._linkedBinding() in the target Environment and all |
1053 |
|
|
// Worker threads that it creates. |
1054 |
|
|
// In each variant, the registration function needs to be usable at least for |
1055 |
|
|
// the time during which the Environment exists. |
1056 |
|
|
NODE_EXTERN void AddLinkedBinding(Environment* env, const node_module& mod); |
1057 |
|
|
NODE_EXTERN void AddLinkedBinding(Environment* env, |
1058 |
|
|
const struct napi_module& mod); |
1059 |
|
|
NODE_EXTERN void AddLinkedBinding(Environment* env, |
1060 |
|
|
const char* name, |
1061 |
|
|
addon_context_register_func fn, |
1062 |
|
|
void* priv); |
1063 |
|
|
|
1064 |
|
|
/* Registers a callback with the passed-in Environment instance. The callback |
1065 |
|
|
* is called after the event loop exits, but before the VM is disposed. |
1066 |
|
|
* Callbacks are run in reverse order of registration, i.e. newest first. |
1067 |
|
|
*/ |
1068 |
|
|
NODE_EXTERN void AtExit(Environment* env, |
1069 |
|
|
void (*cb)(void* arg), |
1070 |
|
|
void* arg); |
1071 |
|
|
|
1072 |
|
|
typedef double async_id; |
1073 |
|
|
struct async_context { |
1074 |
|
|
::node::async_id async_id; |
1075 |
|
|
::node::async_id trigger_async_id; |
1076 |
|
|
}; |
1077 |
|
|
|
1078 |
|
|
/* This is a lot like node::AtExit, except that the hooks added via this |
1079 |
|
|
* function are run before the AtExit ones and will always be registered |
1080 |
|
|
* for the current Environment instance. |
1081 |
|
|
* These functions are safe to use in an addon supporting multiple |
1082 |
|
|
* threads/isolates. */ |
1083 |
|
|
NODE_EXTERN void AddEnvironmentCleanupHook(v8::Isolate* isolate, |
1084 |
|
|
void (*fun)(void* arg), |
1085 |
|
|
void* arg); |
1086 |
|
|
|
1087 |
|
|
NODE_EXTERN void RemoveEnvironmentCleanupHook(v8::Isolate* isolate, |
1088 |
|
|
void (*fun)(void* arg), |
1089 |
|
|
void* arg); |
1090 |
|
|
|
1091 |
|
|
/* These are async equivalents of the above. After the cleanup hook is invoked, |
1092 |
|
|
* `cb(cbarg)` *must* be called, and attempting to remove the cleanup hook will |
1093 |
|
|
* have no effect. */ |
1094 |
|
|
struct ACHHandle; |
1095 |
|
|
struct NODE_EXTERN DeleteACHHandle { void operator()(ACHHandle*) const; }; |
1096 |
|
|
typedef std::unique_ptr<ACHHandle, DeleteACHHandle> AsyncCleanupHookHandle; |
1097 |
|
|
|
1098 |
|
|
/* This function is not intended to be used externally, it exists to aid in |
1099 |
|
|
* keeping ABI compatibility between Node and Electron. */ |
1100 |
|
|
NODE_EXTERN ACHHandle* AddEnvironmentCleanupHookInternal( |
1101 |
|
|
v8::Isolate* isolate, |
1102 |
|
|
void (*fun)(void* arg, void (*cb)(void*), void* cbarg), |
1103 |
|
|
void* arg); |
1104 |
|
6 |
inline AsyncCleanupHookHandle AddEnvironmentCleanupHook( |
1105 |
|
|
v8::Isolate* isolate, |
1106 |
|
|
void (*fun)(void* arg, void (*cb)(void*), void* cbarg), |
1107 |
|
|
void* arg) { |
1108 |
|
|
return AsyncCleanupHookHandle(AddEnvironmentCleanupHookInternal(isolate, fun, |
1109 |
|
6 |
arg)); |
1110 |
|
|
} |
1111 |
|
|
|
1112 |
|
|
/* This function is not intended to be used externally, it exists to aid in |
1113 |
|
|
* keeping ABI compatibility between Node and Electron. */ |
1114 |
|
|
NODE_EXTERN void RemoveEnvironmentCleanupHookInternal(ACHHandle* holder); |
1115 |
|
6 |
inline void RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle holder) { |
1116 |
|
6 |
RemoveEnvironmentCleanupHookInternal(holder.get()); |
1117 |
|
6 |
} |
1118 |
|
|
|
1119 |
|
|
// This behaves like V8's Isolate::RequestInterrupt(), but also wakes up |
1120 |
|
|
// the event loop if it is currently idle. Interrupt requests are drained |
1121 |
|
|
// in `FreeEnvironment()`. The passed callback can not call back into |
1122 |
|
|
// JavaScript. |
1123 |
|
|
// This function can be called from any thread. |
1124 |
|
|
NODE_EXTERN void RequestInterrupt(Environment* env, |
1125 |
|
|
void (*fun)(void* arg), |
1126 |
|
|
void* arg); |
1127 |
|
|
|
1128 |
|
|
/* Returns the id of the current execution context. If the return value is |
1129 |
|
|
* zero then no execution has been set. This will happen if the user handles |
1130 |
|
|
* I/O from native code. */ |
1131 |
|
|
NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate); |
1132 |
|
|
|
1133 |
|
|
/* Return same value as async_hooks.triggerAsyncId(); */ |
1134 |
|
|
NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate); |
1135 |
|
|
|
1136 |
|
|
/* If the native API doesn't inherit from the helper class then the callbacks |
1137 |
|
|
* must be triggered manually. This triggers the init() callback. The return |
1138 |
|
|
* value is the async id assigned to the resource. |
1139 |
|
|
* |
1140 |
|
|
* The `trigger_async_id` parameter should correspond to the resource which is |
1141 |
|
|
* creating the new resource, which will usually be the return value of |
1142 |
|
|
* `AsyncHooksGetTriggerAsyncId()`. */ |
1143 |
|
|
NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate, |
1144 |
|
|
v8::Local<v8::Object> resource, |
1145 |
|
|
const char* name, |
1146 |
|
|
async_id trigger_async_id = -1); |
1147 |
|
|
|
1148 |
|
|
NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate, |
1149 |
|
|
v8::Local<v8::Object> resource, |
1150 |
|
|
v8::Local<v8::String> name, |
1151 |
|
|
async_id trigger_async_id = -1); |
1152 |
|
|
|
1153 |
|
|
/* Emit the destroy() callback. The overload taking an `Environment*` argument |
1154 |
|
|
* should be used when the Isolate’s current Context is not associated with |
1155 |
|
|
* a Node.js Environment, or when there is no current Context, for example |
1156 |
|
|
* when calling this function during garbage collection. In that case, the |
1157 |
|
|
* `Environment*` value should have been acquired previously, e.g. through |
1158 |
|
|
* `GetCurrentEnvironment()`. */ |
1159 |
|
|
NODE_EXTERN void EmitAsyncDestroy(v8::Isolate* isolate, |
1160 |
|
|
async_context asyncContext); |
1161 |
|
|
NODE_EXTERN void EmitAsyncDestroy(Environment* env, |
1162 |
|
|
async_context asyncContext); |
1163 |
|
|
|
1164 |
|
|
class InternalCallbackScope; |
1165 |
|
|
|
1166 |
|
|
/* This class works like `MakeCallback()` in that it sets up a specific |
1167 |
|
|
* asyncContext as the current one and informs the async_hooks and domains |
1168 |
|
|
* modules that this context is currently active. |
1169 |
|
|
* |
1170 |
|
|
* `MakeCallback()` is a wrapper around this class as well as |
1171 |
|
|
* `Function::Call()`. Either one of these mechanisms needs to be used for |
1172 |
|
|
* top-level calls into JavaScript (i.e. without any existing JS stack). |
1173 |
|
|
* |
1174 |
|
|
* This object should be stack-allocated to ensure that it is contained in a |
1175 |
|
|
* valid HandleScope. |
1176 |
|
|
* |
1177 |
|
|
* Exceptions happening within this scope will be treated like uncaught |
1178 |
|
|
* exceptions. If this behaviour is undesirable, a new `v8::TryCatch` scope |
1179 |
|
|
* needs to be created inside of this scope. |
1180 |
|
|
*/ |
1181 |
|
|
class NODE_EXTERN CallbackScope { |
1182 |
|
|
public: |
1183 |
|
|
CallbackScope(v8::Isolate* isolate, |
1184 |
|
|
v8::Local<v8::Object> resource, |
1185 |
|
|
async_context asyncContext); |
1186 |
|
|
CallbackScope(Environment* env, |
1187 |
|
|
v8::Local<v8::Object> resource, |
1188 |
|
|
async_context asyncContext); |
1189 |
|
|
~CallbackScope(); |
1190 |
|
|
|
1191 |
|
|
void operator=(const CallbackScope&) = delete; |
1192 |
|
|
void operator=(CallbackScope&&) = delete; |
1193 |
|
|
CallbackScope(const CallbackScope&) = delete; |
1194 |
|
|
CallbackScope(CallbackScope&&) = delete; |
1195 |
|
|
|
1196 |
|
|
private: |
1197 |
|
|
InternalCallbackScope* private_; |
1198 |
|
|
v8::TryCatch try_catch_; |
1199 |
|
|
}; |
1200 |
|
|
|
1201 |
|
|
/* An API specific to emit before/after callbacks is unnecessary because |
1202 |
|
|
* MakeCallback will automatically call them for you. |
1203 |
|
|
* |
1204 |
|
|
* These methods may create handles on their own, so run them inside a |
1205 |
|
|
* HandleScope. |
1206 |
|
|
* |
1207 |
|
|
* `asyncId` and `triggerAsyncId` should correspond to the values returned by |
1208 |
|
|
* `EmitAsyncInit()` and `AsyncHooksGetTriggerAsyncId()`, respectively, when the |
1209 |
|
|
* invoking resource was created. If these values are unknown, 0 can be passed. |
1210 |
|
|
* */ |
1211 |
|
|
NODE_EXTERN |
1212 |
|
|
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate, |
1213 |
|
|
v8::Local<v8::Object> recv, |
1214 |
|
|
v8::Local<v8::Function> callback, |
1215 |
|
|
int argc, |
1216 |
|
|
v8::Local<v8::Value>* argv, |
1217 |
|
|
async_context asyncContext); |
1218 |
|
|
NODE_EXTERN |
1219 |
|
|
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate, |
1220 |
|
|
v8::Local<v8::Object> recv, |
1221 |
|
|
const char* method, |
1222 |
|
|
int argc, |
1223 |
|
|
v8::Local<v8::Value>* argv, |
1224 |
|
|
async_context asyncContext); |
1225 |
|
|
NODE_EXTERN |
1226 |
|
|
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate, |
1227 |
|
|
v8::Local<v8::Object> recv, |
1228 |
|
|
v8::Local<v8::String> symbol, |
1229 |
|
|
int argc, |
1230 |
|
|
v8::Local<v8::Value>* argv, |
1231 |
|
|
async_context asyncContext); |
1232 |
|
|
|
1233 |
|
|
/* Helper class users can optionally inherit from. If |
1234 |
|
|
* `AsyncResource::MakeCallback()` is used, then all four callbacks will be |
1235 |
|
|
* called automatically. */ |
1236 |
|
|
class NODE_EXTERN AsyncResource { |
1237 |
|
|
public: |
1238 |
|
|
AsyncResource(v8::Isolate* isolate, |
1239 |
|
|
v8::Local<v8::Object> resource, |
1240 |
|
|
const char* name, |
1241 |
|
|
async_id trigger_async_id = -1); |
1242 |
|
|
|
1243 |
|
|
virtual ~AsyncResource(); |
1244 |
|
|
|
1245 |
|
|
AsyncResource(const AsyncResource&) = delete; |
1246 |
|
|
void operator=(const AsyncResource&) = delete; |
1247 |
|
|
|
1248 |
|
|
v8::MaybeLocal<v8::Value> MakeCallback( |
1249 |
|
|
v8::Local<v8::Function> callback, |
1250 |
|
|
int argc, |
1251 |
|
|
v8::Local<v8::Value>* argv); |
1252 |
|
|
|
1253 |
|
|
v8::MaybeLocal<v8::Value> MakeCallback( |
1254 |
|
|
const char* method, |
1255 |
|
|
int argc, |
1256 |
|
|
v8::Local<v8::Value>* argv); |
1257 |
|
|
|
1258 |
|
|
v8::MaybeLocal<v8::Value> MakeCallback( |
1259 |
|
|
v8::Local<v8::String> symbol, |
1260 |
|
|
int argc, |
1261 |
|
|
v8::Local<v8::Value>* argv); |
1262 |
|
|
|
1263 |
|
|
v8::Local<v8::Object> get_resource(); |
1264 |
|
|
async_id get_async_id() const; |
1265 |
|
|
async_id get_trigger_async_id() const; |
1266 |
|
|
|
1267 |
|
|
protected: |
1268 |
|
|
class NODE_EXTERN CallbackScope : public node::CallbackScope { |
1269 |
|
|
public: |
1270 |
|
|
explicit CallbackScope(AsyncResource* res); |
1271 |
|
|
}; |
1272 |
|
|
|
1273 |
|
|
private: |
1274 |
|
|
Environment* env_; |
1275 |
|
|
v8::Global<v8::Object> resource_; |
1276 |
|
|
async_context async_context_; |
1277 |
|
|
}; |
1278 |
|
|
|
1279 |
|
|
#ifndef _WIN32 |
1280 |
|
|
// Register a signal handler without interrupting any handlers that node |
1281 |
|
|
// itself needs. This does override handlers registered through |
1282 |
|
|
// process.on('SIG...', function() { ... }). The `reset_handler` flag indicates |
1283 |
|
|
// whether the signal handler for the given signal should be reset to its |
1284 |
|
|
// default value before executing the handler (i.e. it works like SA_RESETHAND). |
1285 |
|
|
// The `reset_handler` flag is invalid when `signal` is SIGSEGV. |
1286 |
|
|
NODE_EXTERN |
1287 |
|
|
void RegisterSignalHandler(int signal, |
1288 |
|
|
void (*handler)(int signal, |
1289 |
|
|
siginfo_t* info, |
1290 |
|
|
void* ucontext), |
1291 |
|
|
bool reset_handler = false); |
1292 |
|
|
#endif // _WIN32 |
1293 |
|
|
|
1294 |
|
|
} // namespace node |
1295 |
|
|
|
1296 |
|
|
#endif // SRC_NODE_H_ |