blob: 7c0b03bcac4fc2a7b812f8694a7a2b5cf31c90dd [file] [log] [blame]
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COBALT_SCRIPT_JAVASCRIPTCORE_JSC_DEBUGGER_H_
#define COBALT_SCRIPT_JAVASCRIPTCORE_JSC_DEBUGGER_H_
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/threading/thread_checker.h"
#include "cobalt/script/javascriptcore/jsc_global_environment.h"
#include "cobalt/script/script_debugger.h"
#include "cobalt/script/source_provider.h"
#include "third_party/WebKit/Source/JavaScriptCore/config.h"
#include "third_party/WebKit/Source/JavaScriptCore/debugger/Debugger.h"
#include "third_party/WebKit/Source/JavaScriptCore/debugger/DebuggerCallFrame.h"
#include "third_party/WebKit/Source/WTF/wtf/HashSet.h"
#include "third_party/WebKit/Source/WTF/wtf/text/WTFString.h"
namespace JSC {
class ExecState;
class JSGlobalData;
class JSGlobalObject;
class JSScope;
class JSValue;
class SourceProvider;
}
namespace cobalt {
namespace script {
namespace javascriptcore {
// JavaScriptCore-specific implementation of a JavaScript debugger.
// Uses multiple inheritance in accordance with the C++ style guide to extend
// JSC::Debugger and implement ScriptDebugger.
//
// Only the ScriptDebugger is publicly exposed.
// This class is not designed to be thread-safe - it is assumed that all
// public methods will be run on the same message loop as the JavaScript
// global object to which this debugger connects.
class JSCDebugger : protected JSC::Debugger, public ScriptDebugger {
public:
JSCDebugger(GlobalEnvironment* global_environment, Delegate* delegate);
~JSCDebugger() OVERRIDE;
// Implementation of ScriptDebugger.
void Attach() OVERRIDE;
void Detach() OVERRIDE;
void Pause() OVERRIDE;
void Resume() OVERRIDE;
void SetBreakpoint(const std::string& script_id, int line_number,
int column_number) OVERRIDE;
PauseOnExceptionsState SetPauseOnExceptions(
PauseOnExceptionsState state) OVERRIDE;
void StepInto() OVERRIDE;
void StepOut() OVERRIDE;
void StepOver() OVERRIDE;
protected:
// Hides a non-virtual JSC::Debugger method with the same name.
void attach(JSC::JSGlobalObject* global_object);
// The following methods are overrides of pure virtual methods in
// JSC::Debugger, hence the non-standard names.
void detach(JSC::JSGlobalObject* global_object) OVERRIDE;
void sourceParsed(JSC::ExecState* exec_state,
JSC::SourceProvider* source_provider, int error_line,
const WTF::String& error_message) OVERRIDE;
void exception(const JSC::DebuggerCallFrame& call_frame, intptr_t source_id,
int line_number, int column_number, bool has_handler) OVERRIDE;
void atStatement(const JSC::DebuggerCallFrame& call_frame, intptr_t source_id,
int line_number, int column_number) OVERRIDE;
void callEvent(const JSC::DebuggerCallFrame& call_frame, intptr_t source_id,
int line_number, int column_number) OVERRIDE;
void returnEvent(const JSC::DebuggerCallFrame& call_frame, intptr_t source_id,
int line_number, int column_number) OVERRIDE;
void willExecuteProgram(const JSC::DebuggerCallFrame& call_frame,
intptr_t source_id, int line_number,
int column_number) OVERRIDE;
void didExecuteProgram(const JSC::DebuggerCallFrame& call_frame,
intptr_t source_id, int line_number,
int column_number) OVERRIDE;
void didReachBreakpoint(const JSC::DebuggerCallFrame& call_frame,
intptr_t source_id, int line_number,
int column_number) OVERRIDE;
private:
// Physical breakpoint corresponding to a specific source location.
// TODO: Include other attributes, e.g. condition.
struct Breakpoint {
Breakpoint(intptr_t source_id, int line_number, int column_number)
: source_id(source_id),
line_number(line_number),
column_number(column_number) {}
intptr_t source_id;
int line_number;
int column_number;
};
typedef std::vector<Breakpoint> BreakpointVector;
// Sets the |is_paused_| member of the debugger while in scope, unsets it
// on destruction.
class ScopedPausedState {
public:
explicit ScopedPausedState(JSCDebugger* debugger) : debugger(debugger) {
debugger->is_paused_ = true;
}
~ScopedPausedState() { debugger->is_paused_ = false; }
private:
JSCDebugger* debugger;
};
// Convenience function to get the global object pointer from the proxy.
JSCGlobalObject* GetGlobalObject() const;
// Update functions called by the overridden methods from JSC:Debugger above
// (e.g. |atStatement|) as script is executed.
void UpdateAndPauseIfNeeded(const JSC::DebuggerCallFrame& call_frame,
intptr_t source_id, int line_number,
int column_number);
void UpdateSourceLocation(intptr_t source_id, int line_number,
int column_number);
void UpdateCallFrame(const JSC::DebuggerCallFrame& call_frame);
void PauseIfNeeded(const JSC::DebuggerCallFrame& call_frame);
// Sends event notifications via |delegate_|.
void SendPausedEvent(const JSC::DebuggerCallFrame& call_frame);
void SendResumedEvent();
// Whether any of the currently active breakpoints matches the current
// source location.
bool IsBreakpointAtCurrentLocation() const;
base::ThreadChecker thread_checker_;
GlobalEnvironment* global_environment_;
// Lifetime managed by the caller of this object's constructor.
Delegate* delegate_;
// Whether script execution pauses on exceptions.
PauseOnExceptionsState pause_on_exceptions_;
// Code execution control flags. Script execution can pause on the next
// statement, or on a specific call frame.
bool pause_on_next_statement_;
JSC::CallFrame* pause_on_call_frame_;
// Current call frame.
JSC::DebuggerCallFrame current_call_frame_;
// Current source location.
intptr_t current_source_id_;
int current_line_number_;
int current_column_number_;
// Whether script execution is currently paused.
bool is_paused_;
// Currently active breakpoints.
BreakpointVector breakpoints_;
};
} // namespace javascriptcore
} // namespace script
} // namespace cobalt
#endif // COBALT_SCRIPT_JAVASCRIPTCORE_JSC_DEBUGGER_H_