Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/node/node.h
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 SIGQUIT 3 71 #define SIGKILL 9 72 #endif 73 74 #include "v8.h" // NOLINT(build/include_order) 75 76 #include "v8-platform.h" // NOLINT(build/include_order) 77 #include "node_version.h" // NODE_MODULE_VERSION 78 79 #include "node_api.h" 80 81 #include <functional> 82 #include <memory> 83 #include <optional> 84 #include <ostream> 85 86 // We cannot use __POSIX__ in this header because that's only defined when 87 // building Node.js. 88 #ifndef _WIN32 89 #include <signal.h> 90 #endif // _WIN32 91 92 #define NODE_MAKE_VERSION(major, minor, patch) \ 93 ((major) * 0x1000 + (minor) * 0x100 + (patch)) 94 95 #ifdef __clang__ 96 # define NODE_CLANG_AT_LEAST(major, minor, patch) \ 97 (NODE_MAKE_VERSION(major, minor, patch) <= \ 98 NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)) 99 #else 100 # define NODE_CLANG_AT_LEAST(major, minor, patch) (0) 101 #endif 102 103 #ifdef __GNUC__ 104 # define NODE_GNUC_AT_LEAST(major, minor, patch) \ 105 (NODE_MAKE_VERSION(major, minor, patch) <= \ 106 NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)) 107 #else 108 # define NODE_GNUC_AT_LEAST(major, minor, patch) (0) 109 #endif 110 111 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 112 # define NODE_DEPRECATED(message, declarator) declarator 113 #else // NODE_WANT_INTERNALS 114 # if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0) 115 # define NODE_DEPRECATED(message, declarator) \ 116 __attribute__((deprecated(message))) declarator 117 # elif defined(_MSC_VER) 118 # define NODE_DEPRECATED(message, declarator) \ 119 __declspec(deprecated) declarator 120 # else 121 # define NODE_DEPRECATED(message, declarator) declarator 122 # endif 123 #endif 124 125 // Forward-declare libuv loop 126 struct uv_loop_s; 127 128 // Forward-declare these functions now to stop MSVS from becoming 129 // terminally confused when it's done in node_internals.h 130 namespace node { 131 132 struct SnapshotData; 133 134 namespace tracing { 135 136 class TracingController; 137 138 } 139 140 NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate, 141 int errorno, 142 const char* syscall = nullptr, 143 const char* message = nullptr, 144 const char* path = nullptr); 145 NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate, 146 int errorno, 147 const char* syscall = nullptr, 148 const char* message = nullptr, 149 const char* path = nullptr, 150 const char* dest = nullptr); 151 152 NODE_DEPRECATED("Use ErrnoException(isolate, ...)", 153 inline v8::Local<v8::Value> ErrnoException( 154 int errorno, 155 const char* syscall = nullptr, 156 const char* message = nullptr, 157 const char* path = nullptr) { 158 return ErrnoException(v8::Isolate::GetCurrent(), 159 errorno, 160 syscall, 161 message, 162 path); 163 }) 164 165 NODE_DEPRECATED("Use UVException(isolate, ...)", 166 inline v8::Local<v8::Value> UVException(int errorno, 167 const char* syscall = nullptr, 168 const char* message = nullptr, 169 const char* path = nullptr) { 170 return UVException(v8::Isolate::GetCurrent(), 171 errorno, 172 syscall, 173 message, 174 path); 175 }) 176 177 /* 178 * These methods need to be called in a HandleScope. 179 * 180 * It is preferred that you use the `MakeCallback` overloads taking 181 * `async_context` arguments. 182 */ 183 184 NODE_DEPRECATED("Use MakeCallback(..., async_context)", 185 NODE_EXTERN v8::Local<v8::Value> MakeCallback( 186 v8::Isolate* isolate, 187 v8::Local<v8::Object> recv, 188 const char* method, 189 int argc, 190 v8::Local<v8::Value>* argv)); 191 NODE_DEPRECATED("Use MakeCallback(..., async_context)", 192 NODE_EXTERN v8::Local<v8::Value> MakeCallback( 193 v8::Isolate* isolate, 194 v8::Local<v8::Object> recv, 195 v8::Local<v8::String> symbol, 196 int argc, 197 v8::Local<v8::Value>* argv)); 198 NODE_DEPRECATED("Use MakeCallback(..., async_context)", 199 NODE_EXTERN v8::Local<v8::Value> MakeCallback( 200 v8::Isolate* isolate, 201 v8::Local<v8::Object> recv, 202 v8::Local<v8::Function> callback, 203 int argc, 204 v8::Local<v8::Value>* argv)); 205 206 } // namespace node 207 208 #include <cassert> 209 #include <cstdint> 210 211 #ifndef NODE_STRINGIFY 212 # define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) 213 # define NODE_STRINGIFY_HELPER(n) #n 214 #endif 215 216 #ifdef _WIN32 217 #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) 218 typedef intptr_t ssize_t; 219 # define _SSIZE_T_ 220 # define _SSIZE_T_DEFINED 221 #endif 222 #else // !_WIN32 223 # include <sys/types.h> // size_t, ssize_t 224 #endif // _WIN32 225 226 227 namespace node { 228 229 class IsolateData; 230 class Environment; 231 class MultiIsolatePlatform; 232 class InitializationResultImpl; 233 234 namespace ProcessInitializationFlags { 235 enum Flags : uint32_t { 236 kNoFlags = 0, 237 // Enable stdio inheritance, which is disabled by default. 238 // This flag is also implied by kNoStdioInitialization. 239 kEnableStdioInheritance = 1 << 0, 240 // Disable reading the NODE_OPTIONS environment variable. 241 kDisableNodeOptionsEnv = 1 << 1, 242 // Do not parse CLI options. 243 kDisableCLIOptions = 1 << 2, 244 // Do not initialize ICU. 245 kNoICU = 1 << 3, 246 // Do not modify stdio file descriptor or TTY state. 247 kNoStdioInitialization = 1 << 4, 248 // Do not register Node.js-specific signal handlers 249 // and reset other signal handlers to default state. 250 kNoDefaultSignalHandling = 1 << 5, 251 // Do not perform V8 initialization. 252 kNoInitializeV8 = 1 << 6, 253 // Do not initialize a default Node.js-provided V8 platform instance. 254 kNoInitializeNodeV8Platform = 1 << 7, 255 // Do not initialize OpenSSL config. 256 kNoInitOpenSSL = 1 << 8, 257 // Do not initialize Node.js debugging based on environment variables. 258 kNoParseGlobalDebugVariables = 1 << 9, 259 // Do not adjust OS resource limits for this process. 260 kNoAdjustResourceLimits = 1 << 10, 261 // Do not map code segments into large pages for this process. 262 kNoUseLargePages = 1 << 11, 263 // Skip printing output for --help, --version, --v8-options. 264 kNoPrintHelpOrVersionOutput = 1 << 12, 265 // Do not perform cppgc initialization. If set, the embedder must call 266 // cppgc::InitializeProcess() before creating a Node.js environment 267 // and call cppgc::ShutdownProcess() before process shutdown. 268 kNoInitializeCppgc = 1 << 13, 269 // Initialize the process for predictable snapshot generation. 270 kGeneratePredictableSnapshot = 1 << 14, 271 272 // Emulate the behavior of InitializeNodeWithArgs() when passing 273 // a flags argument to the InitializeOncePerProcess() replacement 274 // function. 275 kLegacyInitializeNodeWithArgsBehavior = 276 kNoStdioInitialization | kNoDefaultSignalHandling | kNoInitializeV8 | 277 kNoInitializeNodeV8Platform | kNoInitOpenSSL | 278 kNoParseGlobalDebugVariables | kNoAdjustResourceLimits | 279 kNoUseLargePages | kNoPrintHelpOrVersionOutput | kNoInitializeCppgc, 280 }; 281 } // namespace ProcessInitializationFlags 282 namespace ProcessFlags = ProcessInitializationFlags; // Legacy alias. 283 284 namespace StopFlags { 285 enum Flags : uint32_t { 286 kNoFlags = 0, 287 // Do not explicitly terminate the Isolate 288 // when exiting the Environment. 289 kDoNotTerminateIsolate = 1 << 0, 290 }; 291 } // namespace StopFlags 292 293 class NODE_EXTERN InitializationResult { 294 public: 295 virtual ~InitializationResult() = default; 296 297 // Returns a suggested process exit code. 298 virtual int exit_code() const = 0; 299 300 // Returns 'true' if initialization was aborted early due to errors. 301 virtual bool early_return() const = 0; 302 303 // Returns the parsed list of non-Node.js arguments. 304 virtual const std::vector<std::string>& args() const = 0; 305 306 // Returns the parsed list of Node.js arguments. 307 virtual const std::vector<std::string>& exec_args() const = 0; 308 309 // Returns an array of errors. Note that these may be warnings 310 // whose existence does not imply a non-zero exit code. 311 virtual const std::vector<std::string>& errors() const = 0; 312 313 // If kNoInitializeNodeV8Platform was not specified, the global Node.js 314 // platform instance. 315 virtual MultiIsolatePlatform* platform() const = 0; 316 317 private: 318 InitializationResult() = default; 319 friend class InitializationResultImpl; 320 }; 321 322 // TODO(addaleax): Officially deprecate this and replace it with something 323 // better suited for a public embedder API. 324 NODE_EXTERN int Start(int argc, char* argv[]); 325 326 // Tear down Node.js while it is running (there are active handles 327 // in the loop and / or actively executing JavaScript code). 328 NODE_EXTERN int Stop(Environment* env, 329 StopFlags::Flags flags = StopFlags::kNoFlags); 330 331 // Set up per-process state needed to run Node.js. This will consume arguments 332 // from argv, fill exec_argv, and possibly add errors resulting from parsing 333 // the arguments to `errors`. The return value is a suggested exit code for the 334 // program; If it is 0, then initializing Node.js succeeded. 335 // This runs a subset of the initialization performed by 336 // InitializeOncePerProcess(), which supersedes this function. 337 // The subset is roughly equivalent to the one given by 338 // `ProcessInitializationFlags::kLegacyInitializeNodeWithArgsBehavior`. 339 NODE_DEPRECATED("Use InitializeOncePerProcess() instead", 340 NODE_EXTERN int InitializeNodeWithArgs( 341 std::vector<std::string>* argv, 342 std::vector<std::string>* exec_argv, 343 std::vector<std::string>* errors, 344 ProcessInitializationFlags::Flags flags = 345 ProcessInitializationFlags::kNoFlags)); 346 347 // Set up per-process state needed to run Node.js. This will consume arguments 348 // from args, and return information about the initialization success, 349 // including the arguments split into argv/exec_argv, a list of potential 350 // errors encountered during initialization, and a potential suggested 351 // exit code. 352 NODE_EXTERN std::shared_ptr<InitializationResult> InitializeOncePerProcess( 353 const std::vector<std::string>& args, 354 ProcessInitializationFlags::Flags flags = 355 ProcessInitializationFlags::kNoFlags); 356 // Undoes the initialization performed by InitializeOncePerProcess(), 357 // where cleanup is necessary. 358 NODE_EXTERN void TearDownOncePerProcess(); 359 // Convenience overload for specifying multiple flags without having 360 // to worry about casts. 361 inline std::shared_ptr<InitializationResult> InitializeOncePerProcess( 362 const std::vector<std::string>& args, 363 std::initializer_list<ProcessInitializationFlags::Flags> list) { 364 uint64_t flags_accum = ProcessInitializationFlags::kNoFlags; 365 for (const auto flag : list) flags_accum |= static_cast<uint64_t>(flag); 366 return InitializeOncePerProcess( 367 args, static_cast<ProcessInitializationFlags::Flags>(flags_accum)); 368 } 369 370 enum OptionEnvvarSettings { 371 // Allow the options to be set via the environment variable, like 372 // `NODE_OPTIONS`. 373 kAllowedInEnvvar = 0, 374 // Disallow the options to be set via the environment variable, like 375 // `NODE_OPTIONS`. 376 kDisallowedInEnvvar = 1, 377 // Deprecated, use kAllowedInEnvvar instead. 378 kAllowedInEnvironment = kAllowedInEnvvar, 379 // Deprecated, use kDisallowedInEnvvar instead. 380 kDisallowedInEnvironment = kDisallowedInEnvvar, 381 }; 382 383 // Process the arguments and set up the per-process options. 384 // If the `settings` is set as OptionEnvvarSettings::kAllowedInEnvvar, the 385 // options that are allowed in the environment variable are processed. Options 386 // that are disallowed to be set via environment variable are processed as 387 // errors. 388 // Otherwise all the options that are disallowed (and those are allowed) to be 389 // set via environment variable are processed. 390 NODE_EXTERN int ProcessGlobalArgs(std::vector<std::string>* args, 391 std::vector<std::string>* exec_args, 392 std::vector<std::string>* errors, 393 OptionEnvvarSettings settings); 394 395 class NodeArrayBufferAllocator; 396 397 // An ArrayBuffer::Allocator class with some Node.js-specific tweaks. If you do 398 // not have to use another allocator, using this class is recommended: 399 // - It supports Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() with 400 // uninitialized memory. 401 // - It supports transferring, rather than copying, ArrayBuffers when using 402 // MessagePorts. 403 class NODE_EXTERN ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { 404 public: 405 // If `always_debug` is true, create an ArrayBuffer::Allocator instance 406 // that performs additional integrity checks (e.g. make sure that only memory 407 // that was allocated by the it is also freed by it). 408 // This can also be set using the --debug-arraybuffer-allocations flag. 409 static std::unique_ptr<ArrayBufferAllocator> Create( 410 bool always_debug = false); 411 412 private: 413 virtual NodeArrayBufferAllocator* GetImpl() = 0; 414 415 friend class IsolateData; 416 }; 417 418 // Legacy equivalents for ArrayBufferAllocator::Create(). 419 NODE_EXTERN ArrayBufferAllocator* CreateArrayBufferAllocator(); 420 NODE_EXTERN void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator); 421 422 class NODE_EXTERN IsolatePlatformDelegate { 423 public: 424 virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner() = 0; 425 virtual bool IdleTasksEnabled() = 0; 426 }; 427 428 class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { 429 public: 430 ~MultiIsolatePlatform() override = default; 431 // Returns true if work was dispatched or executed. New tasks that are 432 // posted during flushing of the queue are postponed until the next 433 // flushing. 434 virtual bool FlushForegroundTasks(v8::Isolate* isolate) = 0; 435 virtual void DrainTasks(v8::Isolate* isolate) = 0; 436 437 // This needs to be called between the calls to `Isolate::Allocate()` and 438 // `Isolate::Initialize()`, so that initialization can already start 439 // using the platform. 440 // When using `NewIsolate()`, this is taken care of by that function. 441 // This function may only be called once per `Isolate`. 442 virtual void RegisterIsolate(v8::Isolate* isolate, 443 struct uv_loop_s* loop) = 0; 444 // This method can be used when an application handles task scheduling on its 445 // own through `IsolatePlatformDelegate`. Upon registering an isolate with 446 // this overload any other method in this class with the exception of 447 // `UnregisterIsolate` *must not* be used on that isolate. 448 virtual void RegisterIsolate(v8::Isolate* isolate, 449 IsolatePlatformDelegate* delegate) = 0; 450 451 // This function may only be called once per `Isolate`, and discard any 452 // pending delayed tasks scheduled for that isolate. 453 // This needs to be called right before calling `Isolate::Dispose()`. 454 virtual void UnregisterIsolate(v8::Isolate* isolate) = 0; 455 456 // The platform should call the passed function once all state associated 457 // with the given isolate has been cleaned up. This can, but does not have to, 458 // happen asynchronously. 459 virtual void AddIsolateFinishedCallback(v8::Isolate* isolate, 460 void (*callback)(void*), 461 void* data) = 0; 462 463 static std::unique_ptr<MultiIsolatePlatform> Create( 464 int thread_pool_size, 465 v8::TracingController* tracing_controller = nullptr, 466 v8::PageAllocator* page_allocator = nullptr); 467 }; 468 469 enum IsolateSettingsFlags { 470 MESSAGE_LISTENER_WITH_ERROR_LEVEL = 1 << 0, 471 DETAILED_SOURCE_POSITIONS_FOR_PROFILING = 1 << 1, 472 SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK = 1 << 2, 473 SHOULD_NOT_SET_PREPARE_STACK_TRACE_CALLBACK = 1 << 3, 474 ALLOW_MODIFY_CODE_GENERATION_FROM_STRINGS_CALLBACK = 0, /* legacy no-op */ 475 }; 476 477 struct IsolateSettings { 478 uint64_t flags = MESSAGE_LISTENER_WITH_ERROR_LEVEL | 479 DETAILED_SOURCE_POSITIONS_FOR_PROFILING; 480 v8::MicrotasksPolicy policy = v8::MicrotasksPolicy::kExplicit; 481 482 // Error handling callbacks 483 v8::Isolate::AbortOnUncaughtExceptionCallback 484 should_abort_on_uncaught_exception_callback = nullptr; 485 v8::FatalErrorCallback fatal_error_callback = nullptr; 486 v8::OOMErrorCallback oom_error_callback = nullptr; 487 v8::PrepareStackTraceCallback prepare_stack_trace_callback = nullptr; 488 489 // Miscellaneous callbacks 490 v8::PromiseRejectCallback promise_reject_callback = nullptr; 491 v8::AllowWasmCodeGenerationCallback 492 allow_wasm_code_generation_callback = nullptr; 493 v8::ModifyCodeGenerationFromStringsCallback2 494 modify_code_generation_from_strings_callback = nullptr; 495 }; 496 497 // Represents a startup snapshot blob, e.g. created by passing 498 // --node-snapshot-main=entry.js to the configure script at build time, 499 // or by running Node.js with the --build-snapshot option. 500 // 501 // If used, the snapshot *must* have been built with the same Node.js 502 // version and V8 flags as the version that is currently running, and will 503 // be rejected otherwise. 504 // The same EmbedderSnapshotData instance *must* be passed to both 505 // `NewIsolate()` and `CreateIsolateData()`. The first `Environment` instance 506 // should be created with an empty `context` argument and will then 507 // use the main context included in the snapshot blob. It can be retrieved 508 // using `GetMainContext()`. `LoadEnvironment` can receive an empty 509 // `StartExecutionCallback` in this case. 510 // If V8 was configured with the shared-readonly-heap option, it requires 511 // all snapshots used to create `Isolate` instances to be identical. 512 // This option *must* be unset by embedders who wish to use the startup 513 // feature during the build step by passing the --disable-shared-readonly-heap 514 // flag to the configure script. 515 // 516 // The snapshot *must* be kept alive during the execution of the Isolate 517 // that was created using it. 518 // 519 // Snapshots are an *experimental* feature. In particular, the embedder API 520 // exposed through this class is subject to change or removal between Node.js 521 // versions, including possible API and ABI breakage. 522 class EmbedderSnapshotData { 523 public: 524 struct DeleteSnapshotData { 525 void operator()(const EmbedderSnapshotData*) const; 526 }; 527 using Pointer = 528 std::unique_ptr<const EmbedderSnapshotData, DeleteSnapshotData>; 529 530 // Return an EmbedderSnapshotData object that refers to the built-in 531 // snapshot of Node.js. This can have been configured through e.g. 532 // --node-snapshot-main=entry.js. 533 static Pointer BuiltinSnapshotData(); 534 535 // Return an EmbedderSnapshotData object that is based on an input file. 536 // Calling this method will consume but not close the FILE* handle. 537 // The FILE* handle can be closed immediately following this call. 538 // If the snapshot is invalid, this returns an empty pointer. 539 static Pointer FromFile(FILE* in); 540 static Pointer FromBlob(const std::vector<char>& in); 541 static Pointer FromBlob(std::string_view in); 542 543 // Write this EmbedderSnapshotData object to an output file. 544 // Calling this method will not close the FILE* handle. 545 // The FILE* handle can be closed immediately following this call. 546 void ToFile(FILE* out) const; 547 std::vector<char> ToBlob() const; 548 549 // Returns whether custom snapshots can be used. Currently, this means 550 // that V8 was configured without the shared-readonly-heap feature. 551 static bool CanUseCustomSnapshotPerIsolate(); 552 553 EmbedderSnapshotData(const EmbedderSnapshotData&) = delete; 554 EmbedderSnapshotData& operator=(const EmbedderSnapshotData&) = delete; 555 EmbedderSnapshotData(EmbedderSnapshotData&&) = delete; 556 EmbedderSnapshotData& operator=(EmbedderSnapshotData&&) = delete; 557 558 protected: 559 EmbedderSnapshotData(const SnapshotData* impl, bool owns_impl); 560 561 private: 562 const SnapshotData* impl_; 563 bool owns_impl_; 564 friend struct SnapshotData; 565 friend class CommonEnvironmentSetup; 566 }; 567 568 // Overriding IsolateSettings may produce unexpected behavior 569 // in Node.js core functionality, so proceed at your own risk. 570 NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate, 571 const IsolateSettings& settings); 572 573 // Set a number of callbacks for the `isolate`, in particular the Node.js 574 // uncaught exception listener. 575 NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate); 576 577 // Creates a new isolate with Node.js-specific settings. 578 // This is a convenience method equivalent to using SetIsolateCreateParams(), 579 // Isolate::Allocate(), MultiIsolatePlatform::RegisterIsolate(), 580 // Isolate::Initialize(), and SetIsolateUpForNode(). 581 NODE_EXTERN v8::Isolate* NewIsolate( 582 ArrayBufferAllocator* allocator, 583 struct uv_loop_s* event_loop, 584 MultiIsolatePlatform* platform, 585 const EmbedderSnapshotData* snapshot_data = nullptr, 586 const IsolateSettings& settings = {}); 587 NODE_EXTERN v8::Isolate* NewIsolate( 588 std::shared_ptr<ArrayBufferAllocator> allocator, 589 struct uv_loop_s* event_loop, 590 MultiIsolatePlatform* platform, 591 const EmbedderSnapshotData* snapshot_data = nullptr, 592 const IsolateSettings& settings = {}); 593 594 // Creates a new context with Node.js-specific tweaks. 595 NODE_EXTERN v8::Local<v8::Context> NewContext( 596 v8::Isolate* isolate, 597 v8::Local<v8::ObjectTemplate> object_template = 598 v8::Local<v8::ObjectTemplate>()); 599 600 // Runs Node.js-specific tweaks on an already constructed context 601 // Return value indicates success of operation 602 NODE_EXTERN v8::Maybe<bool> InitializeContext(v8::Local<v8::Context> context); 603 604 // If `platform` is passed, it will be used to register new Worker instances. 605 // It can be `nullptr`, in which case creating new Workers inside of 606 // Environments that use this `IsolateData` will not work. 607 NODE_EXTERN IsolateData* CreateIsolateData( 608 v8::Isolate* isolate, 609 struct uv_loop_s* loop, 610 MultiIsolatePlatform* platform = nullptr, 611 ArrayBufferAllocator* allocator = nullptr, 612 const EmbedderSnapshotData* snapshot_data = nullptr); 613 NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data); 614 615 struct ThreadId { 616 uint64_t id = static_cast<uint64_t>(-1); 617 }; 618 NODE_EXTERN ThreadId AllocateEnvironmentThreadId(); 619 620 namespace EnvironmentFlags { 621 enum Flags : uint64_t { 622 kNoFlags = 0, 623 // Use the default behaviour for Node.js instances. 624 kDefaultFlags = 1 << 0, 625 // Controls whether this Environment is allowed to affect per-process state 626 // (e.g. cwd, process title, uid, etc.). 627 // This is set when using kDefaultFlags. 628 kOwnsProcessState = 1 << 1, 629 // Set if this Environment instance is associated with the global inspector 630 // handling code (i.e. listening on SIGUSR1). 631 // This is set when using kDefaultFlags. 632 kOwnsInspector = 1 << 2, 633 // Set if Node.js should not run its own esm loader. This is needed by some 634 // embedders, because it's possible for the Node.js esm loader to conflict 635 // with another one in an embedder environment, e.g. Blink's in Chromium. 636 kNoRegisterESMLoader = 1 << 3, 637 // Set this flag to make Node.js track "raw" file descriptors, i.e. managed 638 // by fs.open() and fs.close(), and close them during FreeEnvironment(). 639 kTrackUnmanagedFds = 1 << 4, 640 // Set this flag to force hiding console windows when spawning child 641 // processes. This is usually used when embedding Node.js in GUI programs on 642 // Windows. 643 kHideConsoleWindows = 1 << 5, 644 // Set this flag to disable loading native addons via `process.dlopen`. 645 // This environment flag is especially important for worker threads 646 // so that a worker thread can't load a native addon even if `execArgv` 647 // is overwritten and `--no-addons` is not specified but was specified 648 // for this Environment instance. 649 kNoNativeAddons = 1 << 6, 650 // Set this flag to disable searching modules from global paths like 651 // $HOME/.node_modules and $NODE_PATH. This is used by standalone apps that 652 // do not expect to have their behaviors changed because of globally 653 // installed modules. 654 kNoGlobalSearchPaths = 1 << 7, 655 // Do not export browser globals like setTimeout, console, etc. 656 kNoBrowserGlobals = 1 << 8, 657 // Controls whether or not the Environment should call V8Inspector::create(). 658 // This control is needed by embedders who may not want to initialize the V8 659 // inspector in situations where one has already been created, 660 // e.g. Blink's in Chromium. 661 kNoCreateInspector = 1 << 9, 662 // Controls whether or not the InspectorAgent for this Environment should 663 // call StartDebugSignalHandler. This control is needed by embedders who may 664 // not want to allow other processes to start the V8 inspector. 665 kNoStartDebugSignalHandler = 1 << 10, 666 // Controls whether the InspectorAgent created for this Environment waits for 667 // Inspector frontend events during the Environment creation. It's used to 668 // call node::Stop(env) on a Worker thread that is waiting for the events. 669 kNoWaitForInspectorFrontend = 1 << 11 670 }; 671 } // namespace EnvironmentFlags 672 673 enum class SnapshotFlags : uint32_t { 674 kDefault = 0, 675 // Whether code cache should be generated as part of the snapshot. 676 // Code cache reduces the time spent on compiling functions included 677 // in the snapshot at the expense of a bigger snapshot size and 678 // potentially breaking portability of the snapshot. 679 kWithoutCodeCache = 1 << 0, 680 }; 681 682 struct SnapshotConfig { 683 SnapshotFlags flags = SnapshotFlags::kDefault; 684 685 // When builder_script_path is std::nullopt, the snapshot is generated as a 686 // built-in snapshot instead of a custom one, and it's expected that the 687 // built-in snapshot only contains states that reproduce in every run of the 688 // application. The event loop won't be run when generating a built-in 689 // snapshot, so asynchronous operations should be avoided. 690 // 691 // When builder_script_path is an std::string, it should match args[1] 692 // passed to CreateForSnapshotting(). The embedder is also expected to use 693 // LoadEnvironment() to run a script matching this path. In that case the 694 // snapshot is generated as a custom snapshot and the event loop is run, so 695 // the snapshot builder can execute asynchronous operations as long as they 696 // are run to completion when the snapshot is taken. 697 std::optional<std::string> builder_script_path; 698 }; 699 700 struct InspectorParentHandle { 701 virtual ~InspectorParentHandle() = default; 702 }; 703 704 // TODO(addaleax): Maybe move per-Environment options parsing here. 705 // Returns nullptr when the Environment cannot be created e.g. there are 706 // pending JavaScript exceptions. 707 // `context` may be empty if an `EmbedderSnapshotData` instance was provided 708 // to `NewIsolate()` and `CreateIsolateData()`. 709 NODE_EXTERN Environment* CreateEnvironment( 710 IsolateData* isolate_data, 711 v8::Local<v8::Context> context, 712 const std::vector<std::string>& args, 713 const std::vector<std::string>& exec_args, 714 EnvironmentFlags::Flags flags = EnvironmentFlags::kDefaultFlags, 715 ThreadId thread_id = {} /* allocates a thread id automatically */, 716 std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {}); 717 718 NODE_EXTERN Environment* CreateEnvironment( 719 IsolateData* isolate_data, 720 v8::Local<v8::Context> context, 721 const std::vector<std::string>& args, 722 const std::vector<std::string>& exec_args, 723 EnvironmentFlags::Flags flags, 724 ThreadId thread_id, 725 std::unique_ptr<InspectorParentHandle> inspector_parent_handle, 726 std::string_view thread_name); 727 728 // Returns a handle that can be passed to `LoadEnvironment()`, making the 729 // child Environment accessible to the inspector as if it were a Node.js Worker. 730 // `child_thread_id` can be created using `AllocateEnvironmentThreadId()` 731 // and then later passed on to `CreateEnvironment()` to create the child 732 // Environment, together with the inspector handle. 733 // This method should not be called while the parent Environment is active 734 // on another thread. 735 NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle( 736 Environment* parent_env, 737 ThreadId child_thread_id, 738 const char* child_url); 739 740 NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle( 741 Environment* parent_env, 742 ThreadId child_thread_id, 743 const char* child_url, 744 const char* name); 745 746 NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle( 747 Environment* parent_env, 748 ThreadId child_thread_id, 749 std::string_view child_url, 750 std::string_view name); 751 752 struct StartExecutionCallbackInfo { 753 v8::Local<v8::Object> process_object; 754 v8::Local<v8::Function> native_require; 755 v8::Local<v8::Function> run_cjs; 756 }; 757 758 using StartExecutionCallback = 759 std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>; 760 using EmbedderPreloadCallback = 761 std::function<void(Environment* env, 762 v8::Local<v8::Value> process, 763 v8::Local<v8::Value> require)>; 764 765 // Run initialization for the environment. 766 // 767 // The |preload| function, usually used by embedders to inject scripts, 768 // will be run by Node.js before Node.js executes the entry point. 769 // The function is guaranteed to run before the user land module loader running 770 // any user code, so it is safe to assume that at this point, no user code has 771 // been run yet. 772 // The function will be executed with preload(process, require), and the passed 773 // require function has access to internal Node.js modules. There is no 774 // stability guarantee about the internals exposed to the internal require 775 // function. Expect breakages when updating Node.js versions if the embedder 776 // imports internal modules with the internal require function. 777 // Worker threads created in the environment will also respect The |preload| 778 // function, so make sure the function is thread-safe. 779 NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment( 780 Environment* env, 781 StartExecutionCallback cb, 782 EmbedderPreloadCallback preload = nullptr); 783 NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment( 784 Environment* env, 785 std::string_view main_script_source_utf8, 786 EmbedderPreloadCallback preload = nullptr); 787 NODE_EXTERN void FreeEnvironment(Environment* env); 788 789 // Set a callback that is called when process.exit() is called from JS, 790 // overriding the default handler. 791 // It receives the Environment* instance and the exit code as arguments. 792 // This could e.g. call Stop(env); in order to terminate execution and stop 793 // the event loop. 794 // The default handler disposes of the global V8 platform instance, if one is 795 // being used, and calls exit(). 796 NODE_EXTERN void SetProcessExitHandler( 797 Environment* env, 798 std::function<void(Environment*, int)>&& handler); 799 NODE_EXTERN void DefaultProcessExitHandler(Environment* env, int exit_code); 800 801 // This may return nullptr if context is not associated with a Node instance. 802 NODE_EXTERN Environment* GetCurrentEnvironment(v8::Local<v8::Context> context); 803 NODE_EXTERN IsolateData* GetEnvironmentIsolateData(Environment* env); 804 NODE_EXTERN ArrayBufferAllocator* GetArrayBufferAllocator(IsolateData* data); 805 // This is mostly useful for Environment* instances that were created through 806 // a snapshot and have a main context that was read from that snapshot. 807 NODE_EXTERN v8::Local<v8::Context> GetMainContext(Environment* env); 808 809 [[noreturn]] NODE_EXTERN void OnFatalError(const char* location, 810 const char* message); 811 NODE_EXTERN void PromiseRejectCallback(v8::PromiseRejectMessage message); 812 NODE_EXTERN bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context, 813 v8::Local<v8::String>); 814 NODE_EXTERN bool ShouldAbortOnUncaughtException(v8::Isolate* isolate); 815 NODE_EXTERN v8::MaybeLocal<v8::Value> PrepareStackTraceCallback( 816 v8::Local<v8::Context> context, 817 v8::Local<v8::Value> exception, 818 v8::Local<v8::Array> trace); 819 820 // Writes a diagnostic report to a file. If filename is not provided, the 821 // default filename includes the date, time, PID, and a sequence number. 822 // The report's JavaScript stack trace is taken from err, if present. 823 // If isolate is nullptr, no information about the JavaScript environment 824 // is included in the report. 825 // Returns the filename of the written report. 826 NODE_EXTERN std::string TriggerNodeReport(v8::Isolate* isolate, 827 const char* message, 828 const char* trigger, 829 const std::string& filename, 830 v8::Local<v8::Value> error); 831 NODE_EXTERN std::string TriggerNodeReport(Environment* env, 832 const char* message, 833 const char* trigger, 834 const std::string& filename, 835 v8::Local<v8::Value> error); 836 NODE_EXTERN void GetNodeReport(v8::Isolate* isolate, 837 const char* message, 838 const char* trigger, 839 v8::Local<v8::Value> error, 840 std::ostream& out); 841 NODE_EXTERN void GetNodeReport(Environment* env, 842 const char* message, 843 const char* trigger, 844 v8::Local<v8::Value> error, 845 std::ostream& out); 846 847 // This returns the MultiIsolatePlatform used for an Environment or IsolateData 848 // instance, if one exists. 849 NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(Environment* env); 850 NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env); 851 852 NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead", 853 NODE_EXTERN MultiIsolatePlatform* CreatePlatform( 854 int thread_pool_size, 855 v8::TracingController* tracing_controller)); 856 NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead", 857 NODE_EXTERN void FreePlatform(MultiIsolatePlatform* platform)); 858 859 // Get/set the currently active tracing controller. Using CreatePlatform() 860 // will implicitly set this by default. This is global and should be initialized 861 // along with the v8::Platform instance that is being used. `controller` 862 // is allowed to be `nullptr`. 863 // This is used for tracing events from Node.js itself. V8 uses the tracing 864 // controller returned from the active `v8::Platform` instance. 865 NODE_EXTERN v8::TracingController* GetTracingController(); 866 NODE_EXTERN void SetTracingController(v8::TracingController* controller); 867 868 // Run `process.emit('beforeExit')` as it would usually happen when Node.js is 869 // run in standalone mode. 870 NODE_EXTERN v8::Maybe<bool> EmitProcessBeforeExit(Environment* env); 871 NODE_DEPRECATED("Use Maybe version (EmitProcessBeforeExit) instead", 872 NODE_EXTERN void EmitBeforeExit(Environment* env)); 873 // Run `process.emit('exit')` as it would usually happen when Node.js is run 874 // in standalone mode. The return value corresponds to the exit code. 875 NODE_EXTERN v8::Maybe<int> EmitProcessExit(Environment* env); 876 NODE_DEPRECATED("Use Maybe version (EmitProcessExit) instead", 877 NODE_EXTERN int EmitExit(Environment* env)); 878 879 // Runs hooks added through `AtExit()`. This is part of `FreeEnvironment()`, 880 // so calling it manually is typically not necessary. 881 NODE_EXTERN void RunAtExit(Environment* env); 882 883 // This may return nullptr if the current v8::Context is not associated 884 // with a Node instance. 885 NODE_EXTERN struct uv_loop_s* GetCurrentEventLoop(v8::Isolate* isolate); 886 887 // Runs the main loop for a given Environment. This roughly performs the 888 // following steps: 889 // 1. Call uv_run() on the event loop until it is drained. 890 // 2. Call platform->DrainTasks() on the associated platform/isolate. 891 // 3. If the event loop is alive again, go to Step 1. 892 // 4. Call EmitProcessBeforeExit(). 893 // 5. If the event loop is alive again, go to Step 1. 894 // 6. Call EmitProcessExit() and forward the return value. 895 // If at any point node::Stop() is called, the function will attempt to return 896 // as soon as possible, returning an empty `Maybe`. 897 // This function only works if `env` has an associated `MultiIsolatePlatform`. 898 NODE_EXTERN v8::Maybe<int> SpinEventLoop(Environment* env); 899 900 NODE_EXTERN std::string GetAnonymousMainPath(); 901 902 class NODE_EXTERN CommonEnvironmentSetup { 903 public: 904 ~CommonEnvironmentSetup(); 905 906 // Create a new CommonEnvironmentSetup, that is, a group of objects that 907 // together form the typical setup for a single Node.js Environment instance. 908 // If any error occurs, `*errors` will be populated and the returned pointer 909 // will be empty. 910 // env_args will be passed through as arguments to CreateEnvironment(), after 911 // `isolate_data` and `context`. 912 template <typename... EnvironmentArgs> 913 static std::unique_ptr<CommonEnvironmentSetup> Create( 914 MultiIsolatePlatform* platform, 915 std::vector<std::string>* errors, 916 EnvironmentArgs&&... env_args); 917 template <typename... EnvironmentArgs> 918 static std::unique_ptr<CommonEnvironmentSetup> CreateFromSnapshot( 919 MultiIsolatePlatform* platform, 920 std::vector<std::string>* errors, 921 const EmbedderSnapshotData* snapshot_data, 922 EnvironmentArgs&&... env_args); 923 924 // Create an embedding setup which will be used for creating a snapshot 925 // using CreateSnapshot(). 926 // 927 // This will create and attach a v8::SnapshotCreator to this instance, 928 // and the same restrictions apply to this instance that also apply to 929 // other V8 snapshotting environments. 930 // Not all Node.js APIs are supported in this case. Currently, there is 931 // no support for native/host objects other than Node.js builtins 932 // in the snapshot. 933 // 934 // If the embedder wants to use LoadEnvironment() later to run a snapshot 935 // builder script they should make sure args[1] contains the path of the 936 // snapshot script, which will be used to create __filename and __dirname 937 // in the context where the builder script is run. If they do not want to 938 // include the build-time paths into the snapshot, use the string returned 939 // by GetAnonymousMainPath() as args[1] to anonymize the script. 940 // 941 // Snapshots are an *experimental* feature. In particular, the embedder API 942 // exposed through this class is subject to change or removal between Node.js 943 // versions, including possible API and ABI breakage. 944 static std::unique_ptr<CommonEnvironmentSetup> CreateForSnapshotting( 945 MultiIsolatePlatform* platform, 946 std::vector<std::string>* errors, 947 const std::vector<std::string>& args = {}, 948 const std::vector<std::string>& exec_args = {}, 949 const SnapshotConfig& snapshot_config = {}); 950 EmbedderSnapshotData::Pointer CreateSnapshot(); 951 952 struct uv_loop_s* event_loop() const; 953 v8::SnapshotCreator* snapshot_creator(); 954 // Empty for snapshotting environments. 955 std::shared_ptr<ArrayBufferAllocator> array_buffer_allocator() const; 956 v8::Isolate* isolate() const; 957 IsolateData* isolate_data() const; 958 Environment* env() const; 959 v8::Local<v8::Context> context() const; 960 961 CommonEnvironmentSetup(const CommonEnvironmentSetup&) = delete; 962 CommonEnvironmentSetup& operator=(const CommonEnvironmentSetup&) = delete; 963 CommonEnvironmentSetup(CommonEnvironmentSetup&&) = delete; 964 CommonEnvironmentSetup& operator=(CommonEnvironmentSetup&&) = delete; 965 966 private: 967 enum Flags : uint32_t { 968 kNoFlags = 0, 969 kIsForSnapshotting = 1, 970 }; 971 972 struct Impl; 973 Impl* impl_; 974 975 CommonEnvironmentSetup( 976 MultiIsolatePlatform*, 977 std::vector<std::string>*, 978 std::function<Environment*(const CommonEnvironmentSetup*)>); 979 CommonEnvironmentSetup( 980 MultiIsolatePlatform*, 981 std::vector<std::string>*, 982 const EmbedderSnapshotData*, 983 uint32_t flags, 984 std::function<Environment*(const CommonEnvironmentSetup*)>, 985 const SnapshotConfig* config = nullptr); 986 }; 987 988 // Implementation for CommonEnvironmentSetup::Create 989 template <typename... EnvironmentArgs> 990 std::unique_ptr<CommonEnvironmentSetup> CommonEnvironmentSetup::Create( 991 MultiIsolatePlatform* platform, 992 std::vector<std::string>* errors, 993 EnvironmentArgs&&... env_args) { 994 auto ret = std::unique_ptr<CommonEnvironmentSetup>(new CommonEnvironmentSetup( 995 platform, errors, 996 [&](const CommonEnvironmentSetup* setup) -> Environment* { 997 return CreateEnvironment( 998 setup->isolate_data(), setup->context(), 999 std::forward<EnvironmentArgs>(env_args)...); 1000 })); 1001 if (!errors->empty()) ret.reset(); 1002 return ret; 1003 } 1004 1005 // Implementation for ::CreateFromSnapshot -- the ::Create() method 1006 // could call this with a nullptr snapshot_data in a major version. 1007 template <typename... EnvironmentArgs> 1008 std::unique_ptr<CommonEnvironmentSetup> 1009 CommonEnvironmentSetup::CreateFromSnapshot( 1010 MultiIsolatePlatform* platform, 1011 std::vector<std::string>* errors, 1012 const EmbedderSnapshotData* snapshot_data, 1013 EnvironmentArgs&&... env_args) { 1014 auto ret = std::unique_ptr<CommonEnvironmentSetup>(new CommonEnvironmentSetup( 1015 platform, 1016 errors, 1017 snapshot_data, 1018 Flags::kNoFlags, 1019 [&](const CommonEnvironmentSetup* setup) -> Environment* { 1020 return CreateEnvironment(setup->isolate_data(), 1021 setup->context(), 1022 std::forward<EnvironmentArgs>(env_args)...); 1023 })); 1024 if (!errors->empty()) ret.reset(); 1025 return ret; 1026 } 1027 1028 /* Converts a unixtime to V8 Date */ 1029 NODE_DEPRECATED("Use v8::Date::New() directly", 1030 inline v8::Local<v8::Value> NODE_UNIXTIME_V8(double time) { 1031 return v8::Date::New( 1032 v8::Isolate::GetCurrent()->GetCurrentContext(), 1033 1000 * time) 1034 .ToLocalChecked(); 1035 }) 1036 #define NODE_UNIXTIME_V8 node::NODE_UNIXTIME_V8 1037 NODE_DEPRECATED("Use v8::Date::ValueOf() directly", 1038 inline double NODE_V8_UNIXTIME(v8::Local<v8::Date> date) { 1039 return date->ValueOf() / 1000; 1040 }) 1041 #define NODE_V8_UNIXTIME node::NODE_V8_UNIXTIME 1042 1043 #define NODE_DEFINE_CONSTANT(target, constant) \ 1044 do { \ 1045 v8::Isolate* isolate = target->GetIsolate(); \ 1046 v8::Local<v8::Context> context = isolate->GetCurrentContext(); \ 1047 v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \ 1048 isolate, #constant, v8::NewStringType::kInternalized); \ 1049 v8::Local<v8::Number> constant_value = \ 1050 v8::Number::New(isolate, static_cast<double>(constant)); \ 1051 v8::PropertyAttribute constant_attributes = \ 1052 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); \ 1053 (target) \ 1054 ->DefineOwnProperty( \ 1055 context, constant_name, constant_value, constant_attributes) \ 1056 .Check(); \ 1057 } while (0) 1058 1059 #define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \ 1060 do { \ 1061 v8::Isolate* isolate = target->GetIsolate(); \ 1062 v8::Local<v8::Context> context = isolate->GetCurrentContext(); \ 1063 v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \ 1064 isolate, #constant, v8::NewStringType::kInternalized); \ 1065 v8::Local<v8::Number> constant_value = \ 1066 v8::Number::New(isolate, static_cast<double>(constant)); \ 1067 v8::PropertyAttribute constant_attributes = \ 1068 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete | \ 1069 v8::DontEnum); \ 1070 (target) \ 1071 ->DefineOwnProperty( \ 1072 context, constant_name, constant_value, constant_attributes) \ 1073 .Check(); \ 1074 } while (0) 1075 1076 // Used to be a macro, hence the uppercase name. 1077 inline void NODE_SET_METHOD(v8::Local<v8::Template> recv, 1078 const char* name, 1079 v8::FunctionCallback callback) { 1080 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 1081 v8::HandleScope handle_scope(isolate); 1082 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate, 1083 callback); 1084 v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name, 1085 v8::NewStringType::kInternalized).ToLocalChecked(); 1086 t->SetClassName(fn_name); 1087 recv->Set(fn_name, t); 1088 } 1089 1090 // Used to be a macro, hence the uppercase name. 1091 inline void NODE_SET_METHOD(v8::Local<v8::Object> recv, 1092 const char* name, 1093 v8::FunctionCallback callback) { 1094 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 1095 v8::HandleScope handle_scope(isolate); 1096 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 1097 v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate, 1098 callback); 1099 v8::Local<v8::Function> fn = t->GetFunction(context).ToLocalChecked(); 1100 v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name, 1101 v8::NewStringType::kInternalized).ToLocalChecked(); 1102 fn->SetName(fn_name); 1103 recv->Set(context, fn_name, fn).Check(); 1104 } 1105 #define NODE_SET_METHOD node::NODE_SET_METHOD 1106 1107 // Used to be a macro, hence the uppercase name. 1108 // Not a template because it only makes sense for FunctionTemplates. 1109 inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv, 1110 const char* name, 1111 v8::FunctionCallback callback) { 1112 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 1113 v8::HandleScope handle_scope(isolate); 1114 v8::Local<v8::Signature> s = v8::Signature::New(isolate, recv); 1115 v8::Local<v8::FunctionTemplate> t = 1116 v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), s); 1117 v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name, 1118 v8::NewStringType::kInternalized).ToLocalChecked(); 1119 t->SetClassName(fn_name); 1120 recv->PrototypeTemplate()->Set(fn_name, t); 1121 } 1122 #define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD 1123 1124 // BINARY is a deprecated alias of LATIN1. 1125 // BASE64URL is not currently exposed to the JavaScript side. 1126 enum encoding { 1127 ASCII, 1128 UTF8, 1129 BASE64, 1130 UCS2, 1131 BINARY, 1132 HEX, 1133 BUFFER, 1134 BASE64URL, 1135 LATIN1 = BINARY 1136 }; 1137 1138 NODE_EXTERN enum encoding ParseEncoding( 1139 v8::Isolate* isolate, 1140 v8::Local<v8::Value> encoding_v, 1141 enum encoding default_encoding = LATIN1); 1142 1143 NODE_EXTERN void FatalException(v8::Isolate* isolate, 1144 const v8::TryCatch& try_catch); 1145 1146 NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate, 1147 const char* buf, 1148 size_t len, 1149 enum encoding encoding = LATIN1); 1150 1151 // Warning: This reverses endianness on Big Endian platforms, even though the 1152 // signature using uint16_t implies that it should not. 1153 NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate, 1154 const uint16_t* buf, 1155 size_t len); 1156 1157 // Returns -1 if the handle was not valid for decoding 1158 NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate, 1159 v8::Local<v8::Value>, 1160 enum encoding encoding = LATIN1); 1161 // returns bytes written. 1162 NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate, 1163 char* buf, 1164 size_t buflen, 1165 v8::Local<v8::Value>, 1166 enum encoding encoding = LATIN1); 1167 #ifdef _WIN32 1168 NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException( 1169 v8::Isolate* isolate, 1170 int errorno, 1171 const char* syscall = nullptr, 1172 const char* msg = "", 1173 const char* path = nullptr); 1174 #endif 1175 1176 const char* signo_string(int errorno); 1177 1178 1179 typedef void (*addon_register_func)( 1180 v8::Local<v8::Object> exports, 1181 v8::Local<v8::Value> module, 1182 void* priv); 1183 1184 typedef void (*addon_context_register_func)( 1185 v8::Local<v8::Object> exports, 1186 v8::Local<v8::Value> module, 1187 v8::Local<v8::Context> context, 1188 void* priv); 1189 1190 enum ModuleFlags { 1191 kLinked = 0x02 1192 }; 1193 1194 struct node_module { 1195 int nm_version; 1196 unsigned int nm_flags; 1197 void* nm_dso_handle; 1198 const char* nm_filename; 1199 node::addon_register_func nm_register_func; 1200 node::addon_context_register_func nm_context_register_func; 1201 const char* nm_modname; 1202 void* nm_priv; 1203 struct node_module* nm_link; 1204 }; 1205 1206 extern "C" NODE_EXTERN void node_module_register(void* mod); 1207 1208 #ifdef _WIN32 1209 # define NODE_MODULE_EXPORT __declspec(dllexport) 1210 #else 1211 # define NODE_MODULE_EXPORT __attribute__((visibility("default"))) 1212 #endif 1213 1214 #ifdef NODE_SHARED_MODE 1215 # define NODE_CTOR_PREFIX 1216 #else 1217 # define NODE_CTOR_PREFIX static 1218 #endif 1219 1220 #if defined(_MSC_VER) 1221 #define NODE_C_CTOR(fn) \ 1222 NODE_CTOR_PREFIX void __cdecl fn(void); \ 1223 namespace { \ 1224 struct fn##_ { \ 1225 fn##_() { fn(); }; \ 1226 } fn##_v_; \ 1227 } \ 1228 NODE_CTOR_PREFIX void __cdecl fn(void) 1229 #else 1230 #define NODE_C_CTOR(fn) \ 1231 NODE_CTOR_PREFIX void fn(void) __attribute__((constructor)); \ 1232 NODE_CTOR_PREFIX void fn(void) 1233 #endif 1234 1235 #define NODE_MODULE_X(modname, regfunc, priv, flags) \ 1236 extern "C" { \ 1237 static node::node_module _module = \ 1238 { \ 1239 NODE_MODULE_VERSION, \ 1240 flags, \ 1241 NULL, /* NOLINT (readability/null_usage) */ \ 1242 __FILE__, \ 1243 (node::addon_register_func) (regfunc), \ 1244 NULL, /* NOLINT (readability/null_usage) */ \ 1245 NODE_STRINGIFY(modname), \ 1246 priv, \ 1247 NULL /* NOLINT (readability/null_usage) */ \ 1248 }; \ 1249 NODE_C_CTOR(_register_ ## modname) { \ 1250 node_module_register(&_module); \ 1251 } \ 1252 } 1253 1254 #define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags) \ 1255 extern "C" { \ 1256 static node::node_module _module = \ 1257 { \ 1258 NODE_MODULE_VERSION, \ 1259 flags, \ 1260 NULL, /* NOLINT (readability/null_usage) */ \ 1261 __FILE__, \ 1262 NULL, /* NOLINT (readability/null_usage) */ \ 1263 (node::addon_context_register_func) (regfunc), \ 1264 NODE_STRINGIFY(modname), \ 1265 priv, \ 1266 NULL /* NOLINT (readability/null_usage) */ \ 1267 }; \ 1268 NODE_C_CTOR(_register_ ## modname) { \ 1269 node_module_register(&_module); \ 1270 } \ 1271 } 1272 1273 // Usage: `NODE_MODULE(NODE_GYP_MODULE_NAME, InitializerFunction)` 1274 // If no NODE_MODULE is declared, Node.js looks for the well-known 1275 // symbol `node_register_module_v${NODE_MODULE_VERSION}`. 1276 #define NODE_MODULE(modname, regfunc) \ 1277 NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage) 1278 1279 #define NODE_MODULE_CONTEXT_AWARE(modname, regfunc) \ 1280 /* NOLINTNEXTLINE (readability/null_usage) */ \ 1281 NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0) 1282 1283 // Embedders can use this type of binding for statically linked native bindings. 1284 // It is used the same way addon bindings are used, except that linked bindings 1285 // can be accessed through `process._linkedBinding(modname)`. 1286 #define NODE_MODULE_LINKED(modname, regfunc) \ 1287 /* NOLINTNEXTLINE (readability/null_usage) */ \ 1288 NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, \ 1289 node::ModuleFlags::kLinked) 1290 1291 /* 1292 * For backward compatibility in add-on modules. 1293 */ 1294 #define NODE_MODULE_DECL /* nothing */ 1295 1296 #define NODE_MODULE_INITIALIZER_BASE node_register_module_v 1297 1298 #define NODE_MODULE_INITIALIZER_X(base, version) \ 1299 NODE_MODULE_INITIALIZER_X_HELPER(base, version) 1300 1301 #define NODE_MODULE_INITIALIZER_X_HELPER(base, version) base##version 1302 1303 #define NODE_MODULE_INITIALIZER \ 1304 NODE_MODULE_INITIALIZER_X(NODE_MODULE_INITIALIZER_BASE, \ 1305 NODE_MODULE_VERSION) 1306 1307 #define NODE_MODULE_INIT() \ 1308 extern "C" NODE_MODULE_EXPORT void \ 1309 NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports, \ 1310 v8::Local<v8::Value> module, \ 1311 v8::Local<v8::Context> context); \ 1312 NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, \ 1313 NODE_MODULE_INITIALIZER) \ 1314 void NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports, \ 1315 v8::Local<v8::Value> module, \ 1316 v8::Local<v8::Context> context) 1317 1318 // Allows embedders to add a binding to the current Environment* that can be 1319 // accessed through process._linkedBinding() in the target Environment and all 1320 // Worker threads that it creates. 1321 // In each variant, the registration function needs to be usable at least for 1322 // the time during which the Environment exists. 1323 NODE_EXTERN void AddLinkedBinding(Environment* env, const node_module& mod); 1324 NODE_EXTERN void AddLinkedBinding(Environment* env, 1325 const struct napi_module& mod); 1326 NODE_EXTERN void AddLinkedBinding(Environment* env, 1327 const char* name, 1328 addon_context_register_func fn, 1329 void* priv); 1330 NODE_EXTERN void AddLinkedBinding( 1331 Environment* env, 1332 const char* name, 1333 napi_addon_register_func fn, 1334 int32_t module_api_version = NODE_API_DEFAULT_MODULE_API_VERSION); 1335 1336 /* Registers a callback with the passed-in Environment instance. The callback 1337 * is called after the event loop exits, but before the VM is disposed. 1338 * Callbacks are run in reverse order of registration, i.e. newest first. 1339 */ 1340 NODE_EXTERN void AtExit(Environment* env, 1341 void (*cb)(void* arg), 1342 void* arg); 1343 1344 typedef double async_id; 1345 struct async_context { 1346 ::node::async_id async_id; 1347 ::node::async_id trigger_async_id; 1348 }; 1349 1350 /* This is a lot like node::AtExit, except that the hooks added via this 1351 * function are run before the AtExit ones and will always be registered 1352 * for the current Environment instance. 1353 * These functions are safe to use in an addon supporting multiple 1354 * threads/isolates. */ 1355 NODE_EXTERN void AddEnvironmentCleanupHook(v8::Isolate* isolate, 1356 void (*fun)(void* arg), 1357 void* arg); 1358 1359 NODE_EXTERN void RemoveEnvironmentCleanupHook(v8::Isolate* isolate, 1360 void (*fun)(void* arg), 1361 void* arg); 1362 1363 /* These are async equivalents of the above. After the cleanup hook is invoked, 1364 * `cb(cbarg)` *must* be called, and attempting to remove the cleanup hook will 1365 * have no effect. */ 1366 struct ACHHandle; 1367 struct NODE_EXTERN DeleteACHHandle { void operator()(ACHHandle*) const; }; 1368 typedef std::unique_ptr<ACHHandle, DeleteACHHandle> AsyncCleanupHookHandle; 1369 1370 /* This function is not intended to be used externally, it exists to aid in 1371 * keeping ABI compatibility between Node and Electron. */ 1372 NODE_EXTERN ACHHandle* AddEnvironmentCleanupHookInternal( 1373 v8::Isolate* isolate, 1374 void (*fun)(void* arg, void (*cb)(void*), void* cbarg), 1375 void* arg); 1376 inline AsyncCleanupHookHandle AddEnvironmentCleanupHook( 1377 v8::Isolate* isolate, 1378 void (*fun)(void* arg, void (*cb)(void*), void* cbarg), 1379 void* arg) { 1380 return AsyncCleanupHookHandle(AddEnvironmentCleanupHookInternal(isolate, fun, 1381 arg)); 1382 } 1383 1384 /* This function is not intended to be used externally, it exists to aid in 1385 * keeping ABI compatibility between Node and Electron. */ 1386 NODE_EXTERN void RemoveEnvironmentCleanupHookInternal(ACHHandle* holder); 1387 inline void RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle holder) { 1388 RemoveEnvironmentCleanupHookInternal(holder.get()); 1389 } 1390 1391 // This behaves like V8's Isolate::RequestInterrupt(), but also wakes up 1392 // the event loop if it is currently idle. Interrupt requests are drained 1393 // in `FreeEnvironment()`. The passed callback can not call back into 1394 // JavaScript. 1395 // This function can be called from any thread. 1396 NODE_EXTERN void RequestInterrupt(Environment* env, 1397 void (*fun)(void* arg), 1398 void* arg); 1399 1400 /* Returns the id of the current execution context. If the return value is 1401 * zero then no execution has been set. This will happen if the user handles 1402 * I/O from native code. */ 1403 NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate); 1404 1405 /* Returns the id of the current execution context. If the return value is 1406 * zero then no execution has been set. This will happen if the user handles 1407 * I/O from native code. */ 1408 NODE_EXTERN async_id 1409 AsyncHooksGetExecutionAsyncId(v8::Local<v8::Context> context); 1410 1411 /* Return same value as async_hooks.triggerAsyncId(); */ 1412 NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate); 1413 1414 /* If the native API doesn't inherit from the helper class then the callbacks 1415 * must be triggered manually. This triggers the init() callback. The return 1416 * value is the async id assigned to the resource. 1417 * 1418 * The `trigger_async_id` parameter should correspond to the resource which is 1419 * creating the new resource, which will usually be the return value of 1420 * `AsyncHooksGetTriggerAsyncId()`. */ 1421 NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate, 1422 v8::Local<v8::Object> resource, 1423 const char* name, 1424 async_id trigger_async_id = -1); 1425 1426 NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate, 1427 v8::Local<v8::Object> resource, 1428 v8::Local<v8::String> name, 1429 async_id trigger_async_id = -1); 1430 1431 /* Emit the destroy() callback. The overload taking an `Environment*` argument 1432 * should be used when the Isolate’s current Context is not associated with 1433 * a Node.js Environment, or when there is no current Context, for example 1434 * when calling this function during garbage collection. In that case, the 1435 * `Environment*` value should have been acquired previously, e.g. through 1436 * `GetCurrentEnvironment()`. */ 1437 NODE_EXTERN void EmitAsyncDestroy(v8::Isolate* isolate, 1438 async_context asyncContext); 1439 NODE_EXTERN void EmitAsyncDestroy(Environment* env, 1440 async_context asyncContext); 1441 1442 class InternalCallbackScope; 1443 1444 /* This class works like `MakeCallback()` in that it sets up a specific 1445 * asyncContext as the current one and informs the async_hooks and domains 1446 * modules that this context is currently active. 1447 * 1448 * `MakeCallback()` is a wrapper around this class as well as 1449 * `Function::Call()`. Either one of these mechanisms needs to be used for 1450 * top-level calls into JavaScript (i.e. without any existing JS stack). 1451 * 1452 * This object should be stack-allocated to ensure that it is contained in a 1453 * valid HandleScope. 1454 * 1455 * Exceptions happening within this scope will be treated like uncaught 1456 * exceptions. If this behaviour is undesirable, a new `v8::TryCatch` scope 1457 * needs to be created inside of this scope. 1458 */ 1459 class NODE_EXTERN CallbackScope { 1460 public: 1461 CallbackScope(v8::Isolate* isolate, 1462 v8::Local<v8::Object> resource, 1463 async_context asyncContext); 1464 CallbackScope(Environment* env, 1465 v8::Local<v8::Object> resource, 1466 async_context asyncContext); 1467 ~CallbackScope(); 1468 1469 void operator=(const CallbackScope&) = delete; 1470 void operator=(CallbackScope&&) = delete; 1471 CallbackScope(const CallbackScope&) = delete; 1472 CallbackScope(CallbackScope&&) = delete; 1473 1474 private: 1475 InternalCallbackScope* private_; 1476 v8::TryCatch try_catch_; 1477 }; 1478 1479 /* An API specific to emit before/after callbacks is unnecessary because 1480 * MakeCallback will automatically call them for you. 1481 * 1482 * These methods may create handles on their own, so run them inside a 1483 * HandleScope. 1484 * 1485 * `asyncId` and `triggerAsyncId` should correspond to the values returned by 1486 * `EmitAsyncInit()` and `AsyncHooksGetTriggerAsyncId()`, respectively, when the 1487 * invoking resource was created. If these values are unknown, 0 can be passed. 1488 * */ 1489 NODE_EXTERN 1490 v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate, 1491 v8::Local<v8::Object> recv, 1492 v8::Local<v8::Function> callback, 1493 int argc, 1494 v8::Local<v8::Value>* argv, 1495 async_context asyncContext); 1496 NODE_EXTERN 1497 v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate, 1498 v8::Local<v8::Object> recv, 1499 const char* method, 1500 int argc, 1501 v8::Local<v8::Value>* argv, 1502 async_context asyncContext); 1503 NODE_EXTERN 1504 v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate, 1505 v8::Local<v8::Object> recv, 1506 v8::Local<v8::String> symbol, 1507 int argc, 1508 v8::Local<v8::Value>* argv, 1509 async_context asyncContext); 1510 1511 /* Helper class users can optionally inherit from. If 1512 * `AsyncResource::MakeCallback()` is used, then all four callbacks will be 1513 * called automatically. */ 1514 class NODE_EXTERN AsyncResource { 1515 public: 1516 AsyncResource(v8::Isolate* isolate, 1517 v8::Local<v8::Object> resource, 1518 const char* name, 1519 async_id trigger_async_id = -1); 1520 1521 virtual ~AsyncResource(); 1522 1523 AsyncResource(const AsyncResource&) = delete; 1524 void operator=(const AsyncResource&) = delete; 1525 1526 v8::MaybeLocal<v8::Value> MakeCallback( 1527 v8::Local<v8::Function> callback, 1528 int argc, 1529 v8::Local<v8::Value>* argv); 1530 1531 v8::MaybeLocal<v8::Value> MakeCallback( 1532 const char* method, 1533 int argc, 1534 v8::Local<v8::Value>* argv); 1535 1536 v8::MaybeLocal<v8::Value> MakeCallback( 1537 v8::Local<v8::String> symbol, 1538 int argc, 1539 v8::Local<v8::Value>* argv); 1540 1541 v8::Local<v8::Object> get_resource(); 1542 async_id get_async_id() const; 1543 async_id get_trigger_async_id() const; 1544 1545 protected: 1546 class NODE_EXTERN CallbackScope : public node::CallbackScope { 1547 public: 1548 explicit CallbackScope(AsyncResource* res); 1549 }; 1550 1551 private: 1552 Environment* env_; 1553 v8::Global<v8::Object> resource_; 1554 async_context async_context_; 1555 }; 1556 1557 #ifndef _WIN32 1558 // Register a signal handler without interrupting any handlers that node 1559 // itself needs. This does override handlers registered through 1560 // process.on('SIG...', function() { ... }). The `reset_handler` flag indicates 1561 // whether the signal handler for the given signal should be reset to its 1562 // default value before executing the handler (i.e. it works like SA_RESETHAND). 1563 // The `reset_handler` flag is invalid when `signal` is SIGSEGV. 1564 NODE_EXTERN 1565 void RegisterSignalHandler(int signal, 1566 void (*handler)(int signal, 1567 siginfo_t* info, 1568 void* ucontext), 1569 bool reset_handler = false); 1570 #endif // _WIN32 1571 1572 // Configure the layout of the JavaScript object with a cppgc::GarbageCollected 1573 // instance so that when the JavaScript object is reachable, the garbage 1574 // collected instance would have its Trace() method invoked per the cppgc 1575 // contract. To make it work, the process must have called 1576 // cppgc::InitializeProcess() before, which is usually the case for addons 1577 // loaded by the stand-alone Node.js executable. Embedders of Node.js can use 1578 // either need to call it themselves or make sure that 1579 // ProcessInitializationFlags::kNoInitializeCppgc is *not* set for cppgc to 1580 // work. 1581 // If the CppHeap is owned by Node.js, which is usually the case for addon, 1582 // the object must be created with at least two internal fields available, 1583 // and the first two internal fields would be configured by Node.js. 1584 // This may be superseded by a V8 API in the future, see 1585 // https://bugs.chromium.org/p/v8/issues/detail?id=13960. Until then this 1586 // serves as a helper for Node.js isolates. 1587 NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate, 1588 v8::Local<v8::Object> object, 1589 void* wrappable); 1590 1591 } // namespace node 1592 1593 #endif // SRC_NODE_H_