Commit 305cfcd7298 for nodejs

commit 305cfcd729843977b92d1d84753c0e2d8bea99ba
Author: Shelley Vohr <shelley.vohr@gmail.com>
Date:   Wed Sep 23 12:24:53 2026 +0200

    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>

diff --git a/src/api/environment.cc b/src/api/environment.cc
index 3b2ce77b7bf..ee9da42b606 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -269,7 +269,9 @@ void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
   isolate->SetModifyCodeGenerationFromStringsCallback(
       modify_code_generation_from_strings_callback);

-  isolate->SetWasmStreamingCallback(wasm_web_api::StartStreamingCompilation);
+  if ((s.flags & SHOULD_NOT_SET_WASM_STREAMING_CALLBACK) == 0) {
+    isolate->SetWasmStreamingCallback(wasm_web_api::StartStreamingCompilation);
+  }

   Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
   if (per_process::cli_options->get_per_isolate_options()
diff --git a/src/node.h b/src/node.h
index ca81c4818b4..9018a4b39b0 100644
--- a/src/node.h
+++ b/src/node.h
@@ -427,6 +427,7 @@ enum IsolateSettingsFlags {
   DETAILED_SOURCE_POSITIONS_FOR_PROFILING = 1 << 1,
   SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK = 1 << 2,
   SHOULD_NOT_SET_PREPARE_STACK_TRACE_CALLBACK = 1 << 3,
+  SHOULD_NOT_SET_WASM_STREAMING_CALLBACK = 1 << 4,
   ALLOW_MODIFY_CODE_GENERATION_FROM_STRINGS_CALLBACK = 0, /* legacy no-op */
 };

diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
index 6ecb9284bd5..359f720c508 100644
--- a/test/cctest/test_environment.cc
+++ b/test/cctest/test_environment.cc
@@ -69,6 +69,39 @@ TEST_F(EnvironmentTest, ManagedBufferCache) {
   (*env)->release_managed_buffer(buffer);
 }

+static int embedder_wasm_streaming_calls = 0;
+static void EmbedderWasmStreaming(const v8::FunctionCallbackInfo<v8::Value>&) {
+  embedder_wasm_streaming_calls++;
+}
+
+TEST_F(EnvironmentTest, KeepsEmbedderWasmStreamingCallbackWhenAsked) {
+  const v8::HandleScope handle_scope(isolate_);
+  const Argv argv;
+  Env env{handle_scope, argv};
+
+  auto compile_streaming = [&]() {
+    v8::Local<v8::Context> context = isolate_->GetCurrentContext();
+    v8::Script::Compile(context,
+                        v8::String::NewFromUtf8Literal(
+                            isolate_, "WebAssembly.compileStreaming(0); 0"))
+        .ToLocalChecked()
+        ->Run(context)
+        .ToLocalChecked();
+    isolate_->PerformMicrotaskCheckpoint();
+  };
+
+  node::IsolateSettings settings;
+  settings.flags |= node::SHOULD_NOT_SET_WASM_STREAMING_CALLBACK;
+  isolate_->SetWasmStreamingCallback(EmbedderWasmStreaming);
+  node::SetIsolateUpForNode(isolate_, settings);
+  compile_streaming();
+  EXPECT_EQ(embedder_wasm_streaming_calls, 1);
+
+  node::SetIsolateUpForNode(isolate_);
+  compile_streaming();
+  EXPECT_EQ(embedder_wasm_streaming_calls, 1);
+}
+
 TEST_F(EnvironmentTest, EnvironmentWithoutBrowserGlobals) {
   const v8::HandleScope handle_scope(isolate_);
   Argv argv;