X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/81345200c95645a1b0d2635520f96ad55dfde63f..refs/heads/master:/inspector/ScriptDebugServer.cpp diff --git a/inspector/ScriptDebugServer.cpp b/inspector/ScriptDebugServer.cpp index d279893..74602c5 100644 --- a/inspector/ScriptDebugServer.cpp +++ b/inspector/ScriptDebugServer.cpp @@ -31,9 +31,9 @@ #include "config.h" #include "ScriptDebugServer.h" -#if ENABLE(INSPECTOR) - #include "DebuggerCallFrame.h" +#include "DebuggerScope.h" +#include "Exception.h" #include "JSJavaScriptCallFrame.h" #include "JSLock.h" #include "JavaScriptCallFrame.h" @@ -49,8 +49,6 @@ namespace Inspector { ScriptDebugServer::ScriptDebugServer(bool isInWorkerThread) : Debugger(isInWorkerThread) - , m_doneProcessingDebuggerEvents(true) - , m_callingListeners(false) { } @@ -96,7 +94,7 @@ bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& b break; } case ScriptBreakpointActionTypeEvaluate: { - JSValue exception; + NakedPtr exception; debuggerCallFrame->evaluate(breakpointAction.data, exception); if (exception) reportException(debuggerCallFrame->exec(), exception); @@ -106,13 +104,13 @@ bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& b dispatchBreakpointActionSound(debuggerCallFrame->exec(), breakpointAction.identifier); break; case ScriptBreakpointActionTypeProbe: { - JSValue exception; + NakedPtr 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 : result); + Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception->value() : result); dispatchBreakpointActionProbe(state, breakpointAction, wrappedResult); break; } @@ -137,7 +135,8 @@ void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener) JSC::ExecState* state = globalObject->globalExec(); RefPtr javaScriptCallFrame = JavaScriptCallFrame::create(debuggerCallFrame); JSValue jsCallFrame = toJS(state, globalObject, javaScriptCallFrame.get()); - listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), Deprecated::ScriptValue()); + + listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), exceptionOrCaughtValue(state)); } void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const String& message) @@ -145,53 +144,52 @@ void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const Strin if (m_callingListeners) return; - ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); - if (!listeners) + ListenerSet& listeners = getListeners(); + if (listeners.isEmpty()) return; - ASSERT(!listeners->isEmpty()); TemporaryChange change(m_callingListeners, true); Vector listenersCopy; - copyToVector(*listeners, listenersCopy); + copyToVector(listeners, listenersCopy); for (auto* listener : listenersCopy) listener->breakpointActionLog(exec, message); } -void ScriptDebugServer::dispatchBreakpointActionSound(ExecState* exec, int breakpointActionIdentifier) +void ScriptDebugServer::dispatchBreakpointActionSound(ExecState*, int breakpointActionIdentifier) { if (m_callingListeners) return; - ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); - if (!listeners) + ListenerSet& listeners = getListeners(); + if (listeners.isEmpty()) return; - ASSERT(!listeners->isEmpty()); TemporaryChange change(m_callingListeners, true); Vector listenersCopy; - copyToVector(*listeners, listenersCopy); + copyToVector(listeners, listenersCopy); for (auto* listener : listenersCopy) listener->breakpointActionSound(breakpointActionIdentifier); } -void ScriptDebugServer::dispatchBreakpointActionProbe(ExecState* exec, const ScriptBreakpointAction& action, const Deprecated::ScriptValue& sample) +void ScriptDebugServer::dispatchBreakpointActionProbe(ExecState* exec, const ScriptBreakpointAction& action, const Deprecated::ScriptValue& sampleValue) { if (m_callingListeners) return; - ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); - if (!listeners) + ListenerSet& listeners = getListeners(); + if (listeners.isEmpty()) return; - ASSERT(!listeners->isEmpty()); TemporaryChange change(m_callingListeners, true); + unsigned sampleId = m_nextProbeSampleId++; + Vector listenersCopy; - copyToVector(*listeners, listenersCopy); + copyToVector(listeners, listenersCopy); for (auto* listener : listenersCopy) - listener->breakpointActionProbe(exec, action, m_hitCount, sample); + listener->breakpointActionProbe(exec, action, m_currentProbeBatchId, sampleId, sampleValue); } void ScriptDebugServer::dispatchDidContinue(ScriptDebugListener* listener) @@ -249,79 +247,77 @@ void ScriptDebugServer::sourceParsed(ExecState* exec, SourceProvider* sourceProv if (m_callingListeners) return; - ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); - if (!listeners) + ListenerSet& listeners = getListeners(); + if (listeners.isEmpty()) return; - ASSERT(!listeners->isEmpty()); TemporaryChange 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)); + dispatchDidParseSource(listeners, sourceProvider, isContentScript(exec)); } -void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback) -{ - Vector copy; - copyToVector(listeners, copy); - for (size_t i = 0; i < copy.size(); ++i) - (this->*callback)(copy[i]); -} - -void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, JSGlobalObject* globalObject) +void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback) { if (m_callingListeners) return; TemporaryChange change(m_callingListeners, true); - if (ListenerSet* listeners = getListenersForGlobalObject(globalObject)) { - if (!listeners->isEmpty()) - dispatchFunctionToListeners(*listeners, callback); - } + ListenerSet& listeners = getListeners(); + if (!listeners.isEmpty()) + dispatchFunctionToListeners(listeners, callback); } -void ScriptDebugServer::notifyDoneProcessingDebuggerEvents() +void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback) { - m_doneProcessingDebuggerEvents = true; + Vector copy; + copyToVector(listeners, copy); + for (size_t i = 0; i < copy.size(); ++i) + (this->*callback)(copy[i]); } -bool ScriptDebugServer::needPauseHandling(JSGlobalObject* globalObject) +void ScriptDebugServer::notifyDoneProcessingDebuggerEvents() { - return !!getListenersForGlobalObject(globalObject); + m_doneProcessingDebuggerEvents = true; } -void ScriptDebugServer::handleBreakpointHit(const JSC::Breakpoint& breakpoint) +void ScriptDebugServer::handleBreakpointHit(JSC::JSGlobalObject* globalObject, const JSC::Breakpoint& breakpoint) { - m_hitCount++; + ASSERT(isAttached(globalObject)); + + m_currentProbeBatchId++; + 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::JSValue exception) const +void ScriptDebugServer::handleExceptionInBreakpointCondition(JSC::ExecState* exec, JSC::Exception* exception) const { reportException(exec, exception); } -void ScriptDebugServer::handlePause(Debugger::ReasonForPause, JSGlobalObject* vmEntryGlobalObject) +void ScriptDebugServer::handlePause(JSGlobalObject* vmEntryGlobalObject, Debugger::ReasonForPause) { - dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, vmEntryGlobalObject); + dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause); didPause(vmEntryGlobalObject); m_doneProcessingDebuggerEvents = false; runEventLoopWhilePaused(); didContinue(vmEntryGlobalObject); - dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, vmEntryGlobalObject); + dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue); } const BreakpointActions& ScriptDebugServer::getActionsForBreakpoint(JSC::BreakpointID breakpointID) @@ -335,6 +331,20 @@ const BreakpointActions& ScriptDebugServer::getActionsForBreakpoint(JSC::Breakpo return emptyActionVector; } -} // namespace Inspector +Deprecated::ScriptValue ScriptDebugServer::exceptionOrCaughtValue(JSC::ExecState* state) +{ + if (reasonForPause() == PausedForException) + return Deprecated::ScriptValue(state->vm(), currentException()); + + RefPtr debuggerCallFrame = currentDebuggerCallFrame(); + while (debuggerCallFrame) { + DebuggerScope* scope = debuggerCallFrame->scope(); + if (scope->isCatchScope()) + return Deprecated::ScriptValue(state->vm(), scope->caughtValue()); + debuggerCallFrame = debuggerCallFrame->callerFrame(); + } -#endif // ENABLE(INSPECTOR) + return Deprecated::ScriptValue(); +} + +} // namespace Inspector