📄 javascriptdebugserver.cpp
字号:
for (size_t i = 0; i < copy.size(); ++i) (copy[i]->*callback)();}void JavaScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, Page* page){ if (m_callingListeners) return; m_callingListeners = true; ASSERT(hasListeners()); WebCore::dispatchFunctionToListeners(m_listeners, callback); if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) { ASSERT(!pageListeners->isEmpty()); WebCore::dispatchFunctionToListeners(*pageListeners, callback); } m_callingListeners = false;}void JavaScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused){ setMainThreadCallbacksPaused(paused); const HashSet<Page*>& pages = pageGroup.pages(); HashSet<Page*>::const_iterator end = pages.end(); for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) setJavaScriptPaused(*it, paused);}void JavaScriptDebugServer::setJavaScriptPaused(Page* page, bool paused){ ASSERT_ARG(page, page); page->setDefersLoading(paused); for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) setJavaScriptPaused(frame, paused);}void JavaScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused){ ASSERT_ARG(frame, frame); if (!frame->script()->isEnabled()) return; frame->script()->setPaused(paused); Document* document = frame->document(); if (paused) document->suspendActiveDOMObjects(); else document->resumeActiveDOMObjects(); setJavaScriptPaused(frame->view(), paused);}#if PLATFORM(MAC)void JavaScriptDebugServer::setJavaScriptPaused(FrameView*, bool){}#elsevoid JavaScriptDebugServer::setJavaScriptPaused(FrameView* view, bool paused){ if (!view) return; const HashSet<Widget*>* children = view->children(); ASSERT(children); HashSet<Widget*>::const_iterator end = children->end(); for (HashSet<Widget*>::const_iterator it = children->begin(); it != end; ++it) { Widget* widget = *it; if (!widget->isPluginView()) continue; static_cast<PluginView*>(widget)->setJavaScriptPaused(paused); }}#endifvoid JavaScriptDebugServer::pauseIfNeeded(Page* page){ if (m_paused) return; if (!page || !hasListenersInterestedInPage(page)) return; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); pauseNow |= (m_currentCallFrame->line() > 0 && hasBreakpoint(m_currentCallFrame->sourceID(), m_currentCallFrame->line())); if (!pauseNow) return; m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; m_paused = true; dispatchFunctionToListeners(&JavaScriptDebugListener::didPause, page); setJavaScriptPaused(page->group(), true); TimerBase::fireTimersInNestedEventLoop(); EventLoop loop; m_doneProcessingDebuggerEvents = false; while (!m_doneProcessingDebuggerEvents && !loop.ended()) loop.cycle(); setJavaScriptPaused(page->group(), false); m_paused = false;}void JavaScriptDebugServer::callEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));}void JavaScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));}void JavaScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); // Treat stepping over a return statement like stepping out. if (m_currentCallFrame == m_pauseOnCallFrame) m_pauseOnCallFrame = m_currentCallFrame->caller(); m_currentCallFrame = m_currentCallFrame->caller();}void JavaScriptDebugServer::exception(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; if (m_pauseOnExceptions) m_pauseOnNextStatement = true; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));}void JavaScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));}void JavaScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); // Treat stepping over the end of a program like stepping out. if (m_currentCallFrame == m_pauseOnCallFrame) m_pauseOnCallFrame = m_currentCallFrame->caller(); m_currentCallFrame = m_currentCallFrame->caller();}void JavaScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber){ if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; m_pauseOnNextStatement = true; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));}void JavaScriptDebugServer::recompileAllJSFunctionsSoon(){ m_recompileTimer.startOneShot(0);}void JavaScriptDebugServer::recompileAllJSFunctions(Timer<JavaScriptDebugServer>*){ JSLock lock(false); JSGlobalData* globalData = JSDOMWindow::commonJSGlobalData(); // If JavaScript is running, it's not safe to recompile, since we'll end // up throwing away code that is live on the stack. ASSERT(!globalData->dynamicGlobalObject); if (globalData->dynamicGlobalObject) return; Vector<ProtectedPtr<JSFunction> > functions; Heap::iterator heapEnd = globalData->heap.primaryHeapEnd(); for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) { if ((*it)->isObject(&JSFunction::info)) functions.append(static_cast<JSFunction*>(*it)); } typedef HashMap<RefPtr<FunctionBodyNode>, RefPtr<FunctionBodyNode> > FunctionBodyMap; typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap; FunctionBodyMap functionBodies; SourceProviderMap sourceProviders; size_t size = functions.size(); for (size_t i = 0; i < size; ++i) { JSFunction* function = functions[i]; FunctionBodyNode* oldBody = function->body(); pair<FunctionBodyMap::iterator, bool> result = functionBodies.add(oldBody, 0); if (!result.second) { function->setBody(result.first->second.get()); continue; } ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec(); const SourceCode& sourceCode = oldBody->source(); RefPtr<FunctionBodyNode> newBody = globalData->parser->parse<FunctionBodyNode>(exec, 0, sourceCode); ASSERT(newBody); newBody->finishParsing(oldBody->copyParameters(), oldBody->parameterCount()); result.first->second = newBody; function->setBody(newBody.release()); if (hasListeners()) sourceProviders.add(sourceCode.provider(), exec); } // Call sourceParsed() after reparsing all functions because it will execute // JavaScript in the inspector. SourceProviderMap::const_iterator end = sourceProviders.end(); for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter) sourceParsed((*iter).second, SourceCode((*iter).first), -1, 0);}void JavaScriptDebugServer::didAddListener(Page* page){ recompileAllJSFunctionsSoon(); if (page) page->setDebugger(this); else Page::setDebuggerForAllPages(this);}void JavaScriptDebugServer::didRemoveListener(Page* page){ if (hasGlobalListeners() || (page && hasListenersInterestedInPage(page))) return; recompileAllJSFunctionsSoon(); if (page) page->setDebugger(0); else Page::setDebuggerForAllPages(0);}void JavaScriptDebugServer::didRemoveLastListener(){ m_doneProcessingDebuggerEvents = true;}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -