diff --git a/src/node_sea.cc b/src/node_sea.cc index a8dbfeaa424943..521f2f670b28c8 100644 --- a/src/node_sea.cc +++ b/src/node_sea.cc @@ -411,7 +411,7 @@ ExitCode GenerateSnapshotForSEA(const SeaConfig& config, std::optional GenerateCodeCache(std::string_view main_path, std::string_view main_script) { - RAIIIsolate raii_isolate; + RAIIIsolate raii_isolate(SnapshotBuilder::GetEmbeddedSnapshotData()); Isolate* isolate = raii_isolate.get(); HandleScope handle_scope(isolate); @@ -489,14 +489,19 @@ ExitCode GenerateSingleExecutableBlob( std::optional optional_sv_code_cache; std::string code_cache; if (static_cast(config.flags & SeaFlags::kUseCodeCache)) { - std::optional optional_code_cache = - GenerateCodeCache(config.main_path, main_script); - if (!optional_code_cache.has_value()) { - FPrintF(stderr, "Cannot generate V8 code cache\n"); - return ExitCode::kGenericUserError; + if (builds_snapshot_from_main) { + FPrintF(stderr, + "\"useCodeCache\" is redundant when \"useSnapshot\" is true\n"); + } else { + std::optional optional_code_cache = + GenerateCodeCache(config.main_path, main_script); + if (!optional_code_cache.has_value()) { + FPrintF(stderr, "Cannot generate V8 code cache\n"); + return ExitCode::kGenericUserError; + } + code_cache = optional_code_cache.value(); + optional_sv_code_cache = code_cache; } - code_cache = optional_code_cache.value(); - optional_sv_code_cache = code_cache; } SeaResource sea{ diff --git a/test/sequential/test-single-executable-application-snapshot-and-code-cache.js b/test/sequential/test-single-executable-application-snapshot-and-code-cache.js new file mode 100644 index 00000000000000..66012e38a4faa6 --- /dev/null +++ b/test/sequential/test-single-executable-application-snapshot-and-code-cache.js @@ -0,0 +1,63 @@ +'use strict'; + +require('../common'); + +const { + injectAndCodeSign, + skipIfSingleExecutableIsNotSupported, +} = require('../common/sea'); + +skipIfSingleExecutableIsNotSupported(); + +// This tests "useCodeCache" is ignored when "useSnapshot" is true. + +const tmpdir = require('../common/tmpdir'); +const { copyFileSync, writeFileSync, existsSync } = require('fs'); +const { spawnSync } = require('child_process'); +const { join } = require('path'); +const assert = require('assert'); + +const configFile = join(tmpdir.path, 'sea-config.json'); +const seaPrepBlob = join(tmpdir.path, 'sea-prep.blob'); +const outputFile = join(tmpdir.path, process.platform === 'win32' ? 'sea.exe' : 'sea'); + +{ + tmpdir.refresh(); + const code = ` + const { + setDeserializeMainFunction, + } = require('v8').startupSnapshot; + + setDeserializeMainFunction(() => { + console.log('Hello from snapshot'); + }); + `; + + writeFileSync(join(tmpdir.path, 'snapshot.js'), code, 'utf-8'); + writeFileSync(configFile, ` + { + "main": "snapshot.js", + "output": "sea-prep.blob", + "useSnapshot": true, + "useCodeCache": true + } + `); + + let child = spawnSync( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { + cwd: tmpdir.path + }); + assert.match( + child.stderr.toString(), + /"useCodeCache" is redundant when "useSnapshot" is true/); + + assert(existsSync(seaPrepBlob)); + + copyFileSync(process.execPath, outputFile); + injectAndCodeSign(outputFile, seaPrepBlob); + + child = spawnSync(outputFile); + assert.strictEqual(child.stdout.toString().trim(), 'Hello from snapshot'); +}