|
123 | 123 | #include "JavaScriptCore/CustomGetterSetter.h"
|
124 | 124 |
|
125 | 125 | #include "ErrorStackFrame.h"
|
| 126 | +#include "ErrorStackTrace.h" |
126 | 127 | #include "ObjectBindings.h"
|
127 | 128 |
|
128 | 129 | #if OS(DARWIN)
|
@@ -6030,3 +6031,75 @@ CPP_DECL bool Bun__CallFrame__isFromBunMain(JSC::CallFrame* callFrame, JSC::VM*
|
6030 | 6031 | return false;
|
6031 | 6032 | return source.string() == "builtin://bun/main"_s;
|
6032 | 6033 | }
|
| 6034 | + |
| 6035 | +CPP_DECL void Bun__CallFrame__getCallerSrcLoc(JSC::CallFrame* callFrame, JSC::JSGlobalObject* globalObject, unsigned int* outSourceID, unsigned int* outLine, unsigned int* outColumn) |
| 6036 | +{ |
| 6037 | + JSC::VM& vm = globalObject->vm(); |
| 6038 | + JSC::LineColumn lineColumn; |
| 6039 | + JSC::SourceID sourceID = 0; |
| 6040 | + String sourceURL; |
| 6041 | + |
| 6042 | + ZigStackFrame remappedFrame = {}; |
| 6043 | + |
| 6044 | + JSC::StackVisitor::visit(callFrame, vm, [&](JSC::StackVisitor& visitor) -> WTF::IterationStatus { |
| 6045 | + if (Zig::isImplementationVisibilityPrivate(visitor)) |
| 6046 | + return WTF::IterationStatus::Continue; |
| 6047 | + |
| 6048 | + if (visitor->hasLineAndColumnInfo()) { |
| 6049 | + lineColumn = visitor->computeLineAndColumn(); |
| 6050 | + |
| 6051 | + String sourceURLForFrame = visitor->sourceURL(); |
| 6052 | + |
| 6053 | + // Sometimes, the sourceURL is empty. |
| 6054 | + // For example, pages in Next.js. |
| 6055 | + if (sourceURLForFrame.isEmpty()) { |
| 6056 | + |
| 6057 | + // hasLineAndColumnInfo() checks codeBlock(), so this is safe to access here. |
| 6058 | + const auto& source = visitor->codeBlock()->source(); |
| 6059 | + |
| 6060 | + // source.isNull() is true when the SourceProvider is a null pointer. |
| 6061 | + if (!source.isNull()) { |
| 6062 | + auto* provider = source.provider(); |
| 6063 | + // I'm not 100% sure we should show sourceURLDirective here. |
| 6064 | + if (!provider->sourceURLDirective().isEmpty()) { |
| 6065 | + sourceURLForFrame = provider->sourceURLDirective(); |
| 6066 | + } else if (!provider->sourceURL().isEmpty()) { |
| 6067 | + sourceURLForFrame = provider->sourceURL(); |
| 6068 | + } else { |
| 6069 | + const auto& origin = provider->sourceOrigin(); |
| 6070 | + if (!origin.isNull()) { |
| 6071 | + sourceURLForFrame = origin.string(); |
| 6072 | + } |
| 6073 | + } |
| 6074 | + |
| 6075 | + sourceID = provider->asID(); |
| 6076 | + } |
| 6077 | + } |
| 6078 | + |
| 6079 | + sourceURL = sourceURLForFrame; |
| 6080 | + |
| 6081 | + return WTF::IterationStatus::Done; |
| 6082 | + } |
| 6083 | + |
| 6084 | + return WTF::IterationStatus::Continue; |
| 6085 | + }); |
| 6086 | + |
| 6087 | + if (!sourceURL.isEmpty() and lineColumn.line > 0) { |
| 6088 | + OrdinalNumber originalLine = OrdinalNumber::fromOneBasedInt(lineColumn.line); |
| 6089 | + OrdinalNumber originalColumn = OrdinalNumber::fromOneBasedInt(lineColumn.column); |
| 6090 | + |
| 6091 | + remappedFrame.position.line_zero_based = originalLine.zeroBasedInt(); |
| 6092 | + remappedFrame.position.column_zero_based = originalColumn.zeroBasedInt(); |
| 6093 | + remappedFrame.source_url = Bun::toStringRef(sourceURL); |
| 6094 | + |
| 6095 | + Bun__remapStackFramePositions(globalObject, &remappedFrame, 1); |
| 6096 | + |
| 6097 | + sourceURL = remappedFrame.source_url.toWTFString(); |
| 6098 | + lineColumn.line = OrdinalNumber::fromZeroBasedInt(remappedFrame.position.line_zero_based).oneBasedInt(); |
| 6099 | + lineColumn.column = OrdinalNumber::fromZeroBasedInt(remappedFrame.position.column_zero_based).oneBasedInt(); |
| 6100 | + } |
| 6101 | + |
| 6102 | + *outSourceID = sourceID; |
| 6103 | + *outLine = lineColumn.line; |
| 6104 | + *outColumn = lineColumn.column; |
| 6105 | +} |
0 commit comments