Fix missing source URL when Error.prepareStackTrace is set

`source_url` was empty when eval'ing:

```js
const fn = new Function("throw new Error('example')" + "\n//# sourceURL=/example.js");
```

This copies code added in:
https://github.com/oven-sh/bun/pull/13073
This commit is contained in:
Kyle Carberry
2025-01-04 14:16:02 -05:00
parent 8a469cce7e
commit 44368d07d7
2 changed files with 34 additions and 3 deletions

View File

@@ -80,6 +80,7 @@ public:
void setLineNumber(OrdinalNumber lineNumber) { m_lineNumber = lineNumber; }
void setColumnNumber(OrdinalNumber columnNumber) { m_columnNumber = columnNumber; }
void setSourceURL(JSC::VM& vm, JSC::JSValue sourceURL) { m_sourceURL.set(vm, this, sourceURL); }
void formatAsString(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WTF::StringBuilder& sb);

View File

@@ -690,7 +690,38 @@ static JSValue computeErrorInfoWithPrepareStackTrace(JSC::VM& vm, Zig::GlobalObj
framesCount = framesCount > 64 ? 64 : framesCount;
for (int i = 0; i < framesCount; i++) {
remappedFrames[i] = {};
remappedFrames[i].source_url = Bun::toStringRef(lexicalGlobalObject, stackTrace.at(i).sourceURL());
String sourceURLForFrame = stackFrames.at(i).sourceURL(vm);
if (sourceURLForFrame.isEmpty()) {
const auto& source = stackFrames.at(i).codeBlock()->source();
if (!source.isNull()) {
auto* provider = source.provider();
// I'm not 100% sure we should show sourceURLDirective here.
if (!provider->sourceURLDirective().isEmpty()) {
sourceURLForFrame = provider->sourceURLDirective();
} else if (!provider->sourceURL().isEmpty()) {
sourceURLForFrame = provider->sourceURL();
} else {
const auto& origin = provider->sourceOrigin();
if (!origin.isNull()) {
sourceURLForFrame = origin.string();
}
}
}
}
if (!sourceURLForFrame.isEmpty()) {
remappedFrames[i].source_url = Bun::toStringRef(sourceURLForFrame);
// This ensures the lifetime of the sourceURL is accounted for correctly
Bun__remapStackFramePositions(globalObject, &remappedFrames[i], 1);
sourceURLForFrame = remappedFrames[i].source_url.toWTFString();
}
remappedFrames[i].source_url = Bun::toStringRef(sourceURLForFrame.isolatedCopy());
if (JSCStackFrame::SourcePositions* sourcePositions = stackTrace.at(i).getSourcePositions()) {
remappedFrames[i].position.line_zero_based = sourcePositions->line.zeroBasedInt();
remappedFrames[i].position.column_zero_based = sourcePositions->column.zeroBasedInt();
@@ -700,14 +731,13 @@ static JSValue computeErrorInfoWithPrepareStackTrace(JSC::VM& vm, Zig::GlobalObj
}
}
Bun__remapStackFramePositions(globalObject, remappedFrames, framesCount);
for (size_t i = 0; i < framesCount; i++) {
JSC::JSValue callSiteValue = callSites.at(i);
if (remappedFrames[i].remapped) {
CallSite* callSite = JSC::jsCast<CallSite*>(callSiteValue);
callSite->setColumnNumber(remappedFrames[i].position.column());
callSite->setLineNumber(remappedFrames[i].position.line());
callSite->setSourceURL(vm, jsString(vm, remappedFrames[i].source_url.toWTFString()));
}
}
}