Commit Graph
267 Commits
Author SHA1 Message Date
Nigro Simone a0ce8f152b src: keep ALS store in AsyncResource::MakeCallback
AsyncResource saves the async context frame when it is created, and
MakeCallback() enters it with async_context_frame::Scope. Then
node::MakeCallback() opens the callback scope with an undefined frame,
so the callback never runs in the saved one. Since AsyncContextFrame is
the default, AsyncLocalStorage loses its store in these callbacks.

Pass the saved frame to InternalMakeCallback(), as the Node-API
AsyncContext already does. This also removes the Scope from every call,
with its two Environment lookups and its global handle.

Refs: https://github.com/nodejs/node/pull/66316
Refs: https://github.com/nodejs/node/issues/43038
Refs: https://github.com/nodejs/performance/issues/24
Signed-off-by: Nigro Simone <nigro.simone@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66326
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-10-14 01:57:03 +00:00
Shelley Vohr 06c6e36ee5 tools: lint thread_local in src
Several Environments can share a thread, so state in src/ that belongs
to one of them cannot be kept in a thread_local. Add a cpplint rule
that rejects thread_local in src/ unless the declaration is marked with
NOLINTNEXTLINE(runtime/thread_local), and mark the existing uses, which
are per-thread by design.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66411
Refs: https://github.com/nodejs/node/pull/66239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2026-10-07 10:56:09 +00:00
Michaël ZassoandJoyee Cheung 45287a975f src: migrate from deprecated xxxV2 APIs
- Set/GetPrototype
- Holder

Co-Authored-by: Joyee Cheung <joyeec9h3@gmail.com>
Signed-Off-By: Michaël Zasso <targos@protonmail.com>
Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65161
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
2026-10-04 22:38:19 +02:00
Shelley Vohr 6fbab72e37 src: track handle cleanup per thread, not per IsolateData
The FreeEnvironment() fix for sibling Environments keeps the depth of
nested Environment::CleanupHandles() calls on the IsolateData, so that
InternalCallbackScope can re-allow JavaScript for sibling Environments
while one of them is being freed. Environments that each have their own
IsolateData on the same isolate and loop never see that counter and
still fail with "illegal access". Environments that share a loop share a
thread, so keep the depth in a thread_local instead.

Refs: https://github.com/nodejs/node/pull/65977
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66239
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2026-09-30 09:30:39 +00:00
Nigro Simone d97041fff9 src: reduce InternalCallbackScope overhead
InternalCallbackScope looks up the Environment from the isolate two
times per call, inside async_context_frame::exchange, and it keeps the
prior async context frame in a v8::Global also when there is no frame,
that is the common case. Every call from native code into JS pays this:
MakeCallback, CallbackScope, AsyncWrap, Node-API.

Now the scope passes the Environment it already has, the option is read
with an inline accessor instead of copying the shared_ptr, and the
global handle is created only when the prior frame is not undefined.

benchmark/napi/make_callback, Node 26.3.0 built with and without this
change, Linux x64, 30 runs: from 202-208 ns to 155-159 ns per call.

Refs: https://github.com/nodejs/performance/issues/24
Signed-off-by: Nigro Simone <nigro.simone@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66316
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-09-29 06:45:35 +00:00
Shelley Vohr 6dfe4eb0f0 src: fix FreeEnvironment() breaking JS in sibling Environments
`FreeEnvironment()` forbids JavaScript on the whole isolate with a
`DisallowJavascriptExecutionScope` and then spins the event loop in
`Environment::CleanupHandles()` until its handles are closed. When the
loop and isolate are shared with other Environments, as they are for an
embedder hosting several Environments on one thread, those loop turns
also run the other Environments' timers and I/O callbacks, and every
one of them failed with an "illegal access" exception thrown into
unrelated code.

While an Environment is closing its handles, let `InternalCallbackScope`
re-allow JavaScript for callbacks of Environments that can still call
into JS. The Environment being freed stays blocked: its callbacks fail
the `can_call_into_js()` check before that point, and anything that
bypasses `InternalCallbackScope` (V8 foreground tasks, raw addon
callbacks) still runs under the disallow scope.

