diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/inspector/ScriptDebugServer.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/inspector/ScriptDebugServer.cpp')
-rw-r--r-- | Source/JavaScriptCore/inspector/ScriptDebugServer.cpp | 169 |
1 files changed, 68 insertions, 101 deletions
diff --git a/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp b/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp index 98c65de0b..b1151cf7f 100644 --- a/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp +++ b/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -32,22 +32,25 @@ #include "ScriptDebugServer.h" #include "DebuggerCallFrame.h" -#include "DebuggerScope.h" -#include "Exception.h" #include "JSJavaScriptCallFrame.h" #include "JSLock.h" #include "JavaScriptCallFrame.h" #include "ScriptValue.h" #include "SourceProvider.h" +#include <wtf/MainThread.h> #include <wtf/NeverDestroyed.h> #include <wtf/TemporaryChange.h> +#include <wtf/text/WTFString.h> using namespace JSC; +using namespace Inspector; namespace Inspector { -ScriptDebugServer::ScriptDebugServer(VM& vm) - : Debugger(vm) +ScriptDebugServer::ScriptDebugServer(bool isInWorkerThread) + : Debugger(isInWorkerThread) + , m_doneProcessingDebuggerEvents(true) + , m_callingListeners(false) { } @@ -60,14 +63,14 @@ JSC::BreakpointID ScriptDebugServer::setBreakpoint(JSC::SourceID sourceID, const if (!sourceID) return JSC::noBreakpointID; - JSC::Breakpoint breakpoint(sourceID, scriptBreakpoint.lineNumber, scriptBreakpoint.columnNumber, scriptBreakpoint.condition, scriptBreakpoint.autoContinue, scriptBreakpoint.ignoreCount); + JSC::Breakpoint breakpoint(sourceID, scriptBreakpoint.lineNumber, scriptBreakpoint.columnNumber, scriptBreakpoint.condition, scriptBreakpoint.autoContinue); JSC::BreakpointID id = Debugger::setBreakpoint(breakpoint, *actualLineNumber, *actualColumnNumber); if (id != JSC::noBreakpointID && !scriptBreakpoint.actions.isEmpty()) { #ifndef NDEBUG BreakpointIDToActionsMap::iterator it = m_breakpointIDToActions.find(id); ASSERT(it == m_breakpointIDToActions.end()); #endif - const BreakpointActions& actions = scriptBreakpoint.actions; + const Vector<ScriptBreakpointAction> &actions = scriptBreakpoint.actions; m_breakpointIDToActions.set(id, actions); } return id; @@ -93,24 +96,24 @@ bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& b break; } case ScriptBreakpointActionTypeEvaluate: { - NakedPtr<Exception> exception; + JSValue exception; debuggerCallFrame->evaluate(breakpointAction.data, exception); if (exception) reportException(debuggerCallFrame->exec(), exception); break; } case ScriptBreakpointActionTypeSound: - dispatchBreakpointActionSound(debuggerCallFrame->exec(), breakpointAction.identifier); + dispatchBreakpointActionSound(debuggerCallFrame->exec()); break; case ScriptBreakpointActionTypeProbe: { - NakedPtr<Exception> exception; + JSValue exception; JSValue result = debuggerCallFrame->evaluate(breakpointAction.data, exception); if (exception) reportException(debuggerCallFrame->exec(), exception); JSC::ExecState* state = debuggerCallFrame->scope()->globalObject()->globalExec(); - Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception->value() : result); - dispatchBreakpointActionProbe(state, breakpointAction, wrappedResult); + Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception : result); + dispatchDidSampleProbe(state, breakpointAction.identifier, wrappedResult); break; } default: @@ -134,8 +137,7 @@ void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener) JSC::ExecState* state = globalObject->globalExec(); RefPtr<JavaScriptCallFrame> javaScriptCallFrame = JavaScriptCallFrame::create(debuggerCallFrame); JSValue jsCallFrame = toJS(state, globalObject, javaScriptCallFrame.get()); - - listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), exceptionOrCaughtValue(state)); + listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), Deprecated::ScriptValue()); } void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const String& message) @@ -143,49 +145,53 @@ void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const Strin if (m_callingListeners) return; - if (m_listeners.isEmpty()) + ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); + if (!listeners) return; + ASSERT(!listeners->isEmpty()); TemporaryChange<bool> change(m_callingListeners, true); Vector<ScriptDebugListener*> listenersCopy; - copyToVector(m_listeners, listenersCopy); - for (auto* listener : listenersCopy) + copyToVector(*listeners, listenersCopy); + for (auto listener : listenersCopy) listener->breakpointActionLog(exec, message); } -void ScriptDebugServer::dispatchBreakpointActionSound(ExecState*, int breakpointActionIdentifier) +void ScriptDebugServer::dispatchBreakpointActionSound(ExecState* exec) { if (m_callingListeners) return; - if (m_listeners.isEmpty()) + ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); + if (!listeners) return; + ASSERT(!listeners->isEmpty()); TemporaryChange<bool> change(m_callingListeners, true); Vector<ScriptDebugListener*> listenersCopy; - copyToVector(m_listeners, listenersCopy); - for (auto* listener : listenersCopy) - listener->breakpointActionSound(breakpointActionIdentifier); + copyToVector(*listeners, listenersCopy); + for (auto listener : listenersCopy) + listener->breakpointActionSound(); } -void ScriptDebugServer::dispatchBreakpointActionProbe(ExecState* exec, const ScriptBreakpointAction& action, const Deprecated::ScriptValue& sampleValue) +void ScriptDebugServer::dispatchDidSampleProbe(ExecState* exec, int identifier, const Deprecated::ScriptValue& sample) { if (m_callingListeners) return; - if (m_listeners.isEmpty()) + ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); + if (!listeners) return; + ASSERT(!listeners->isEmpty()); TemporaryChange<bool> change(m_callingListeners, true); - unsigned sampleId = m_nextProbeSampleId++; - Vector<ScriptDebugListener*> listenersCopy; - copyToVector(m_listeners, listenersCopy); - for (auto* listener : listenersCopy) - listener->breakpointActionProbe(exec, action, m_currentProbeBatchId, sampleId, sampleValue); + copyToVector(*listeners, listenersCopy); + for (auto listener : listenersCopy) + listener->didSampleProbe(exec, identifier, m_hitCount, sample); } void ScriptDebugServer::dispatchDidContinue(ScriptDebugListener* listener) @@ -199,12 +205,10 @@ void ScriptDebugServer::dispatchDidParseSource(const ListenerSet& listeners, Sou ScriptDebugListener::Script script; script.url = sourceProvider->url(); - script.source = sourceProvider->source().toString(); + script.source = sourceProvider->source(); script.startLine = sourceProvider->startPosition().m_line.zeroBasedInt(); script.startColumn = sourceProvider->startPosition().m_column.zeroBasedInt(); script.isContentScript = isContentScript; - script.sourceURL = sourceProvider->sourceURL(); - script.sourceMappingURL = sourceProvider->sourceMappingURL(); int sourceLength = script.source.length(); int lineCount = 1; @@ -231,7 +235,7 @@ void ScriptDebugServer::dispatchDidParseSource(const ListenerSet& listeners, Sou void ScriptDebugServer::dispatchFailedToParseSource(const ListenerSet& listeners, SourceProvider* sourceProvider, int errorLine, const String& errorMessage) { String url = sourceProvider->url(); - String data = sourceProvider->source().toString(); + const String& data = sourceProvider->source(); int firstLine = sourceProvider->startPosition().m_line.oneBasedInt(); Vector<ScriptDebugListener*> copy; @@ -245,29 +249,18 @@ void ScriptDebugServer::sourceParsed(ExecState* exec, SourceProvider* sourceProv if (m_callingListeners) return; - if (m_listeners.isEmpty()) + ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); + if (!listeners) return; + ASSERT(!listeners->isEmpty()); TemporaryChange<bool> change(m_callingListeners, true); bool isError = errorLine != -1; if (isError) - dispatchFailedToParseSource(m_listeners, sourceProvider, errorLine, errorMessage); + dispatchFailedToParseSource(*listeners, sourceProvider, errorLine, errorMessage); else - dispatchDidParseSource(m_listeners, sourceProvider, isContentScript(exec)); -} - -void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback) -{ - if (m_callingListeners) - return; - - if (m_listeners.isEmpty()) - return; - - TemporaryChange<bool> change(m_callingListeners, true); - - dispatchFunctionToListeners(m_listeners, callback); + dispatchDidParseSource(*listeners, sourceProvider, isContentScript(exec)); } void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback) @@ -278,94 +271,68 @@ void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners (this->*callback)(copy[i]); } +void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, JSGlobalObject* globalObject) +{ + if (m_callingListeners) + return; + + TemporaryChange<bool> change(m_callingListeners, true); + + if (ListenerSet* listeners = getListenersForGlobalObject(globalObject)) { + ASSERT(!listeners->isEmpty()); + dispatchFunctionToListeners(*listeners, callback); + } +} + void ScriptDebugServer::notifyDoneProcessingDebuggerEvents() { m_doneProcessingDebuggerEvents = true; } -void ScriptDebugServer::handleBreakpointHit(JSC::JSGlobalObject* globalObject, const JSC::Breakpoint& breakpoint) +bool ScriptDebugServer::needPauseHandling(JSGlobalObject* globalObject) { - ASSERT(isAttached(globalObject)); - - m_currentProbeBatchId++; + return !!getListenersForGlobalObject(globalObject); +} +void ScriptDebugServer::handleBreakpointHit(const JSC::Breakpoint& breakpoint) +{ + m_hitCount++; BreakpointIDToActionsMap::iterator it = m_breakpointIDToActions.find(breakpoint.id); if (it != m_breakpointIDToActions.end()) { - BreakpointActions actions = it->value; + BreakpointActions& actions = it->value; for (size_t i = 0; i < actions.size(); ++i) { if (!evaluateBreakpointAction(actions[i])) return; - if (!isAttached(globalObject)) - return; } } } -void ScriptDebugServer::handleExceptionInBreakpointCondition(JSC::ExecState* exec, JSC::Exception* exception) const +void ScriptDebugServer::handleExceptionInBreakpointCondition(JSC::ExecState* exec, JSC::JSValue exception) const { reportException(exec, exception); } -void ScriptDebugServer::handlePause(JSGlobalObject* vmEntryGlobalObject, Debugger::ReasonForPause) +void ScriptDebugServer::handlePause(Debugger::ReasonForPause, JSGlobalObject* vmEntryGlobalObject) { - dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause); + dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, vmEntryGlobalObject); didPause(vmEntryGlobalObject); m_doneProcessingDebuggerEvents = false; runEventLoopWhilePaused(); didContinue(vmEntryGlobalObject); - dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue); + dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, vmEntryGlobalObject); } -const BreakpointActions& ScriptDebugServer::getActionsForBreakpoint(JSC::BreakpointID breakpointID) +const Vector<ScriptBreakpointAction>& ScriptDebugServer::getActionsForBreakpoint(JSC::BreakpointID breakpointID) { ASSERT(breakpointID != JSC::noBreakpointID); if (m_breakpointIDToActions.contains(breakpointID)) return m_breakpointIDToActions.find(breakpointID)->value; - static NeverDestroyed<BreakpointActions> emptyActionVector = BreakpointActions(); + static NeverDestroyed<Vector<ScriptBreakpointAction>> emptyActionVector = Vector<ScriptBreakpointAction>(); return emptyActionVector; } -void ScriptDebugServer::addListener(ScriptDebugListener* listener) -{ - ASSERT(listener); - - bool wasEmpty = m_listeners.isEmpty(); - m_listeners.add(listener); - - // First listener. Attach the debugger. - if (wasEmpty) - attachDebugger(); -} - -void ScriptDebugServer::removeListener(ScriptDebugListener* listener, bool isBeingDestroyed) -{ - ASSERT(listener); - - m_listeners.remove(listener); - - // Last listener. Detach the debugger. - if (m_listeners.isEmpty()) - detachDebugger(isBeingDestroyed); -} - -Deprecated::ScriptValue ScriptDebugServer::exceptionOrCaughtValue(JSC::ExecState* state) -{ - if (reasonForPause() == PausedForException) - return Deprecated::ScriptValue(state->vm(), currentException()); - - RefPtr<DebuggerCallFrame> debuggerCallFrame = currentDebuggerCallFrame(); - while (debuggerCallFrame) { - DebuggerScope* scope = debuggerCallFrame->scope(); - if (scope->isCatchScope()) - return Deprecated::ScriptValue(state->vm(), scope->caughtValue(state)); - debuggerCallFrame = debuggerCallFrame->callerFrame(); - } - - return Deprecated::ScriptValue(); -} - } // namespace Inspector |