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