2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
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.
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.
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
25 #include "Breakpoint.h"
26 #include "DebuggerCallFrame.h"
27 #include "DebuggerPrimitives.h"
28 #include "JSCJSValue.h"
29 #include <wtf/HashMap.h>
30 #include <wtf/HashSet.h>
31 #include <wtf/RefPtr.h>
32 #include <wtf/text/TextPosition.h>
41 typedef ExecState CallFrame
;
43 class JS_EXPORT_PRIVATE Debugger
{
45 Debugger(bool isInWorkerThread
= false);
48 JSC::DebuggerCallFrame
* currentDebuggerCallFrame() const;
49 bool hasHandlerForExceptionCallback() const
51 ASSERT(m_reasonForPause
== PausedForException
);
52 return m_hasHandlerForExceptionCallback
;
54 JSValue
currentException()
56 ASSERT(m_reasonForPause
== PausedForException
);
57 return m_currentException
;
60 bool needsExceptionCallbacks() const { return m_pauseOnExceptionsState
!= DontPauseOnExceptions
; }
62 void attach(JSGlobalObject
*);
63 enum ReasonForDetach
{
64 TerminatingDebuggingSession
,
65 GlobalObjectIsDestructing
67 virtual void detach(JSGlobalObject
*, ReasonForDetach
);
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); }
76 enum PauseOnExceptionsState
{
77 DontPauseOnExceptions
,
79 PauseOnUncaughtExceptions
81 PauseOnExceptionsState
pauseOnExceptionsState() const { return m_pauseOnExceptionsState
; }
82 void setPauseOnExceptionsState(PauseOnExceptionsState
);
84 void setPauseOnNextStatement(bool);
86 void continueProgram();
87 void stepIntoStatement();
88 void stepOverStatement();
89 void stepOutOfFunction();
91 bool isPaused() { return m_isPaused
; }
92 bool isStepping() const { return m_steppingMode
== SteppingModeEnabled
; }
94 virtual void sourceParsed(ExecState
*, SourceProvider
*, int errorLineNumber
, const WTF::String
& errorMessage
) = 0;
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
*);
104 void recompileAllJSFunctions(VM
*);
106 void registerCodeBlock(CodeBlock
*);
109 virtual bool needPauseHandling(JSGlobalObject
*) { return false; }
110 virtual void handleBreakpointHit(const Breakpoint
&) { }
111 virtual void handleExceptionInBreakpointCondition(ExecState
*, JSValue exception
) const { UNUSED_PARAM(exception
); }
113 enum ReasonForPause
{
119 PausedAtStartOfProgram
,
120 PausedAtEndOfProgram
,
124 virtual void handlePause(ReasonForPause
, JSGlobalObject
*) { }
125 virtual void notifyDoneProcessingDebuggerEvents() { }
128 typedef HashMap
<BreakpointID
, Breakpoint
*> BreakpointIDToBreakpointMap
;
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
;
133 class ClearCodeBlockDebuggerRequestsFunctor
;
134 class ClearDebuggerRequestsFunctor
;
135 class SetSteppingModeFunctor
;
136 class ToggleBreakpointFunctor
;
138 class PauseReasonDeclaration
{
140 PauseReasonDeclaration(Debugger
& debugger
, ReasonForPause reason
)
141 : m_debugger(debugger
)
143 m_debugger
.m_reasonForPause
= reason
;
146 ~PauseReasonDeclaration()
148 m_debugger
.m_reasonForPause
= NotPaused
;
151 Debugger
& m_debugger
;
154 bool hasBreakpoint(SourceID
, const TextPosition
&, Breakpoint
* hitBreakpoint
);
156 void updateNeedForOpDebugCallbacks();
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
*);
168 SteppingModeDisabled
,
171 void setSteppingMode(SteppingMode
);
173 enum BreakpointState
{
177 void toggleBreakpoint(CodeBlock
*, Breakpoint
&, BreakpointState
);
178 void applyBreakpoints(CodeBlock
*);
179 void toggleBreakpoint(Breakpoint
&, BreakpointState
);
181 void clearDebuggerRequests(JSGlobalObject
*);
183 template<typename Functor
> inline void forEachCodeBlock(Functor
&);
186 HashSet
<JSGlobalObject
*> m_globalObjects
;
188 PauseOnExceptionsState m_pauseOnExceptionsState
;
189 bool m_pauseOnNextStatement
: 1;
191 bool m_breakpointsActivated
: 1;
192 bool m_hasHandlerForExceptionCallback
: 1;
193 bool m_isInWorkerThread
: 1;
194 SteppingMode m_steppingMode
: 1;
196 ReasonForPause m_reasonForPause
;
197 JSValue m_currentException
;
198 CallFrame
* m_pauseOnCallFrame
;
199 CallFrame
* m_currentCallFrame
;
200 unsigned m_lastExecutedLine
;
201 SourceID m_lastExecutedSourceID
;
203 BreakpointID m_topBreakpointID
;
204 BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint
;
205 SourceIDToBreakpointsMap m_sourceIDToBreakpoints
;
207 RefPtr
<JSC::DebuggerCallFrame
> m_currentDebuggerCallFrame
;
209 friend class DebuggerCallFrameScope
;
210 friend class TemporaryPausedState
;
211 friend class LLIntOffsetsExtractor
;