diff --git a/lib/internal/util/embedding.js b/lib/internal/util/embedding.js index 09e77988966f29..d5a9ccb5207f22 100644 --- a/lib/internal/util/embedding.js +++ b/lib/internal/util/embedding.js @@ -2,7 +2,7 @@ const { BuiltinModule: { normalizeRequirableId } } = require('internal/bootstrap/realm'); const { Module, wrapSafe } = require('internal/modules/cjs/loader'); const { codes: { ERR_UNKNOWN_BUILTIN_MODULE } } = require('internal/errors'); -const { getCodeCache } = internalBinding('sea'); +const { getCodeCache, getCodePath } = internalBinding('sea'); // This is roughly the same as: // @@ -16,7 +16,8 @@ const { getCodeCache } = internalBinding('sea'); function embedderRunCjs(contents) { const filename = process.execPath; - const compiledWrapper = wrapSafe(filename, contents, undefined, getCodeCache()); + const codeCache = getCodeCache(); + const compiledWrapper = wrapSafe(codeCache ? getCodePath() : filename, contents, undefined, codeCache); const customModule = new Module(filename, null); customModule.filename = filename; diff --git a/src/node_sea.cc b/src/node_sea.cc index 0bdd87e8424bbf..15e86f832e990f 100644 --- a/src/node_sea.cc +++ b/src/node_sea.cc @@ -83,6 +83,12 @@ size_t SeaSerializer::Write(const SeaResource& sea) { written_total += WriteArithmetic(flags); DCHECK_EQ(written_total, SeaResource::kHeaderSize); + Debug("Write SEA code path %p, size=%zu\n", + sea.code_path.data(), + sea.code_path.size()); + written_total += + WriteStringView(sea.code_path, StringLogMode::kAddressAndContent); + Debug("Write SEA resource code %p, size=%zu\n", sea.code.data(), sea.code.size()); @@ -117,6 +123,11 @@ SeaResource SeaDeserializer::Read() { Debug("Read SEA flags %x\n", static_cast(flags)); CHECK_EQ(read_total, SeaResource::kHeaderSize); + std::string_view code_path = + ReadStringView(StringLogMode::kAddressAndContent); + Debug( + "Read SEA code path %p, size=%zu\n", code_path.data(), code_path.size()); + std::string_view code = ReadStringView(StringLogMode::kAddressAndContent); Debug("Read SEA resource code %p, size=%zu\n", code.data(), code.size()); @@ -124,7 +135,7 @@ SeaResource SeaDeserializer::Read() { Debug("Read SEA resource code cache %p, size=%zu\n", code_cache.data(), code_cache.size()); - return {flags, code, code_cache}; + return {flags, code_path, code, code_cache}; } std::string_view FindSingleExecutableBlob() { @@ -208,6 +219,26 @@ void GetCodeCache(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(buf); } +void GetCodePath(const FunctionCallbackInfo& args) { + if (!IsSingleExecutable()) { + return; + } + + Environment* env = Environment::GetCurrent(args); + Isolate* isolate = env->isolate(); + HandleScope scope(isolate); + + SeaResource sea_resource = FindSingleExecutableResource(); + + Local code_path; + if (!String::NewFromUtf8(isolate, sea_resource.code_path.data()) + .ToLocal(&code_path)) { + return; + } + + args.GetReturnValue().Set(code_path); +} + std::tuple FixupArgsForSEA(int argc, char** argv) { // Repeats argv[0] at position 1 on argv as a replacement for the missing // entry point file path. @@ -346,7 +377,7 @@ ExitCode GenerateSingleExecutableBlob(const SeaConfig& config) { } std::string code_cache = optional_code_cache.value(); - SeaResource sea{config.flags, main_script, code_cache}; + SeaResource sea{config.flags, config.main_path, main_script, code_cache}; SeaSerializer serializer; serializer.Write(sea); @@ -386,11 +417,13 @@ void Initialize(Local target, target, "isExperimentalSeaWarningNeeded", IsExperimentalSeaWarningNeeded); + SetMethod(context, target, "getCodePath", GetCodePath); SetMethod(context, target, "getCodeCache", GetCodeCache); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(IsExperimentalSeaWarningNeeded); + registry->Register(GetCodePath); registry->Register(GetCodeCache); } diff --git a/src/node_sea.h b/src/node_sea.h index cb72cd01f7640b..eaebad7e47b320 100644 --- a/src/node_sea.h +++ b/src/node_sea.h @@ -25,6 +25,7 @@ enum class SeaFlags : uint32_t { struct SeaResource { SeaFlags flags = SeaFlags::kDefault; + std::string_view code_path; std::string_view code; std::string_view code_cache; diff --git a/test/fixtures/sea.js b/test/fixtures/sea.js index 4e1f37ce5d8fad..a1246d555e0e79 100644 --- a/test/fixtures/sea.js +++ b/test/fixtures/sea.js @@ -18,6 +18,9 @@ if (createdRequire('./sea-config.json').disableExperimentalSEAWarning) { const { deepStrictEqual, strictEqual, throws } = require('assert'); const { dirname } = require('node:path'); +// Checks that the source filename is used in the error stack trace. +strictEqual(new Error('lol').stack.split('\n')[1], ' at sea.js:22:13'); + // Should be possible to require a core module that requires using the "node:" // scheme. {