@@ -1209,10 +1209,39 @@ ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr,
12091209 // nullptr indicates there's no snapshot data.
12101210 DCHECK_NULL (*snapshot_data_ptr);
12111211
1212+ SnapshotConfig snapshot_config;
1213+ const std::string& config_path =
1214+ per_process::cli_options->per_isolate ->build_snapshot_config ;
1215+ // For snapshot config read from JSON, we fix up process.argv[1] using the
1216+ // "builder" field.
1217+ std::vector<std::string> args_maybe_patched;
1218+ args_maybe_patched.reserve (result->args ().size () + 1 );
1219+ if (!config_path.empty ()) {
1220+ std::optional<SnapshotConfig> optional_config =
1221+ ReadSnapshotConfig (config_path.c_str ());
1222+ if (!optional_config.has_value ()) {
1223+ return ExitCode::kGenericUserError ;
1224+ }
1225+ snapshot_config = std::move (optional_config.value ());
1226+ DCHECK (snapshot_config.builder_script_path .has_value ());
1227+ args_maybe_patched.emplace_back (result->args ()[0 ]);
1228+ args_maybe_patched.emplace_back (
1229+ snapshot_config.builder_script_path .value ());
1230+ if (result->args ().size () > 1 ) {
1231+ args_maybe_patched.insert (args_maybe_patched.end (),
1232+ result->args ().begin () + 1 ,
1233+ result->args ().end ());
1234+ }
1235+ } else {
1236+ snapshot_config.builder_script_path = result->args ()[1 ];
1237+ args_maybe_patched = result->args ();
1238+ }
1239+ DCHECK (snapshot_config.builder_script_path .has_value ());
1240+ const std::string& builder_script =
1241+ snapshot_config.builder_script_path .value ();
12121242 // node:embedded_snapshot_main indicates that we are using the
12131243 // embedded snapshot and we are not supposed to clean it up.
1214- const std::string& main_script = result->args ()[1 ];
1215- if (main_script == " node:embedded_snapshot_main" ) {
1244+ if (builder_script == " node:embedded_snapshot_main" ) {
12161245 *snapshot_data_ptr = SnapshotBuilder::GetEmbeddedSnapshotData ();
12171246 if (*snapshot_data_ptr == nullptr ) {
12181247 // The Node.js binary is built without embedded snapshot
@@ -1224,24 +1253,25 @@ ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr,
12241253 return exit_code;
12251254 }
12261255 } else {
1227- // Otherwise, load and run the specified main script.
1256+ // Otherwise, load and run the specified builder script.
12281257 std::unique_ptr<SnapshotData> generated_data =
12291258 std::make_unique<SnapshotData>();
1230- std::string main_script_content ;
1231- int r = ReadFileSync (&main_script_content, main_script .c_str ());
1259+ std::string builder_script_content ;
1260+ int r = ReadFileSync (&builder_script_content, builder_script .c_str ());
12321261 if (r != 0 ) {
12331262 FPrintF (stderr,
1234- " Cannot read main script %s for building snapshot. %s: %s" ,
1235- main_script ,
1263+ " Cannot read builder script %s for building snapshot. %s: %s" ,
1264+ builder_script ,
12361265 uv_err_name (r),
12371266 uv_strerror (r));
12381267 return ExitCode::kGenericUserError ;
12391268 }
12401269
12411270 exit_code = node::SnapshotBuilder::Generate (generated_data.get (),
1242- result-> args () ,
1271+ args_maybe_patched ,
12431272 result->exec_args (),
1244- main_script_content);
1273+ builder_script_content,
1274+ snapshot_config);
12451275 if (exit_code == ExitCode::kNoFailure ) {
12461276 *snapshot_data_ptr = generated_data.release ();
12471277 } else {
@@ -1371,7 +1401,8 @@ static ExitCode StartInternal(int argc, char** argv) {
13711401
13721402 // --build-snapshot indicates that we are in snapshot building mode.
13731403 if (per_process::cli_options->per_isolate ->build_snapshot ) {
1374- if (result->args ().size () < 2 ) {
1404+ if (per_process::cli_options->per_isolate ->build_snapshot_config .empty () &&
1405+ result->args ().size () < 2 ) {
13751406 fprintf (stderr,
13761407 " --build-snapshot must be used with an entry point script.\n "
13771408 " Usage: node --build-snapshot /path/to/entry.js\n " );
0 commit comments