Compare commits

...

1 Commits

Author SHA1 Message Date
Dylan Conway
baa8934545 some of it 2023-09-20 00:25:59 -07:00
4 changed files with 100 additions and 3 deletions

View File

@@ -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)
{

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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*);