sea: support execArgv in sea config · nodejs/node@c6e3d5d

@@ -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

}

190217191218

std::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

};

291338292339

std::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};

609684610685

SeaSerializer serializer;

611686

serializer.Write(sea);