@@ -292,6 +292,17 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
292
292
293
293
CHECK (!env->isolate_data ()->is_building_snapshot ());
294
294
295
+ #ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION
296
+ if (sea::IsSingleExecutable ()) {
297
+ sea::SeaResource sea = sea::FindSingleExecutableResource ();
298
+ // The SEA preparation blob building process should already enforce this,
299
+ // this check is just here to guard against the unlikely case where
300
+ // the SEA preparation blob has been manually modified by someone.
301
+ CHECK_IMPLIES (sea.use_snapshot (),
302
+ !env->snapshot_deserialize_main ().IsEmpty ());
303
+ }
304
+ #endif
305
+
295
306
// TODO(joyeecheung): move these conditions into JS land and let the
296
307
// deserialize main function take precedence. For workers, we need to
297
308
// move the pre-execution part into a different file that can be
@@ -1198,49 +1209,66 @@ ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr,
1198
1209
return exit_code;
1199
1210
}
1200
1211
1201
- ExitCode LoadSnapshotDataAndRun (const SnapshotData** snapshot_data_ptr,
1202
- const InitializationResultImpl* result) {
1203
- ExitCode exit_code = result->exit_code_enum ();
1212
+ bool LoadSnapshotData (const SnapshotData** snapshot_data_ptr) {
1204
1213
// nullptr indicates there's no snapshot data.
1205
1214
DCHECK_NULL (*snapshot_data_ptr);
1215
+
1216
+ bool is_sea = false ;
1217
+ #ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION
1218
+ if (sea::IsSingleExecutable ()) {
1219
+ is_sea = true ;
1220
+ sea::SeaResource sea = sea::FindSingleExecutableResource ();
1221
+ if (sea.use_snapshot ()) {
1222
+ std::unique_ptr<SnapshotData> read_data =
1223
+ std::make_unique<SnapshotData>();
1224
+ std::string_view snapshot = sea.main_code_or_snapshot ;
1225
+ if (SnapshotData::FromBlob (read_data.get (), snapshot)) {
1226
+ *snapshot_data_ptr = read_data.release ();
1227
+ return true ;
1228
+ } else {
1229
+ fprintf (stderr, " Invalid snapshot data in single executable binary\n " );
1230
+ return false ;
1231
+ }
1232
+ }
1233
+ }
1234
+ #endif
1235
+
1206
1236
// --snapshot-blob indicates that we are reading a customized snapshot.
1207
- if (!per_process::cli_options->snapshot_blob .empty ()) {
1237
+ // Ignore it when we are loading from SEA.
1238
+ if (!is_sea && !per_process::cli_options->snapshot_blob .empty ()) {
1208
1239
std::string filename = per_process::cli_options->snapshot_blob ;
1209
1240
FILE* fp = fopen (filename.c_str (), " rb" );
1210
1241
if (fp == nullptr ) {
1211
1242
fprintf (stderr, " Cannot open %s" , filename.c_str ());
1212
- exit_code = ExitCode::kStartupSnapshotFailure ;
1213
- return exit_code;
1243
+ return false ;
1214
1244
}
1215
1245
std::unique_ptr<SnapshotData> read_data = std::make_unique<SnapshotData>();
1216
1246
bool ok = SnapshotData::FromFile (read_data.get (), fp);
1217
1247
fclose (fp);
1218
1248
if (!ok) {
1219
- // If we fail to read the customized snapshot,
1220
- // simply exit with kStartupSnapshotFailure.
1221
- exit_code = ExitCode::kStartupSnapshotFailure ;
1222
- return exit_code;
1249
+ return false ;
1223
1250
}
1224
1251
*snapshot_data_ptr = read_data.release ();
1225
- } else if (per_process::cli_options->node_snapshot ) {
1226
- // If --snapshot-blob is not specified, we are reading the embedded
1227
- // snapshot, but we will skip it if --no-node-snapshot is specified.
1252
+ return true ;
1253
+ }
1254
+
1255
+ if (per_process::cli_options->node_snapshot ) {
1256
+ // If --snapshot-blob is not specified or if the SEA contains no snapshot,
1257
+ // we are reading the embedded snapshot, but we will skip it if
1258
+ // --no-node-snapshot is specified.
1228
1259
const node::SnapshotData* read_data =
1229
1260
SnapshotBuilder::GetEmbeddedSnapshotData ();
1230
- if (read_data != nullptr && read_data->Check ()) {
1261
+ if (read_data != nullptr ) {
1262
+ if (!read_data->Check ()) {
1263
+ return false ;
1264
+ }
1231
1265
// If we fail to read the embedded snapshot, treat it as if Node.js
1232
1266
// was built without one.
1233
1267
*snapshot_data_ptr = read_data;
1234
1268
}
1235
1269
}
1236
1270
1237
- NodeMainInstance main_instance (*snapshot_data_ptr,
1238
- uv_default_loop (),
1239
- per_process::v8_platform.Platform (),
1240
- result->args (),
1241
- result->exec_args ());
1242
- exit_code = main_instance.Run ();
1243
- return exit_code;
1271
+ return true ;
1244
1272
}
1245
1273
1246
1274
static ExitCode StartInternal (int argc, char ** argv) {
@@ -1275,7 +1303,8 @@ static ExitCode StartInternal(int argc, char** argv) {
1275
1303
1276
1304
std::string sea_config = per_process::cli_options->experimental_sea_config ;
1277
1305
if (!sea_config.empty ()) {
1278
- return sea::BuildSingleExecutableBlob (sea_config);
1306
+ return sea::BuildSingleExecutableBlob (
1307
+ sea_config, result->args (), result->exec_args ());
1279
1308
}
1280
1309
1281
1310
// --build-snapshot indicates that we are in snapshot building mode.
@@ -1290,7 +1319,15 @@ static ExitCode StartInternal(int argc, char** argv) {
1290
1319
}
1291
1320
1292
1321
// Without --build-snapshot, we are in snapshot loading mode.
1293
- return LoadSnapshotDataAndRun (&snapshot_data, result.get ());
1322
+ if (!LoadSnapshotData (&snapshot_data)) {
1323
+ return ExitCode::kStartupSnapshotFailure ;
1324
+ }
1325
+ NodeMainInstance main_instance (snapshot_data,
1326
+ uv_default_loop (),
1327
+ per_process::v8_platform.Platform (),
1328
+ result->args (),
1329
+ result->exec_args ());
1330
+ return main_instance.Run ();
1294
1331
}
1295
1332
1296
1333
int Start (int argc, char ** argv) {
0 commit comments