summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/debugger/Debugger.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-10-15 09:45:50 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-10-15 09:45:50 +0000
commite15dd966d523731101f70ccf768bba12435a0208 (patch)
treeae9cb828a24ded2585a41af3f21411523b47897d /Source/JavaScriptCore/debugger/Debugger.h
downloadWebKitGtk-tarball-e15dd966d523731101f70ccf768bba12435a0208.tar.gz
webkitgtk-2.10.2webkitgtk-2.10.2
Diffstat (limited to 'Source/JavaScriptCore/debugger/Debugger.h')
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.h222
1 files changed, 222 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/debugger/Debugger.h b/Source/JavaScriptCore/debugger/Debugger.h
new file mode 100644
index 000000000..d70f3b76f
--- /dev/null
+++ b/Source/JavaScriptCore/debugger/Debugger.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef Debugger_h
+#define Debugger_h
+
+#include "Breakpoint.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 CodeBlock;
+class Exception;
+class ExecState;
+class JSGlobalObject;
+class SourceProvider;
+class VM;
+
+typedef ExecState CallFrame;
+
+class JS_EXPORT_PRIVATE Debugger {
+public:
+ Debugger(bool isInWorkerThread = false);
+ virtual ~Debugger();
+
+ 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; }
+
+ 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*);
+
+ void recompileAllJSFunctions(VM*);
+
+ void registerCodeBlock(CodeBlock*);
+
+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() { }
+
+private:
+ typedef HashMap<BreakpointID, Breakpoint*> BreakpointIDToBreakpointMap;
+
+ 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;
+
+ class PauseReasonDeclaration {
+ public:
+ PauseReasonDeclaration(Debugger& debugger, ReasonForPause reason)
+ : m_debugger(debugger)
+ {
+ m_debugger.m_reasonForPause = reason;
+ }
+
+ ~PauseReasonDeclaration()
+ {
+ m_debugger.m_reasonForPause = NotPaused;
+ }
+ private:
+ Debugger& m_debugger;
+ };
+
+ 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*);
+
+ template<typename Functor> inline void forEachCodeBlock(Functor&);
+
+ 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_isInWorkerThread : 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;
+
+ friend class DebuggerPausedScope;
+ friend class TemporaryPausedState;
+ friend class LLIntOffsetsExtractor;
+};
+
+} // namespace JSC
+
+#endif // Debugger_h