Refs: https://github.com/nodejs/node/pull/33874
Refs: https://github.com/nodejs/node/pull/65819
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65977
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-09-23 15:24:31 +00:00
Shelley Vohr 305cfcd729 src: add a flag to keep the embedder's wasm streaming callback
`SetIsolateMiscHandlers()` always installs Node.js's
`WebAssembly.compileStreaming()` implementation, which is backed by the
Environment's fetch-based handler. An embedder that provides its own
streaming callback (for example one wired to its own network stack) has
to re-install it after every `SetIsolateUpForNode()` or `NewIsolate()`
call. Add `SHOULD_NOT_SET_WASM_STREAMING_CALLBACK` next to the existing
`SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK` and
`SHOULD_NOT_SET_PREPARE_STACK_TRACE_CALLBACK` flags so it can opt out
the same way.

Refs: https://github.com/nodejs/node/pull/36447
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65690
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-09-23 10:24:53 +00:00
Shelley Vohr 892916667a src: let Environments on one isolate share a cleanup hook
The registry behind `AddEnvironmentCleanupHook()` is keyed on
{isolate, fun, arg} and asserts that every insertion is unique. Two
Environments on one isolate that register the same hook, which the
Node-API documentation allows per environment, abort the process on
the second `napi_add_env_cleanup_hook()`.

Key the registry on `arg` only and tell entries apart by Environment:
adding the same hook to one Environment twice still aborts as
documented, and removal prefers the current Environment's registration,
falling back to a matching one from another Environment when there is
no current context. Because the entry to remove after a hook has run can
no longer be found by {isolate, fun, arg} alone, `CleanupHookThunkRun()`
marks its entry as running and erases exactly that entry afterwards; a
removal of a running entry (a hook removing itself, as `~ObjectWrap()`
does) is a no-op, which keeps the use-after-free fixed by #65630 fixed.

Refs: https://github.com/nodejs/node/pull/63985
Refs: https://github.com/nodejs/node/pull/65630
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65777
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-09-20 16:35:51 +00:00
Shelley Vohr 524564e4e5 src: keep the first snapshot blob alive for later isolates
`NewIsolate()` creates every isolate from the snapshot blob the first
isolate in the process used, because V8 shares the read-only heap
between isolates, and did so by keeping a pointer to the first
`CreateParams`. When that blob came from an `EmbedderSnapshotData` the
embedder had since released, e.g. a second
`CommonEnvironmentSetup::CreateFromSnapshot()` after the first setup and
its snapshot were destroyed, V8 deserialized freed memory.

Record the first blob and external references under a mutex instead of
copying the caller's `CreateParams`, and make `~SnapshotData()` leave
that one blob allocated, since its owner can go away before the last
isolate is created. Nothing is copied and `node` itself is unaffected.
embedtest grows an `--embedder-run-twice` switch so the sequence can be
tested.

Refs: https://github.com/nodejs/node/pull/45885
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65779
Refs: https://github.com/nodejs/node/pull/32984
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-09-11 18:29:11 +00:00
Shelley Vohr 0de4fcceb9 src: fix Stop() terminating the next Environment on the isolate
After `Stop(env)`, freeing the Environment and creating another one on
the same isolate failed whenever no JavaScript ran in between: the new
Environment's first script was terminated before it started. That is
the normal case when `Stop()` is called from the process exit handler
for an uncaught exception, or by an embedder while the loop is idle.
`Stop()` calls `isolate->TerminateExecution()` unless
`kDoNotTerminateIsolate` is set, and V8 only clears that request the
next time JavaScript runs, so it outlived the Environment it was meant
for.

Cancel a pending termination when the Environment it was meant for is
freed. `Worker::Run()` already did this by hand before freeing its
Environment, with a TODO asking why V8 hit a DCHECK without it; this is
why, and that call now happens in `FreeEnvironment()`.

