diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/debugger/Debugger.h | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/debugger/Debugger.h')
-rw-r--r-- | Source/JavaScriptCore/debugger/Debugger.h | 222 |
1 files changed, 199 insertions, 23 deletions
diff --git a/Source/JavaScriptCore/debugger/Debugger.h b/Source/JavaScriptCore/debugger/Debugger.h index 95dd62b06..2e91aafbe 100644 --- a/Source/JavaScriptCore/debugger/Debugger.h +++ b/Source/JavaScriptCore/debugger/Debugger.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,44 +22,220 @@ #ifndef Debugger_h #define Debugger_h +#include "Breakpoint.h" +#include "CallData.h" +#include "DebuggerCallFrame.h" +#include "DebuggerPrimitives.h" +#include "JSCJSValue.h" +#include <wtf/HashMap.h> #include <wtf/HashSet.h> +#include <wtf/RefPtr.h> +#include <wtf/text/TextPosition.h> namespace JSC { - class DebuggerCallFrame; - class ExecState; - class VM; - class JSGlobalObject; - class JSValue; - class SourceProvider; +class CodeBlock; +class Exception; +class ExecState; +class JSGlobalObject; +class SourceProvider; +class VM; - class JS_EXPORT_PRIVATE Debugger { +typedef ExecState CallFrame; + +class JS_EXPORT_PRIVATE Debugger { +public: + Debugger(VM&); + virtual ~Debugger(); + + VM& vm() { return m_vm; } + + JSC::DebuggerCallFrame* currentDebuggerCallFrame() const; + bool hasHandlerForExceptionCallback() const + { + ASSERT(m_reasonForPause == PausedForException); + return m_hasHandlerForExceptionCallback; + } + JSValue currentException() + { + ASSERT(m_reasonForPause == PausedForException); + return m_currentException; + } + + bool needsExceptionCallbacks() const { return m_pauseOnExceptionsState != DontPauseOnExceptions; } + + enum ReasonForDetach { + TerminatingDebuggingSession, + GlobalObjectIsDestructing + }; + void attach(JSGlobalObject*); + void detach(JSGlobalObject*, ReasonForDetach); + bool isAttached(JSGlobalObject*); + + BreakpointID setBreakpoint(Breakpoint, unsigned& actualLine, unsigned& actualColumn); + void removeBreakpoint(BreakpointID); + void clearBreakpoints(); + void setBreakpointsActivated(bool); + void activateBreakpoints() { setBreakpointsActivated(true); } + void deactivateBreakpoints() { setBreakpointsActivated(false); } + + enum PauseOnExceptionsState { + DontPauseOnExceptions, + PauseOnAllExceptions, + PauseOnUncaughtExceptions + }; + PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; } + void setPauseOnExceptionsState(PauseOnExceptionsState); + + enum ReasonForPause { + NotPaused, + PausedForException, + PausedAtStatement, + PausedAfterCall, + PausedBeforeReturn, + PausedAtStartOfProgram, + PausedAtEndOfProgram, + PausedForBreakpoint, + PausedForDebuggerStatement, + }; + ReasonForPause reasonForPause() const { return m_reasonForPause; } + BreakpointID pausingBreakpointID() const { return m_pausingBreakpointID; } + + void setPauseOnNextStatement(bool); + void breakProgram(); + void continueProgram(); + void stepIntoStatement(); + void stepOverStatement(); + void stepOutOfFunction(); + + bool isPaused() const { return m_isPaused; } + bool isStepping() const { return m_steppingMode == SteppingModeEnabled; } + + bool suppressAllPauses() const { return m_suppressAllPauses; } + void setSuppressAllPauses(bool suppress) { m_suppressAllPauses = suppress; } + + virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0; + + void exception(CallFrame*, JSValue exceptionValue, bool hasCatchHandler); + void atStatement(CallFrame*); + void callEvent(CallFrame*); + void returnEvent(CallFrame*); + void willExecuteProgram(CallFrame*); + void didExecuteProgram(CallFrame*); + void didReachBreakpoint(CallFrame*); + + virtual void recompileAllJSFunctions(); + + void registerCodeBlock(CodeBlock*); + + class ProfilingClient { public: - virtual ~Debugger(); + virtual ~ProfilingClient() { } + virtual bool isAlreadyProfiling() const = 0; + virtual double willEvaluateScript() = 0; + virtual void didEvaluateScript(double startTime, ProfilingReason) = 0; + }; - void attach(JSGlobalObject*); - virtual void detach(JSGlobalObject*); + void setProfilingClient(ProfilingClient*); + bool hasProfilingClient() const { return m_profilingClient != nullptr; } + bool isAlreadyProfiling() const { return m_profilingClient && m_profilingClient->isAlreadyProfiling(); } + double willEvaluateScript(); + void didEvaluateScript(double startTime, ProfilingReason); - virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0; +protected: + virtual bool needPauseHandling(JSGlobalObject*) { return false; } + virtual void handleBreakpointHit(JSGlobalObject*, const Breakpoint&) { } + virtual void handleExceptionInBreakpointCondition(ExecState*, Exception*) const { } + virtual void handlePause(JSGlobalObject*, ReasonForPause) { } + virtual void notifyDoneProcessingDebuggerEvents() { } - virtual void exception(const DebuggerCallFrame&, intptr_t, int, int, bool) = 0; - virtual void atStatement(const DebuggerCallFrame&, intptr_t, int, int) = 0; - virtual void callEvent(const DebuggerCallFrame&, intptr_t, int, int) = 0; - virtual void returnEvent(const DebuggerCallFrame&, intptr_t, int, int) = 0; +private: + typedef HashMap<BreakpointID, Breakpoint*> BreakpointIDToBreakpointMap; - virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t, int, int) = 0; - virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t, int, int) = 0; - virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int, int) = 0; + typedef HashMap<unsigned, RefPtr<BreakpointsList>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> LineToBreakpointsMap; + typedef HashMap<SourceID, LineToBreakpointsMap, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> SourceIDToBreakpointsMap; + class ClearCodeBlockDebuggerRequestsFunctor; + class ClearDebuggerRequestsFunctor; + class SetSteppingModeFunctor; + class ToggleBreakpointFunctor; - void recompileAllJSFunctions(VM*); + class PauseReasonDeclaration { + public: + PauseReasonDeclaration(Debugger& debugger, ReasonForPause reason) + : m_debugger(debugger) + { + m_debugger.m_reasonForPause = reason; + } + ~PauseReasonDeclaration() + { + m_debugger.m_reasonForPause = NotPaused; + } private: - HashSet<JSGlobalObject*> m_globalObjects; + Debugger& m_debugger; }; - // This function exists only for backwards compatibility with existing WebScriptDebugger clients. - JS_EXPORT_PRIVATE JSValue evaluateInGlobalCallFrame(const WTF::String&, JSValue& exception, JSGlobalObject*); + bool hasBreakpoint(SourceID, const TextPosition&, Breakpoint* hitBreakpoint); + + void updateNeedForOpDebugCallbacks(); + + // These update functions are only needed because our current breakpoints are + // key'ed off the source position instead of the bytecode PC. This ensures + // that we don't break on the same line more than once. Once we switch to a + // bytecode PC key'ed breakpoint, we will not need these anymore and should + // be able to remove them. + void updateCallFrame(JSC::CallFrame*); + void updateCallFrameAndPauseIfNeeded(JSC::CallFrame*); + void pauseIfNeeded(JSC::CallFrame*); + + enum SteppingMode { + SteppingModeDisabled, + SteppingModeEnabled + }; + void setSteppingMode(SteppingMode); + + enum BreakpointState { + BreakpointDisabled, + BreakpointEnabled + }; + void toggleBreakpoint(CodeBlock*, Breakpoint&, BreakpointState); + void applyBreakpoints(CodeBlock*); + void toggleBreakpoint(Breakpoint&, BreakpointState); + + void clearDebuggerRequests(JSGlobalObject*); + + VM& m_vm; + HashSet<JSGlobalObject*> m_globalObjects; + + PauseOnExceptionsState m_pauseOnExceptionsState; + bool m_pauseOnNextStatement : 1; + bool m_isPaused : 1; + bool m_breakpointsActivated : 1; + bool m_hasHandlerForExceptionCallback : 1; + bool m_suppressAllPauses : 1; + unsigned m_steppingMode : 1; // SteppingMode + + ReasonForPause m_reasonForPause; + JSValue m_currentException; + CallFrame* m_pauseOnCallFrame; + CallFrame* m_currentCallFrame; + unsigned m_lastExecutedLine; + SourceID m_lastExecutedSourceID; + + BreakpointID m_topBreakpointID; + BreakpointID m_pausingBreakpointID; + BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint; + SourceIDToBreakpointsMap m_sourceIDToBreakpoints; + + RefPtr<JSC::DebuggerCallFrame> m_currentDebuggerCallFrame; + + ProfilingClient* m_profilingClient { nullptr }; + + friend class DebuggerPausedScope; + friend class TemporaryPausedState; + friend class LLIntOffsetsExtractor; +}; } // namespace JSC |