@@ -123,6 +123,18 @@ size_t SeaSerializer::Write(const SeaResource& sea) {
123123      written_total += WriteStringView (content, StringLogMode::kAddressOnly );
124124    }
125125  }
126+ 
127+   if  (static_cast <bool >(sea.flags  & SeaFlags::kIncludeExecArgv )) {
128+     Debug (" Write SEA resource exec argv size %zu\n "  , sea.exec_argv .size ());
129+     written_total += WriteArithmetic<size_t >(sea.exec_argv .size ());
130+     for  (const  auto & arg : sea.exec_argv ) {
131+       Debug (" Write SEA resource exec arg %s at %p, size=%zu\n "  ,
132+             arg.data (),
133+             arg.data (),
134+             arg.size ());
135+       written_total += WriteStringView (arg, StringLogMode::kAddressAndContent );
136+     }
137+   }
126138  return  written_total;
127139}
128140
@@ -185,7 +197,22 @@ SeaResource SeaDeserializer::Read() {
185197      assets.emplace (key, content);
186198    }
187199  }
188-   return  {flags, code_path, code, code_cache, assets};
200+ 
201+   std::vector<std::string_view> exec_argv;
202+   if  (static_cast <bool >(flags & SeaFlags::kIncludeExecArgv )) {
203+     size_t  exec_argv_size = ReadArithmetic<size_t >();
204+     Debug (" Read SEA resource exec args size %zu\n "  , exec_argv_size);
205+     exec_argv.reserve (exec_argv_size);
206+     for  (size_t  i = 0 ; i < exec_argv_size; ++i) {
207+       std::string_view arg = ReadStringView (StringLogMode::kAddressAndContent );
208+       Debug (" Read SEA resource exec arg %s at %p, size=%zu\n "  ,
209+             arg.data (),
210+             arg.data (),
211+             arg.size ());
212+       exec_argv.emplace_back (arg);
213+     }
214+   }
215+   return  {flags, code_path, code, code_cache, assets, exec_argv};
189216}
190217
191218std::string_view FindSingleExecutableBlob () {
@@ -269,8 +296,27 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
269296  //  entry point file path.
270297  if  (IsSingleExecutable ()) {
271298    static  std::vector<char *> new_argv;
272-     new_argv.reserve (argc + 2 );
299+     static  std::vector<std::string> exec_argv_storage;
300+ 
301+     SeaResource sea_resource = FindSingleExecutableResource ();
302+ 
303+     new_argv.clear ();
304+     exec_argv_storage.clear ();
305+ 
306+     //  Reserve space for argv[0], exec argv, original argv, and nullptr
307+     new_argv.reserve (argc + sea_resource.exec_argv .size () + 2 );
273308    new_argv.emplace_back (argv[0 ]);
309+ 
310+     //  Insert exec argv from SEA config
311+     if  (!sea_resource.exec_argv .empty ()) {
312+       exec_argv_storage.reserve (sea_resource.exec_argv .size ());
313+       for  (const  auto & arg : sea_resource.exec_argv ) {
314+         exec_argv_storage.emplace_back (arg);
315+         new_argv.emplace_back (exec_argv_storage.back ().data ());
316+       }
317+     }
318+ 
319+     //  Add actual run time arguments.
274320    new_argv.insert (new_argv.end (), argv, argv + argc);
275321    new_argv.emplace_back (nullptr );
276322    argc = new_argv.size () - 1 ;
@@ -287,6 +333,7 @@ struct SeaConfig {
287333  std::string output_path;
288334  SeaFlags flags = SeaFlags::kDefault ;
289335  std::unordered_map<std::string, std::string> assets;
336+   std::vector<std::string> exec_argv;
290337};
291338
292339std::optional<SeaConfig> ParseSingleExecutableConfig (
@@ -405,6 +452,29 @@ std::optional<SeaConfig> ParseSingleExecutableConfig(
405452      if  (!result.assets .empty ()) {
406453        result.flags  |= SeaFlags::kIncludeAssets ;
407454      }
455+     } else  if  (key == " execArgv"  ) {
456+       simdjson::ondemand::array exec_argv_array;
457+       if  (field.value ().get_array ().get (exec_argv_array)) {
458+         FPrintF (stderr,
459+                 " \" execArgv\"  field of %s is not an array of strings\n "  ,
460+                 config_path);
461+         return  std::nullopt ;
462+       }
463+       std::vector<std::string> exec_argv;
464+       for  (auto  argv : exec_argv_array) {
465+         std::string_view argv_str;
466+         if  (argv.get_string ().get (argv_str)) {
467+           FPrintF (stderr,
468+                   " \" execArgv\"  field of %s is not an array of strings\n "  ,
469+                   config_path);
470+           return  std::nullopt ;
471+         }
472+         exec_argv.emplace_back (argv_str);
473+       }
474+       if  (!exec_argv.empty ()) {
475+         result.flags  |= SeaFlags::kIncludeExecArgv ;
476+         result.exec_argv  = std::move (exec_argv);
477+       }
408478    }
409479  }
410480
@@ -598,14 +668,19 @@ ExitCode GenerateSingleExecutableBlob(
598668  for  (auto  const & [key, content] : assets) {
599669    assets_view.emplace (key, content);
600670  }
671+   std::vector<std::string_view> exec_argv_view;
672+   for  (const  auto & arg : config.exec_argv ) {
673+     exec_argv_view.emplace_back (arg);
674+   }
601675  SeaResource sea{
602676      config.flags ,
603677      config.main_path ,
604678      builds_snapshot_from_main
605679          ? std::string_view{snapshot_blob.data (), snapshot_blob.size ()}
606680          : std::string_view{main_script.data (), main_script.size ()},
607681      optional_sv_code_cache,
608-       assets_view};
682+       assets_view,
683+       exec_argv_view};
609684
610685  SeaSerializer serializer;
611686  serializer.Write (sea);
0 commit comments