chore: remove node patches by using the preload feature (#41080)
This commit is contained in:
		
					parent
					
						
							
								031d636823
							
						
					
				
			
			
				commit
				
					
						d13a93fb61
					
				
			
		
					 21 changed files with 403 additions and 135 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,3 @@
 | 
			
		|||
refactor_alter_child_process_fork_to_use_execute_script_with.patch
 | 
			
		||||
feat_initialize_asar_support.patch
 | 
			
		||||
expose_get_builtin_module_function.patch
 | 
			
		||||
build_add_gn_build_files.patch
 | 
			
		||||
fix_add_default_values_for_variables_in_common_gypi.patch
 | 
			
		||||
| 
						 | 
				
			
			@ -46,3 +44,4 @@ build_do_not_rely_on_gn_helpers_in_gn_build.patch
 | 
			
		|||
test_make_test-node-output-v8-warning_generic.patch
 | 
			
		||||
test_match_wpt_streams_transferable_transform-stream-members_any_js.patch
 | 
			
		||||
build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch
 | 
			
		||||
src_preload_function_for_environment.patch
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,10 +26,10 @@ index 1f3b719048f2477de183e2856b9b8eee8502f708..21116088c101f4679b5a5f41762ce710
 | 
			
		|||
         try {
 | 
			
		||||
           resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
 | 
			
		||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
 | 
			
		||||
index fc8f61ee6d30cf18951ec7a5eb5f09a9583a85ae..61858f6bdcdbc231d7e2327e42732ad928d47ac7 100644
 | 
			
		||||
index 9142fed75e9050fcc17c01208e82f1bc57923fcd..157a85623c7eb5338baa77aba5dc448a4614ded0 100644
 | 
			
		||||
--- a/lib/internal/process/pre_execution.js
 | 
			
		||||
+++ b/lib/internal/process/pre_execution.js
 | 
			
		||||
@@ -238,12 +238,14 @@ function patchProcessObject(expandArgv1) {
 | 
			
		||||
@@ -232,12 +232,14 @@ function patchProcessObject(expandArgv1) {
 | 
			
		||||
   if (expandArgv1 && process.argv[1] &&
 | 
			
		||||
       !StringPrototypeStartsWith(process.argv[1], '-')) {
 | 
			
		||||
     // Expand process.argv[1] into a full path.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ to child processes spawned with `ELECTRON_RUN_AS_NODE` which is used
 | 
			
		|||
by the crashpad client to connect with the handler process.
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/child_process.js b/lib/child_process.js
 | 
			
		||||
index 9dd33ecbac3a5d516f9bff76fdbe1a8aece531f2..0464ecc7b53389cdff97a7fe4cb01582e8b72dbb 100644
 | 
			
		||||
index 449013906e93e59568a90264d5372a3962db6cb0..168163001f13b641bc284fd01a71f075e1ada94f 100644
 | 
			
		||||
--- a/lib/child_process.js
 | 
			
		||||
+++ b/lib/child_process.js
 | 
			
		||||
@@ -61,6 +61,7 @@ let debug = require('internal/util/debuglog').debuglog(
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ index 9dd33ecbac3a5d516f9bff76fdbe1a8aece531f2..0464ecc7b53389cdff97a7fe4cb01582
 | 
			
		|||
 
 | 
			
		||||
 const {
 | 
			
		||||
   AbortError,
 | 
			
		||||
@@ -162,7 +163,6 @@ function fork(modulePath, args = [], options) {
 | 
			
		||||
@@ -154,7 +155,6 @@ function fork(modulePath, args = [], options) {
 | 
			
		||||
       ArrayPrototypeSplice(execArgv, index - 1, 2);
 | 
			
		||||
     }
 | 
			
		||||
   }
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ index 9dd33ecbac3a5d516f9bff76fdbe1a8aece531f2..0464ecc7b53389cdff97a7fe4cb01582
 | 
			
		|||
   args = [...execArgv, modulePath, ...args];
 | 
			
		||||
 
 | 
			
		||||
   if (typeof options.stdio === 'string') {
 | 
			
		||||
@@ -625,6 +625,21 @@ function normalizeSpawnArguments(file, args, options) {
 | 
			
		||||
@@ -617,6 +617,21 @@ function normalizeSpawnArguments(file, args, options) {
 | 
			
		||||
                     'options.windowsVerbatimArguments');
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Shelley Vohr <shelley.vohr@gmail.com>
 | 
			
		||||
Date: Thu, 13 Sep 2018 08:56:07 -0700
 | 
			
		||||
Subject: feat: initialize asar support
 | 
			
		||||
 | 
			
		||||
This patch initializes asar support in Node.js.
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
 | 
			
		||||
index 9142fed75e9050fcc17c01208e82f1bc57923fcd..fc8f61ee6d30cf18951ec7a5eb5f09a9583a85ae 100644
 | 
			
		||||
--- a/lib/internal/process/pre_execution.js
 | 
			
		||||
+++ b/lib/internal/process/pre_execution.js
 | 
			
		||||
@@ -87,6 +87,7 @@ function prepareShadowRealmExecution() {
 | 
			
		||||
   });
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+let processLinkedBinding = process._linkedBinding;
 | 
			
		||||
 function prepareExecution(options) {
 | 
			
		||||
   const { expandArgv1, initializeModules, isMainThread } = options;
 | 
			
		||||
 
 | 
			
		||||
@@ -193,12 +194,17 @@ function setupUserModules(forceDefaultLoader = false) {
 | 
			
		||||
   }
 | 
			
		||||
   // Need to be done after --require setup.
 | 
			
		||||
   initializeFrozenIntrinsics();
 | 
			
		||||
+  setupAsarSupport();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 function refreshRuntimeOptions() {
 | 
			
		||||
   refreshOptions();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+function setupAsarSupport() {
 | 
			
		||||
+  processLinkedBinding('electron_common_asar').initAsarSupport(require);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * Patch the process object with legacy properties and normalizations.
 | 
			
		||||
  * Replace `process.argv[0]` with `process.execPath`, preserving the original `argv[0]` value as `process.argv0`.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Shelley Vohr <shelley.vohr@gmail.com>
 | 
			
		||||
Date: Mon, 30 Jul 2018 10:30:35 -0700
 | 
			
		||||
Subject: refactor: alter child_process.fork to use execute script with
 | 
			
		||||
 Electron
 | 
			
		||||
 | 
			
		||||
When forking a child script, we setup a special environment to make the Electron binary run like the upstream node. On Mac, we use the helper app as node binary.
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/child_process.js b/lib/child_process.js
 | 
			
		||||
index 449013906e93e59568a90264d5372a3962db6cb0..9dd33ecbac3a5d516f9bff76fdbe1a8aece531f2 100644
 | 
			
		||||
--- a/lib/child_process.js
 | 
			
		||||
+++ b/lib/child_process.js
 | 
			
		||||
@@ -139,6 +139,14 @@ function fork(modulePath, args = [], options) {
 | 
			
		||||
     validateObject(options, 'options');
 | 
			
		||||
   }
 | 
			
		||||
   options = { __proto__: null, ...options, shell: false };
 | 
			
		||||
+  // When forking a child script, we setup a special environment to make
 | 
			
		||||
+  // the electron binary run like upstream Node.js
 | 
			
		||||
+  options.env = Object.create(options.env || process.env)
 | 
			
		||||
+  options.env.ELECTRON_RUN_AS_NODE = 1;
 | 
			
		||||
+
 | 
			
		||||
+  if (!options.execPath && process.type && process.platform == 'darwin') {
 | 
			
		||||
+     options.execPath = process.helperExecPath;
 | 
			
		||||
+  }
 | 
			
		||||
   options.execPath = options.execPath || process.execPath;
 | 
			
		||||
   validateArgumentNullCheck(options.execPath, 'options.execPath');
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										299
									
								
								patches/node/src_preload_function_for_environment.patch
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								patches/node/src_preload_function_for_environment.patch
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,299 @@
 | 
			
		|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cheng Zhao <zcbenz@gmail.com>
 | 
			
		||||
Date: Mon, 22 Jan 2024 13:45:55 +0900
 | 
			
		||||
Subject: src: preload function for Environment
 | 
			
		||||
 | 
			
		||||
https://github.com/nodejs/node/pull/51539
 | 
			
		||||
 | 
			
		||||
This PR adds a |preload| arg to the node::CreateEnvironment to allow
 | 
			
		||||
embedders to set a preload function for the environment, which will run
 | 
			
		||||
after the environment is loaded and before the main script runs.
 | 
			
		||||
 | 
			
		||||
This is similiar to the --require CLI option, but runs a C++ function,
 | 
			
		||||
and can only be set by embedders.
 | 
			
		||||
 | 
			
		||||
The preload function can be used by embedders to inject scripts before
 | 
			
		||||
running the main script, for example:
 | 
			
		||||
1. In Electron it is used to initialize the ASAR virtual filesystem,
 | 
			
		||||
   inject custom process properties, etc.
 | 
			
		||||
2. In VS Code it can be used to reset the module search paths for
 | 
			
		||||
   extensions.
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
 | 
			
		||||
index 157a85623c7eb5338baa77aba5dc448a4614ded0..701f91f1c9603c1da03e0fe6d20c8627c8d644fb 100644
 | 
			
		||||
--- a/lib/internal/process/pre_execution.js
 | 
			
		||||
+++ b/lib/internal/process/pre_execution.js
 | 
			
		||||
@@ -185,6 +185,9 @@ function setupUserModules(forceDefaultLoader = false) {
 | 
			
		||||
   initializeESMLoader(forceDefaultLoader);
 | 
			
		||||
   const CJSLoader = require('internal/modules/cjs/loader');
 | 
			
		||||
   assert(!CJSLoader.hasLoadedAnyUserCJSModule);
 | 
			
		||||
+  if (getEmbedderOptions().hasEmbedderPreload) {
 | 
			
		||||
+    runEmbedderPreload();
 | 
			
		||||
+  }
 | 
			
		||||
   // Do not enable preload modules if custom loaders are disabled.
 | 
			
		||||
   // For example, loader workers are responsible for doing this themselves.
 | 
			
		||||
   // And preload modules are not supported in ShadowRealm as well.
 | 
			
		||||
@@ -742,6 +745,10 @@ function initializeFrozenIntrinsics() {
 | 
			
		||||
   }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+function runEmbedderPreload() {
 | 
			
		||||
+  internalBinding('mksnapshot').runEmbedderPreload(process, require);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 function loadPreloadModules() {
 | 
			
		||||
   // For user code, we preload modules if `-r` is passed
 | 
			
		||||
   const preloadModules = getOptionValue('--require');
 | 
			
		||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
 | 
			
		||||
index 9045de3b17c93c4864a1bb1024b08f7d1ffa83be..7c580e1ce1af66e010083240aaf8b0037dd41f2e 100644
 | 
			
		||||
--- a/src/api/environment.cc
 | 
			
		||||
+++ b/src/api/environment.cc
 | 
			
		||||
@@ -442,7 +442,8 @@ Environment* CreateEnvironment(
 | 
			
		||||
     const std::vector<std::string>& exec_args,
 | 
			
		||||
     EnvironmentFlags::Flags flags,
 | 
			
		||||
     ThreadId thread_id,
 | 
			
		||||
-    std::unique_ptr<InspectorParentHandle> inspector_parent_handle) {
 | 
			
		||||
+    std::unique_ptr<InspectorParentHandle> inspector_parent_handle,
 | 
			
		||||
+    EmbedderPreloadCallback preload) {
 | 
			
		||||
   Isolate* isolate = isolate_data->isolate();
 | 
			
		||||
 
 | 
			
		||||
   Isolate::Scope isolate_scope(isolate);
 | 
			
		||||
@@ -463,7 +464,8 @@ Environment* CreateEnvironment(
 | 
			
		||||
                                      exec_args,
 | 
			
		||||
                                      env_snapshot_info,
 | 
			
		||||
                                      flags,
 | 
			
		||||
-                                     thread_id);
 | 
			
		||||
+                                     thread_id,
 | 
			
		||||
+                                     std::move(preload));
 | 
			
		||||
   CHECK_NOT_NULL(env);
 | 
			
		||||
 
 | 
			
		||||
   if (use_snapshot) {
 | 
			
		||||
diff --git a/src/env-inl.h b/src/env-inl.h
 | 
			
		||||
index 564de2990c09a54693686666f9ad66398ff76ab5..b10bc2396539b011dec6f09719251bfc842072af 100644
 | 
			
		||||
--- a/src/env-inl.h
 | 
			
		||||
+++ b/src/env-inl.h
 | 
			
		||||
@@ -438,6 +438,10 @@ inline void Environment::set_embedder_entry_point(StartExecutionCallback&& fn) {
 | 
			
		||||
   embedder_entry_point_ = std::move(fn);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+inline const EmbedderPreloadCallback& Environment::embedder_preload() const {
 | 
			
		||||
+  return embedder_preload_;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 inline double Environment::new_async_id() {
 | 
			
		||||
   async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
 | 
			
		||||
   return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
 | 
			
		||||
diff --git a/src/env.cc b/src/env.cc
 | 
			
		||||
index ba575a04340b91709fb6c8710ab160a4ca1f8b77..76db0ac4ef72b902a7567a96cfd751ff879117b7 100644
 | 
			
		||||
--- a/src/env.cc
 | 
			
		||||
+++ b/src/env.cc
 | 
			
		||||
@@ -767,7 +767,8 @@ Environment::Environment(IsolateData* isolate_data,
 | 
			
		||||
                          const std::vector<std::string>& exec_args,
 | 
			
		||||
                          const EnvSerializeInfo* env_info,
 | 
			
		||||
                          EnvironmentFlags::Flags flags,
 | 
			
		||||
-                         ThreadId thread_id)
 | 
			
		||||
+                         ThreadId thread_id,
 | 
			
		||||
+                         EmbedderPreloadCallback preload)
 | 
			
		||||
     : isolate_(isolate),
 | 
			
		||||
       isolate_data_(isolate_data),
 | 
			
		||||
       async_hooks_(isolate, MAYBE_FIELD_PTR(env_info, async_hooks)),
 | 
			
		||||
@@ -793,7 +794,8 @@ Environment::Environment(IsolateData* isolate_data,
 | 
			
		||||
       flags_(flags),
 | 
			
		||||
       thread_id_(thread_id.id == static_cast<uint64_t>(-1)
 | 
			
		||||
                      ? AllocateEnvironmentThreadId().id
 | 
			
		||||
-                     : thread_id.id) {
 | 
			
		||||
+                     : thread_id.id),
 | 
			
		||||
+      embedder_preload_(std::move(preload)) {
 | 
			
		||||
   constexpr bool is_shared_ro_heap =
 | 
			
		||||
 #ifdef NODE_V8_SHARED_RO_HEAP
 | 
			
		||||
       true;
 | 
			
		||||
diff --git a/src/env.h b/src/env.h
 | 
			
		||||
index 448075e354c760a2dbd1dd763f40b7a645730250..a5aad9596953536b0a1f741dfbc4f21f6a961404 100644
 | 
			
		||||
--- a/src/env.h
 | 
			
		||||
+++ b/src/env.h
 | 
			
		||||
@@ -635,7 +635,8 @@ class Environment : public MemoryRetainer {
 | 
			
		||||
               const std::vector<std::string>& exec_args,
 | 
			
		||||
               const EnvSerializeInfo* env_info,
 | 
			
		||||
               EnvironmentFlags::Flags flags,
 | 
			
		||||
-              ThreadId thread_id);
 | 
			
		||||
+              ThreadId thread_id,
 | 
			
		||||
+              EmbedderPreloadCallback preload);
 | 
			
		||||
   void InitializeMainContext(v8::Local<v8::Context> context,
 | 
			
		||||
                              const EnvSerializeInfo* env_info);
 | 
			
		||||
   ~Environment() override;
 | 
			
		||||
@@ -986,6 +987,8 @@ class Environment : public MemoryRetainer {
 | 
			
		||||
   inline const StartExecutionCallback& embedder_entry_point() const;
 | 
			
		||||
   inline void set_embedder_entry_point(StartExecutionCallback&& fn);
 | 
			
		||||
 
 | 
			
		||||
+  inline const EmbedderPreloadCallback& embedder_preload() const;
 | 
			
		||||
+
 | 
			
		||||
   inline void set_process_exit_handler(
 | 
			
		||||
       std::function<void(Environment*, ExitCode)>&& handler);
 | 
			
		||||
 
 | 
			
		||||
@@ -1186,6 +1189,7 @@ class Environment : public MemoryRetainer {
 | 
			
		||||
 
 | 
			
		||||
   builtins::BuiltinLoader builtin_loader_;
 | 
			
		||||
   StartExecutionCallback embedder_entry_point_;
 | 
			
		||||
+  EmbedderPreloadCallback embedder_preload_;
 | 
			
		||||
 
 | 
			
		||||
   // Used by allocate_managed_buffer() and release_managed_buffer() to keep
 | 
			
		||||
   // track of the BackingStore for a given pointer.
 | 
			
		||||
diff --git a/src/node.h b/src/node.h
 | 
			
		||||
index 36da93a7b41ea450a5f288ec17b61adae46ae178..09e044e86bab2cef42c86dbfc9bbcc743daf564d 100644
 | 
			
		||||
--- a/src/node.h
 | 
			
		||||
+++ b/src/node.h
 | 
			
		||||
@@ -678,11 +678,23 @@ struct InspectorParentHandle {
 | 
			
		||||
   virtual ~InspectorParentHandle() = default;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+using EmbedderPreloadCallback =
 | 
			
		||||
+    std::function<void(Environment* env,
 | 
			
		||||
+                       v8::Local<v8::Value> process,
 | 
			
		||||
+                       v8::Local<v8::Value> require)>;
 | 
			
		||||
+
 | 
			
		||||
 // TODO(addaleax): Maybe move per-Environment options parsing here.
 | 
			
		||||
 // Returns nullptr when the Environment cannot be created e.g. there are
 | 
			
		||||
 // pending JavaScript exceptions.
 | 
			
		||||
 // `context` may be empty if an `EmbedderSnapshotData` instance was provided
 | 
			
		||||
 // to `NewIsolate()` and `CreateIsolateData()`.
 | 
			
		||||
+//
 | 
			
		||||
+// The |preload| function will run before executing the entry point, which
 | 
			
		||||
+// is usually used by embedders to inject scripts. The function is executed
 | 
			
		||||
+// with preload(process, require), and the passed require function has access
 | 
			
		||||
+// to internal Node.js modules. The |preload| function is inherited by worker
 | 
			
		||||
+// threads and thus will run in work threads, so make sure the function is
 | 
			
		||||
+// thread-safe.
 | 
			
		||||
 NODE_EXTERN Environment* CreateEnvironment(
 | 
			
		||||
     IsolateData* isolate_data,
 | 
			
		||||
     v8::Local<v8::Context> context,
 | 
			
		||||
@@ -690,7 +702,8 @@ NODE_EXTERN Environment* CreateEnvironment(
 | 
			
		||||
     const std::vector<std::string>& exec_args,
 | 
			
		||||
     EnvironmentFlags::Flags flags = EnvironmentFlags::kDefaultFlags,
 | 
			
		||||
     ThreadId thread_id = {} /* allocates a thread id automatically */,
 | 
			
		||||
-    std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {});
 | 
			
		||||
+    std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {},
 | 
			
		||||
+    EmbedderPreloadCallback preload = nullptr);
 | 
			
		||||
 
 | 
			
		||||
 // Returns a handle that can be passed to `LoadEnvironment()`, making the
 | 
			
		||||
 // child Environment accessible to the inspector as if it were a Node.js Worker.
 | 
			
		||||
diff --git a/src/node_options.cc b/src/node_options.cc
 | 
			
		||||
index 48ce3f3b68a94fc35e5ce93a385ddbebb03741b9..39d34e18e483882a71145110962109711a1566e2 100644
 | 
			
		||||
--- a/src/node_options.cc
 | 
			
		||||
+++ b/src/node_options.cc
 | 
			
		||||
@@ -1290,6 +1290,12 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
 | 
			
		||||
           .IsNothing())
 | 
			
		||||
     return;
 | 
			
		||||
 
 | 
			
		||||
+  if (ret->Set(context,
 | 
			
		||||
+               FIXED_ONE_BYTE_STRING(env->isolate(), "hasEmbedderPreload"),
 | 
			
		||||
+               Boolean::New(isolate, env->embedder_preload() != nullptr))
 | 
			
		||||
+          .IsNothing())
 | 
			
		||||
+    return;
 | 
			
		||||
+
 | 
			
		||||
   args.GetReturnValue().Set(ret);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
 | 
			
		||||
index 562a47ddcc9c8e61590b7b09d84dc08ab4b3653d..325bebc1df9ad2e8b0bad468951cf1563ecefc14 100644
 | 
			
		||||
--- a/src/node_snapshotable.cc
 | 
			
		||||
+++ b/src/node_snapshotable.cc
 | 
			
		||||
@@ -1369,6 +1369,13 @@ static void RunEmbedderEntryPoint(const FunctionCallbackInfo<Value>& args) {
 | 
			
		||||
   }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void RunEmbedderPreload(const FunctionCallbackInfo<Value>& args) {
 | 
			
		||||
+  Environment* env = Environment::GetCurrent(args);
 | 
			
		||||
+  CHECK(env->embedder_preload());
 | 
			
		||||
+  CHECK_EQ(args.Length(), 2);
 | 
			
		||||
+  env->embedder_preload()(env, args[0], args[1]);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
 | 
			
		||||
   CHECK(args[0]->IsString());
 | 
			
		||||
   Local<String> filename = args[0].As<String>();
 | 
			
		||||
@@ -1493,6 +1500,7 @@ void CreatePerIsolateProperties(IsolateData* isolate_data,
 | 
			
		||||
                                 Local<ObjectTemplate> target) {
 | 
			
		||||
   Isolate* isolate = isolate_data->isolate();
 | 
			
		||||
   SetMethod(isolate, target, "runEmbedderEntryPoint", RunEmbedderEntryPoint);
 | 
			
		||||
+  SetMethod(isolate, target, "runEmbedderPreload", RunEmbedderPreload);
 | 
			
		||||
   SetMethod(isolate, target, "compileSerializeMain", CompileSerializeMain);
 | 
			
		||||
   SetMethod(isolate, target, "setSerializeCallback", SetSerializeCallback);
 | 
			
		||||
   SetMethod(isolate, target, "setDeserializeCallback", SetDeserializeCallback);
 | 
			
		||||
@@ -1506,6 +1514,7 @@ void CreatePerIsolateProperties(IsolateData* isolate_data,
 | 
			
		||||
 
 | 
			
		||||
 void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
 | 
			
		||||
   registry->Register(RunEmbedderEntryPoint);
 | 
			
		||||
+  registry->Register(RunEmbedderPreload);
 | 
			
		||||
   registry->Register(CompileSerializeMain);
 | 
			
		||||
   registry->Register(SetSerializeCallback);
 | 
			
		||||
   registry->Register(SetDeserializeCallback);
 | 
			
		||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
 | 
			
		||||
index 900674bbe4c90e9aeb2013c06c9979864b06dcd5..2a22d986585e93ea00c6dcdca1f7b783ef0723f8 100644
 | 
			
		||||
--- a/src/node_worker.cc
 | 
			
		||||
+++ b/src/node_worker.cc
 | 
			
		||||
@@ -63,6 +63,7 @@ Worker::Worker(Environment* env,
 | 
			
		||||
       thread_id_(AllocateEnvironmentThreadId()),
 | 
			
		||||
       name_(name),
 | 
			
		||||
       env_vars_(env_vars),
 | 
			
		||||
+      embedder_preload_(env->embedder_preload()),
 | 
			
		||||
       snapshot_data_(snapshot_data) {
 | 
			
		||||
   Debug(this, "Creating new worker instance with thread id %llu",
 | 
			
		||||
         thread_id_.id);
 | 
			
		||||
@@ -360,7 +361,8 @@ void Worker::Run() {
 | 
			
		||||
             std::move(exec_argv_),
 | 
			
		||||
             static_cast<EnvironmentFlags::Flags>(environment_flags_),
 | 
			
		||||
             thread_id_,
 | 
			
		||||
-            std::move(inspector_parent_handle_)));
 | 
			
		||||
+            std::move(inspector_parent_handle_),
 | 
			
		||||
+            std::move(embedder_preload_)));
 | 
			
		||||
         if (is_stopped()) return;
 | 
			
		||||
         CHECK_NOT_NULL(env_);
 | 
			
		||||
         env_->set_env_vars(std::move(env_vars_));
 | 
			
		||||
diff --git a/src/node_worker.h b/src/node_worker.h
 | 
			
		||||
index 531e2b5287010f9206ab4fd7f4dd0f3dec9fe55c..07fd7b460654e169e8b6822474dc3cc70fcec4c0 100644
 | 
			
		||||
--- a/src/node_worker.h
 | 
			
		||||
+++ b/src/node_worker.h
 | 
			
		||||
@@ -114,6 +114,7 @@ class Worker : public AsyncWrap {
 | 
			
		||||
 
 | 
			
		||||
   std::unique_ptr<MessagePortData> child_port_data_;
 | 
			
		||||
   std::shared_ptr<KVStore> env_vars_;
 | 
			
		||||
+  EmbedderPreloadCallback embedder_preload_;
 | 
			
		||||
 
 | 
			
		||||
   // A raw flag that is used by creator and worker threads to
 | 
			
		||||
   // sync up on pre-mature termination of worker  - while in the
 | 
			
		||||
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
 | 
			
		||||
index 2e747c7be58922897abd0424b797f3f12a89ada1..658f8df4b01d60759e858cf5283b9be9467dd142 100644
 | 
			
		||||
--- a/test/cctest/test_environment.cc
 | 
			
		||||
+++ b/test/cctest/test_environment.cc
 | 
			
		||||
@@ -773,3 +773,31 @@ TEST_F(EnvironmentTest, RequestInterruptAtExit) {
 | 
			
		||||
 
 | 
			
		||||
   context->Exit();
 | 
			
		||||
 }
 | 
			
		||||
+
 | 
			
		||||
+TEST_F(EnvironmentTest, EmbedderPreload) {
 | 
			
		||||
+  v8::HandleScope handle_scope(isolate_);
 | 
			
		||||
+  v8::Local<v8::Context> context = node::NewContext(isolate_);
 | 
			
		||||
+  v8::Context::Scope context_scope(context);
 | 
			
		||||
+
 | 
			
		||||
+  node::EmbedderPreloadCallback preload = [](node::Environment* env,
 | 
			
		||||
+                                             v8::Local<v8::Value> process,
 | 
			
		||||
+                                             v8::Local<v8::Value> require) {
 | 
			
		||||
+    CHECK(process->IsObject());
 | 
			
		||||
+    CHECK(require->IsFunction());
 | 
			
		||||
+    process.As<v8::Object>()->Set(
 | 
			
		||||
+        env->context(),
 | 
			
		||||
+        v8::String::NewFromUtf8Literal(env->isolate(), "prop"),
 | 
			
		||||
+        v8::String::NewFromUtf8Literal(env->isolate(), "preload")).Check();
 | 
			
		||||
+  };
 | 
			
		||||
+
 | 
			
		||||
+  std::unique_ptr<node::Environment, decltype(&node::FreeEnvironment)> env(
 | 
			
		||||
+      node::CreateEnvironment(isolate_data_, context, {}, {},
 | 
			
		||||
+                              node::EnvironmentFlags::kDefaultFlags, {}, {},
 | 
			
		||||
+                              preload),
 | 
			
		||||
+      node::FreeEnvironment);
 | 
			
		||||
+
 | 
			
		||||
+  v8::Local<v8::Value> main_ret =
 | 
			
		||||
+      node::LoadEnvironment(env.get(), "return process.prop;").ToLocalChecked();
 | 
			
		||||
+  node::Utf8Value main_ret_str(isolate_, main_ret);
 | 
			
		||||
+  EXPECT_EQ(std::string(*main_ret_str), "preload");
 | 
			
		||||
+}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue