PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize) { Vector<ScriptCallFrame> frames; CallFrame* frame = exec->vm().topCallFrame; CreateScriptCallStackFunctor functor(true, frames, maxStackSize); frame->iterate(functor); if (frames.isEmpty()) { CreateScriptCallStackFunctor functor(false, frames, maxStackSize); frame->iterate(functor); } return ScriptCallStack::create(frames); }
Ref<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec, size_t maxStackSize) { if (!exec) return ScriptCallStack::create(); JSLockHolder locker(exec); Vector<ScriptCallFrame> frames; CallFrame* frame = exec->vm().topCallFrame; if (!frame) return ScriptCallStack::create(); CreateScriptCallStackFunctor functor(true, frames, maxStackSize); frame->iterate(functor); if (frames.isEmpty()) { CreateScriptCallStackFunctor functor(false, frames, maxStackSize); frame->iterate(functor); } return ScriptCallStack::create(frames); }
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); JSLockHolder lock(exec); StringBuilder builder; CallFrame* frame = exec->vm().topCallFrame; ASSERT(maxStackSize); BacktraceFunctor functor(builder, maxStackSize); frame->iterate(functor); return OpaqueJSString::create(builder.toString()).leakRef(); }
PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize, bool emptyIsAllowed) { Vector<ScriptCallFrame> frames; if (exec) { CallFrame* frame = exec->vm().topCallFrame; CreateScriptCallStackFunctor functor(false, frames, maxStackSize); frame->iterate(functor); } if (frames.isEmpty() && !emptyIsAllowed) { // No frames found. It may happen in the case where // a bound function is called from native code for example. // Fallback to setting lineNumber to 0, and source and function name to "undefined". frames.append(ScriptCallFrame(ASCIILiteral("undefined"), ASCIILiteral("undefined"), 0, 0)); } return ScriptCallStack::create(frames); }