Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-04 08:44:09

0001 // Copyright Joyent, Inc. and other Node contributors.
0002 //
0003 // Permission is hereby granted, free of charge, to any person obtaining a
0004 // copy of this software and associated documentation files (the
0005 // "Software"), to deal in the Software without restriction, including
0006 // without limitation the rights to use, copy, modify, merge, publish,
0007 // distribute, sublicense, and/or sell copies of the Software, and to permit
0008 // persons to whom the Software is furnished to do so, subject to the
0009 // following conditions:
0010 //
0011 // The above copyright notice and this permission notice shall be included
0012 // in all copies or substantial portions of the Software.
0013 //
0014 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0015 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0016 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
0017 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
0018 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0019 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0020 // USE OR OTHER DEALINGS IN THE SOFTWARE.
0021 
0022 #ifndef SRC_NODE_H_
0023 #define SRC_NODE_H_
0024 
0025 #ifdef _WIN32
0026 # ifndef BUILDING_NODE_EXTENSION
0027 #  define NODE_EXTERN __declspec(dllexport)
0028 # else
0029 #  define NODE_EXTERN __declspec(dllimport)
0030 # endif
0031 #else
0032 # define NODE_EXTERN __attribute__((visibility("default")))
0033 #endif
0034 
0035 // Declarations annotated with NODE_EXTERN_PRIVATE do not form part of
0036 // the public API. They are implementation details that can and will
0037 // change between releases, even in semver patch releases. Do not use
0038 // any such symbol in external code.
0039 #ifdef NODE_SHARED_MODE
0040 #define NODE_EXTERN_PRIVATE NODE_EXTERN
0041 #else
0042 #define NODE_EXTERN_PRIVATE
0043 #endif
0044 
0045 #ifdef BUILDING_NODE_EXTENSION
0046 # undef BUILDING_V8_SHARED
0047 # undef BUILDING_UV_SHARED
0048 # define USING_V8_SHARED 1
0049 # define USING_UV_SHARED 1
0050 #endif
0051 
0052 // This should be defined in make system.
0053 // See issue https://github.com/nodejs/node-v0.x-archive/issues/1236
0054 #if defined(__MINGW32__) || defined(_MSC_VER)
0055 #ifndef _WIN32_WINNT
0056 # define _WIN32_WINNT 0x0600  // Windows Server 2008
0057 #endif
0058 
0059 #ifndef NOMINMAX
0060 # define NOMINMAX
0061 #endif
0062 
0063 #endif
0064 
0065 #if defined(_MSC_VER)
0066 #define PATH_MAX MAX_PATH
0067 #endif
0068 
0069 #ifdef _WIN32
0070 #define SIGQUIT 3
0071 #define SIGKILL 9
0072 #endif
0073 
0074 #include "v8.h"  // NOLINT(build/include_order)
0075 
0076 #include "v8-platform.h"  // NOLINT(build/include_order)
0077 #include "node_version.h"  // NODE_MODULE_VERSION
0078 
0079 #include "node_api.h"
0080 
0081 #include <functional>
0082 #include <memory>
0083 #include <optional>
0084 #include <ostream>
0085 
0086 // We cannot use __POSIX__ in this header because that's only defined when
0087 // building Node.js.
0088 #ifndef _WIN32
0089 #include <signal.h>
0090 #endif  // _WIN32
0091 
0092 #define NODE_MAKE_VERSION(major, minor, patch)                                \
0093   ((major) * 0x1000 + (minor) * 0x100 + (patch))
0094 
0095 #ifdef __clang__
0096 # define NODE_CLANG_AT_LEAST(major, minor, patch)                             \
0097   (NODE_MAKE_VERSION(major, minor, patch) <=                                  \
0098       NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__))
0099 #else
0100 # define NODE_CLANG_AT_LEAST(major, minor, patch) (0)
0101 #endif
0102 
0103 #ifdef __GNUC__
0104 # define NODE_GNUC_AT_LEAST(major, minor, patch)                              \
0105   (NODE_MAKE_VERSION(major, minor, patch) <=                                  \
0106       NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__))
0107 #else
0108 # define NODE_GNUC_AT_LEAST(major, minor, patch) (0)
0109 #endif
0110 
0111 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
0112 # define NODE_DEPRECATED(message, declarator) declarator
0113 #else  // NODE_WANT_INTERNALS
0114 # if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0)
0115 #  define NODE_DEPRECATED(message, declarator)                                 \
0116     __attribute__((deprecated(message))) declarator
0117 # elif defined(_MSC_VER)
0118 #  define NODE_DEPRECATED(message, declarator)                                 \
0119     __declspec(deprecated) declarator
0120 # else
0121 #  define NODE_DEPRECATED(message, declarator) declarator
0122 # endif
0123 #endif
0124 
0125 // Forward-declare libuv loop
0126 struct uv_loop_s;
0127 
0128 // Forward-declare these functions now to stop MSVS from becoming
0129 // terminally confused when it's done in node_internals.h
0130 namespace node {
0131 
0132 struct SnapshotData;
0133 
0134 namespace tracing {
0135 
0136 class TracingController;
0137 
0138 }
0139 
0140 NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
0141                                                 int errorno,
0142                                                 const char* syscall = nullptr,
0143                                                 const char* message = nullptr,
0144                                                 const char* path = nullptr);
0145 NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
0146                                              int errorno,
0147                                              const char* syscall = nullptr,
0148                                              const char* message = nullptr,
0149                                              const char* path = nullptr,
0150                                              const char* dest = nullptr);
0151 
0152 NODE_DEPRECATED("Use ErrnoException(isolate, ...)",
0153                 inline v8::Local<v8::Value> ErrnoException(
0154       int errorno,
0155       const char* syscall = nullptr,
0156       const char* message = nullptr,
0157       const char* path = nullptr) {
0158   return ErrnoException(v8::Isolate::GetCurrent(),
0159                         errorno,
0160                         syscall,
0161                         message,
0162                         path);
0163 })
0164 
0165 NODE_DEPRECATED("Use UVException(isolate, ...)",
0166                 inline v8::Local<v8::Value> UVException(int errorno,
0167                                         const char* syscall = nullptr,
0168                                         const char* message = nullptr,
0169                                         const char* path = nullptr) {
0170   return UVException(v8::Isolate::GetCurrent(),
0171                      errorno,
0172                      syscall,
0173                      message,
0174                      path);
0175 })
0176 
0177 /*
0178  * These methods need to be called in a HandleScope.
0179  *
0180  * It is preferred that you use the `MakeCallback` overloads taking
0181  * `async_context` arguments.
0182  */
0183 
0184 NODE_DEPRECATED("Use MakeCallback(..., async_context)",
0185                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
0186                     v8::Isolate* isolate,
0187                     v8::Local<v8::Object> recv,
0188                     const char* method,
0189                     int argc,
0190                     v8::Local<v8::Value>* argv));
0191 NODE_DEPRECATED("Use MakeCallback(..., async_context)",
0192                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
0193                     v8::Isolate* isolate,
0194                     v8::Local<v8::Object> recv,
0195                     v8::Local<v8::String> symbol,
0196                     int argc,
0197                     v8::Local<v8::Value>* argv));
0198 NODE_DEPRECATED("Use MakeCallback(..., async_context)",
0199                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
0200                     v8::Isolate* isolate,
0201                     v8::Local<v8::Object> recv,
0202                     v8::Local<v8::Function> callback,
0203                     int argc,
0204                     v8::Local<v8::Value>* argv));
0205 
0206 }  // namespace node
0207 
0208 #include <cassert>
0209 #include <cstdint>
0210 
0211 #ifndef NODE_STRINGIFY
0212 # define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
0213 # define NODE_STRINGIFY_HELPER(n) #n
0214 #endif
0215 
0216 #ifdef _WIN32
0217 #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
0218 typedef intptr_t ssize_t;
0219 # define _SSIZE_T_
0220 # define _SSIZE_T_DEFINED
0221 #endif
0222 #else  // !_WIN32
0223 # include <sys/types.h>  // size_t, ssize_t
0224 #endif  // _WIN32
0225 
0226 
0227 namespace node {
0228 
0229 class IsolateData;
0230 class Environment;
0231 class MultiIsolatePlatform;
0232 class InitializationResultImpl;
0233 
0234 namespace ProcessInitializationFlags {
0235 enum Flags : uint32_t {
0236   kNoFlags = 0,
0237   // Enable stdio inheritance, which is disabled by default.
0238   // This flag is also implied by kNoStdioInitialization.
0239   kEnableStdioInheritance = 1 << 0,
0240   // Disable reading the NODE_OPTIONS environment variable.
0241   kDisableNodeOptionsEnv = 1 << 1,
0242   // Do not parse CLI options.
0243   kDisableCLIOptions = 1 << 2,
0244   // Do not initialize ICU.
0245   kNoICU = 1 << 3,
0246   // Do not modify stdio file descriptor or TTY state.
0247   kNoStdioInitialization = 1 << 4,
0248   // Do not register Node.js-specific signal handlers
0249   // and reset other signal handlers to default state.
0250   kNoDefaultSignalHandling = 1 << 5,
0251   // Do not perform V8 initialization.
0252   kNoInitializeV8 = 1 << 6,
0253   // Do not initialize a default Node.js-provided V8 platform instance.
0254   kNoInitializeNodeV8Platform = 1 << 7,
0255   // Do not initialize OpenSSL config.
0256   kNoInitOpenSSL = 1 << 8,
0257   // Do not initialize Node.js debugging based on environment variables.
0258   kNoParseGlobalDebugVariables = 1 << 9,
0259   // Do not adjust OS resource limits for this process.
0260   kNoAdjustResourceLimits = 1 << 10,
0261   // Do not map code segments into large pages for this process.
0262   kNoUseLargePages = 1 << 11,
0263   // Skip printing output for --help, --version, --v8-options.
0264   kNoPrintHelpOrVersionOutput = 1 << 12,
0265   // Do not perform cppgc initialization. If set, the embedder must call
0266   // cppgc::InitializeProcess() before creating a Node.js environment
0267   // and call cppgc::ShutdownProcess() before process shutdown.
0268   kNoInitializeCppgc = 1 << 13,
0269   // Initialize the process for predictable snapshot generation.
0270   kGeneratePredictableSnapshot = 1 << 14,
0271 
0272   // Emulate the behavior of InitializeNodeWithArgs() when passing
0273   // a flags argument to the InitializeOncePerProcess() replacement
0274   // function.
0275   kLegacyInitializeNodeWithArgsBehavior =
0276       kNoStdioInitialization | kNoDefaultSignalHandling | kNoInitializeV8 |
0277       kNoInitializeNodeV8Platform | kNoInitOpenSSL |
0278       kNoParseGlobalDebugVariables | kNoAdjustResourceLimits |
0279       kNoUseLargePages | kNoPrintHelpOrVersionOutput | kNoInitializeCppgc,
0280 };
0281 }  // namespace ProcessInitializationFlags
0282 namespace ProcessFlags = ProcessInitializationFlags;  // Legacy alias.
0283 
0284 namespace StopFlags {
0285 enum Flags : uint32_t {
0286   kNoFlags = 0,
0287   // Do not explicitly terminate the Isolate
0288   // when exiting the Environment.
0289   kDoNotTerminateIsolate = 1 << 0,
0290 };
0291 }  // namespace StopFlags
0292 
0293 class NODE_EXTERN InitializationResult {
0294  public:
0295   virtual ~InitializationResult() = default;
0296 
0297   // Returns a suggested process exit code.
0298   virtual int exit_code() const = 0;
0299 
0300   // Returns 'true' if initialization was aborted early due to errors.
0301   virtual bool early_return() const = 0;
0302 
0303   // Returns the parsed list of non-Node.js arguments.
0304   virtual const std::vector<std::string>& args() const = 0;
0305 
0306   // Returns the parsed list of Node.js arguments.
0307   virtual const std::vector<std::string>& exec_args() const = 0;
0308 
0309   // Returns an array of errors. Note that these may be warnings
0310   // whose existence does not imply a non-zero exit code.
0311   virtual const std::vector<std::string>& errors() const = 0;
0312 
0313   // If kNoInitializeNodeV8Platform was not specified, the global Node.js
0314   // platform instance.
0315   virtual MultiIsolatePlatform* platform() const = 0;
0316 
0317  private:
0318   InitializationResult() = default;
0319   friend class InitializationResultImpl;
0320 };
0321 
0322 // TODO(addaleax): Officially deprecate this and replace it with something
0323 // better suited for a public embedder API.
0324 NODE_EXTERN int Start(int argc, char* argv[]);
0325 
0326 // Tear down Node.js while it is running (there are active handles
0327 // in the loop and / or actively executing JavaScript code).
0328 NODE_EXTERN int Stop(Environment* env,
0329                      StopFlags::Flags flags = StopFlags::kNoFlags);
0330 
0331 // Set up per-process state needed to run Node.js. This will consume arguments
0332 // from argv, fill exec_argv, and possibly add errors resulting from parsing
0333 // the arguments to `errors`. The return value is a suggested exit code for the
0334 // program; If it is 0, then initializing Node.js succeeded.
0335 // This runs a subset of the initialization performed by
0336 // InitializeOncePerProcess(), which supersedes this function.
0337 // The subset is roughly equivalent to the one given by
0338 // `ProcessInitializationFlags::kLegacyInitializeNodeWithArgsBehavior`.
0339 NODE_DEPRECATED("Use InitializeOncePerProcess() instead",
0340                 NODE_EXTERN int InitializeNodeWithArgs(
0341                     std::vector<std::string>* argv,
0342                     std::vector<std::string>* exec_argv,
0343                     std::vector<std::string>* errors,
0344                     ProcessInitializationFlags::Flags flags =
0345                         ProcessInitializationFlags::kNoFlags));
0346 
0347 // Set up per-process state needed to run Node.js. This will consume arguments
0348 // from args, and return information about the initialization success,
0349 // including the arguments split into argv/exec_argv, a list of potential
0350 // errors encountered during initialization, and a potential suggested
0351 // exit code.
0352 NODE_EXTERN std::shared_ptr<InitializationResult> InitializeOncePerProcess(
0353     const std::vector<std::string>& args,
0354     ProcessInitializationFlags::Flags flags =
0355         ProcessInitializationFlags::kNoFlags);
0356 // Undoes the initialization performed by InitializeOncePerProcess(),
0357 // where cleanup is necessary.
0358 NODE_EXTERN void TearDownOncePerProcess();
0359 // Convenience overload for specifying multiple flags without having
0360 // to worry about casts.
0361 inline std::shared_ptr<InitializationResult> InitializeOncePerProcess(
0362     const std::vector<std::string>& args,
0363     std::initializer_list<ProcessInitializationFlags::Flags> list) {
0364   uint64_t flags_accum = ProcessInitializationFlags::kNoFlags;
0365   for (const auto flag : list) flags_accum |= static_cast<uint64_t>(flag);
0366   return InitializeOncePerProcess(
0367       args, static_cast<ProcessInitializationFlags::Flags>(flags_accum));
0368 }
0369 
0370 enum OptionEnvvarSettings {
0371   // Allow the options to be set via the environment variable, like
0372   // `NODE_OPTIONS`.
0373   kAllowedInEnvvar = 0,
0374   // Disallow the options to be set via the environment variable, like
0375   // `NODE_OPTIONS`.
0376   kDisallowedInEnvvar = 1,
0377 };
0378 
0379 // Process the arguments and set up the per-process options.
0380 // If the `settings` is set as OptionEnvvarSettings::kAllowedInEnvvar, the
0381 // options that are allowed in the environment variable are processed. Options
0382 // that are disallowed to be set via environment variable are processed as
0383 // errors.
0384 // Otherwise all the options that are disallowed (and those are allowed) to be
0385 // set via environment variable are processed.
0386 NODE_EXTERN int ProcessGlobalArgs(std::vector<std::string>* args,
0387                       std::vector<std::string>* exec_args,
0388                       std::vector<std::string>* errors,
0389                       OptionEnvvarSettings settings);
0390 
0391 class NodeArrayBufferAllocator;
0392 
0393 // An ArrayBuffer::Allocator class with some Node.js-specific tweaks. If you do
0394 // not have to use another allocator, using this class is recommended:
0395 // - It supports Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() with
0396 //   uninitialized memory.
0397 // - It supports transferring, rather than copying, ArrayBuffers when using
0398 //   MessagePorts.
0399 class NODE_EXTERN ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
0400  public:
0401   // If `always_debug` is true, create an ArrayBuffer::Allocator instance
0402   // that performs additional integrity checks (e.g. make sure that only memory
0403   // that was allocated by the it is also freed by it).
0404   // This can also be set using the --debug-arraybuffer-allocations flag.
0405   static std::unique_ptr<ArrayBufferAllocator> Create(
0406       bool always_debug = false);
0407 
0408  private:
0409   virtual NodeArrayBufferAllocator* GetImpl() = 0;
0410 
0411   friend class IsolateData;
0412 };
0413 
0414 // Legacy equivalents for ArrayBufferAllocator::Create().
0415 NODE_EXTERN ArrayBufferAllocator* CreateArrayBufferAllocator();
0416 NODE_EXTERN void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator);
0417 
0418 class NODE_EXTERN IsolatePlatformDelegate {
0419  public:
0420   virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner() = 0;
0421   virtual bool IdleTasksEnabled() = 0;
0422 };
0423 
0424 class NODE_EXTERN MultiIsolatePlatform : public v8::Platform {
0425  public:
0426   ~MultiIsolatePlatform() override = default;
0427   // Returns true if work was dispatched or executed. New tasks that are
0428   // posted during flushing of the queue are postponed until the next
0429   // flushing.
0430   virtual bool FlushForegroundTasks(v8::Isolate* isolate) = 0;
0431   virtual void DrainTasks(v8::Isolate* isolate) = 0;
0432 
0433   // This needs to be called between the calls to `Isolate::Allocate()` and
0434   // `Isolate::Initialize()`, so that initialization can already start
0435   // using the platform.
0436   // When using `NewIsolate()`, this is taken care of by that function.
0437   // This function may only be called once per `Isolate`.
0438   virtual void RegisterIsolate(v8::Isolate* isolate,
0439                                struct uv_loop_s* loop) = 0;
0440   // This method can be used when an application handles task scheduling on its
0441   // own through `IsolatePlatformDelegate`. Upon registering an isolate with
0442   // this overload any other method in this class with the exception of
0443   // `UnregisterIsolate` *must not* be used on that isolate.
0444   virtual void RegisterIsolate(v8::Isolate* isolate,
0445                                IsolatePlatformDelegate* delegate) = 0;
0446 
0447   // This function may only be called once per `Isolate`, and discard any
0448   // pending delayed tasks scheduled for that isolate.
0449   // This needs to be called right after calling `Isolate::Dispose()`.
0450   virtual void UnregisterIsolate(v8::Isolate* isolate) = 0;
0451   // This disposes, unregisters and frees up an isolate that's allocated using
0452   // v8::Isolate::Allocate() in the correct order to prevent race conditions.
0453   void DisposeIsolate(v8::Isolate* isolate);
0454 
0455   // The platform should call the passed function once all state associated
0456   // with the given isolate has been cleaned up. This can, but does not have to,
0457   // happen asynchronously.
0458   virtual void AddIsolateFinishedCallback(v8::Isolate* isolate,
0459                                           void (*callback)(void*),
0460                                           void* data) = 0;
0461 
0462   static std::unique_ptr<MultiIsolatePlatform> Create(
0463       int thread_pool_size,
0464       v8::TracingController* tracing_controller = nullptr,
0465       v8::PageAllocator* page_allocator = nullptr);
0466 };
0467 
0468 enum IsolateSettingsFlags {
0469   MESSAGE_LISTENER_WITH_ERROR_LEVEL = 1 << 0,
0470   DETAILED_SOURCE_POSITIONS_FOR_PROFILING = 1 << 1,
0471   SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK = 1 << 2,
0472   SHOULD_NOT_SET_PREPARE_STACK_TRACE_CALLBACK = 1 << 3,
0473   ALLOW_MODIFY_CODE_GENERATION_FROM_STRINGS_CALLBACK = 0, /* legacy no-op */
0474 };
0475 
0476 struct IsolateSettings {
0477   uint64_t flags = MESSAGE_LISTENER_WITH_ERROR_LEVEL |
0478       DETAILED_SOURCE_POSITIONS_FOR_PROFILING;
0479   v8::MicrotasksPolicy policy = v8::MicrotasksPolicy::kExplicit;
0480 
0481   // Error handling callbacks
0482   v8::Isolate::AbortOnUncaughtExceptionCallback
0483       should_abort_on_uncaught_exception_callback = nullptr;
0484   v8::FatalErrorCallback fatal_error_callback = nullptr;
0485   v8::OOMErrorCallback oom_error_callback = nullptr;
0486   v8::PrepareStackTraceCallback prepare_stack_trace_callback = nullptr;
0487 
0488   // Miscellaneous callbacks
0489   v8::PromiseRejectCallback promise_reject_callback = nullptr;
0490   v8::AllowWasmCodeGenerationCallback
0491       allow_wasm_code_generation_callback = nullptr;
0492   v8::ModifyCodeGenerationFromStringsCallback2
0493       modify_code_generation_from_strings_callback = nullptr;
0494 
0495   // When the settings is passed to NewIsolate():
0496   // - If cpp_heap is not nullptr, this CppHeap will be used to create
0497   //   the isolate and its ownership will be passed to V8.
0498   // - If this is nullptr, Node.js will create a CppHeap that will be
0499   //   owned by V8.
0500   //
0501   // When the settings is passed to SetIsolateUpForNode():
0502   // cpp_heap will be ignored. Embedders must ensure that the
0503   // v8::Isolate has a CppHeap attached while it's still used by
0504   // Node.js, for example using v8::CreateParams.
0505   //
0506   // See https://issues.chromium.org/issues/42203693. In future version
0507   // of V8, this CppHeap will be created by V8 if not provided.
0508   v8::CppHeap* cpp_heap = nullptr;
0509 };
0510 
0511 // Represents a startup snapshot blob, e.g. created by passing
0512 // --node-snapshot-main=entry.js to the configure script at build time,
0513 // or by running Node.js with the --build-snapshot option.
0514 //
0515 // If used, the snapshot *must* have been built with the same Node.js
0516 // version and V8 flags as the version that is currently running, and will
0517 // be rejected otherwise.
0518 // The same EmbedderSnapshotData instance *must* be passed to both
0519 // `NewIsolate()` and `CreateIsolateData()`. The first `Environment` instance
0520 // should be created with an empty `context` argument and will then
0521 // use the main context included in the snapshot blob. It can be retrieved
0522 // using `GetMainContext()`. `LoadEnvironment` can receive an empty
0523 // `StartExecutionCallback` in this case.
0524 // If V8 was configured with the shared-readonly-heap option, it requires
0525 // all snapshots used to create `Isolate` instances to be identical.
0526 // This option *must* be unset by embedders who wish to use the startup
0527 // feature during the build step by passing the --disable-shared-readonly-heap
0528 // flag to the configure script.
0529 //
0530 // The snapshot *must* be kept alive during the execution of the Isolate
0531 // that was created using it.
0532 //
0533 // Snapshots are an *experimental* feature. In particular, the embedder API
0534 // exposed through this class is subject to change or removal between Node.js
0535 // versions, including possible API and ABI breakage.
0536 class EmbedderSnapshotData {
0537  public:
0538   struct DeleteSnapshotData {
0539     void operator()(const EmbedderSnapshotData*) const;
0540   };
0541   using Pointer =
0542       std::unique_ptr<const EmbedderSnapshotData, DeleteSnapshotData>;
0543 
0544   // Return an EmbedderSnapshotData object that refers to the built-in
0545   // snapshot of Node.js. This can have been configured through e.g.
0546   // --node-snapshot-main=entry.js.
0547   static Pointer BuiltinSnapshotData();
0548 
0549   // Return an EmbedderSnapshotData object that is based on an input file.
0550   // Calling this method will consume but not close the FILE* handle.
0551   // The FILE* handle can be closed immediately following this call.
0552   // If the snapshot is invalid, this returns an empty pointer.
0553   static Pointer FromFile(FILE* in);
0554   static Pointer FromBlob(const std::vector<char>& in);
0555   static Pointer FromBlob(std::string_view in);
0556 
0557   // Write this EmbedderSnapshotData object to an output file.
0558   // Calling this method will not close the FILE* handle.
0559   // The FILE* handle can be closed immediately following this call.
0560   void ToFile(FILE* out) const;
0561   std::vector<char> ToBlob() const;
0562 
0563   // Returns whether custom snapshots can be used. Currently, this always
0564   // returns false since V8 enforces shared readonly-heap.
0565   static bool CanUseCustomSnapshotPerIsolate();
0566 
0567   EmbedderSnapshotData(const EmbedderSnapshotData&) = delete;
0568   EmbedderSnapshotData& operator=(const EmbedderSnapshotData&) = delete;
0569   EmbedderSnapshotData(EmbedderSnapshotData&&) = delete;
0570   EmbedderSnapshotData& operator=(EmbedderSnapshotData&&) = delete;
0571 
0572  protected:
0573   EmbedderSnapshotData(const SnapshotData* impl, bool owns_impl);
0574 
0575  private:
0576   const SnapshotData* impl_;
0577   bool owns_impl_;
0578   friend struct SnapshotData;
0579   friend class CommonEnvironmentSetup;
0580 };
0581 
0582 // Overriding IsolateSettings may produce unexpected behavior
0583 // in Node.js core functionality, so proceed at your own risk.
0584 NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate,
0585                                      const IsolateSettings& settings);
0586 
0587 // Set a number of callbacks for the `isolate`, in particular the Node.js
0588 // uncaught exception listener.
0589 NODE_EXTERN void SetIsolateUpForNode(v8::Isolate* isolate);
0590 
0591 // Creates a new isolate with Node.js-specific settings.
0592 // This is a convenience method equivalent to using SetIsolateCreateParams(),
0593 // Isolate::Allocate(), MultiIsolatePlatform::RegisterIsolate(),
0594 // Isolate::Initialize(), and SetIsolateUpForNode().
0595 NODE_EXTERN v8::Isolate* NewIsolate(
0596     ArrayBufferAllocator* allocator,
0597     struct uv_loop_s* event_loop,
0598     MultiIsolatePlatform* platform,
0599     const EmbedderSnapshotData* snapshot_data = nullptr,
0600     const IsolateSettings& settings = {});
0601 NODE_EXTERN v8::Isolate* NewIsolate(
0602     std::shared_ptr<ArrayBufferAllocator> allocator,
0603     struct uv_loop_s* event_loop,
0604     MultiIsolatePlatform* platform,
0605     const EmbedderSnapshotData* snapshot_data = nullptr,
0606     const IsolateSettings& settings = {});
0607 
0608 // Creates a new context with Node.js-specific tweaks.
0609 NODE_EXTERN v8::Local<v8::Context> NewContext(
0610     v8::Isolate* isolate,
0611     v8::Local<v8::ObjectTemplate> object_template =
0612         v8::Local<v8::ObjectTemplate>());
0613 
0614 // Runs Node.js-specific tweaks on an already constructed context
0615 // Return value indicates success of operation
0616 NODE_EXTERN v8::Maybe<bool> InitializeContext(v8::Local<v8::Context> context);
0617 
0618 // If `platform` is passed, it will be used to register new Worker instances.
0619 // It can be `nullptr`, in which case creating new Workers inside of
0620 // Environments that use this `IsolateData` will not work.
0621 NODE_EXTERN IsolateData* CreateIsolateData(
0622     v8::Isolate* isolate,
0623     struct uv_loop_s* loop,
0624     MultiIsolatePlatform* platform = nullptr,
0625     ArrayBufferAllocator* allocator = nullptr,
0626     const EmbedderSnapshotData* snapshot_data = nullptr);
0627 NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data);
0628 
0629 struct ThreadId {
0630   uint64_t id = static_cast<uint64_t>(-1);
0631 };
0632 NODE_EXTERN ThreadId AllocateEnvironmentThreadId();
0633 
0634 namespace EnvironmentFlags {
0635 enum Flags : uint64_t {
0636   kNoFlags = 0,
0637   // Use the default behaviour for Node.js instances.
0638   kDefaultFlags = 1 << 0,
0639   // Controls whether this Environment is allowed to affect per-process state
0640   // (e.g. cwd, process title, uid, etc.).
0641   // This is set when using kDefaultFlags.
0642   kOwnsProcessState = 1 << 1,
0643   // Set if this Environment instance is associated with the global inspector
0644   // handling code (i.e. listening on SIGUSR1).
0645   // This is set when using kDefaultFlags.
0646   kOwnsInspector = 1 << 2,
0647   // Set if Node.js should not run its own esm loader. This is needed by some
0648   // embedders, because it's possible for the Node.js esm loader to conflict
0649   // with another one in an embedder environment, e.g. Blink's in Chromium.
0650   kNoRegisterESMLoader = 1 << 3,
0651   // Set this flag to make Node.js track "raw" file descriptors, i.e. managed
0652   // by fs.open() and fs.close(), and close them during FreeEnvironment().
0653   kTrackUnmanagedFds = 1 << 4,
0654   // Set this flag to force hiding console windows when spawning child
0655   // processes. This is usually used when embedding Node.js in GUI programs on
0656   // Windows.
0657   kHideConsoleWindows = 1 << 5,
0658   // Set this flag to disable loading native addons via `process.dlopen`.
0659   // This environment flag is especially important for worker threads
0660   // so that a worker thread can't load a native addon even if `execArgv`
0661   // is overwritten and `--no-addons` is not specified but was specified
0662   // for this Environment instance.
0663   kNoNativeAddons = 1 << 6,
0664   // Set this flag to disable searching modules from global paths like
0665   // $HOME/.node_modules and $NODE_PATH. This is used by standalone apps that
0666   // do not expect to have their behaviors changed because of globally
0667   // installed modules.
0668   kNoGlobalSearchPaths = 1 << 7,
0669   // Do not export browser globals like setTimeout, console, etc.
0670   kNoBrowserGlobals = 1 << 8,
0671   // Controls whether or not the Environment should call V8Inspector::create().
0672   // This control is needed by embedders who may not want to initialize the V8
0673   // inspector in situations where one has already been created,
0674   // e.g. Blink's in Chromium.
0675   kNoCreateInspector = 1 << 9,
0676   // Controls whether or not the InspectorAgent for this Environment should
0677   // call StartDebugSignalHandler. This control is needed by embedders who may
0678   // not want to allow other processes to start the V8 inspector.
0679   kNoStartDebugSignalHandler = 1 << 10,
0680   // Controls whether the InspectorAgent created for this Environment waits for
0681   // Inspector frontend events during the Environment creation. It's used to
0682   // call node::Stop(env) on a Worker thread that is waiting for the events.
0683   kNoWaitForInspectorFrontend = 1 << 11
0684 };
0685 }  // namespace EnvironmentFlags
0686 
0687 enum class SnapshotFlags : uint32_t {
0688   kDefault = 0,
0689   // Whether code cache should be generated as part of the snapshot.
0690   // Code cache reduces the time spent on compiling functions included
0691   // in the snapshot at the expense of a bigger snapshot size and
0692   // potentially breaking portability of the snapshot.
0693   kWithoutCodeCache = 1 << 0,
0694 };
0695 
0696 struct SnapshotConfig {
0697   SnapshotFlags flags = SnapshotFlags::kDefault;
0698 
0699   // When builder_script_path is std::nullopt, the snapshot is generated as a
0700   // built-in snapshot instead of a custom one, and it's expected that the
0701   // built-in snapshot only contains states that reproduce in every run of the
0702   // application. The event loop won't be run when generating a built-in
0703   // snapshot, so asynchronous operations should be avoided.
0704   //
0705   // When builder_script_path is an std::string, it should match args[1]
0706   // passed to CreateForSnapshotting(). The embedder is also expected to use
0707   // LoadEnvironment() to run a script matching this path. In that case the
0708   // snapshot is generated as a custom snapshot and the event loop is run, so
0709   // the snapshot builder can execute asynchronous operations as long as they
0710   // are run to completion when the snapshot is taken.
0711   std::optional<std::string> builder_script_path;
0712 };
0713 
0714 struct InspectorParentHandle {
0715   virtual ~InspectorParentHandle() = default;
0716 };
0717 
0718 // TODO(addaleax): Maybe move per-Environment options parsing here.
0719 // Returns nullptr when the Environment cannot be created e.g. there are
0720 // pending JavaScript exceptions.
0721 // `context` may be empty if an `EmbedderSnapshotData` instance was provided
0722 // to `NewIsolate()` and `CreateIsolateData()`.
0723 NODE_EXTERN Environment* CreateEnvironment(
0724     IsolateData* isolate_data,
0725     v8::Local<v8::Context> context,
0726     const std::vector<std::string>& args,
0727     const std::vector<std::string>& exec_args,
0728     EnvironmentFlags::Flags flags = EnvironmentFlags::kDefaultFlags,
0729     ThreadId thread_id = {} /* allocates a thread id automatically */,
0730     std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {});
0731 
0732 NODE_EXTERN Environment* CreateEnvironment(
0733     IsolateData* isolate_data,
0734     v8::Local<v8::Context> context,
0735     const std::vector<std::string>& args,
0736     const std::vector<std::string>& exec_args,
0737     EnvironmentFlags::Flags flags,
0738     ThreadId thread_id,
0739     std::unique_ptr<InspectorParentHandle> inspector_parent_handle,
0740     std::string_view thread_name);
0741 
0742 // Returns a handle that can be passed to `LoadEnvironment()`, making the
0743 // child Environment accessible to the inspector as if it were a Node.js Worker.
0744 // `child_thread_id` can be created using `AllocateEnvironmentThreadId()`
0745 // and then later passed on to `CreateEnvironment()` to create the child
0746 // Environment, together with the inspector handle.
0747 // This method should not be called while the parent Environment is active
0748 // on another thread.
0749 NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
0750     Environment* parent_env,
0751     ThreadId child_thread_id,
0752     const char* child_url);
0753 
0754 NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
0755     Environment* parent_env,
0756     ThreadId child_thread_id,
0757     const char* child_url,
0758     const char* name);
0759 
0760 NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
0761     Environment* parent_env,
0762     ThreadId child_thread_id,
0763     std::string_view child_url,
0764     std::string_view name);
0765 
0766 struct StartExecutionCallbackInfo {
0767   v8::Local<v8::Object> process_object;
0768   v8::Local<v8::Function> native_require;
0769   v8::Local<v8::Function> run_cjs;
0770 };
0771 
0772 using StartExecutionCallback =
0773     std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>;
0774 using EmbedderPreloadCallback =
0775     std::function<void(Environment* env,
0776                        v8::Local<v8::Value> process,
0777                        v8::Local<v8::Value> require)>;
0778 
0779 // Run initialization for the environment.
0780 //
0781 // The |preload| function, usually used by embedders to inject scripts,
0782 // will be run by Node.js before Node.js executes the entry point.
0783 // The function is guaranteed to run before the user land module loader running
0784 // any user code, so it is safe to assume that at this point, no user code has
0785 // been run yet.
0786 // The function will be executed with preload(process, require), and the passed
0787 // require function has access to internal Node.js modules. There is no
0788 // stability guarantee about the internals exposed to the internal require
0789 // function. Expect breakages when updating Node.js versions if the embedder
0790 // imports internal modules with the internal require function.
0791 // Worker threads created in the environment will also respect The |preload|
0792 // function, so make sure the function is thread-safe.
0793 NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
0794     Environment* env,
0795     StartExecutionCallback cb,
0796     EmbedderPreloadCallback preload = nullptr);
0797 NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
0798     Environment* env,
0799     std::string_view main_script_source_utf8,
0800     EmbedderPreloadCallback preload = nullptr);
0801 NODE_EXTERN void FreeEnvironment(Environment* env);
0802 
0803 // Set a callback that is called when process.exit() is called from JS,
0804 // overriding the default handler.
0805 // It receives the Environment* instance and the exit code as arguments.
0806 // This could e.g. call Stop(env); in order to terminate execution and stop
0807 // the event loop.
0808 // The default handler disposes of the global V8 platform instance, if one is
0809 // being used, and calls exit().
0810 NODE_EXTERN void SetProcessExitHandler(
0811     Environment* env,
0812     std::function<void(Environment*, int)>&& handler);
0813 NODE_EXTERN void DefaultProcessExitHandler(Environment* env, int exit_code);
0814 
0815 // This may return nullptr if context is not associated with a Node instance.
0816 NODE_EXTERN Environment* GetCurrentEnvironment(v8::Local<v8::Context> context);
0817 NODE_EXTERN IsolateData* GetEnvironmentIsolateData(Environment* env);
0818 NODE_EXTERN ArrayBufferAllocator* GetArrayBufferAllocator(IsolateData* data);
0819 // This is mostly useful for Environment* instances that were created through
0820 // a snapshot and have a main context that was read from that snapshot.
0821 NODE_EXTERN v8::Local<v8::Context> GetMainContext(Environment* env);
0822 
0823 [[noreturn]] NODE_EXTERN void OnFatalError(const char* location,
0824                                            const char* message);
0825 NODE_EXTERN void PromiseRejectCallback(v8::PromiseRejectMessage message);
0826 NODE_EXTERN bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
0827                                             v8::Local<v8::String>);
0828 NODE_EXTERN bool ShouldAbortOnUncaughtException(v8::Isolate* isolate);
0829 NODE_EXTERN v8::MaybeLocal<v8::Value> PrepareStackTraceCallback(
0830     v8::Local<v8::Context> context,
0831     v8::Local<v8::Value> exception,
0832     v8::Local<v8::Array> trace);
0833 
0834 // Writes a diagnostic report to a file. If filename is not provided, the
0835 // default filename includes the date, time, PID, and a sequence number.
0836 // The report's JavaScript stack trace is taken from err, if present.
0837 // If isolate is nullptr, no information about the JavaScript environment
0838 // is included in the report.
0839 // Returns the filename of the written report.
0840 NODE_EXTERN std::string TriggerNodeReport(v8::Isolate* isolate,
0841                                           const char* message,
0842                                           const char* trigger,
0843                                           const std::string& filename,
0844                                           v8::Local<v8::Value> error);
0845 NODE_EXTERN std::string TriggerNodeReport(Environment* env,
0846                                           const char* message,
0847                                           const char* trigger,
0848                                           const std::string& filename,
0849                                           v8::Local<v8::Value> error);
0850 NODE_EXTERN void GetNodeReport(v8::Isolate* isolate,
0851                                const char* message,
0852                                const char* trigger,
0853                                v8::Local<v8::Value> error,
0854                                std::ostream& out);
0855 NODE_EXTERN void GetNodeReport(Environment* env,
0856                                const char* message,
0857                                const char* trigger,
0858                                v8::Local<v8::Value> error,
0859                                std::ostream& out);
0860 
0861 // This returns the MultiIsolatePlatform used for an Environment or IsolateData
0862 // instance, if one exists.
0863 NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(Environment* env);
0864 NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env);
0865 
0866 NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead",
0867     NODE_EXTERN MultiIsolatePlatform* CreatePlatform(
0868         int thread_pool_size,
0869         v8::TracingController* tracing_controller));
0870 NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead",
0871     NODE_EXTERN void FreePlatform(MultiIsolatePlatform* platform));
0872 
0873 // Get/set the currently active tracing controller. Using CreatePlatform()
0874 // will implicitly set this by default. This is global and should be initialized
0875 // along with the v8::Platform instance that is being used. `controller`
0876 // is allowed to be `nullptr`.
0877 // This is used for tracing events from Node.js itself. V8 uses the tracing
0878 // controller returned from the active `v8::Platform` instance.
0879 NODE_EXTERN v8::TracingController* GetTracingController();
0880 NODE_EXTERN void SetTracingController(v8::TracingController* controller);
0881 
0882 // Run `process.emit('beforeExit')` as it would usually happen when Node.js is
0883 // run in standalone mode.
0884 NODE_EXTERN v8::Maybe<bool> EmitProcessBeforeExit(Environment* env);
0885 NODE_DEPRECATED("Use Maybe version (EmitProcessBeforeExit) instead",
0886     NODE_EXTERN void EmitBeforeExit(Environment* env));
0887 // Run `process.emit('exit')` as it would usually happen when Node.js is run
0888 // in standalone mode. The return value corresponds to the exit code.
0889 NODE_EXTERN v8::Maybe<int> EmitProcessExit(Environment* env);
0890 NODE_DEPRECATED("Use Maybe version (EmitProcessExit) instead",
0891     NODE_EXTERN int EmitExit(Environment* env));
0892 
0893 // Runs hooks added through `AtExit()`. This is part of `FreeEnvironment()`,
0894 // so calling it manually is typically not necessary.
0895 NODE_EXTERN void RunAtExit(Environment* env);
0896 
0897 // This may return nullptr if the current v8::Context is not associated
0898 // with a Node instance.
0899 NODE_EXTERN struct uv_loop_s* GetCurrentEventLoop(v8::Isolate* isolate);
0900 
0901 // Runs the main loop for a given Environment. This roughly performs the
0902 // following steps:
0903 // 1. Call uv_run() on the event loop until it is drained.
0904 // 2. Call platform->DrainTasks() on the associated platform/isolate.
0905 //   3. If the event loop is alive again, go to Step 1.
0906 // 4. Call EmitProcessBeforeExit().
0907 //   5. If the event loop is alive again, go to Step 1.
0908 // 6. Call EmitProcessExit() and forward the return value.
0909 // If at any point node::Stop() is called, the function will attempt to return
0910 // as soon as possible, returning an empty `Maybe`.
0911 // This function only works if `env` has an associated `MultiIsolatePlatform`.
0912 NODE_EXTERN v8::Maybe<int> SpinEventLoop(Environment* env);
0913 
0914 NODE_EXTERN std::string GetAnonymousMainPath();
0915 
0916 class NODE_EXTERN CommonEnvironmentSetup {
0917  public:
0918   ~CommonEnvironmentSetup();
0919 
0920   // Create a new CommonEnvironmentSetup, that is, a group of objects that
0921   // together form the typical setup for a single Node.js Environment instance.
0922   // If any error occurs, `*errors` will be populated and the returned pointer
0923   // will be empty.
0924   // env_args will be passed through as arguments to CreateEnvironment(), after
0925   // `isolate_data` and `context`.
0926   template <typename... EnvironmentArgs>
0927   static std::unique_ptr<CommonEnvironmentSetup> Create(
0928       MultiIsolatePlatform* platform,
0929       std::vector<std::string>* errors,
0930       EnvironmentArgs&&... env_args);
0931   template <typename... EnvironmentArgs>
0932   static std::unique_ptr<CommonEnvironmentSetup> CreateFromSnapshot(
0933       MultiIsolatePlatform* platform,
0934       std::vector<std::string>* errors,
0935       const EmbedderSnapshotData* snapshot_data,
0936       EnvironmentArgs&&... env_args);
0937 
0938   // Create an embedding setup which will be used for creating a snapshot
0939   // using CreateSnapshot().
0940   //
0941   // This will create and attach a v8::SnapshotCreator to this instance,
0942   // and the same restrictions apply to this instance that also apply to
0943   // other V8 snapshotting environments.
0944   // Not all Node.js APIs are supported in this case. Currently, there is
0945   // no support for native/host objects other than Node.js builtins
0946   // in the snapshot.
0947   //
0948   // If the embedder wants to use LoadEnvironment() later to run a snapshot
0949   // builder script they should make sure args[1] contains the path of the
0950   // snapshot script, which will be used to create __filename and __dirname
0951   // in the context where the builder script is run. If they do not want to
0952   // include the build-time paths into the snapshot, use the string returned
0953   // by GetAnonymousMainPath() as args[1] to anonymize the script.
0954   //
0955   // Snapshots are an *experimental* feature. In particular, the embedder API
0956   // exposed through this class is subject to change or removal between Node.js
0957   // versions, including possible API and ABI breakage.
0958   static std::unique_ptr<CommonEnvironmentSetup> CreateForSnapshotting(
0959       MultiIsolatePlatform* platform,
0960       std::vector<std::string>* errors,
0961       const std::vector<std::string>& args = {},
0962       const std::vector<std::string>& exec_args = {},
0963       const SnapshotConfig& snapshot_config = {});
0964   EmbedderSnapshotData::Pointer CreateSnapshot();
0965 
0966   struct uv_loop_s* event_loop() const;
0967   v8::SnapshotCreator* snapshot_creator();
0968   // Empty for snapshotting environments.
0969   std::shared_ptr<ArrayBufferAllocator> array_buffer_allocator() const;
0970   v8::Isolate* isolate() const;
0971   IsolateData* isolate_data() const;
0972   Environment* env() const;
0973   v8::Local<v8::Context> context() const;
0974 
0975   CommonEnvironmentSetup(const CommonEnvironmentSetup&) = delete;
0976   CommonEnvironmentSetup& operator=(const CommonEnvironmentSetup&) = delete;
0977   CommonEnvironmentSetup(CommonEnvironmentSetup&&) = delete;
0978   CommonEnvironmentSetup& operator=(CommonEnvironmentSetup&&) = delete;
0979 
0980  private:
0981   enum Flags : uint32_t {
0982     kNoFlags = 0,
0983     kIsForSnapshotting = 1,
0984   };
0985 
0986   struct Impl;
0987   Impl* impl_;
0988 
0989   CommonEnvironmentSetup(
0990       MultiIsolatePlatform*,
0991       std::vector<std::string>*,
0992       std::function<Environment*(const CommonEnvironmentSetup*)>);
0993   CommonEnvironmentSetup(
0994       MultiIsolatePlatform*,
0995       std::vector<std::string>*,
0996       const EmbedderSnapshotData*,
0997       uint32_t flags,
0998       std::function<Environment*(const CommonEnvironmentSetup*)>,
0999       const SnapshotConfig* config = nullptr);
1000 };
1001 
1002 // Implementation for CommonEnvironmentSetup::Create
1003 template <typename... EnvironmentArgs>
1004 std::unique_ptr<CommonEnvironmentSetup> CommonEnvironmentSetup::Create(
1005     MultiIsolatePlatform* platform,
1006     std::vector<std::string>* errors,
1007     EnvironmentArgs&&... env_args) {
1008   auto ret = std::unique_ptr<CommonEnvironmentSetup>(new CommonEnvironmentSetup(
1009       platform, errors,
1010       [&](const CommonEnvironmentSetup* setup) -> Environment* {
1011         return CreateEnvironment(
1012             setup->isolate_data(), setup->context(),
1013             std::forward<EnvironmentArgs>(env_args)...);
1014       }));
1015   if (!errors->empty()) ret.reset();
1016   return ret;
1017 }
1018 
1019 // Implementation for ::CreateFromSnapshot -- the ::Create() method
1020 // could call this with a nullptr snapshot_data in a major version.
1021 template <typename... EnvironmentArgs>
1022 std::unique_ptr<CommonEnvironmentSetup>
1023 CommonEnvironmentSetup::CreateFromSnapshot(
1024     MultiIsolatePlatform* platform,
1025     std::vector<std::string>* errors,
1026     const EmbedderSnapshotData* snapshot_data,
1027     EnvironmentArgs&&... env_args) {
1028   auto ret = std::unique_ptr<CommonEnvironmentSetup>(new CommonEnvironmentSetup(
1029       platform,
1030       errors,
1031       snapshot_data,
1032       Flags::kNoFlags,
1033       [&](const CommonEnvironmentSetup* setup) -> Environment* {
1034         return CreateEnvironment(setup->isolate_data(),
1035                                  setup->context(),
1036                                  std::forward<EnvironmentArgs>(env_args)...);
1037       }));
1038   if (!errors->empty()) ret.reset();
1039   return ret;
1040 }
1041 
1042 /* Converts a unixtime to V8 Date */
1043 NODE_DEPRECATED("Use v8::Date::New() directly",
1044                 inline v8::Local<v8::Value> NODE_UNIXTIME_V8(double time) {
1045                   return v8::Date::New(
1046                              v8::Isolate::GetCurrent()->GetCurrentContext(),
1047                              1000 * time)
1048                       .ToLocalChecked();
1049                 })
1050 #define NODE_UNIXTIME_V8 node::NODE_UNIXTIME_V8
1051 NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
1052                 inline double NODE_V8_UNIXTIME(v8::Local<v8::Date> date) {
1053   return date->ValueOf() / 1000;
1054 })
1055 #define NODE_V8_UNIXTIME node::NODE_V8_UNIXTIME
1056 
1057 #define NODE_DEFINE_CONSTANT(target, constant)                                 \
1058   do {                                                                         \
1059     v8::Isolate* isolate = target->GetIsolate();                               \
1060     v8::Local<v8::Context> context = isolate->GetCurrentContext();             \
1061     v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal(      \
1062         isolate, #constant, v8::NewStringType::kInternalized);                 \
1063     v8::Local<v8::Number> constant_value =                                     \
1064         v8::Number::New(isolate, static_cast<double>(constant));               \
1065     v8::PropertyAttribute constant_attributes =                                \
1066         static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);     \
1067     (target)                                                                   \
1068         ->DefineOwnProperty(                                                   \
1069             context, constant_name, constant_value, constant_attributes)       \
1070         .Check();                                                              \
1071   } while (0)
1072 
1073 #define NODE_DEFINE_HIDDEN_CONSTANT(target, constant)                          \
1074   do {                                                                         \
1075     v8::Isolate* isolate = target->GetIsolate();                               \
1076     v8::Local<v8::Context> context = isolate->GetCurrentContext();             \
1077     v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal(      \
1078         isolate, #constant, v8::NewStringType::kInternalized);                 \
1079     v8::Local<v8::Number> constant_value =                                     \
1080         v8::Number::New(isolate, static_cast<double>(constant));               \
1081     v8::PropertyAttribute constant_attributes =                                \
1082         static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete |     \
1083                                            v8::DontEnum);                      \
1084     (target)                                                                   \
1085         ->DefineOwnProperty(                                                   \
1086             context, constant_name, constant_value, constant_attributes)       \
1087         .Check();                                                              \
1088   } while (0)
1089 
1090 // Used to be a macro, hence the uppercase name.
1091 inline void NODE_SET_METHOD(v8::Local<v8::Template> 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::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
1097                                                                 callback);
1098   v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name,
1099       v8::NewStringType::kInternalized).ToLocalChecked();
1100   t->SetClassName(fn_name);
1101   recv->Set(fn_name, t);
1102 }
1103 
1104 // Used to be a macro, hence the uppercase name.
1105 inline void NODE_SET_METHOD(v8::Local<v8::Object> recv,
1106                             const char* name,
1107                             v8::FunctionCallback callback) {
1108   v8::Isolate* isolate = v8::Isolate::GetCurrent();
1109   v8::HandleScope handle_scope(isolate);
1110   v8::Local<v8::Context> context = isolate->GetCurrentContext();
1111   v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
1112                                                                 callback);
1113   v8::Local<v8::Function> fn = t->GetFunction(context).ToLocalChecked();
1114   v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name,
1115       v8::NewStringType::kInternalized).ToLocalChecked();
1116   fn->SetName(fn_name);
1117   recv->Set(context, fn_name, fn).Check();
1118 }
1119 #define NODE_SET_METHOD node::NODE_SET_METHOD
1120 
1121 // Used to be a macro, hence the uppercase name.
1122 // Not a template because it only makes sense for FunctionTemplates.
1123 inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv,
1124                                       const char* name,
1125                                       v8::FunctionCallback callback) {
1126   v8::Isolate* isolate = v8::Isolate::GetCurrent();
1127   v8::HandleScope handle_scope(isolate);
1128   v8::Local<v8::Signature> s = v8::Signature::New(isolate, recv);
1129   v8::Local<v8::FunctionTemplate> t =
1130       v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), s);
1131   v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name,
1132       v8::NewStringType::kInternalized).ToLocalChecked();
1133   t->SetClassName(fn_name);
1134   recv->PrototypeTemplate()->Set(fn_name, t);
1135 }
1136 #define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD
1137 
1138 // BINARY is a deprecated alias of LATIN1.
1139 // BASE64URL is not currently exposed to the JavaScript side.
1140 enum encoding {
1141   ASCII,
1142   UTF8,
1143   BASE64,
1144   UCS2,
1145   BINARY,
1146   HEX,
1147   BUFFER,
1148   BASE64URL,
1149   LATIN1 = BINARY
1150 };
1151 
1152 NODE_EXTERN enum encoding ParseEncoding(
1153     v8::Isolate* isolate,
1154     v8::Local<v8::Value> encoding_v,
1155     enum encoding default_encoding = LATIN1);
1156 
1157 NODE_EXTERN void FatalException(v8::Isolate* isolate,
1158                                 const v8::TryCatch& try_catch);
1159 
1160 NODE_EXTERN v8::MaybeLocal<v8::Value> TryEncode(
1161     v8::Isolate* isolate,
1162     const char* buf,
1163     size_t len,
1164     enum encoding encoding = LATIN1);
1165 
1166 // Warning: This reverses endianness on Big Endian platforms, even though the
1167 // signature using uint16_t implies that it should not.
1168 NODE_EXTERN v8::MaybeLocal<v8::Value> TryEncode(v8::Isolate* isolate,
1169                                                 const uint16_t* buf,
1170                                                 size_t len);
1171 
1172 // The original Encode(...) functions are deprecated because they do not
1173 // appropriately propagate exceptions and instead rely on ToLocalChecked()
1174 // which crashes the process if an exception occurs. We cannot just remove
1175 // these as it would break ABI compatibility, so we keep them around but
1176 // deprecate them in favor of the TryEncode(...) variations which return
1177 // a MaybeLocal<> and do not crash the process if an exception occurs.
1178 NODE_DEPRECATED(
1179     "Use TryEncode(...) instead",
1180     NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
1181                                             const char* buf,
1182                                             size_t len,
1183                                             enum encoding encoding = LATIN1));
1184 
1185 // Warning: This reverses endianness on Big Endian platforms, even though the
1186 // signature using uint16_t implies that it should not.
1187 NODE_DEPRECATED("Use TryEncode(...) instead",
1188                 NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
1189                                                         const uint16_t* buf,
1190                                                         size_t len));
1191 
1192 // Returns -1 if the handle was not valid for decoding
1193 NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
1194                                 v8::Local<v8::Value>,
1195                                 enum encoding encoding = LATIN1);
1196 // returns bytes written.
1197 NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate,
1198                                 char* buf,
1199                                 size_t buflen,
1200                                 v8::Local<v8::Value>,
1201                                 enum encoding encoding = LATIN1);
1202 #ifdef _WIN32
1203 NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
1204     v8::Isolate* isolate,
1205     int errorno,
1206     const char* syscall = nullptr,
1207     const char* msg = "",
1208     const char* path = nullptr);
1209 #endif
1210 
1211 const char* signo_string(int errorno);
1212 
1213 
1214 typedef void (*addon_register_func)(
1215     v8::Local<v8::Object> exports,
1216     v8::Local<v8::Value> module,
1217     void* priv);
1218 
1219 typedef void (*addon_context_register_func)(
1220     v8::Local<v8::Object> exports,
1221     v8::Local<v8::Value> module,
1222     v8::Local<v8::Context> context,
1223     void* priv);
1224 
1225 enum ModuleFlags {
1226   kLinked = 0x02
1227 };
1228 
1229 struct node_module {
1230   int nm_version;
1231   unsigned int nm_flags;
1232   void* nm_dso_handle;
1233   const char* nm_filename;
1234   node::addon_register_func nm_register_func;
1235   node::addon_context_register_func nm_context_register_func;
1236   const char* nm_modname;
1237   void* nm_priv;
1238   struct node_module* nm_link;
1239 };
1240 
1241 extern "C" NODE_EXTERN void node_module_register(void* mod);
1242 
1243 #ifdef _WIN32
1244 # define NODE_MODULE_EXPORT __declspec(dllexport)
1245 #else
1246 # define NODE_MODULE_EXPORT __attribute__((visibility("default")))
1247 #endif
1248 
1249 #ifdef NODE_SHARED_MODE
1250 # define NODE_CTOR_PREFIX
1251 #else
1252 # define NODE_CTOR_PREFIX static
1253 #endif
1254 
1255 #if defined(_MSC_VER)
1256 #define NODE_C_CTOR(fn)                                               \
1257   NODE_CTOR_PREFIX void __cdecl fn(void);                             \
1258   namespace {                                                         \
1259   struct fn##_ {                                                      \
1260     fn##_() { fn(); };                                                \
1261   } fn##_v_;                                                          \
1262   }                                                                   \
1263   NODE_CTOR_PREFIX void __cdecl fn(void)
1264 #else
1265 #define NODE_C_CTOR(fn)                                               \
1266   NODE_CTOR_PREFIX void fn(void) __attribute__((constructor));        \
1267   NODE_CTOR_PREFIX void fn(void)
1268 #endif
1269 
1270 #define NODE_MODULE_X(modname, regfunc, priv, flags)                  \
1271   extern "C" {                                                        \
1272     static node::node_module _module =                                \
1273     {                                                                 \
1274       NODE_MODULE_VERSION,                                            \
1275       flags,                                                          \
1276       NULL,  /* NOLINT (readability/null_usage) */                    \
1277       __FILE__,                                                       \
1278       (node::addon_register_func) (regfunc),                          \
1279       NULL,  /* NOLINT (readability/null_usage) */                    \
1280       NODE_STRINGIFY(modname),                                        \
1281       priv,                                                           \
1282       NULL   /* NOLINT (readability/null_usage) */                    \
1283     };                                                                \
1284     NODE_C_CTOR(_register_ ## modname) {                              \
1285       node_module_register(&_module);                                 \
1286     }                                                                 \
1287   }
1288 
1289 #define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags)    \
1290   extern "C" {                                                        \
1291     static node::node_module _module =                                \
1292     {                                                                 \
1293       NODE_MODULE_VERSION,                                            \
1294       flags,                                                          \
1295       NULL,  /* NOLINT (readability/null_usage) */                    \
1296       __FILE__,                                                       \
1297       NULL,  /* NOLINT (readability/null_usage) */                    \
1298       (node::addon_context_register_func) (regfunc),                  \
1299       NODE_STRINGIFY(modname),                                        \
1300       priv,                                                           \
1301       NULL  /* NOLINT (readability/null_usage) */                     \
1302     };                                                                \
1303     NODE_C_CTOR(_register_ ## modname) {                              \
1304       node_module_register(&_module);                                 \
1305     }                                                                 \
1306   }
1307 
1308 // Usage: `NODE_MODULE(NODE_GYP_MODULE_NAME, InitializerFunction)`
1309 // If no NODE_MODULE is declared, Node.js looks for the well-known
1310 // symbol `node_register_module_v${NODE_MODULE_VERSION}`.
1311 #define NODE_MODULE(modname, regfunc)                                 \
1312   NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
1313 
1314 #define NODE_MODULE_CONTEXT_AWARE(modname, regfunc)                   \
1315   /* NOLINTNEXTLINE (readability/null_usage) */                       \
1316   NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)
1317 
1318 // Embedders can use this type of binding for statically linked native bindings.
1319 // It is used the same way addon bindings are used, except that linked bindings
1320 // can be accessed through `process._linkedBinding(modname)`.
1321 #define NODE_MODULE_LINKED(modname, regfunc)                               \
1322   /* NOLINTNEXTLINE (readability/null_usage) */                            \
1323   NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL,                      \
1324                               node::ModuleFlags::kLinked)
1325 
1326 /*
1327  * For backward compatibility in add-on modules.
1328  */
1329 #define NODE_MODULE_DECL /* nothing */
1330 
1331 #define NODE_MODULE_INITIALIZER_BASE node_register_module_v
1332 
1333 #define NODE_MODULE_INITIALIZER_X(base, version)                      \
1334     NODE_MODULE_INITIALIZER_X_HELPER(base, version)
1335 
1336 #define NODE_MODULE_INITIALIZER_X_HELPER(base, version) base##version
1337 
1338 #define NODE_MODULE_INITIALIZER                                       \
1339   NODE_MODULE_INITIALIZER_X(NODE_MODULE_INITIALIZER_BASE,             \
1340       NODE_MODULE_VERSION)
1341 
1342 #define NODE_MODULE_INIT()                                            \
1343   extern "C" NODE_MODULE_EXPORT void                                  \
1344   NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports,              \
1345                           v8::Local<v8::Value> module,                \
1346                           v8::Local<v8::Context> context);            \
1347   NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME,                     \
1348                             NODE_MODULE_INITIALIZER)                  \
1349   void NODE_MODULE_INITIALIZER(v8::Local<v8::Object> exports,         \
1350                                v8::Local<v8::Value> module,           \
1351                                v8::Local<v8::Context> context)
1352 
1353 // Allows embedders to add a binding to the current Environment* that can be
1354 // accessed through process._linkedBinding() in the target Environment and all
1355 // Worker threads that it creates.
1356 // In each variant, the registration function needs to be usable at least for
1357 // the time during which the Environment exists.
1358 NODE_EXTERN void AddLinkedBinding(Environment* env, const node_module& mod);
1359 NODE_EXTERN void AddLinkedBinding(Environment* env,
1360                                   const struct napi_module& mod);
1361 NODE_EXTERN void AddLinkedBinding(Environment* env,
1362                                   const char* name,
1363                                   addon_context_register_func fn,
1364                                   void* priv);
1365 NODE_EXTERN void AddLinkedBinding(
1366     Environment* env,
1367     const char* name,
1368     napi_addon_register_func fn,
1369     int32_t module_api_version = NODE_API_DEFAULT_MODULE_API_VERSION);
1370 
1371 /* Registers a callback with the passed-in Environment instance. The callback
1372  * is called after the event loop exits, but before the VM is disposed.
1373  * Callbacks are run in reverse order of registration, i.e. newest first.
1374  */
1375 NODE_EXTERN void AtExit(Environment* env,
1376                         void (*cb)(void* arg),
1377                         void* arg);
1378 
1379 typedef double async_id;
1380 struct async_context {
1381   ::node::async_id async_id;
1382   ::node::async_id trigger_async_id;
1383 };
1384 
1385 /* This is a lot like node::AtExit, except that the hooks added via this
1386  * function are run before the AtExit ones and will always be registered
1387  * for the current Environment instance.
1388  * These functions are safe to use in an addon supporting multiple
1389  * threads/isolates. */
1390 NODE_EXTERN void AddEnvironmentCleanupHook(v8::Isolate* isolate,
1391                                            void (*fun)(void* arg),
1392                                            void* arg);
1393 
1394 NODE_EXTERN void RemoveEnvironmentCleanupHook(v8::Isolate* isolate,
1395                                               void (*fun)(void* arg),
1396                                               void* arg);
1397 
1398 /* These are async equivalents of the above. After the cleanup hook is invoked,
1399  * `cb(cbarg)` *must* be called, and attempting to remove the cleanup hook will
1400  * have no effect. */
1401 struct ACHHandle;
1402 struct NODE_EXTERN DeleteACHHandle { void operator()(ACHHandle*) const; };
1403 typedef std::unique_ptr<ACHHandle, DeleteACHHandle> AsyncCleanupHookHandle;
1404 
1405 /* This function is not intended to be used externally, it exists to aid in
1406  * keeping ABI compatibility between Node and Electron. */
1407 NODE_EXTERN ACHHandle* AddEnvironmentCleanupHookInternal(
1408     v8::Isolate* isolate,
1409     void (*fun)(void* arg, void (*cb)(void*), void* cbarg),
1410     void* arg);
1411 inline AsyncCleanupHookHandle AddEnvironmentCleanupHook(
1412     v8::Isolate* isolate,
1413     void (*fun)(void* arg, void (*cb)(void*), void* cbarg),
1414     void* arg) {
1415   return AsyncCleanupHookHandle(AddEnvironmentCleanupHookInternal(isolate, fun,
1416       arg));
1417 }
1418 
1419 /* This function is not intended to be used externally, it exists to aid in
1420  * keeping ABI compatibility between Node and Electron. */
1421 NODE_EXTERN void RemoveEnvironmentCleanupHookInternal(ACHHandle* holder);
1422 inline void RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle holder) {
1423   RemoveEnvironmentCleanupHookInternal(holder.get());
1424 }
1425 
1426 // This behaves like V8's Isolate::RequestInterrupt(), but also wakes up
1427 // the event loop if it is currently idle. Interrupt requests are drained
1428 // in `FreeEnvironment()`. The passed callback can not call back into
1429 // JavaScript.
1430 // This function can be called from any thread.
1431 NODE_EXTERN void RequestInterrupt(Environment* env,
1432                                   void (*fun)(void* arg),
1433                                   void* arg);
1434 
1435 /* Returns the id of the current execution context. If the return value is
1436  * zero then no execution has been set. This will happen if the user handles
1437  * I/O from native code. */
1438 NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate);
1439 
1440 /* Returns the id of the current execution context. If the return value is
1441  * zero then no execution has been set. This will happen if the user handles
1442  * I/O from native code. */
1443 NODE_EXTERN async_id
1444 AsyncHooksGetExecutionAsyncId(v8::Local<v8::Context> context);
1445 
1446 /* Return same value as async_hooks.triggerAsyncId(); */
1447 NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);
1448 
1449 /* If the native API doesn't inherit from the helper class then the callbacks
1450  * must be triggered manually. This triggers the init() callback. The return
1451  * value is the async id assigned to the resource.
1452  *
1453  * The `trigger_async_id` parameter should correspond to the resource which is
1454  * creating the new resource, which will usually be the return value of
1455  * `AsyncHooksGetTriggerAsyncId()`. */
1456 NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
1457                                         v8::Local<v8::Object> resource,
1458                                         const char* name,
1459                                         async_id trigger_async_id = -1);
1460 NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
1461                                         v8::Local<v8::Object> resource,
1462                                         std::string_view name,
1463                                         async_id trigger_async_id = -1);
1464 
1465 NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
1466                                         v8::Local<v8::Object> resource,
1467                                         v8::Local<v8::String> name,
1468                                         async_id trigger_async_id = -1);
1469 
1470 /* Emit the destroy() callback. The overload taking an `Environment*` argument
1471  * should be used when the Isolate’s current Context is not associated with
1472  * a Node.js Environment, or when there is no current Context, for example
1473  * when calling this function during garbage collection. In that case, the
1474  * `Environment*` value should have been acquired previously, e.g. through
1475  * `GetCurrentEnvironment()`. */
1476 NODE_EXTERN void EmitAsyncDestroy(v8::Isolate* isolate,
1477                                   async_context asyncContext);
1478 NODE_EXTERN void EmitAsyncDestroy(Environment* env,
1479                                   async_context asyncContext);
1480 
1481 class InternalCallbackScope;
1482 
1483 /* This class works like `MakeCallback()` in that it sets up a specific
1484  * asyncContext as the current one and informs the async_hooks and domains
1485  * modules that this context is currently active.
1486  *
1487  * `MakeCallback()` is a wrapper around this class as well as
1488  * `Function::Call()`. Either one of these mechanisms needs to be used for
1489  * top-level calls into JavaScript (i.e. without any existing JS stack).
1490  *
1491  * This object should be stack-allocated to ensure that it is contained in a
1492  * valid HandleScope.
1493  *
1494  * Exceptions happening within this scope will be treated like uncaught
1495  * exceptions. If this behaviour is undesirable, a new `v8::TryCatch` scope
1496  * needs to be created inside of this scope.
1497  */
1498 class NODE_EXTERN CallbackScope {
1499  public:
1500   CallbackScope(v8::Isolate* isolate,
1501                 v8::Local<v8::Object> resource,
1502                 async_context asyncContext);
1503   CallbackScope(Environment* env,
1504                 v8::Local<v8::Object> resource,
1505                 async_context asyncContext);
1506   ~CallbackScope();
1507 
1508   void operator=(const CallbackScope&) = delete;
1509   void operator=(CallbackScope&&) = delete;
1510   CallbackScope(const CallbackScope&) = delete;
1511   CallbackScope(CallbackScope&&) = delete;
1512 
1513  private:
1514   InternalCallbackScope* private_;
1515   v8::TryCatch try_catch_;
1516 };
1517 
1518 /* An API specific to emit before/after callbacks is unnecessary because
1519  * MakeCallback will automatically call them for you.
1520  *
1521  * These methods may create handles on their own, so run them inside a
1522  * HandleScope.
1523  *
1524  * `asyncId` and `triggerAsyncId` should correspond to the values returned by
1525  * `EmitAsyncInit()` and `AsyncHooksGetTriggerAsyncId()`, respectively, when the
1526  * invoking resource was created. If these values are unknown, 0 can be passed.
1527  * */
1528 NODE_EXTERN
1529 v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
1530                                        v8::Local<v8::Object> recv,
1531                                        v8::Local<v8::Function> callback,
1532                                        int argc,
1533                                        v8::Local<v8::Value>* argv,
1534                                        async_context asyncContext);
1535 NODE_EXTERN
1536 v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
1537                                        v8::Local<v8::Object> recv,
1538                                        const char* method,
1539                                        int argc,
1540                                        v8::Local<v8::Value>* argv,
1541                                        async_context asyncContext);
1542 NODE_EXTERN
1543 v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
1544                                        v8::Local<v8::Object> recv,
1545                                        v8::Local<v8::String> symbol,
1546                                        int argc,
1547                                        v8::Local<v8::Value>* argv,
1548                                        async_context asyncContext);
1549 
1550 /* Helper class users can optionally inherit from. If
1551  * `AsyncResource::MakeCallback()` is used, then all four callbacks will be
1552  * called automatically. */
1553 class NODE_EXTERN AsyncResource {
1554  public:
1555   AsyncResource(v8::Isolate* isolate,
1556                 v8::Local<v8::Object> resource,
1557                 const char* name,
1558                 async_id trigger_async_id = -1);
1559   AsyncResource(v8::Isolate* isolate,
1560                 v8::Local<v8::Object> resource,
1561                 std::string_view name,
1562                 async_id trigger_async_id = -1);
1563 
1564   virtual ~AsyncResource();
1565 
1566   AsyncResource(const AsyncResource&) = delete;
1567   void operator=(const AsyncResource&) = delete;
1568 
1569   v8::MaybeLocal<v8::Value> MakeCallback(
1570       v8::Local<v8::Function> callback,
1571       int argc,
1572       v8::Local<v8::Value>* argv);
1573 
1574   v8::MaybeLocal<v8::Value> MakeCallback(
1575       const char* method,
1576       int argc,
1577       v8::Local<v8::Value>* argv);
1578 
1579   v8::MaybeLocal<v8::Value> MakeCallback(
1580       v8::Local<v8::String> symbol,
1581       int argc,
1582       v8::Local<v8::Value>* argv);
1583 
1584   v8::Local<v8::Object> get_resource();
1585   async_id get_async_id() const;
1586   async_id get_trigger_async_id() const;
1587 
1588  protected:
1589   class NODE_EXTERN CallbackScope : public node::CallbackScope {
1590    public:
1591     explicit CallbackScope(AsyncResource* res);
1592   };
1593 
1594  private:
1595   Environment* env_;
1596   v8::Global<v8::Object> resource_;
1597   v8::Global<v8::Value> context_frame_;
1598   async_context async_context_;
1599 };
1600 
1601 #ifndef _WIN32
1602 // Register a signal handler without interrupting any handlers that node
1603 // itself needs. This does override handlers registered through
1604 // process.on('SIG...', function() { ... }). The `reset_handler` flag indicates
1605 // whether the signal handler for the given signal should be reset to its
1606 // default value before executing the handler (i.e. it works like SA_RESETHAND).
1607 // The `reset_handler` flag is invalid when `signal` is SIGSEGV.
1608 NODE_EXTERN
1609 void RegisterSignalHandler(int signal,
1610                            void (*handler)(int signal,
1611                                            siginfo_t* info,
1612                                            void* ucontext),
1613                            bool reset_handler = false);
1614 #endif  // _WIN32
1615 
1616 // This is kept as a compatibility layer for addons to wrap cppgc-managed
1617 // objects on Node.js versions without v8::Object::Wrap(). Addons created to
1618 // work with only Node.js versions with v8::Object::Wrap() should use that
1619 // instead.
1620 NODE_DEPRECATED("Use v8::Object::Wrap()",
1621                 NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate,
1622                                                    v8::Local<v8::Object> object,
1623                                                    void* wrappable));
1624 
1625 }  // namespace node
1626 
1627 #endif  // SRC_NODE_H_