diff options
Diffstat (limited to 'Source/JavaScriptCore/inspector/ScriptDebugServer.cpp')
-rw-r--r-- | Source/JavaScriptCore/inspector/ScriptDebugServer.cpp | 136 |
1 files changed, 62 insertions, 74 deletions
diff --git a/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp b/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp index 356de1cbc..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,23 +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(bool isInWorkerThread) : Debugger(isInWorkerThread) + , m_doneProcessingDebuggerEvents(true) + , m_callingListeners(false) { } @@ -68,7 +70,7 @@ JSC::BreakpointID ScriptDebugServer::setBreakpoint(JSC::SourceID sourceID, const 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; @@ -94,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: @@ -135,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) @@ -144,52 +145,53 @@ void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const Strin if (m_callingListeners) return; - ListenerSet& listeners = getListeners(); - if (listeners.isEmpty()) + ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); + if (!listeners) return; + ASSERT(!listeners->isEmpty()); TemporaryChange<bool> change(m_callingListeners, true); Vector<ScriptDebugListener*> listenersCopy; - copyToVector(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; - ListenerSet& listeners = getListeners(); - if (listeners.isEmpty()) + ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); + if (!listeners) return; + ASSERT(!listeners->isEmpty()); TemporaryChange<bool> change(m_callingListeners, true); Vector<ScriptDebugListener*> listenersCopy; - copyToVector(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; - ListenerSet& listeners = getListeners(); - if (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(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) @@ -247,29 +249,18 @@ void ScriptDebugServer::sourceParsed(ExecState* exec, SourceProvider* sourceProv if (m_callingListeners) return; - ListenerSet& listeners = getListeners(); - if (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(listeners, sourceProvider, errorLine, errorMessage); + dispatchFailedToParseSource(*listeners, sourceProvider, errorLine, errorMessage); else - dispatchDidParseSource(listeners, sourceProvider, isContentScript(exec)); -} - -void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback) -{ - if (m_callingListeners) - return; - - TemporaryChange<bool> change(m_callingListeners, true); - - ListenerSet& listeners = getListeners(); - if (!listeners.isEmpty()) - dispatchFunctionToListeners(listeners, callback); + dispatchDidParseSource(*listeners, sourceProvider, isContentScript(exec)); } void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback) @@ -280,71 +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; } -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 |