@@ -142,6 +142,18 @@ size_t SeaSerializer::Write(const SeaResource& sea) {
142142 written_total += WriteStringView (arg, StringLogMode::kAddressAndContent );
143143 }
144144 }
145+
146+ if (static_cast <bool >(sea.flags & SeaFlags::kIncludeUserArgv )) {
147+ Debug (" Write SEA resource user argv size %zu\n " , sea.user_argv .size ());
148+ written_total += WriteArithmetic<size_t >(sea.user_argv .size ());
149+ for (const auto & arg : sea.user_argv ) {
150+ Debug (" Write SEA resource user arg %s at %p, size=%zu\n " ,
151+ arg.data (),
152+ arg.data (),
153+ arg.size ());
154+ written_total += WriteStringView (arg, StringLogMode::kAddressAndContent );
155+ }
156+ }
145157 return written_total;
146158}
147159
@@ -224,13 +236,29 @@ SeaResource SeaDeserializer::Read() {
224236 exec_argv.emplace_back (arg);
225237 }
226238 }
239+
240+ std::vector<std::string_view> user_argv;
241+ if (static_cast <bool >(flags & SeaFlags::kIncludeUserArgv )) {
242+ size_t user_argv_size = ReadArithmetic<size_t >();
243+ Debug (" Read SEA resource user args size %zu\n " , user_argv_size);
244+ user_argv.reserve (user_argv_size);
245+ for (size_t i = 0 ; i < user_argv_size; ++i) {
246+ std::string_view arg = ReadStringView (StringLogMode::kAddressAndContent );
247+ Debug (" Read SEA resource user arg %s at %p, size=%zu\n " ,
248+ arg.data (),
249+ arg.data (),
250+ arg.size ());
251+ user_argv.emplace_back (arg);
252+ }
253+ }
227254 return {flags,
228255 exec_argv_extension,
229256 code_path,
230257 code,
231258 code_cache,
232259 assets,
233- exec_argv};
260+ exec_argv,
261+ user_argv};
234262}
235263
236264std::string_view FindSingleExecutableBlob () {
@@ -316,12 +344,14 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
316344 static std::vector<char *> new_argv;
317345 static std::vector<std::string> exec_argv_storage;
318346 static std::vector<std::string> cli_extension_args;
347+ static std::vector<std::string> user_argv_storage;
319348
320349 SeaResource sea_resource = FindSingleExecutableResource ();
321350
322351 new_argv.clear ();
323352 exec_argv_storage.clear ();
324353 cli_extension_args.clear ();
354+ user_argv_storage.clear ();
325355
326356 // Handle CLI extension mode for --node-options
327357 if (sea_resource.exec_argv_extension == SeaExecArgvExtension::kCli ) {
@@ -341,10 +371,11 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
341371 }
342372 }
343373
344- // Reserve space for argv[0], exec argv, cli extension args, original argv,
345- // and nullptr
374+ // Reserve space for two argv[0] , exec argv, cli extension args, user argv,
375+ // original argv and nullptr
346376 new_argv.reserve (argc + sea_resource.exec_argv .size () +
347- cli_extension_args.size () + 2 );
377+ cli_extension_args.size () + sea_resource.user_argv .size () +
378+ 3 );
348379 new_argv.emplace_back (argv[0 ]);
349380
350381 // Insert exec argv from SEA config
@@ -363,8 +394,18 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
363394 new_argv.emplace_back (exec_argv_storage.back ().data ());
364395 }
365396
366- // Add actual run time arguments
367- new_argv.insert (new_argv.end (), argv, argv + argc);
397+ new_argv.emplace_back (argv[0 ]);
398+ // Insert user argv from SEA config
399+ if (!sea_resource.user_argv .empty ()) {
400+ user_argv_storage.reserve (sea_resource.user_argv .size ());
401+ for (const auto & arg : sea_resource.user_argv ) {
402+ user_argv_storage.emplace_back (arg);
403+ new_argv.emplace_back (user_argv_storage.back ().data ());
404+ }
405+ }
406+
407+ // Add actual run time arguments.
408+ new_argv.insert (new_argv.end (), argv + 1 , argv + argc);
368409 new_argv.emplace_back (nullptr );
369410 argc = new_argv.size () - 1 ;
370411 argv = new_argv.data ();
@@ -382,6 +423,7 @@ struct SeaConfig {
382423 SeaExecArgvExtension exec_argv_extension = SeaExecArgvExtension::kEnv ;
383424 std::unordered_map<std::string, std::string> assets;
384425 std::vector<std::string> exec_argv;
426+ std::vector<std::string> user_argv;
385427};
386428
387429std::optional<SeaConfig> ParseSingleExecutableConfig (
@@ -544,6 +586,35 @@ std::optional<SeaConfig> ParseSingleExecutableConfig(
544586 config_path);
545587 return std::nullopt ;
546588 }
589+ } else if (key == " argv" ) {
590+ simdjson::ondemand::array argv_array;
591+ FPrintF (stderr, " \" argv\" start \n " );
592+
593+ if (field.value ().get_array ().get (argv_array)) {
594+ FPrintF (stderr,
595+ " \" argv\" field of %s is not an array of strings\n " ,
596+ config_path);
597+ return std::nullopt ;
598+ }
599+ std::vector<std::string> user_argv;
600+
601+ for (auto argv : argv_array) {
602+ FPrintF (stderr, " \" argv\"\n " );
603+
604+ std::string_view argv_str;
605+ if (argv.get_string ().get (argv_str)) {
606+ FPrintF (stderr,
607+ " \" argv\" field of %s is not an array of strings\n " ,
608+ config_path);
609+ return std::nullopt ;
610+ }
611+ FPrintF (stderr, " \" argv\" : %s \n " , argv_str);
612+ user_argv.emplace_back (argv_str);
613+ }
614+ if (!user_argv.empty ()) {
615+ result.flags |= SeaFlags::kIncludeUserArgv ;
616+ result.user_argv = std::move (user_argv);
617+ }
547618 }
548619 }
549620
@@ -579,9 +650,11 @@ ExitCode GenerateSnapshotForSEA(const SeaConfig& config,
579650 const SnapshotConfig& snapshot_config,
580651 std::vector<char >* snapshot_blob) {
581652 SnapshotData snapshot;
582- // TODO(joyeecheung): make the arguments configurable through the JSON
583- // config or a programmatic API.
584653 std::vector<std::string> patched_args = {args[0 ], config.main_path };
654+ if (!config.user_argv .empty ()) {
655+ patched_args.insert (
656+ patched_args.end (), config.user_argv .begin (), config.user_argv .end ());
657+ }
585658 ExitCode exit_code = SnapshotBuilder::Generate (&snapshot,
586659 patched_args,
587660 exec_args,
@@ -741,6 +814,10 @@ ExitCode GenerateSingleExecutableBlob(
741814 for (const auto & arg : config.exec_argv ) {
742815 exec_argv_view.emplace_back (arg);
743816 }
817+ std::vector<std::string_view> user_argv_view;
818+ for (const auto & arg : config.user_argv ) {
819+ user_argv_view.emplace_back (arg);
820+ }
744821 SeaResource sea{
745822 config.flags ,
746823 config.exec_argv_extension ,
@@ -750,7 +827,8 @@ ExitCode GenerateSingleExecutableBlob(
750827 : std::string_view{main_script.data (), main_script.size ()},
751828 optional_sv_code_cache,
752829 assets_view,
753- exec_argv_view};
830+ exec_argv_view,
831+ user_argv_view};
754832
755833 SeaSerializer serializer;
756834 serializer.Write (sea);
0 commit comments