|
@@ -1,23 +1,9 @@
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
From: Cheng Zhao <[email protected]>
|
|
|
-Date: Mon, 22 Jan 2024 13:45:55 +0900
|
|
|
+Date: Mon, 4 Mar 2024 11:41:18 +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.
|
|
|
+Backport https://github.com/nodejs/node/pull/51539
|
|
|
|
|
|
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
|
|
index 31f5d1528c840a2926b59b2b1c82ff265588a37a..1e37bd59f53d3a194b2492c83f8e7299c42c828c 100644
|
|
@@ -45,120 +31,80 @@ index 31f5d1528c840a2926b59b2b1c82ff265588a37a..1e37bd59f53d3a194b2492c83f8e7299
|
|
|
// 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 c4caef25af670658965fc740ce03c2d2c4ed3e66..19443a9672441da5b98921eab9385083a72e3b7e 100644
|
|
|
+index c4caef25af670658965fc740ce03c2d2c4ed3e66..465ff36b79c36d29777c7b1abe3a35d3be5de93e 100644
|
|
|
--- a/src/api/environment.cc
|
|
|
+++ b/src/api/environment.cc
|
|
|
-@@ -404,14 +404,16 @@ 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,
|
|
|
+@@ -484,18 +484,22 @@ NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+
|
|
|
+-MaybeLocal<Value> LoadEnvironment(
|
|
|
+- Environment* env,
|
|
|
+- StartExecutionCallback cb) {
|
|
|
++MaybeLocal<Value> LoadEnvironment(Environment* env,
|
|
|
++ StartExecutionCallback cb,
|
|
|
++ EmbedderPreloadCallback preload) {
|
|
|
+ env->InitializeLibuv();
|
|
|
+ env->InitializeDiagnostics();
|
|
|
++ if (preload) {
|
|
|
++ env->set_embedder_preload(std::move(preload));
|
|
|
++ }
|
|
|
+
|
|
|
+ return StartExecution(env, cb);
|
|
|
+ }
|
|
|
+
|
|
|
+ MaybeLocal<Value> LoadEnvironment(
|
|
|
+ Environment* env,
|
|
|
+- const char* main_script_source_utf8) {
|
|
|
++ const char* main_script_source_utf8,
|
|
|
+ EmbedderPreloadCallback preload) {
|
|
|
- Isolate* isolate = context->GetIsolate();
|
|
|
- HandleScope handle_scope(isolate);
|
|
|
- Context::Scope context_scope(context);
|
|
|
- // TODO(addaleax): This is a much better place for parsing per-Environment
|
|
|
- // options than the global parse call.
|
|
|
- Environment* env = new Environment(
|
|
|
-- isolate_data, context, args, exec_args, nullptr, flags, thread_id);
|
|
|
-+ isolate_data, context, args, exec_args, nullptr, flags, thread_id,
|
|
|
+ CHECK_NOT_NULL(main_script_source_utf8);
|
|
|
+ return LoadEnvironment(
|
|
|
+ env, [&](const StartExecutionCallbackInfo& info) -> MaybeLocal<Value> {
|
|
|
+@@ -508,7 +512,8 @@ MaybeLocal<Value> LoadEnvironment(
|
|
|
+ std::vector<Local<Value>> args = {realm->process_object(),
|
|
|
+ realm->builtin_module_require()};
|
|
|
+ return realm->ExecuteBootstrapper(name.c_str(), &args);
|
|
|
+- });
|
|
|
++ },
|
|
|
+ std::move(preload));
|
|
|
+ }
|
|
|
|
|
|
- #if HAVE_INSPECTOR
|
|
|
- if (env->should_create_inspector()) {
|
|
|
+ Environment* GetCurrentEnvironment(Local<Context> context) {
|
|
|
diff --git a/src/env-inl.h b/src/env-inl.h
|
|
|
-index debd982c75805c51ea7d01229b9d635550060503..6af9217acb6f22c89bc92708aa9ab3d021c5e5bf 100644
|
|
|
+index debd982c75805c51ea7d01229b9d635550060503..a6f160b6e28a01a31d6bb06fcfa384c748463c50 100644
|
|
|
--- a/src/env-inl.h
|
|
|
+++ b/src/env-inl.h
|
|
|
-@@ -388,6 +388,10 @@ inline std::vector<double>* Environment::destroy_async_id_list() {
|
|
|
+@@ -388,6 +388,14 @@ inline std::vector<double>* Environment::destroy_async_id_list() {
|
|
|
return &destroy_async_id_list_;
|
|
|
}
|
|
|
|
|
|
+inline const EmbedderPreloadCallback& Environment::embedder_preload() const {
|
|
|
+ return embedder_preload_;
|
|
|
+}
|
|
|
++
|
|
|
++inline void Environment::set_embedder_preload(EmbedderPreloadCallback fn) {
|
|
|
++ embedder_preload_ = std::move(fn);
|
|
|
++}
|
|
|
+
|
|
|
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 6e8b314680c9175d8d513cc72382012ae5e70b26..e416bca327f181884ff8dad2b3a82ad826c0f3b5 100644
|
|
|
---- a/src/env.cc
|
|
|
-+++ b/src/env.cc
|
|
|
-@@ -645,7 +645,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)),
|
|
|
-@@ -668,7 +669,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)) {
|
|
|
- // We'll be creating new objects so make sure we've entered the context.
|
|
|
- HandleScope handle_scope(isolate);
|
|
|
-
|
|
|
-@@ -738,14 +740,16 @@ 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)
|
|
|
- : Environment(isolate_data,
|
|
|
- context->GetIsolate(),
|
|
|
- args,
|
|
|
- exec_args,
|
|
|
- env_info,
|
|
|
- flags,
|
|
|
-- thread_id) {
|
|
|
-+ thread_id,
|
|
|
-+ std::move(preload)) {
|
|
|
- InitializeMainContext(context, env_info);
|
|
|
- }
|
|
|
-
|
|
|
diff --git a/src/env.h b/src/env.h
|
|
|
-index c914b621f50bcd6bce2617fef9e48737235aa516..d2e7f8534498ca171986cf77ef19d2fc9b950a5b 100644
|
|
|
+index c914b621f50bcd6bce2617fef9e48737235aa516..e8ea98f193fcf579c20c3126dd441850c608752e 100644
|
|
|
--- a/src/env.h
|
|
|
+++ b/src/env.h
|
|
|
-@@ -579,7 +579,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);
|
|
|
- // Create an Environment and initialize the provided principal context for it.
|
|
|
-@@ -589,7 +590,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);
|
|
|
- ~Environment() override;
|
|
|
-
|
|
|
- void InitializeLibuv();
|
|
|
-@@ -933,6 +935,8 @@ class Environment : public MemoryRetainer {
|
|
|
+@@ -933,6 +933,9 @@ class Environment : public MemoryRetainer {
|
|
|
|
|
|
#endif // HAVE_INSPECTOR
|
|
|
|
|
|
+ inline const EmbedderPreloadCallback& embedder_preload() const;
|
|
|
++ inline void set_embedder_preload(EmbedderPreloadCallback fn);
|
|
|
+
|
|
|
inline void set_process_exit_handler(
|
|
|
std::function<void(Environment*, int)>&& handler);
|
|
|
|
|
|
-@@ -1101,6 +1105,7 @@ class Environment : public MemoryRetainer {
|
|
|
+@@ -1101,6 +1104,7 @@ class Environment : public MemoryRetainer {
|
|
|
DefaultProcessExitHandler };
|
|
|
|
|
|
std::unique_ptr<Realm> principal_realm_ = nullptr;
|
|
@@ -167,55 +113,45 @@ index c914b621f50bcd6bce2617fef9e48737235aa516..d2e7f8534498ca171986cf77ef19d2fc
|
|
|
// 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 26368061a909e6abc62a4cf261a5dbbd79404f1a..bb4065e33164c3ea762a27b71606ab4ed7b1b336 100644
|
|
|
+index 26368061a909e6abc62a4cf261a5dbbd79404f1a..0dec1e311d7c00c2b830a0b2a6bde4336aebe68b 100644
|
|
|
--- a/src/node.h
|
|
|
+++ b/src/node.h
|
|
|
-@@ -593,9 +593,21 @@ struct InspectorParentHandle {
|
|
|
- virtual ~InspectorParentHandle();
|
|
|
- };
|
|
|
+@@ -630,13 +630,33 @@ struct StartExecutionCallbackInfo {
|
|
|
|
|
|
+ using StartExecutionCallback =
|
|
|
+ std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>;
|
|
|
+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.
|
|
|
+
|
|
|
++// Run initialization for the environment.
|
|
|
+//
|
|
|
-+// 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,
|
|
|
-@@ -603,7 +615,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 = {},
|
|
|
++// The |preload| function, usually used by embedders to inject scripts,
|
|
|
++// will be run by Node.js before Node.js executes the entry point.
|
|
|
++// The function is guaranteed to run before the user land module loader running
|
|
|
++// any user code, so it is safe to assume that at this point, no user code has
|
|
|
++// been run yet.
|
|
|
++// The function will be executed with preload(process, require), and the passed
|
|
|
++// require function has access to internal Node.js modules. There is no
|
|
|
++// stability guarantee about the internals exposed to the internal require
|
|
|
++// function. Expect breakages when updating Node.js versions if the embedder
|
|
|
++// imports internal modules with the internal require function.
|
|
|
++// Worker threads created in the environment will also respect The |preload|
|
|
|
++// function, so make sure the function is thread-safe.
|
|
|
+ NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
|
|
|
+ Environment* env,
|
|
|
+- StartExecutionCallback cb);
|
|
|
++ StartExecutionCallback cb,
|
|
|
++ EmbedderPreloadCallback preload = nullptr);
|
|
|
+ NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
|
|
|
+ Environment* env,
|
|
|
+- const char* main_script_source_utf8);
|
|
|
++ const char* main_script_source_utf8,
|
|
|
+ EmbedderPreloadCallback preload = nullptr);
|
|
|
+ NODE_EXTERN void FreeEnvironment(Environment* env);
|
|
|
|
|
|
- // 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_main_instance.cc b/src/node_main_instance.cc
|
|
|
-index a8661c3c2263fc62e55659310b8da12fc414361e..849442aa8c923808420cbc888befea7d3f1f4c1b 100644
|
|
|
---- a/src/node_main_instance.cc
|
|
|
-+++ b/src/node_main_instance.cc
|
|
|
-@@ -157,7 +157,8 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code) {
|
|
|
- exec_args_,
|
|
|
- &(snapshot_data_->env_info),
|
|
|
- EnvironmentFlags::kDefaultFlags,
|
|
|
-- {}));
|
|
|
-+ {},
|
|
|
-+ nullptr));
|
|
|
- context = Context::FromSnapshot(isolate_,
|
|
|
- SnapshotData::kNodeMainContextIndex,
|
|
|
- {DeserializeNodeInternalFields, env.get()})
|
|
|
+ // Set a callback that is called when process.exit() is called from JS,
|
|
|
diff --git a/src/node_options.cc b/src/node_options.cc
|
|
|
index 7ad8d80faee840e4dd224d946871b2ff08b0c23c..25842fd531fc7e1485bcd75f1f92aa9bc0640862 100644
|
|
|
--- a/src/node_options.cc
|
|
@@ -234,24 +170,28 @@ index 7ad8d80faee840e4dd224d946871b2ff08b0c23c..25842fd531fc7e1485bcd75f1f92aa9b
|
|
|
}
|
|
|
|
|
|
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
|
|
|
-index bfa048a4a8aa183e747dec84b11b1c1d847db2dd..b8337e68cb946366b2dff78bbd12ce5473ee166c 100644
|
|
|
+index bfa048a4a8aa183e747dec84b11b1c1d847db2dd..970cec6c6e9c5e9646bfd758a2cf908e6b5799cf 100644
|
|
|
--- a/src/node_snapshotable.cc
|
|
|
+++ b/src/node_snapshotable.cc
|
|
|
-@@ -1462,6 +1462,13 @@ void SerializeSnapshotableObjects(Realm* realm,
|
|
|
+@@ -1462,6 +1462,17 @@ void SerializeSnapshotableObjects(Realm* realm,
|
|
|
|
|
|
namespace mksnapshot {
|
|
|
|
|
|
-+static void RunEmbedderPreload(const FunctionCallbackInfo<Value>& args) {
|
|
|
++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]);
|
|
|
++ Local<Value> process_obj = args[0];
|
|
|
++ Local<Value> require_fn = args[1];
|
|
|
++ CHECK(process_obj->IsObject());
|
|
|
++ CHECK(require_fn->IsFunction());
|
|
|
++ env->embedder_preload()(env, process_obj, require_fn);
|
|
|
+}
|
|
|
+
|
|
|
void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
|
|
|
CHECK(args[0]->IsString());
|
|
|
Local<String> filename = args[0].As<String>();
|
|
|
-@@ -1515,6 +1522,7 @@ void Initialize(Local<Object> target,
|
|
|
+@@ -1515,6 +1526,7 @@ void Initialize(Local<Object> target,
|
|
|
Local<Value> unused,
|
|
|
Local<Context> context,
|
|
|
void* priv) {
|
|
@@ -259,7 +199,7 @@ index bfa048a4a8aa183e747dec84b11b1c1d847db2dd..b8337e68cb946366b2dff78bbd12ce54
|
|
|
SetMethod(context, target, "compileSerializeMain", CompileSerializeMain);
|
|
|
SetMethod(context, target, "setSerializeCallback", SetSerializeCallback);
|
|
|
SetMethod(context, target, "setDeserializeCallback", SetDeserializeCallback);
|
|
|
-@@ -1525,6 +1533,7 @@ void Initialize(Local<Object> target,
|
|
|
+@@ -1525,6 +1537,7 @@ void Initialize(Local<Object> target,
|
|
|
}
|
|
|
|
|
|
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
|
@@ -268,7 +208,7 @@ index bfa048a4a8aa183e747dec84b11b1c1d847db2dd..b8337e68cb946366b2dff78bbd12ce54
|
|
|
registry->Register(SetSerializeCallback);
|
|
|
registry->Register(SetDeserializeCallback);
|
|
|
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
|
|
-index 6a49144ec4f2059fe75983609b0768e4c2b1817d..dc2eb247b011f9cb1945c173c49e029f068ef103 100644
|
|
|
+index 6a49144ec4f2059fe75983609b0768e4c2b1817d..13b0445370c70cf3765a4af44336c16ac2e1035d 100644
|
|
|
--- a/src/node_worker.cc
|
|
|
+++ b/src/node_worker.cc
|
|
|
@@ -60,6 +60,7 @@ Worker::Worker(Environment* env,
|
|
@@ -279,16 +219,20 @@ index 6a49144ec4f2059fe75983609b0768e4c2b1817d..dc2eb247b011f9cb1945c173c49e029f
|
|
|
snapshot_data_(snapshot_data) {
|
|
|
Debug(this, "Creating new worker instance with thread id %llu",
|
|
|
thread_id_.id);
|
|
|
-@@ -333,7 +334,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_));
|
|
|
+@@ -354,8 +355,12 @@ void Worker::Run() {
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug(this, "Created message port for worker %llu", thread_id_.id);
|
|
|
+- if (LoadEnvironment(env_.get(), StartExecutionCallback{}).IsEmpty())
|
|
|
++ if (LoadEnvironment(env_.get(),
|
|
|
++ StartExecutionCallback{},
|
|
|
++ std::move(embedder_preload_))
|
|
|
++ .IsEmpty()) {
|
|
|
+ return;
|
|
|
++ }
|
|
|
+
|
|
|
+ Debug(this, "Loaded environment for worker %llu", thread_id_.id);
|
|
|
+ }
|
|
|
diff --git a/src/node_worker.h b/src/node_worker.h
|
|
|
index a77c416735a79feb3f54e40d72a98c8903a20ccd..deab68576f6330f8bcfb4703fd05dbb9c515e473 100644
|
|
|
--- a/src/node_worker.h
|
|
@@ -302,7 +246,7 @@ index a77c416735a79feb3f54e40d72a98c8903a20ccd..deab68576f6330f8bcfb4703fd05dbb9
|
|
|
// 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 547c8ddbffe243113bfe47a51072bb8f1541b94f..19ef2c2a083f908267e6a9365e77b20d46a3feec 100644
|
|
|
+index 547c8ddbffe243113bfe47a51072bb8f1541b94f..9f1fec4c4e47376c3b93a549f5c7ddf8e7ed3ac6 100644
|
|
|
--- a/test/cctest/test_environment.cc
|
|
|
+++ b/test/cctest/test_environment.cc
|
|
|
@@ -749,3 +749,31 @@ TEST_F(EnvironmentTest, RequestInterruptAtExit) {
|
|
@@ -320,20 +264,20 @@ index 547c8ddbffe243113bfe47a51072bb8f1541b94f..19ef2c2a083f908267e6a9365e77b20d
|
|
|
+ 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();
|
|
|
++ 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::CreateEnvironment(isolate_data_, context, {}, {}),
|
|
|
+ node::FreeEnvironment);
|
|
|
+
|
|
|
+ v8::Local<v8::Value> main_ret =
|
|
|
-+ node::LoadEnvironment(env.get(), "return process.prop;").ToLocalChecked();
|
|
|
++ node::LoadEnvironment(env.get(), "return process.prop;", preload)
|
|
|
++ .ToLocalChecked();
|
|
|
+ node::Utf8Value main_ret_str(isolate_, main_ret);
|
|
|
+ EXPECT_EQ(std::string(*main_ret_str), "preload");
|
|
|
+}
|