Refs: https://github.com/nodejs/node/pull/33347
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65819
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
2026-09-10 21:53:48 +00:00
Shelley Vohr 1e0ebefc75 src: fix null pointer call when running without a startup snapshot
Without a startup snapshot (`--no-node-snapshot`, a
`--without-node-snapshot` build, or an embedder Environment that was
bootstrapped from scratch) starting a Worker made a member call through
a null `SnapshotData*`, and so did `NodeMainInstance` while setting
itself up. It only worked because the function called does not touch
`this`; UBSan reports it for every such Worker. The call existed
because `IsolateData::CreateIsolateData()` took an
`EmbedderSnapshotData*` and unwrapped it straight away, so the two
internal callers wrapped their possibly-null `SnapshotData*` with
`AsEmbedderWrapper()` only for it to be unwrapped again.

Let the internal function take the `SnapshotData*` itself, unwrap in
the public `CreateIsolateData()` only, and drop `AsEmbedderWrapper()`,
which has no other users.

Refs: https://github.com/nodejs/node/pull/47731
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65820
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-09-07 21:32:59 +00:00
Shelley Vohr 8e4d830a1b src: stop leaking a CppHeap in CommonEnvironmentSetup
`CommonEnvironmentSetup` created a `CppHeap` for its `CreateParams`
before deciding how to create the isolate, but `NewIsolate()` ignores
`params->cpp_heap` and attaches a heap of its own (or the one from
`IsolateSettings`). The first heap was never attached or destroyed, so
every non-snapshotting setup leaked one `CppHeap`; cppgc's heap
registry keeps it reachable, which is why LSAN stays quiet about it.

Only create the heap on the snapshotting path, where the params go to
the `SnapshotCreator` directly.

Refs: https://github.com/nodejs/node/pull/55337
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65792
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Jake Yuesong Li <jake.yuesong@gmail.com>
2026-09-07 12:34:37 +00:00
Caleb EverettandSreehari Annam 03e2b9bc42 src: fix use-after-free in CleanupHookThunkRun
CleanupHookThunkRun() read thunk->isolate/fun/arg from the
CleanupHookThunk after invoking thunk->fun(). For every
node::ObjectWrap alive at teardown, thunk->fun is
ObjectWrap::CleanupHook, which deletes the wrap; ~ObjectWrap() calls
RemoveEnvironmentCleanupHook() itself, erasing the CleanupHookThunk
from the registry and freeing the node it lives in. The subsequent
read of thunk->isolate/fun/arg to make the (now redundant) second
RemoveEnvironmentCleanupHook() call was therefore a use-after-free.

Cache the fields before running the hook so nothing is read from
`thunk` once it may have been freed.

Taken over from #65196, which has been inactive; the original change is
unmodified apart from the added comment.

