diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp index 8cb916db573db..60d388797d614 100644 --- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp +++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp @@ -372,9 +372,18 @@ void ErrorInstance::computeErrorInfo(VM& vm, bool allocationAllowed) UNUSED_PARAM(allocationAllowed); if (m_stackTrace && !m_stackTrace->isEmpty()) { + auto& fnWithInstance = vm.onComputeErrorInfoWithInstance(); auto& fn = vm.onComputeErrorInfo(); WTF::String stackString; - if (fn) { + if (fnWithInstance) { + // Preferred over onComputeErrorInfo: passing the instance lets the + // callback include the error's name and message in the stack string + // even when this runs from the GC finalizer (finalizeUnconditionally). + if (m_stackPropertyAlreadyMaterialized) + stackString = emptyString(); + else + stackString = fnWithInstance(vm, *m_stackTrace.get(), m_lineColumn.line, m_lineColumn.column, m_sourceURL, this, this->bunErrorData()); + } else if (fn) { if (m_stackPropertyAlreadyMaterialized) stackString = emptyString(); else diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h index 6df90ecf4b5b8..b0c8fac58bfbc 100644 --- a/Source/JavaScriptCore/runtime/VM.h +++ b/Source/JavaScriptCore/runtime/VM.h @@ -170,6 +170,7 @@ constexpr bool validateDFGDoesGC = ENABLE_DFG_DOES_GC_VALIDATION; #if USE(BUN_JSC_ADDITIONS) using StackTraceAppenderFunction = WTF::Function& stackTrace, size_t maxToAppend)>; using ErrorInfoFunction = WTF::Function& stackTrace, unsigned& line, unsigned& column, String& sourceURL, void* bunErrorData)>; +using ErrorInfoWithInstanceFunction = WTF::Function& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSC::JSObject* errorInstance, void* bunErrorData)>; using ErrorInfoFunctionJSValue = WTF::Function& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSC::JSObject*, void* bunErrorData)>; #endif @@ -1062,6 +1063,9 @@ class VM : public ThreadSafeRefCountedWithSuppressingSaferCPPChecking { const ErrorInfoFunction& onComputeErrorInfo() const { return m_onComputeErrorInfo; } ErrorInfoFunction& onComputeErrorInfo() { return m_onComputeErrorInfo; } + const ErrorInfoWithInstanceFunction& onComputeErrorInfoWithInstance() const { return m_onComputeErrorInfoWithInstance; } + ErrorInfoWithInstanceFunction& onComputeErrorInfoWithInstance() { return m_onComputeErrorInfoWithInstance; } + const ErrorInfoFunctionJSValue& onComputeErrorInfoJSValue() const { return m_onComputeErrorInfoJSValue; } ErrorInfoFunctionJSValue& onComputeErrorInfoJSValue() { return m_onComputeErrorInfoJSValue; } @@ -1070,6 +1074,7 @@ class VM : public ThreadSafeRefCountedWithSuppressingSaferCPPChecking { void setOnAppendStackTrace(StackTraceAppenderFunction&& function) { m_onAppendStackTrace = WTF::move(function); } void setOnComputeErrorInfo(ErrorInfoFunction&& function) { m_onComputeErrorInfo = WTF::move(function); } + void setOnComputeErrorInfoWithInstance(ErrorInfoWithInstanceFunction&& function) { m_onComputeErrorInfoWithInstance = WTF::move(function); } void setOnComputeErrorInfoJSValue(ErrorInfoFunctionJSValue&& function) { m_onComputeErrorInfoJSValue = WTF::move(function); } void setComputeLineColumnWithSourcemap(WTF::Function&& function) { m_computeLineColumnWithSourcemap = WTF::move(function); } #endif @@ -1287,6 +1292,7 @@ class VM : public ThreadSafeRefCountedWithSuppressingSaferCPPChecking { WTF::Function m_onEachMicrotaskTick; #if USE(BUN_JSC_ADDITIONS) ErrorInfoFunction m_onComputeErrorInfo; + ErrorInfoWithInstanceFunction m_onComputeErrorInfoWithInstance; ErrorInfoFunctionJSValue m_onComputeErrorInfoJSValue; StackTraceAppenderFunction m_onAppendStackTrace; WTF::Function m_computeLineColumnWithSourcemap;