void ScriptDebugServer::pauseIfNeeded(CallFrame* callFrame) { if (m_paused) return; JSGlobalObject* dynamicGlobalObject = callFrame->dynamicGlobalObject(); if (!getListenersForGlobalObject(dynamicGlobalObject)) return; ScriptBreakpoint breakpoint; bool didHitBreakpoint = false; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); intptr_t sourceId = DebuggerCallFrame::sourceIdForCallFrame(m_currentCallFrame); TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame); pauseNow |= didHitBreakpoint = hasBreakpoint(sourceId, position, &breakpoint); m_lastExecutedLine = position.m_line.zeroBasedInt(); if (!pauseNow) return; DebuggerCallFrameScope debuggerCallFrameScope(*this); if (didHitBreakpoint) { evaluateBreakpointActions(breakpoint); if (breakpoint.autoContinue) return; } m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; m_paused = true; dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, dynamicGlobalObject); didPause(dynamicGlobalObject); TimerBase::fireTimersInNestedEventLoop(); m_runningNestedMessageLoop = true; m_doneProcessingDebuggerEvents = false; runEventLoopWhilePaused(); m_runningNestedMessageLoop = false; didContinue(dynamicGlobalObject); dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, dynamicGlobalObject); m_paused = false; }
void Debugger::pauseIfNeeded(CallFrame* callFrame) { if (m_isPaused) return; JSGlobalObject* vmEntryGlobalObject = callFrame->vmEntryGlobalObject(); if (!needPauseHandling(vmEntryGlobalObject)) return; Breakpoint breakpoint; bool didHitBreakpoint = false; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); intptr_t sourceID = DebuggerCallFrame::sourceIDForCallFrame(m_currentCallFrame); TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame); pauseNow |= didHitBreakpoint = hasBreakpoint(sourceID, position, &breakpoint); m_lastExecutedLine = position.m_line.zeroBasedInt(); if (!pauseNow) return; DebuggerCallFrameScope debuggerCallFrameScope(*this); // Make sure we are not going to pause again on breakpoint actions by // reseting the pause state before executing any breakpoint actions. TemporaryPausedState pausedState(*this); m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; if (didHitBreakpoint) { handleBreakpointHit(breakpoint); // Note that the actions can potentially stop the debugger, so we need to check that // we still have a current call frame when we get back. if (breakpoint.autoContinue || !m_currentCallFrame) return; } handlePause(m_reasonForPause, vmEntryGlobalObject); if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) { setSteppingMode(SteppingModeDisabled); m_currentCallFrame = nullptr; } }