void StackVisitor::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin) { ASSERT(codeOrigin); int frameOffset = inlinedFrameOffset(codeOrigin); bool isInlined = !!frameOffset; if (isInlined) { InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame; m_frame.m_callFrame = callFrame; m_frame.m_inlineCallFrame = inlineCallFrame; if (inlineCallFrame->argumentCountRegister.isValid()) m_frame.m_argumentCountIncludingThis = callFrame->r(inlineCallFrame->argumentCountRegister.offset()).unboxedInt32(); else m_frame.m_argumentCountIncludingThis = inlineCallFrame->arguments.size(); m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock(); m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex; JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame); m_frame.m_callee = callee; ASSERT(m_frame.callee()); // The callerFrame just needs to be non-null to indicate that we // haven't reached the last frame yet. Setting it to the root // frame (i.e. the callFrame that this inlined frame is called from) // would work just fine. m_frame.m_callerFrame = callFrame; return; } readNonInlinedFrame(callFrame, codeOrigin); }
unsigned CallFrame::bytecodeOffsetFromCodeOriginIndex() { ASSERT(hasLocationAsCodeOriginIndex()); CodeBlock* codeBlock = this->codeBlock(); ASSERT(codeBlock); CodeOrigin codeOrigin; unsigned index = locationAsCodeOriginIndex(); ASSERT(codeBlock->canGetCodeOrigin(index)); codeOrigin = codeBlock->codeOrigin(index); for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { if (inlineCallFrame->baselineCodeBlock() == codeBlock) return codeOrigin.bytecodeIndex; codeOrigin = inlineCallFrame->caller; inlineCallFrame = codeOrigin.inlineCallFrame; } return codeOrigin.bytecodeIndex; }
void StackIterator::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin) { ASSERT(codeOrigin); ASSERT(!callFrame->hasHostCallFrameFlag()); unsigned frameOffset = inlinedFrameOffset(codeOrigin); bool isInlined = !!frameOffset; if (isInlined) { InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame; m_frame.m_callFrame = callFrame; m_frame.m_inlineCallFrame = inlineCallFrame; m_frame.m_argumentCountIncludingThis = inlineCallFrame->arguments.size(); m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock(); m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex; JSFunction* callee = inlineCallFrame->callee.get(); if (callee) { m_frame.m_scope = callee->scope(); m_frame.m_callee = callee; } else { CallFrame* inlinedFrame = callFrame + frameOffset; m_frame.m_scope = inlinedFrame->scope(); m_frame.m_callee = inlinedFrame->callee(); } ASSERT(m_frame.scope()); ASSERT(m_frame.callee()); // The callerFrame just needs to be non-null to indicate that we // haven't reached the last frame yet. Setting it to the root // frame (i.e. the callFrame that this inlined frame is called from) // would work just fine. m_frame.m_callerFrame = callFrame; return; } readNonInlinedFrame(callFrame, codeOrigin); }