]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
1 | /* |
2 | * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) | |
3 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) | |
81345200 | 4 | * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved. |
9dae56ea A |
5 | * |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | * | |
20 | */ | |
21 | ||
22 | #ifndef Debugger_h | |
23 | #define Debugger_h | |
24 | ||
81345200 A |
25 | #include "Breakpoint.h" |
26 | #include "DebuggerCallFrame.h" | |
27 | #include "DebuggerPrimitives.h" | |
28 | #include "JSCJSValue.h" | |
29 | #include <wtf/HashMap.h> | |
f9bf01c6 | 30 | #include <wtf/HashSet.h> |
81345200 A |
31 | #include <wtf/RefPtr.h> |
32 | #include <wtf/text/TextPosition.h> | |
9dae56ea A |
33 | |
34 | namespace JSC { | |
35 | ||
81345200 A |
36 | class ExecState; |
37 | class JSGlobalObject; | |
38 | class SourceProvider; | |
39 | class VM; | |
9dae56ea | 40 | |
81345200 A |
41 | typedef ExecState CallFrame; |
42 | ||
43 | class JS_EXPORT_PRIVATE Debugger { | |
44 | public: | |
45 | Debugger(bool isInWorkerThread = false); | |
46 | virtual ~Debugger(); | |
47 | ||
48 | JSC::DebuggerCallFrame* currentDebuggerCallFrame() const; | |
49 | bool hasHandlerForExceptionCallback() const | |
50 | { | |
51 | ASSERT(m_reasonForPause == PausedForException); | |
52 | return m_hasHandlerForExceptionCallback; | |
53 | } | |
54 | JSValue currentException() | |
55 | { | |
56 | ASSERT(m_reasonForPause == PausedForException); | |
57 | return m_currentException; | |
58 | } | |
59 | ||
60 | bool needsExceptionCallbacks() const { return m_pauseOnExceptionsState != DontPauseOnExceptions; } | |
61 | ||
62 | void attach(JSGlobalObject*); | |
63 | enum ReasonForDetach { | |
64 | TerminatingDebuggingSession, | |
65 | GlobalObjectIsDestructing | |
66 | }; | |
67 | virtual void detach(JSGlobalObject*, ReasonForDetach); | |
68 | ||
69 | BreakpointID setBreakpoint(Breakpoint, unsigned& actualLine, unsigned& actualColumn); | |
70 | void removeBreakpoint(BreakpointID); | |
71 | void clearBreakpoints(); | |
72 | void setBreakpointsActivated(bool); | |
73 | void activateBreakpoints() { setBreakpointsActivated(true); } | |
74 | void deactivateBreakpoints() { setBreakpointsActivated(false); } | |
75 | ||
76 | enum PauseOnExceptionsState { | |
77 | DontPauseOnExceptions, | |
78 | PauseOnAllExceptions, | |
79 | PauseOnUncaughtExceptions | |
80 | }; | |
81 | PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; } | |
82 | void setPauseOnExceptionsState(PauseOnExceptionsState); | |
83 | ||
84 | void setPauseOnNextStatement(bool); | |
85 | void breakProgram(); | |
86 | void continueProgram(); | |
87 | void stepIntoStatement(); | |
88 | void stepOverStatement(); | |
89 | void stepOutOfFunction(); | |
90 | ||
91 | bool isPaused() { return m_isPaused; } | |
92 | bool isStepping() const { return m_steppingMode == SteppingModeEnabled; } | |
93 | ||
94 | virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0; | |
95 | ||
96 | void exception(CallFrame*, JSValue exceptionValue, bool hasHandler); | |
97 | void atStatement(CallFrame*); | |
98 | void callEvent(CallFrame*); | |
99 | void returnEvent(CallFrame*); | |
100 | void willExecuteProgram(CallFrame*); | |
101 | void didExecuteProgram(CallFrame*); | |
102 | void didReachBreakpoint(CallFrame*); | |
103 | ||
104 | void recompileAllJSFunctions(VM*); | |
105 | ||
106 | void registerCodeBlock(CodeBlock*); | |
107 | ||
108 | protected: | |
109 | virtual bool needPauseHandling(JSGlobalObject*) { return false; } | |
110 | virtual void handleBreakpointHit(const Breakpoint&) { } | |
111 | virtual void handleExceptionInBreakpointCondition(ExecState*, JSValue exception) const { UNUSED_PARAM(exception); } | |
9dae56ea | 112 | |
81345200 A |
113 | enum ReasonForPause { |
114 | NotPaused, | |
115 | PausedForException, | |
116 | PausedAtStatement, | |
117 | PausedAfterCall, | |
118 | PausedBeforeReturn, | |
119 | PausedAtStartOfProgram, | |
120 | PausedAtEndOfProgram, | |
121 | PausedForBreakpoint | |
122 | }; | |
9dae56ea | 123 | |
81345200 A |
124 | virtual void handlePause(ReasonForPause, JSGlobalObject*) { } |
125 | virtual void notifyDoneProcessingDebuggerEvents() { } | |
9dae56ea | 126 | |
81345200 A |
127 | private: |
128 | typedef HashMap<BreakpointID, Breakpoint*> BreakpointIDToBreakpointMap; | |
f9bf01c6 | 129 | |
81345200 A |
130 | typedef HashMap<unsigned, RefPtr<BreakpointsList>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> LineToBreakpointsMap; |
131 | typedef HashMap<SourceID, LineToBreakpointsMap, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> SourceIDToBreakpointsMap; | |
93a37866 | 132 | |
81345200 A |
133 | class ClearCodeBlockDebuggerRequestsFunctor; |
134 | class ClearDebuggerRequestsFunctor; | |
135 | class SetSteppingModeFunctor; | |
136 | class ToggleBreakpointFunctor; | |
93a37866 | 137 | |
81345200 A |
138 | class PauseReasonDeclaration { |
139 | public: | |
140 | PauseReasonDeclaration(Debugger& debugger, ReasonForPause reason) | |
141 | : m_debugger(debugger) | |
142 | { | |
143 | m_debugger.m_reasonForPause = reason; | |
144 | } | |
9dae56ea | 145 | |
81345200 A |
146 | ~PauseReasonDeclaration() |
147 | { | |
148 | m_debugger.m_reasonForPause = NotPaused; | |
149 | } | |
9dae56ea | 150 | private: |
81345200 A |
151 | Debugger& m_debugger; |
152 | }; | |
153 | ||
154 | bool hasBreakpoint(SourceID, const TextPosition&, Breakpoint* hitBreakpoint); | |
155 | ||
156 | void updateNeedForOpDebugCallbacks(); | |
157 | ||
158 | // These update functions are only needed because our current breakpoints are | |
159 | // key'ed off the source position instead of the bytecode PC. This ensures | |
160 | // that we don't break on the same line more than once. Once we switch to a | |
161 | // bytecode PC key'ed breakpoint, we will not need these anymore and should | |
162 | // be able to remove them. | |
163 | void updateCallFrame(JSC::CallFrame*); | |
164 | void updateCallFrameAndPauseIfNeeded(JSC::CallFrame*); | |
165 | void pauseIfNeeded(JSC::CallFrame*); | |
166 | ||
167 | enum SteppingMode { | |
168 | SteppingModeDisabled, | |
169 | SteppingModeEnabled | |
170 | }; | |
171 | void setSteppingMode(SteppingMode); | |
172 | ||
173 | enum BreakpointState { | |
174 | BreakpointDisabled, | |
175 | BreakpointEnabled | |
9dae56ea | 176 | }; |
81345200 A |
177 | void toggleBreakpoint(CodeBlock*, Breakpoint&, BreakpointState); |
178 | void applyBreakpoints(CodeBlock*); | |
179 | void toggleBreakpoint(Breakpoint&, BreakpointState); | |
180 | ||
181 | void clearDebuggerRequests(JSGlobalObject*); | |
182 | ||
183 | template<typename Functor> inline void forEachCodeBlock(Functor&); | |
184 | ||
185 | VM* m_vm; | |
186 | HashSet<JSGlobalObject*> m_globalObjects; | |
187 | ||
188 | PauseOnExceptionsState m_pauseOnExceptionsState; | |
189 | bool m_pauseOnNextStatement : 1; | |
190 | bool m_isPaused : 1; | |
191 | bool m_breakpointsActivated : 1; | |
192 | bool m_hasHandlerForExceptionCallback : 1; | |
193 | bool m_isInWorkerThread : 1; | |
194 | SteppingMode m_steppingMode : 1; | |
195 | ||
196 | ReasonForPause m_reasonForPause; | |
197 | JSValue m_currentException; | |
198 | CallFrame* m_pauseOnCallFrame; | |
199 | CallFrame* m_currentCallFrame; | |
200 | unsigned m_lastExecutedLine; | |
201 | SourceID m_lastExecutedSourceID; | |
202 | ||
203 | BreakpointID m_topBreakpointID; | |
204 | BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint; | |
205 | SourceIDToBreakpointsMap m_sourceIDToBreakpoints; | |
206 | ||
207 | RefPtr<JSC::DebuggerCallFrame> m_currentDebuggerCallFrame; | |
9dae56ea | 208 | |
81345200 A |
209 | friend class DebuggerCallFrameScope; |
210 | friend class TemporaryPausedState; | |
211 | friend class LLIntOffsetsExtractor; | |
212 | }; | |
9dae56ea A |
213 | |
214 | } // namespace JSC | |
215 | ||
216 | #endif // Debugger_h |