This also unblocks #65042, the backport of the cleanup hook registry to
v24.x. Without that registry ~ObjectWrap() asserts during garbage
collection, so every 24.x runtime aborts for ObjectWrap addons
(#65446), as do 26.x runtimes before 26.4.0 when used with newer
headers (#65262).

Fixes: https://github.com/nodejs/node/issues/65195
Refs: https://github.com/nodejs/node/pull/65196
Refs: https://github.com/nodejs/node/pull/65042
Refs: https://github.com/nodejs/node/issues/65446
Refs: https://github.com/nodejs/node/issues/65262
Assisted-by: a closed-source coding agent
Co-authored-by: Sreehari Annam <sreehari.annam@gmail.com>
Signed-off-by: Caleb Everett <everett.caleb@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65630
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Shelley Vohr <shelley.vohr@gmail.com>
2026-09-04 16:56:42 +00:00
Shelley Vohr ddc0a0aa28 worker: start worker threads from the built-in snapshot
Every `new Worker()` runs the whole internal bootstrap (realm, node, web
exposure, thread and process-state switches) in its fresh isolate,
compiling ~80 builtins with the code cache; only the main thread
deserializes its principal context from the built-in snapshot. That
bootstrap is about half of a worker's cold start.

The bootstrapped principal context in the snapshot is nearly
thread-neutral: the worker-side switch scripts (is_not_main_thread,
does_not_own_process_state) are written as overrides of the main-thread
ones, and the per-thread values of the `worker` binding were the only
thread-specific data baked into the context. Let a worker deserialize
that same context and EnvSerializeInfo and apply the two worker-side
switches on top:

- worker binding: threadId, threadName, isMainThread, isInternalThread,
  ownsProcessState and resourceLimits become lazy properties of the
  per-isolate template, computed from the Environment on first read.
- CreateEnvironment(): when a worker (its IsolateData has a Worker)
  passes an empty context, deserialize kNodeMainContextIndex and run
  internal/bootstrap/switches/is_not_main_thread and, unless the worker
  owns process state, does_not_own_process_state after
  InitializeMainContext().
- Worker::Run(): take that path when the embedded built-in snapshot is
  in use (not an embedder's or a --snapshot-blob one, which has run
  application code), browser globals are not disabled and
  --no-worker-snapshot was not given; otherwise bootstrap as before.
- is_not_main_thread.js: also delete _debugPause and the profiler idle
  notifier helpers that is_main_thread.js installs.
- pre_execution: run the snapshot's deserialize callbacks (Buffer pool,
  default resolver, cached cwd) on worker threads too, now that a worker
  can come from a snapshot.
- --[no-]worker-snapshot per-isolate option, documented.

Sequential new Worker() -> 'online' -> terminate goes from ~20.9 ms to
~10.3 ms per worker on x64 Linux; --no-worker-snapshot restores the old
number.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65336
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2026-09-04 13:28:27 +00:00
Shelley Vohr d9538a92aa src: apply IsolateSettings when using a snapshot
`NewIsolate()` deferred `SetIsolateErrorHandlers()` when snapshot data
was passed, and `CreateEnvironment()` later installed the handlers with
default `IsolateSettings` after deserializing the main context. An
embedder's `fatal_error_callback`, `oom_error_callback`,
`should_abort_on_uncaught_exception_callback` and
`prepare_stack_trace_callback` were therefore dropped whenever a
snapshot was used, and the per-isolate message listener was added even
if `MESSAGE_LISTENER_WITH_ERROR_LEVEL` had been cleared. The only way
to keep custom handlers was to call `SetIsolateUpForNode()` again after
`CreateEnvironment()`.

Install all handlers in `NewIsolate()` regardless of snapshot data, as
its documentation already describes, and stop touching isolate
handlers in `CreateEnvironment()`. The deferral dates from the initial
isolate snapshot work; every handler already copes with a missing
`Environment`, since without a snapshot they are installed before any
context exists, and workers have been calling `SetIsolateUpForNode()`
right after a snapshot `NewIsolate()` anyway.

Refs: https://github.com/nodejs/node/pull/27321
Refs: https://github.com/nodejs/node/pull/45888
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65407
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-31 15:47:18 +00:00
Yeaseen 37aeecc7b6 fs: fix rmSync error messages for non-ASCII paths
fs.rmSync previously embedded paths directly into
custom error messages while also passing the path
to ThrowErrnoException.

This caused duplicated paths for ASCII names and
corrupted paths for non-ASCII directory names on
Linux, and inconsistent path formatting on Windows.

Remove path concatenation from custom messages and
rely on ThrowErrnoException to attach the path safely.
Add a test to cover non-ASCII directory names.

Signed-off-by: Yeaseen <yeaseen.arafat96@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/61233
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
2026-08-27 01:00:46 +00:00
Shelley Vohr f9f3fa96b2 src: allow building the snapshot on top of a V8 startup blob
CommonEnvironmentSetup::CreateForSnapshotting() always created the
SnapshotCreator without a startup blob, so V8 set up its heap from
scratch. That is impossible when the V8 that Node.js is linked against
only carries the deserializer (external startup data, as Chromium builds
it), and it puts the resulting snapshot on a different read-only heap
lineage than isolates the embedder creates from its own blob. Embedders
in that situation cannot use the snapshot support at all today.

Add SnapshotConfig::base_blob, an optional caller-owned v8::StartupData
that is handed to the SnapshotCreator so that V8 deserializes its heap
from that blob and Node.js adds its isolate data and contexts on top,
the way Blink's context snapshot is built. node_mksnapshot accepts
--v8-snapshot-blob=<file> for hosts that build Node.js with such a V8;
Node.js's own build never passes it and is unchanged. Consuming the
result needs no changes.

embedtest can create a plain V8 startup blob and build the embedder
snapshot on top of one, and a test round-trips argv through a snapshot
built that way.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65374
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-25 09:47:18 +00:00
James M Snell 6456418ac1 src: add v8::Local specialization for MaybeStackBuffer
Long-term itch. Per v8 rules, we're not supposed to be
heap allocating v8::Local's; instead we're supposed to
be using v8::LocalVector. Create a specialization of
MaybeStackBuffer that uses either a stack array of
v8::Locals or v8::LocalVector with some additional
utility improvements.

Signed-off-by: James M Snell <jasnell@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65159
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2026-08-17 11:42:11 -07:00
Anna Henningsen 68321eff80 src: keep global list of addon-provided cleanup hooks
A recent change, 215027c8ed, introduced flakiness into our
test suite that exposed an issue with the cleanup hook API design.

Specifically, the signatures of `AddEnvironmentCleanupHook()` and
`RemoveEnvironmentCleanupHook()` are problematic. Both functions
take `Isolate*` arguments, as addons are not generally expected
to have to care about the Node.js `Environment` as a first-class
scope provider.

However, this model made the incorrect assumption that in the
situations in which `RemoveEnvironmentCleanupHook()` would be
invoked an `Environment` would always be associated with the
current `Isolate` (via the current V8 `Context`, if there is one).

This occasionally breaks down when `RemoveEnvironmentCleanupHook()`
is called during garbage collection -- which would be an expected
use case of the functionality, but one that has not been covered
through our tests before 215027c8ed.

Since Node.js guarantees API and ABI stability within a major version,
and this is a bug that is independent from the aforementioned change,
this commit resolves it by adding global mutable state to keep track
off cleanup hooks registered through the Node.js public API.

Obviously, this solution does not represent a desirable long-term
state, and a semver-minor follow up should add an API that does not
require modifications to these data structures, likely based on
the async cleanup hook API which already solves this issue properly.

Refs: https://github.com/nodejs/node/pull/63642
Fixes: https://github.com/nodejs/node/issues/63923
Signed-off-by: Anna Henningsen <anna@addaleax.net>
PR-URL: https://github.com/nodejs/node/pull/63985
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-06-20 18:16:02 +02:00
Anna Henningsen 2d0c926907 src: merge CreateEnvironment() overloads
API-compatible, but ABI-breaking, so done separately from the
original 3090def635.

Signed-off-by: Anna Henningsen <anna@addaleax.net>
PR-URL: https://github.com/nodejs/node/pull/63596
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2026-06-04 00:21:26 +00:00
Chengzhong Wu d92ee51aa6 src: expose node::RegisterContext to make a node managed context
Signed-off-by: Chengzhong Wu <cwu631@bloomberg.net>
PR-URL: https://github.com/nodejs/node/pull/62322
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2026-05-21 13:50:23 +00:00
Antoine du Hamel 59072b8a95 src: clean up experimental flag variables
- `fetch` is no longer disable by a CLI flag
- `node:sqlite` requires SQLite, obviously

Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/62759
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
2026-04-17 15:37:44 +00:00
Joyee Cheung baba7483fc src: add initial support for ESM in embedder API
This patch extends `LoadEnvironment` to support loading ES modules,
and adds the following new types:

```cpp
enum class ModuleFormat : uint8_t {
  kCommonJS,
  kModule,
};

// Data for specifying an entry point script for LoadEnvironment().
// This class uses an opaque layout to allow future additions without
// breaking ABI. Use the setter methods to configure the entry point.
class ModuleData {
  void set_source(std::string_view source);
  void set_format(ModuleFormat format);
  void set_resource_name(std::string_view name);

  std::string_view source() const;
  ModuleFormat format() const;
  std::string_view resource_name() const;
};

class StartExecutionCallbackInfoWithModule {
  void set_env(Environment* env);
  void set_process_object(v8::Local<v8::Object> process_object);
  void set_native_require(v8::Local<v8::Function> native_require);
  void set_run_module(v8::Local<v8::Function> run_module);
  void set_data(void* data);

  Environment* env();
  v8::Local<v8::Object> process();
  v8::Local<v8::Function> native_require();
  v8::Local<v8::Function> run_module();
  void* data();
};
```

And two new `LoadEnvironment()` overloads:

```cpp
// Run entry point with ModuleData configuration
MaybeLocal<Value> LoadEnvironment(
    Environment* env,
    const ModuleData* entry_point,
    EmbedderPreloadCallback preload = nullptr);

// Callback-based with new StartExecutionCallbackInfoWithModule
MaybeLocal<Value> LoadEnvironment(
    Environment* env,
    StartExecutionCallbackWithModule cb,
    EmbedderPreloadCallback preload = nullptr,
    void* callback_data = nullptr);
```

PR-URL: https://github.com/nodejs/node/pull/61548
Refs: https://github.com/nodejs/node/issues/53565
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Aditi Singh <aditisingh1400@gmail.com>
2026-02-02 12:24:51 +00:00
Сковорода Никита АндреевичandRafael Gonzaga 3cdb1cd437 src,lib: refactor unsafe buffer creation to remove zero-fill toggle
This removes the zero-fill toggle mechanism that allowed JavaScript
to control ArrayBuffer initialization via shared memory. Instead,
unsafe buffer creation now uses a dedicated C++ API.

Refs: https://hackerone.com/reports/3405778
Co-Authored-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs-private/node-private/pull/759
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
CVE-ID: CVE-2025-55131
2026-01-13 17:06:20 +01:00
Michaël Zasso 8480f87375 src: remove deprecated and unused isolate fields
Refs: https://github.com/v8/v8/commit/599866f6f1f3474955618d0c41dba6c39ad8ef31
PR-URL: https://github.com/nodejs/node/pull/60488
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
2025-11-13 15:09:37 +01:00
Joyee Cheung 12fad1bd7b src: build v8 tick processor as built-in source text modules
Instead of polyfilling it with vm.SourceTextModule,
use a built-in source text module loader so that we can
also build the code cache for it at build tiem to
embed the code cache for them in the binary.

Drive-by: instead of inferring how to compile a particular
built-in at run time, do the inferring at build time,
so the function-based built-ins can be compiled using
parameters quickly looked up from a static map, and
the builtins that should be compiled as source text
modules are known internally based on extension in
the source code (at run time, the extensions are all
removed).

PR-URL: https://github.com/nodejs/node/pull/60518
Reviewed-By: Aditi Singh <aditisingh1400@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
2025-11-11 02:53:13 +00:00
Joyee Cheung cfbfc1b050 src: add COUNT_GENERIC_USAGE utility for tests
PR-URL: https://github.com/nodejs/node/pull/60434
Fixes: https://github.com/nodejs/node/issues/60423
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
2025-10-28 00:15:54 +00:00
Sohyeon Kim 4b8603f910 src: use cached primordials_string
PR-URL: https://github.com/nodejs/node/pull/60255
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
2025-10-19 10:43:18 +00:00
James M Snell c2f3c2131d src: initial enablement of IsolateGroups
This lays the initial groundwork for enabling the
use of IsolateGroups.

Every isolate in V8 is created within a group. When pointer
compression is enabled, all isolates within a single group
are limited to a 4 GB shared pointer cage. By default, all
isolates in the process share the same group, which means
that when running with pointer compression, the entire
process would be limited to a single 4 GB shared pointer
cage. But, we can create as many IsolateGroups as we want,
limited only by the amount of virtual memory available on
the machine.

PR-URL: https://github.com/nodejs/node/pull/60254
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
2025-10-17 10:22:19 +00:00
Anna Henningsen 39447be4e4 src: use Utf8Value and TwoByteValue instead of V8 helpers
Our own helper classes have the advantage of using stack storage
a lot of the time, so they should always be preferred.

PR-URL: https://github.com/nodejs/node/pull/60244
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Vladimir Morozov <vmorozov@microsoft.com>
2025-10-17 09:17:01 +00:00
Rahul b13f24c2da build, src: fix include paths for vtune files
PR-URL: https://github.com/nodejs/node/pull/59999
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2025-10-07 19:04:32 +00:00
Michaël Zasso 5623194a6b doc,src,test: replace use of deprecated GetIsolate
`Isolate::GetCurrent()` should be used instead as it returns the same
thing.

Refs: https://github.com/v8/v8/commit/5c4a937aafff2ca21257387510101737afbf10ab
PR-URL: https://github.com/nodejs/node/pull/59805
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
2025-10-04 18:48:35 +02:00
Anna Henningsen ce748f6cae src: use Global for storing resource in Node-API callback scope
This is a follow-up to 234c26cca3. The Node-API interface does
not allow us to enforce that values are stored in a specific location,
e.g. on the stack or not; however, V8 requires `Local<>` handles
to be stored on the stack.

To circumvent this restriction, we add the ability to the async handle
stack to store either `Local<>*` pointers or `Global<>*` pointers, with
Node-API making use of the latter.

PR-URL: https://github.com/nodejs/node/pull/59828
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2025-09-22 14:16:10 +00:00
Anna Henningsen 234c26cca3 src: store Local for CallbackScope on stack
This is a requirement of the V8 API, but requires a separate
semver-major change (as it is ABI-breaking) to address.

(There's also a similar requirement for `napi_open_callback_scope`
that would not be easily addressable without breaking ABI compatibility
there as well. In real-world situations, it seems extremely unlikely
that the `CallbackScope` would be the only reference to the resource
object.)

PR-URL: https://github.com/nodejs/node/pull/59705
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2025-09-09 15:00:42 +00:00
Anna Henningsen 3903ee8cf3 src: track async resources via pointers to stack-allocated handles
This addresses an existing `TODO` to remove the need for a separate
`LocalVector`. Since all relevant handles are already present on the
stack, we can track their addresses instead of storing the objects
in a separate container.

PR-URL: https://github.com/nodejs/node/pull/59704
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2025-09-04 09:35:39 +00:00
Chengzhong Wu 737b42e4ee src: fix race on process exit and off thread CA loading
When calling `process.exit()` or on uncaught exceptions as soon as the
process starts, the process will try to terminate immediately. In this
case, there could be a race condition on the unfinished off-thread
system CA loader which tries to access the OpenSSL API which has been
de-inited on the main thread.

PR-URL: https://github.com/nodejs/node/pull/59632
Refs: https://github.com/nodejs/node/pull/59550
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2025-09-02 10:19:25 +00:00
theanarkh cbabdbf3f2 src: remove duplicate code
PR-URL: https://github.com/nodejs/node/pull/59649
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
2025-08-29 17:20:54 +00:00
theanarkh 9ec68afdc5 worker: fix worker name with \0
PR-URL: https://github.com/nodejs/node/pull/59214
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2025-08-13 13:53:24 +00:00
theanarkh 3090def635 worker: add name for worker
PR-URL: https://github.com/nodejs/node/pull/59213
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-08-05 13:45:41 +00:00
Chengzhong Wuandjazelly 5457443210 lib,src: support DOMException ser-des
Added serialization and deserialization support for `DOMException`.

Co-Authored-By: jazelly <xzha4350@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/58649
Fixes: https://github.com/nodejs/node/issues/49181
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
2025-06-11 16:11:18 +00:00
Chengzhong Wu 708fd1945b src: remove node.h APIs to make callback without an async context
PR-URL: https://github.com/nodejs/node/pull/58471
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2025-06-06 10:50:02 +00:00
Chengzhong Wu 56989d33f5 src: remove deprecated node::EmitBeforeExit and node::EmitExit
PR-URL: https://github.com/nodejs/node/pull/58469
Refs: https://github.com/nodejs/node/pull/35486
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
2025-05-29 08:09:13 +00:00
Chengzhong Wu d429aa2d17 src: remove deprecated node::CreatePlatform and node::FreePlatform
PR-URL: https://github.com/nodejs/node/pull/58470
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2025-05-28 17:24:42 +00:00
Joyee Cheung 5d3e1b555c src,test: unregister the isolate after disposal and before freeing
The order of these calls is important. When the Isolate is disposed,
it may still post tasks to the platform, so it must still be registered
for the task runner to be found from the map. After the isolate is torn
down, we need to remove it from the map before we can free the address,
so that when another Isolate::Allocate() is called, that would not be
allocated to the same address and be registered on an existing map
entry.

PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:10:39 +02:00
Joyee Cheung 9aa1afb527 src: use V8-owned CppHeap
As V8 is moving towards built-in CppHeap creation, change the
management so that the automatic CppHeap creation on Node.js's end
is also enforced at Isolate creation time.

1. If embedder uses NewIsolate(), either they use
  IsolateSettings::cpp_heap to specify a CppHeap that will be owned
  by V8, or if it's not configured, Node.js will create a CppHeap
  that will be owned by V8.
2. If the embedder uses SetIsolateUpForNode(),
  IsolateSettings::cpp_heap will be ignored (as V8 has deprecated
  attaching CppHeap post-isolate-creation). The embedders need to
  ensure that the v8::Isolate has a CppHeap attached while it's
  still used by Node.js, preferably using v8::CreateParams.

See https://issues.chromium.org/issues/42203693 for details. In
future version of V8, this CppHeap will be created by V8 if not
provided, and we can remove our own "if no CppHeap provided,
create one" code in NewIsolate().

PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:10:38 +02:00
Michaël Zasso cff3fa5f03 build,src,tools: adapt build config for V8 13.3
Refs: https://github.com/v8/v8/commit/1c9f59c80f37124f0b967c9f62e93ff35380a692
Refs: https://github.com/v8/v8/commit/b1c5eba50ac61e405a4e02bd3682c915a948c8ea
Refs: https://github.com/v8/v8/commit/b3054f77d65ea96ddf6e0a526abadebd91d7114e
Refs: https://github.com/v8/v8/commit/f81e87ee5c6815db81c6ca84ae932c944b1d6191
Refs: https://github.com/v8/v8/commit/dc0e30522358f421585aa9bb8e5e52cd11a7e09f
Refs: https://github.com/v8/v8/commit/41d42cec13ea567f461d98dfb04d641e30d6bb5b
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:10:35 +02:00
Yagiz Nizipli 1c0a40518c src: avoid calling SetPrototypeV2()
PR-URL: https://github.com/nodejs/node/pull/57949
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2025-04-22 15:27:11 +00:00
James M Snell e773e09c3f src: fixup errorhandling more in various places
PR-URL: https://github.com/nodejs/node/pull/57852
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-04-21 03:01:30 +00:00
Attila Szegedi ffb9bfb206 src: add ExecutionAsyncId getter for any Context
Adds a variant of AsyncHooksGetExecutionAsyncId that takes a V8 Context
and returns the async ID belonging to the Environment (if any) of that
Context. Sometimes we want to use Isolate::GetEnteredOrMicrotaskContext
insteads of Isolate::GetCurrentContext (e.g. recording the async ID in
a V8 GC prologue callback) when current context is not set.

PR-URL: https://github.com/nodejs/node/pull/57820
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2025-04-17 18:00:05 +00:00
Joyee Cheung b2405e9b07 src: migrate from deprecated SnapshotCreator constructor
Previously we have been using the variant of SnapshotCreator that
only passes the external references instead of
v8::Isolate::CreateParams and it's about to be deprecated.
Switch to using the new constructor that takes a fully CreateParams
instead.

This also makes sure that the snapshot building script is using
the Node.js array buffer allocator instead of a separate default
one that was previously used by the old constructor. The zero fill
toggle in the Node.js array buffer allocator would still be ignored
during snapshot building, however, until we fixes the array buffer
allocator and let V8 own the toggle backing store instead, because
otherwise the snapshot would contain the external toggle address
and become unreproducible.

PR-URL: https://github.com/nodejs/node/pull/55337
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Vladimir Morozov <vmorozov@microsoft.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-04-14 12:11:43 -07:00