aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-09-20 00:25:59 -0700
committerGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-09-20 00:25:59 -0700
commitbaa89345459006a96bd597a5ed229b45b7369055 (patch)
treeefe7751e772d4ebbdcef9ca7ccee22e85ac57fe5
parent4a0eb19038fc1ae7debf6f4e67a08d53ea67a7de (diff)
downloadbun-fix-prepare-stack-trace.tar.gz
bun-fix-prepare-stack-trace.tar.zst
bun-fix-prepare-stack-trace.zip
-rw-r--r--src/bun.js/bindings/CallSite.cpp40
-rw-r--r--src/bun.js/bindings/CallSite.h9
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp53
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h1
4 files changed, 100 insertions, 3 deletions
diff --git a/src/bun.js/bindings/CallSite.cpp b/src/bun.js/bindings/CallSite.cpp
index 48fe82275..1b42b826f 100644
--- a/src/bun.js/bindings/CallSite.cpp
+++ b/src/bun.js/bindings/CallSite.cpp
@@ -75,6 +75,46 @@ void CallSite::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSCStac
}
}
+void CallSite::finishCreationWithFrame(VM& vm, JSC::JSGlobalObject* globalObject, JSC::StackFrame& stackFrame, bool encounteredStrictFrame)
+{
+ Base::finishCreation(vm);
+
+ bool isStrictFrame = encounteredStrictFrame;
+ if (!isStrictFrame) {
+ JSC::CodeBlock* codeBlock = stackFrame.codeBlock();
+ if (codeBlock) {
+ isStrictFrame = codeBlock->ownerExecutable()->isInStrictContext();
+ }
+ }
+
+ JSObject* calleeObject = jsCast<JSObject*>(stackFrame.callee());
+
+ m_thisValue.set(vm, this, JSC::jsUndefined());
+ if (isStrictFrame) {
+ m_function.set(vm, this, JSC::jsUndefined());
+ m_flags |= static_cast<unsigned int>(Flags::IsStrict);
+ } else {
+ m_function.set(vm, this, stackFrame.callee());
+ }
+
+ // m_functionName.set(vm, this, stackFrame.functionName(vm));
+ // m_sourceURL.set(vm, this, stackFrame.sourceURL(vm));
+
+ unsigned int line = 0;
+ unsigned int column = 0;
+ stackFrame.computeLineAndColumn(line, column);
+ m_lineNumber = jsNumber(line + 1);
+ m_columnNumber = jsNumber(column + 1);
+
+ if (!stackFrame.codeBlock()) {
+ m_flags |= static_cast<unsigned int>(Flags::IsNative);
+ } else {
+ if (stackFrame.codeBlock()->codeType() == EvalCode) {
+ m_flags |= static_cast<unsigned int>(Flags::IsEval);
+ }
+ }
+}
+
template<typename Visitor>
void CallSite::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
diff --git a/src/bun.js/bindings/CallSite.h b/src/bun.js/bindings/CallSite.h
index 93ce9a46b..8a5380c90 100644
--- a/src/bun.js/bindings/CallSite.h
+++ b/src/bun.js/bindings/CallSite.h
@@ -38,6 +38,14 @@ private:
public:
using Base = JSC::JSNonFinalObject;
+ static CallSite* createWithFrame(JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::StackFrame& stackFrame, bool encounteredStrictFrame)
+ {
+ JSC::VM& vm = globalObject->vm();
+ CallSite* callSite = new (NotNull, JSC::allocateCell<CallSite>(vm)) CallSite(vm, structure);
+ callSite->finishCreationWithFrame(vm, globalObject, stackFrame, encounteredStrictFrame);
+ return callSite;
+ }
+
static CallSite* create(JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSCStackFrame& stackFrame, bool encounteredStrictFrame)
{
JSC::VM& vm = globalObject->vm();
@@ -92,6 +100,7 @@ private:
}
void finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSCStackFrame& stackFrame, bool encounteredStrictFrame);
+ void finishCreationWithFrame(VM& vm, JSC::JSGlobalObject* globalObject, JSC::StackFrame& stackFrame, bool encounteredStrictFrame);
DECLARE_VISIT_CHILDREN;
};
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 9b36157fe..aca1663b5 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -438,8 +438,57 @@ static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<Stack
return sb.toString();
}
+void createCallSitesFromFrames(JSGlobalObject* lexicalGlobalObject, Vector<StackFrame>& stackTrace, JSArray* callSites)
+{
+ bool encounteredStrictFrame = false;
+ GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject);
+
+ JSC::Structure* callSiteStructure = globalObject->callSiteStructure();
+ size_t framesCount = stackTrace.size();
+ for (size_t i = 0; i < framesCount; i++) {
+ CallSite* callSite = CallSite::createWithFrame(lexicalGlobalObject, callSiteStructure, stackTrace.at(i), encounteredStrictFrame);
+ callSites->putDirectIndex(lexicalGlobalObject, i, callSite);
+
+ if (!encounteredStrictFrame) {
+ encounteredStrictFrame = callSite->isStrict();
+ }
+ }
+}
+
static String computeErrorInfo(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSObject* errorInstance)
{
+ Zig::GlobalObject* globalObject = jsDynamicCast<Zig::GlobalObject*>(errorInstance->globalObject());
+ JSGlobalObject* lexicalGlobalObject = jsDynamicCast<JSGlobalObject*>(globalObject);
+ auto errorConstructor = globalObject->errorConstructor();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSValue prepareStackTrace = errorConstructor->getIfPropertyExists(globalObject, Identifier::fromString(vm, "prepareStackTrace"_s));
+ if (prepareStackTrace && prepareStackTrace.isCallable()) {
+ CallData prepareStackTraceCallData = JSC::getCallData(prepareStackTrace);
+ if (prepareStackTraceCallData.type != CallData::Type::None) {
+ // create the call site from the Vector<StackFrame>
+ JSArray* callSites = JSArray::create(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), stackTrace.size());
+
+ createCallSitesFromFrames(lexicalGlobalObject, stackTrace, callSites);
+
+ MarkedArgumentBuffer args;
+ args.append(errorInstance);
+ args.append(callSites);
+ ASSERT(!args.hasOverflowed());
+
+ JSValue result = profiledCall(
+ lexicalGlobalObject,
+ ProfilingReason::Other,
+ prepareStackTrace,
+ prepareStackTraceCallData,
+ errorConstructor,
+ args);
+ RETURN_IF_EXCEPTION(scope, String());
+
+ errorInstance->putDirect(vm, vm.propertyNames->stack, result, 0);
+ return String();
+ }
+ }
return computeErrorInfoWithoutPrepareStackTrace(vm, stackTrace, line, column, sourceURL, errorInstance);
}
@@ -2441,7 +2490,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotaskVariadic, (JSGlobalObject * g
return JSValue::encode(jsUndefined());
}
-void GlobalObject::createCallSitesFromFrames(JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites)
+void createCallSitesFromStackTrace(JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites)
{
/* From v8's "Stack Trace API" (https://github.com/v8/v8/wiki/Stack-Trace-API):
* "To maintain restrictions imposed on strict mode functions, frames that have a
@@ -2581,7 +2630,7 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb
stackTrace.size());
// Create the call sites (one per frame)
- GlobalObject::createCallSitesFromFrames(lexicalGlobalObject, stackTrace, callSites);
+ createCallSitesFromStackTrace(lexicalGlobalObject, stackTrace, callSites);
/* Format the stack trace.
* Note that v8 won't actually format the stack trace here, but will create a "stack" accessor
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index ad5138527..90e9bd11d 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -152,7 +152,6 @@ public:
void clearDOMGuardedObjects();
- static void createCallSitesFromFrames(JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites);
JSC::JSValue formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* errorObject, JSC::JSArray* callSites);
static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, JSC::Exception*);