PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyIsAllowed) { Vector<ScriptCallFrame> frames; if (JSC::ExecState* exec = JSMainThreadExecState::currentState()) { CallFrame* frame = exec->vm().topCallFrame; for (StackIterator iter = frame->begin(); iter != frame->end() && maxStackSize--; ++iter) { unsigned line; unsigned column; iter->computeLineAndColumn(line, column); frames.append(ScriptCallFrame(iter->functionName(), iter->sourceURL(), line, column)); } } 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("undefined", "undefined", 0, 0)); } return ScriptCallStack::create(frames); }
PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize) { Vector<ScriptCallFrame> frames; ASSERT(exec); CallFrame* frame = exec->vm().topCallFrame; StackIterator iter = frame->begin(); if (iter.numberOfFrames() > 1) ++iter; for (; iter != frame->end() && maxStackSize--; ++iter) { // This early exit is necessary to maintain our old behaviour // but the stack trace we produce now is complete and handles all // ways in which code may be running if (!iter->callee() && frames.size()) break; unsigned line; unsigned column; iter->computeLineAndColumn(line, column); frames.append(ScriptCallFrame(iter->functionName(), iter->sourceURL(), line, column)); } return ScriptCallStack::create(frames); }