Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-02 09:21:24

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