@@ -123,6 +123,18 @@ size_t SeaSerializer::Write(const SeaResource& sea) {
123
123
written_total += WriteStringView (content, StringLogMode::kAddressOnly );
124
124
}
125
125
}
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
+ }
126
138
return written_total;
127
139
}
128
140
@@ -185,7 +197,22 @@ SeaResource SeaDeserializer::Read() {
185
197
assets.emplace (key, content);
186
198
}
187
199
}
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};
189
216
}
190
217
191
218
std::string_view FindSingleExecutableBlob () {
@@ -269,8 +296,27 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
269
296
// entry point file path.
270
297
if (IsSingleExecutable ()) {
271
298
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 );
273
308
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.
274
320
new_argv.insert (new_argv.end (), argv, argv + argc);
275
321
new_argv.emplace_back (nullptr );
276
322
argc = new_argv.size () - 1 ;
@@ -287,6 +333,7 @@ struct SeaConfig {
287
333
std::string output_path;
288
334
SeaFlags flags = SeaFlags::kDefault ;
289
335
std::unordered_map<std::string, std::string> assets;
336
+ std::vector<std::string> exec_argv;
290
337
};
291
338
292
339
std::optional<SeaConfig> ParseSingleExecutableConfig (
@@ -405,6 +452,29 @@ std::optional<SeaConfig> ParseSingleExecutableConfig(
405
452
if (!result.assets .empty ()) {
406
453
result.flags |= SeaFlags::kIncludeAssets ;
407
454
}
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
+ }
408
478
}
409
479
}
410
480
@@ -598,14 +668,19 @@ ExitCode GenerateSingleExecutableBlob(
598
668
for (auto const & [key, content] : assets) {
599
669
assets_view.emplace (key, content);
600
670
}
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
+ }
601
675
SeaResource sea{
602
676
config.flags ,
603
677
config.main_path ,
604
678
builds_snapshot_from_main
605
679
? std::string_view{snapshot_blob.data (), snapshot_blob.size ()}
606
680
: std::string_view{main_script.data (), main_script.size ()},
607
681
optional_sv_code_cache,
608
- assets_view};
682
+ assets_view,
683
+ exec_argv_view};
609
684
610
685
SeaSerializer serializer;
611
686
serializer.Write (sea);
0 commit comments