lib: create primordials in every context

This allows us to use primordials in other per-context scripts.

PR-URL: https://github.com/nodejs/node/pull/27171
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: MichaĆ«l Zasso <[email protected]>
Reviewed-By: James M Snell <[email protected]>
diff --git a/lib/internal/bootstrap/primordials.js b/lib/internal/per_context/primordials.js
similarity index 100%
rename from lib/internal/bootstrap/primordials.js
rename to lib/internal/per_context/primordials.js
diff --git a/node.gyp b/node.gyp
index 9088c4c..f23fd42 100644
--- a/node.gyp
+++ b/node.gyp
@@ -26,11 +26,11 @@
     'node_lib_target_name%': 'node_lib',
     'node_intermediate_lib_type%': 'static_library',
     'library_files': [
-      'lib/internal/bootstrap/primordials.js',
       'lib/internal/bootstrap/environment.js',
       'lib/internal/bootstrap/loaders.js',
       'lib/internal/bootstrap/node.js',
       'lib/internal/bootstrap/pre_execution.js',
+      'lib/internal/per_context/primordials.js',
       'lib/internal/per_context/setup.js',
       'lib/internal/per_context/domexception.js',
       'lib/async_hooks.js',
diff --git a/src/api/environment.cc b/src/api/environment.cc
index fb7d700..a87f591 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -23,6 +23,7 @@
 using v8::MaybeLocal;
 using v8::Message;
 using v8::MicrotasksPolicy;
+using v8::Null;
 using v8::Object;
 using v8::ObjectTemplate;
 using v8::Private;
@@ -332,24 +333,29 @@
     // Run per-context JS files.
     Context::Scope context_scope(context);
     Local<Object> exports;
-    if (!GetPerContextExports(context).ToLocal(&exports))
-      return Local<Context>();
 
+    Local<String> primordials_string =
+        FIXED_ONE_BYTE_STRING(isolate, "primordials");
     Local<String> global_string = FIXED_ONE_BYTE_STRING(isolate, "global");
     Local<String> exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports");
 
-    static const char* context_files[] = {
-      "internal/per_context/setup",
-      "internal/per_context/domexception",
-      nullptr
-    };
+    // Create primordials first and make it available to per-context scripts.
+    Local<Object> primordials = Object::New(isolate);
+    if (!primordials->SetPrototype(context, Null(isolate)).FromJust() ||
+        !GetPerContextExports(context).ToLocal(&exports) ||
+        !exports->Set(context, primordials_string, primordials).FromJust()) {
+      return Local<Context>();
+    }
+
+    static const char* context_files[] = {"internal/per_context/primordials",
+                                          "internal/per_context/setup",
+                                          "internal/per_context/domexception",
+                                          nullptr};
 
     for (const char** module = context_files; *module != nullptr; module++) {
       std::vector<Local<String>> parameters = {
-        global_string,
-        exports_string
-      };
-      Local<Value> arguments[] = {context->Global(), exports};
+          global_string, exports_string, primordials_string};
+      Local<Value> arguments[] = {context->Global(), exports, primordials};
       MaybeLocal<Function> maybe_fn =
           native_module::NativeModuleEnv::LookupAndCompile(
               context, *module, &parameters, nullptr);
diff --git a/src/node.cc b/src/node.cc
index 09817b8..0e4e361 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -268,14 +268,16 @@
   global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
       .Check();
 
-  // Store primordials
-  env->set_primordials(Object::New(isolate));
-  std::vector<Local<String>> primordials_params = {
-    env->primordials_string()
-  };
-  std::vector<Local<Value>> primordials_args = {
-    env->primordials()
-  };
+  // Store primordials setup by the per-context script in the environment.
+  Local<Object> per_context_bindings;
+  Local<Value> primordials;
+  if (!GetPerContextExports(context).ToLocal(&per_context_bindings) ||
+      !per_context_bindings->Get(context, env->primordials_string())
+           .ToLocal(&primordials) ||
+      !primordials->IsObject()) {
+    return MaybeLocal<Value>();
+  }
+  env->set_primordials(primordials.As<Object>());
 
 #if HAVE_INSPECTOR
   if (env->options()->debug_options().break_node_first_line) {
@@ -283,14 +285,6 @@
         "Break at bootstrap");
   }
 #endif  // HAVE_INSPECTOR
-  MaybeLocal<Value> primordials_ret =
-      ExecuteBootstrapper(env,
-                          "internal/bootstrap/primordials",
-                          &primordials_params,
-                          &primordials_args);
-  if (primordials_ret.IsEmpty()) {
-    return MaybeLocal<Value>();
-  }
 
   // Create binding loaders
   std::vector<Local<String>> loaders_params = {