@@ -142,6 +142,18 @@ size_t SeaSerializer::Write(const SeaResource& sea) {
142
142
written_total += WriteStringView (arg, StringLogMode::kAddressAndContent );
143
143
}
144
144
}
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
+ }
145
157
return written_total;
146
158
}
147
159
@@ -224,13 +236,29 @@ SeaResource SeaDeserializer::Read() {
224
236
exec_argv.emplace_back (arg);
225
237
}
226
238
}
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
+ }
227
254
return {flags,
228
- exec_argv_extension,
229
- code_path,
230
- code,
231
- code_cache,
232
- assets,
233
- exec_argv};
255
+ exec_argv_extension,
256
+ code_path,
257
+ code,
258
+ code_cache,
259
+ assets,
260
+ exec_argv,
261
+ user_argv};
234
262
}
235
263
236
264
std::string_view FindSingleExecutableBlob () {
@@ -316,12 +344,14 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
316
344
static std::vector<char *> new_argv;
317
345
static std::vector<std::string> exec_argv_storage;
318
346
static std::vector<std::string> cli_extension_args;
347
+ static std::vector<std::string> user_argv_storage;
319
348
320
349
SeaResource sea_resource = FindSingleExecutableResource ();
321
350
322
351
new_argv.clear ();
323
352
exec_argv_storage.clear ();
324
353
cli_extension_args.clear ();
354
+ user_argv_storage.clear ();
325
355
326
356
// Handle CLI extension mode for --node-options
327
357
if (sea_resource.exec_argv_extension == SeaExecArgvExtension::kCli ) {
@@ -341,10 +371,11 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
341
371
}
342
372
}
343
373
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
346
376
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 );
348
379
new_argv.emplace_back (argv[0 ]);
349
380
350
381
// Insert exec argv from SEA config
@@ -363,8 +394,18 @@ std::tuple<int, char**> FixupArgsForSEA(int argc, char** argv) {
363
394
new_argv.emplace_back (exec_argv_storage.back ().data ());
364
395
}
365
396
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);
368
409
new_argv.emplace_back (nullptr );
369
410
argc = new_argv.size () - 1 ;
370
411
argv = new_argv.data ();
@@ -382,6 +423,7 @@ struct SeaConfig {
382
423
SeaExecArgvExtension exec_argv_extension = SeaExecArgvExtension::kEnv ;
383
424
std::unordered_map<std::string, std::string> assets;
384
425
std::vector<std::string> exec_argv;
426
+ std::vector<std::string> user_argv;
385
427
};
386
428
387
429
std::optional<SeaConfig> ParseSingleExecutableConfig (
@@ -544,6 +586,35 @@ std::optional<SeaConfig> ParseSingleExecutableConfig(
544
586
config_path);
545
587
return std::nullopt;
546
588
}
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
+ }
547
618
}
548
619
}
549
620
@@ -579,9 +650,11 @@ ExitCode GenerateSnapshotForSEA(const SeaConfig& config,
579
650
const SnapshotConfig& snapshot_config,
580
651
std::vector<char >* snapshot_blob) {
581
652
SnapshotData snapshot;
582
- // TODO(joyeecheung): make the arguments configurable through the JSON
583
- // config or a programmatic API.
584
653
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
+ }
585
658
ExitCode exit_code = SnapshotBuilder::Generate (&snapshot,
586
659
patched_args,
587
660
exec_args,
@@ -741,6 +814,10 @@ ExitCode GenerateSingleExecutableBlob(
741
814
for (const auto & arg : config.exec_argv ) {
742
815
exec_argv_view.emplace_back (arg);
743
816
}
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
+ }
744
821
SeaResource sea{
745
822
config.flags ,
746
823
config.exec_argv_extension ,
@@ -750,7 +827,8 @@ ExitCode GenerateSingleExecutableBlob(
750
827
: std::string_view{main_script.data (), main_script.size ()},
751
828
optional_sv_code_cache,
752
829
assets_view,
753
- exec_argv_view};
830
+ exec_argv_view,
831
+ user_argv_view};
754
832
755
833
SeaSerializer serializer;
756
834
serializer.Write (sea);
0 commit comments