[debug] remove legacy implementation for break points.
R=herhut@chromium.org, jgruber@chromium.org Bug: v8:7310, v8:5510 Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel Change-Id: Icefd10b6cc210e5bb2684d18b091179ead387326 Reviewed-on: https://chromium-review.googlesource.com/934445 Commit-Queue: Yang Guo <yangguo@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#51552}
This commit is contained in:
parent
d504203e93
commit
175fc49c6e
@ -180,12 +180,10 @@ class DebugDelegate {
|
||||
bool is_blackboxed) {}
|
||||
virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited,
|
||||
bool has_compile_error) {}
|
||||
// |break_points_hit| contains installed by JS debug API breakpoint objects.
|
||||
// |inspector_break_points_hit| contains id of breakpoints installed with
|
||||
// debug::Script::SetBreakpoint API.
|
||||
virtual void BreakProgramRequested(
|
||||
v8::Local<v8::Context> paused_context, v8::Local<v8::Object> exec_state,
|
||||
v8::Local<v8::Value> break_points_hit,
|
||||
const std::vector<debug::BreakpointId>& inspector_break_points_hit) {}
|
||||
virtual void ExceptionThrown(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
|
@ -510,9 +510,9 @@ MaybeHandle<FixedArray> Debug::CheckBreakPoints(Handle<DebugInfo> debug_info,
|
||||
if (has_break_points) *has_break_points = has_break_points_to_check;
|
||||
if (!has_break_points_to_check) return {};
|
||||
|
||||
Handle<Object> break_point_objects =
|
||||
debug_info->GetBreakPointObjects(location->position());
|
||||
return Debug::GetHitBreakPointObjects(break_point_objects);
|
||||
Handle<Object> break_points =
|
||||
debug_info->GetBreakPoints(location->position());
|
||||
return Debug::GetHitBreakPoints(break_points);
|
||||
}
|
||||
|
||||
|
||||
@ -567,15 +567,9 @@ MaybeHandle<Object> Debug::CallFunction(const char* name, int argc,
|
||||
|
||||
|
||||
// Check whether a single break point object is triggered.
|
||||
bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
|
||||
Factory* factory = isolate_->factory();
|
||||
bool Debug::CheckBreakPoint(Handle<BreakPoint> break_point) {
|
||||
HandleScope scope(isolate_);
|
||||
|
||||
// TODO(kozyatinskiy): replace this if by DCHEK once the JS debug API has been
|
||||
// removed.
|
||||
if (break_point_object->IsBreakPoint()) {
|
||||
Handle<BreakPoint> break_point =
|
||||
Handle<BreakPoint>::cast(break_point_object);
|
||||
if (!break_point->condition()->length()) return true;
|
||||
Handle<String> condition(break_point->condition());
|
||||
Handle<Object> result;
|
||||
@ -592,27 +586,8 @@ bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
|
||||
return result->BooleanValue();
|
||||
}
|
||||
|
||||
// Ignore check if break point object is not a JSObject.
|
||||
if (!break_point_object->IsJSObject()) return true;
|
||||
|
||||
// Get the break id as an object.
|
||||
Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
|
||||
|
||||
// Call IsBreakPointTriggered.
|
||||
Handle<Object> argv[] = { break_id, break_point_object };
|
||||
Handle<Object> result;
|
||||
if (!CallFunction("IsBreakPointTriggered", arraysize(argv), argv)
|
||||
.ToHandle(&result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return whether the break point is triggered.
|
||||
return result->IsTrue(isolate_);
|
||||
}
|
||||
|
||||
|
||||
bool Debug::SetBreakPoint(Handle<JSFunction> function,
|
||||
Handle<Object> break_point_object,
|
||||
Handle<BreakPoint> break_point,
|
||||
int* source_position) {
|
||||
HandleScope scope(isolate_);
|
||||
|
||||
@ -626,7 +601,7 @@ bool Debug::SetBreakPoint(Handle<JSFunction> function,
|
||||
|
||||
// Find the break point and change it.
|
||||
*source_position = FindBreakablePosition(debug_info, *source_position);
|
||||
DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
|
||||
DebugInfo::SetBreakPoint(debug_info, *source_position, break_point);
|
||||
// At least one active break point now.
|
||||
DCHECK_LT(0, debug_info->GetBreakPointCount());
|
||||
|
||||
@ -638,13 +613,13 @@ bool Debug::SetBreakPoint(Handle<JSFunction> function,
|
||||
}
|
||||
|
||||
bool Debug::SetBreakPointForScript(Handle<Script> script,
|
||||
Handle<Object> break_point_object,
|
||||
Handle<BreakPoint> break_point,
|
||||
int* source_position) {
|
||||
if (script->type() == Script::TYPE_WASM) {
|
||||
Handle<WasmCompiledModule> compiled_module(
|
||||
WasmCompiledModule::cast(script->wasm_compiled_module()), isolate_);
|
||||
return WasmCompiledModule::SetBreakPoint(compiled_module, source_position,
|
||||
break_point_object);
|
||||
break_point);
|
||||
}
|
||||
|
||||
HandleScope scope(isolate_);
|
||||
@ -674,7 +649,7 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
|
||||
if (breakable_position < *source_position) return false;
|
||||
*source_position = breakable_position;
|
||||
|
||||
DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
|
||||
DebugInfo::SetBreakPoint(debug_info, *source_position, break_point);
|
||||
// At least one active break point now.
|
||||
DCHECK_LT(0, debug_info->GetBreakPointCount());
|
||||
|
||||
@ -731,16 +706,16 @@ void Debug::ClearBreakPoints(Handle<DebugInfo> debug_info) {
|
||||
}
|
||||
}
|
||||
|
||||
void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
|
||||
void Debug::ClearBreakPoint(Handle<BreakPoint> break_point) {
|
||||
HandleScope scope(isolate_);
|
||||
|
||||
for (DebugInfoListNode* node = debug_info_list_; node != nullptr;
|
||||
node = node->next()) {
|
||||
Handle<Object> result =
|
||||
DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
|
||||
DebugInfo::FindBreakPointInfo(node->debug_info(), break_point);
|
||||
if (result->IsUndefined(isolate_)) continue;
|
||||
Handle<DebugInfo> debug_info = node->debug_info();
|
||||
if (DebugInfo::ClearBreakPoint(debug_info, break_point_object)) {
|
||||
if (DebugInfo::ClearBreakPoint(debug_info, break_point)) {
|
||||
ClearBreakPoints(debug_info);
|
||||
if (debug_info->GetBreakPointCount() == 0) {
|
||||
RemoveBreakInfoAndMaybeFree(debug_info);
|
||||
@ -806,25 +781,24 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
|
||||
}
|
||||
}
|
||||
|
||||
MaybeHandle<FixedArray> Debug::GetHitBreakPointObjects(
|
||||
Handle<Object> break_point_objects) {
|
||||
DCHECK(!break_point_objects->IsUndefined(isolate_));
|
||||
if (!break_point_objects->IsFixedArray()) {
|
||||
if (!CheckBreakPoint(break_point_objects)) return {};
|
||||
MaybeHandle<FixedArray> Debug::GetHitBreakPoints(Handle<Object> break_points) {
|
||||
DCHECK(!break_points->IsUndefined(isolate_));
|
||||
if (!break_points->IsFixedArray()) {
|
||||
if (!CheckBreakPoint(Handle<BreakPoint>::cast(break_points))) return {};
|
||||
Handle<FixedArray> break_points_hit = isolate_->factory()->NewFixedArray(1);
|
||||
break_points_hit->set(0, *break_point_objects);
|
||||
break_points_hit->set(0, *break_points);
|
||||
return break_points_hit;
|
||||
}
|
||||
|
||||
Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
|
||||
Handle<FixedArray> array(FixedArray::cast(*break_points));
|
||||
int num_objects = array->length();
|
||||
Handle<FixedArray> break_points_hit =
|
||||
isolate_->factory()->NewFixedArray(num_objects);
|
||||
int break_points_hit_count = 0;
|
||||
for (int i = 0; i < num_objects; ++i) {
|
||||
Handle<Object> break_point_object(array->get(i), isolate_);
|
||||
if (CheckBreakPoint(break_point_object)) {
|
||||
break_points_hit->set(break_points_hit_count++, *break_point_object);
|
||||
Handle<Object> break_point(array->get(i), isolate_);
|
||||
if (CheckBreakPoint(Handle<BreakPoint>::cast(break_point))) {
|
||||
break_points_hit->set(break_points_hit_count++, *break_point);
|
||||
}
|
||||
}
|
||||
if (break_points_hit_count == 0) return {};
|
||||
@ -1567,14 +1541,6 @@ MaybeHandle<Object> Debug::MakeExecutionState() {
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
|
||||
// Create the new break event object.
|
||||
Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
|
||||
break_points_hit };
|
||||
return CallFunction("MakeBreakEvent", arraysize(argv), argv);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
|
||||
bool uncaught,
|
||||
Handle<Object> promise) {
|
||||
@ -1750,29 +1716,15 @@ void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit) {
|
||||
int inspector_break_points_count = 0;
|
||||
// This array contains breakpoints installed using JS debug API.
|
||||
for (int i = 0; i < break_points_hit->length(); ++i) {
|
||||
Object* break_point = break_points_hit->get(i);
|
||||
if (break_point->IsBreakPoint()) {
|
||||
inspector_break_points_hit.push_back(BreakPoint::cast(break_point)->id());
|
||||
BreakPoint* break_point = BreakPoint::cast(break_points_hit->get(i));
|
||||
inspector_break_points_hit.push_back(break_point->id());
|
||||
++inspector_break_points_count;
|
||||
} else {
|
||||
break_points_hit->set(i - inspector_break_points_count, break_point);
|
||||
}
|
||||
}
|
||||
int break_points_length =
|
||||
break_points_hit->length() - inspector_break_points_count;
|
||||
Handle<Object> break_points;
|
||||
if (break_points_length) {
|
||||
break_points_hit->Shrink(break_points_length);
|
||||
break_points = isolate_->factory()->NewJSArrayWithElements(
|
||||
break_points_hit, PACKED_ELEMENTS, break_points_length);
|
||||
} else {
|
||||
break_points = isolate_->factory()->undefined_value();
|
||||
}
|
||||
|
||||
debug_delegate_->BreakProgramRequested(
|
||||
GetDebugEventContext(isolate_),
|
||||
v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
|
||||
v8::Utils::ToLocal(break_points), inspector_break_points_hit);
|
||||
inspector_break_points_hit);
|
||||
}
|
||||
|
||||
|
||||
@ -2278,17 +2230,10 @@ void LegacyDebugDelegate::ScriptCompiled(v8::Local<v8::debug::Script> script,
|
||||
|
||||
void LegacyDebugDelegate::BreakProgramRequested(
|
||||
v8::Local<v8::Context> paused_context, v8::Local<v8::Object> exec_state,
|
||||
v8::Local<v8::Value> break_points_hit,
|
||||
const std::vector<debug::BreakpointId>&) {
|
||||
Handle<Object> event_data;
|
||||
if (isolate_->debug()
|
||||
->MakeBreakEvent(v8::Utils::OpenHandle(*break_points_hit))
|
||||
.ToHandle(&event_data)) {
|
||||
ProcessDebugEvent(
|
||||
v8::Break, Handle<JSObject>::cast(event_data),
|
||||
ProcessDebugEvent(v8::Break, isolate_->factory()->NewJSObjectWithNullProto(),
|
||||
Handle<JSObject>::cast(v8::Utils::OpenHandle(*exec_state)));
|
||||
}
|
||||
}
|
||||
|
||||
void LegacyDebugDelegate::ExceptionThrown(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
@ -2314,32 +2259,6 @@ void LegacyDebugDelegate::ProcessDebugEvent(v8::DebugEvent event,
|
||||
}
|
||||
}
|
||||
|
||||
JavaScriptDebugDelegate::JavaScriptDebugDelegate(Isolate* isolate,
|
||||
Handle<JSFunction> listener,
|
||||
Handle<Object> data)
|
||||
: LegacyDebugDelegate(isolate) {
|
||||
GlobalHandles* global_handles = isolate->global_handles();
|
||||
listener_ = global_handles->Create(*listener);
|
||||
data_ = global_handles->Create(*data);
|
||||
}
|
||||
|
||||
JavaScriptDebugDelegate::~JavaScriptDebugDelegate() {
|
||||
GlobalHandles::Destroy(Handle<Object>::cast(listener_).location());
|
||||
GlobalHandles::Destroy(data_.location());
|
||||
}
|
||||
|
||||
void JavaScriptDebugDelegate::ProcessDebugEvent(v8::DebugEvent event,
|
||||
Handle<JSObject> event_data,
|
||||
Handle<JSObject> exec_state) {
|
||||
AllowJavascriptExecutionDebugOnly allow_script(isolate_);
|
||||
Handle<Object> argv[] = {Handle<Object>(Smi::FromInt(event), isolate_),
|
||||
exec_state, event_data, data_};
|
||||
Handle<JSReceiver> global = isolate_->global_proxy();
|
||||
// Listener must not throw.
|
||||
Execution::Call(isolate_, listener_, global, arraysize(argv), argv)
|
||||
.ToHandleChecked();
|
||||
}
|
||||
|
||||
NativeDebugDelegate::NativeDebugDelegate(Isolate* isolate,
|
||||
v8::Debug::EventCallback callback,
|
||||
Handle<Object> data)
|
||||
|
@ -241,12 +241,11 @@ class Debug {
|
||||
|
||||
// Break point handling.
|
||||
bool SetBreakPoint(Handle<JSFunction> function,
|
||||
Handle<Object> break_point_object,
|
||||
int* source_position);
|
||||
Handle<BreakPoint> break_point, int* source_position);
|
||||
bool SetBreakPointForScript(Handle<Script> script,
|
||||
Handle<Object> break_point_object,
|
||||
Handle<BreakPoint> break_point,
|
||||
int* source_position);
|
||||
void ClearBreakPoint(Handle<Object> break_point_object);
|
||||
void ClearBreakPoint(Handle<BreakPoint> break_point);
|
||||
void ChangeBreakOnException(ExceptionBreakType type, bool enable);
|
||||
bool IsBreakOnException(ExceptionBreakType type);
|
||||
|
||||
@ -254,12 +253,11 @@ class Debug {
|
||||
int* offset, int* id);
|
||||
void RemoveBreakpoint(int id);
|
||||
|
||||
// The parameter is either a BreakPointInfo object, or a FixedArray of
|
||||
// BreakPointInfo objects.
|
||||
// The parameter is either a BreakPoint object, or a FixedArray of
|
||||
// BreakPoint objects.
|
||||
// Returns an empty handle if no breakpoint is hit, or a FixedArray with all
|
||||
// hit breakpoints.
|
||||
MaybeHandle<FixedArray> GetHitBreakPointObjects(
|
||||
Handle<Object> break_point_objects);
|
||||
// hit BreakPoint objects.
|
||||
MaybeHandle<FixedArray> GetHitBreakPoints(Handle<Object> break_points);
|
||||
|
||||
// Stepping handling.
|
||||
void PrepareStep(StepAction step_action);
|
||||
@ -437,8 +435,6 @@ class Debug {
|
||||
|
||||
// Constructors for debug event objects.
|
||||
MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
|
||||
MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
|
||||
Handle<Object> break_points_hit);
|
||||
MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
|
||||
Handle<Object> exception,
|
||||
bool uncaught,
|
||||
@ -472,7 +468,7 @@ class Debug {
|
||||
BreakLocation* location,
|
||||
bool* has_break_points = nullptr);
|
||||
bool IsMutedAtCurrentLocation(JavaScriptFrame* frame);
|
||||
bool CheckBreakPoint(Handle<Object> break_point_object);
|
||||
bool CheckBreakPoint(Handle<BreakPoint> break_point);
|
||||
MaybeHandle<Object> CallFunction(const char* name, int argc,
|
||||
Handle<Object> args[],
|
||||
bool catch_exceptions = true);
|
||||
@ -604,7 +600,6 @@ class LegacyDebugDelegate : public v8::debug::DebugDelegate {
|
||||
bool has_compile_error) override;
|
||||
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
v8::Local<v8::Value> break_points_hit,
|
||||
const std::vector<debug::BreakpointId>&) override;
|
||||
void ExceptionThrown(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
@ -626,20 +621,6 @@ class LegacyDebugDelegate : public v8::debug::DebugDelegate {
|
||||
Handle<JSObject> exec_state) = 0;
|
||||
};
|
||||
|
||||
class JavaScriptDebugDelegate : public LegacyDebugDelegate {
|
||||
public:
|
||||
JavaScriptDebugDelegate(Isolate* isolate, Handle<JSFunction> listener,
|
||||
Handle<Object> data);
|
||||
virtual ~JavaScriptDebugDelegate();
|
||||
|
||||
private:
|
||||
void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data,
|
||||
Handle<JSObject> exec_state) override;
|
||||
|
||||
Handle<JSFunction> listener_;
|
||||
Handle<Object> data_;
|
||||
};
|
||||
|
||||
class NativeDebugDelegate : public LegacyDebugDelegate {
|
||||
public:
|
||||
NativeDebugDelegate(Isolate* isolate, v8::Debug::EventCallback callback,
|
||||
|
@ -19,16 +19,8 @@ var ValueMirror = global.ValueMirror;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Default number of frames to include in the response to backtrace request.
|
||||
var kDefaultBacktraceLength = 10;
|
||||
|
||||
var Debug = {};
|
||||
|
||||
// Regular expression to skip "crud" at the beginning of a source line which is
|
||||
// not really code. Currently the regular expression matches whitespace and
|
||||
// comments.
|
||||
var sourceLineBeginningSkip = /^(?:\s*(?:\/\*.*?\*\/)*)*/;
|
||||
|
||||
// Debug events which can occur in the V8 JavaScript engine. These originate
|
||||
// from the API include file debug.h.
|
||||
Debug.DebugEvent = { Break: 1,
|
||||
@ -58,29 +50,12 @@ Debug.ScriptCompilationType = { Host: 0,
|
||||
Eval: 1,
|
||||
JSON: 2 };
|
||||
|
||||
// The different script break point types.
|
||||
Debug.ScriptBreakPointType = { ScriptId: 0,
|
||||
ScriptName: 1,
|
||||
ScriptRegExp: 2 };
|
||||
|
||||
function ScriptTypeFlag(type) {
|
||||
return (1 << type);
|
||||
}
|
||||
|
||||
// Globals.
|
||||
var next_response_seq = 0;
|
||||
var next_break_point_number = 1;
|
||||
var break_points = [];
|
||||
var script_break_points = [];
|
||||
var debugger_flags = {
|
||||
breakPointsActive: {
|
||||
value: true,
|
||||
getValue: function() { return this.value; },
|
||||
setValue: function(value) {
|
||||
this.value = !!value;
|
||||
%SetBreakPointsActive(this.value);
|
||||
}
|
||||
},
|
||||
breakOnCaughtException: {
|
||||
getValue: function() { return Debug.isBreakOnException(); },
|
||||
setValue: function(value) {
|
||||
@ -104,308 +79,6 @@ var debugger_flags = {
|
||||
};
|
||||
|
||||
|
||||
// Create a new break point object and add it to the list of break points.
|
||||
function MakeBreakPoint(source_position, opt_script_break_point) {
|
||||
var break_point = new BreakPoint(source_position, opt_script_break_point);
|
||||
break_points.push(break_point);
|
||||
return break_point;
|
||||
}
|
||||
|
||||
|
||||
// Object representing a break point.
|
||||
// NOTE: This object does not have a reference to the function having break
|
||||
// point as this would cause function not to be garbage collected when it is
|
||||
// not used any more. We do not want break points to keep functions alive.
|
||||
function BreakPoint(source_position, opt_script_break_point) {
|
||||
this.source_position_ = source_position;
|
||||
if (opt_script_break_point) {
|
||||
this.script_break_point_ = opt_script_break_point;
|
||||
} else {
|
||||
this.number_ = next_break_point_number++;
|
||||
}
|
||||
this.active_ = true;
|
||||
this.condition_ = null;
|
||||
}
|
||||
|
||||
|
||||
BreakPoint.prototype.number = function() {
|
||||
return this.number_;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.func = function() {
|
||||
return this.func_;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.source_position = function() {
|
||||
return this.source_position_;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.active = function() {
|
||||
if (this.script_break_point()) {
|
||||
return this.script_break_point().active();
|
||||
}
|
||||
return this.active_;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.condition = function() {
|
||||
if (this.script_break_point() && this.script_break_point().condition()) {
|
||||
return this.script_break_point().condition();
|
||||
}
|
||||
return this.condition_;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.script_break_point = function() {
|
||||
return this.script_break_point_;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.enable = function() {
|
||||
this.active_ = true;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.disable = function() {
|
||||
this.active_ = false;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.setCondition = function(condition) {
|
||||
this.condition_ = condition;
|
||||
};
|
||||
|
||||
|
||||
BreakPoint.prototype.isTriggered = function(exec_state) {
|
||||
// Break point not active - not triggered.
|
||||
if (!this.active()) return false;
|
||||
|
||||
// Check for conditional break point.
|
||||
if (this.condition()) {
|
||||
// If break point has condition try to evaluate it in the top frame.
|
||||
try {
|
||||
var mirror = exec_state.frame(0).evaluate(this.condition());
|
||||
// If no sensible mirror or non true value break point not triggered.
|
||||
if (!(mirror instanceof ValueMirror) || !mirror.value_) {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
// Exception evaluating condition counts as not triggered.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Break point triggered.
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
// Function called from the runtime when a break point is hit. Returns true if
|
||||
// the break point is triggered and supposed to break execution.
|
||||
function IsBreakPointTriggered(break_id, break_point) {
|
||||
return break_point.isTriggered(MakeExecutionState(break_id));
|
||||
}
|
||||
|
||||
|
||||
// Object representing a script break point. The script is referenced by its
|
||||
// script name or script id and the break point is represented as line and
|
||||
// column.
|
||||
function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
|
||||
opt_groupId) {
|
||||
this.type_ = type;
|
||||
if (type == Debug.ScriptBreakPointType.ScriptId) {
|
||||
this.script_id_ = script_id_or_name;
|
||||
} else if (type == Debug.ScriptBreakPointType.ScriptName) {
|
||||
this.script_name_ = script_id_or_name;
|
||||
} else if (type == Debug.ScriptBreakPointType.ScriptRegExp) {
|
||||
this.script_regexp_object_ = new GlobalRegExp(script_id_or_name);
|
||||
} else {
|
||||
throw %make_error(kDebugger, "Unexpected breakpoint type " + type);
|
||||
}
|
||||
this.line_ = opt_line || 0;
|
||||
this.column_ = opt_column;
|
||||
this.groupId_ = opt_groupId;
|
||||
this.active_ = true;
|
||||
this.condition_ = null;
|
||||
this.break_points_ = [];
|
||||
}
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.number = function() {
|
||||
return this.number_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.groupId = function() {
|
||||
return this.groupId_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.type = function() {
|
||||
return this.type_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.script_id = function() {
|
||||
return this.script_id_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.script_name = function() {
|
||||
return this.script_name_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.script_regexp_object = function() {
|
||||
return this.script_regexp_object_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.line = function() {
|
||||
return this.line_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.column = function() {
|
||||
return this.column_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.actual_locations = function() {
|
||||
var locations = [];
|
||||
for (var i = 0; i < this.break_points_.length; i++) {
|
||||
locations.push(this.break_points_[i].actual_location);
|
||||
}
|
||||
return locations;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.update_positions = function(line, column) {
|
||||
this.line_ = line;
|
||||
this.column_ = column;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.active = function() {
|
||||
return this.active_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.condition = function() {
|
||||
return this.condition_;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.enable = function() {
|
||||
this.active_ = true;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.disable = function() {
|
||||
this.active_ = false;
|
||||
};
|
||||
|
||||
|
||||
ScriptBreakPoint.prototype.setCondition = function(condition) {
|
||||
this.condition_ = condition;
|
||||
};
|
||||
|
||||
|
||||
// Check whether a script matches this script break point. Currently this is
|
||||
// only based on script name.
|
||||
ScriptBreakPoint.prototype.matchesScript = function(script) {
|
||||
if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
|
||||
return this.script_id_ == script.id;
|
||||
} else {
|
||||
// We might want to account columns here as well.
|
||||
if (!(script.line_offset <= this.line_ &&
|
||||
this.line_ < script.line_offset + %ScriptLineCount(script))) {
|
||||
return false;
|
||||
}
|
||||
if (this.type_ == Debug.ScriptBreakPointType.ScriptName) {
|
||||
return this.script_name_ == script.nameOrSourceURL();
|
||||
} else if (this.type_ == Debug.ScriptBreakPointType.ScriptRegExp) {
|
||||
return this.script_regexp_object_.test(script.nameOrSourceURL());
|
||||
} else {
|
||||
throw %make_error(kDebugger, "Unexpected breakpoint type " + this.type_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Set the script break point in a script.
|
||||
ScriptBreakPoint.prototype.set = function (script) {
|
||||
var column = this.column();
|
||||
var line = this.line();
|
||||
// If the column is undefined the break is on the line. To help locate the
|
||||
// first piece of breakable code on the line try to find the column on the
|
||||
// line which contains some source.
|
||||
if (IS_UNDEFINED(column)) {
|
||||
var source_line = %ScriptSourceLine(script, line || script.line_offset);
|
||||
|
||||
// Allocate array for caching the columns where the actual source starts.
|
||||
if (!script.sourceColumnStart_) {
|
||||
script.sourceColumnStart_ = new GlobalArray(%ScriptLineCount(script));
|
||||
}
|
||||
|
||||
// Fill cache if needed and get column where the actual source starts.
|
||||
if (IS_UNDEFINED(script.sourceColumnStart_[line])) {
|
||||
script.sourceColumnStart_[line] =
|
||||
source_line.match(sourceLineBeginningSkip)[0].length;
|
||||
}
|
||||
column = script.sourceColumnStart_[line];
|
||||
}
|
||||
|
||||
// Convert the line and column into an absolute position within the script.
|
||||
var position = Debug.findScriptSourcePosition(script, this.line(), column);
|
||||
|
||||
// If the position is not found in the script (the script might be shorter
|
||||
// than it used to be) just ignore it.
|
||||
if (IS_NULL(position)) return;
|
||||
|
||||
// Create a break point object and set the break point.
|
||||
var break_point = MakeBreakPoint(position, this);
|
||||
var actual_position = %SetScriptBreakPoint(script, position,
|
||||
break_point);
|
||||
if (IS_UNDEFINED(actual_position)) {
|
||||
actual_position = position;
|
||||
}
|
||||
var actual_location = script.locationFromPosition(actual_position, true);
|
||||
break_point.actual_location = { line: actual_location.line,
|
||||
column: actual_location.column,
|
||||
script_id: script.id };
|
||||
this.break_points_.push(break_point);
|
||||
return break_point;
|
||||
};
|
||||
|
||||
|
||||
// Clear all the break points created from this script break point
|
||||
ScriptBreakPoint.prototype.clear = function () {
|
||||
var remaining_break_points = [];
|
||||
for (var i = 0; i < break_points.length; i++) {
|
||||
if (break_points[i].script_break_point() &&
|
||||
break_points[i].script_break_point() === this) {
|
||||
%ClearBreakPoint(break_points[i]);
|
||||
} else {
|
||||
remaining_break_points.push(break_points[i]);
|
||||
}
|
||||
}
|
||||
break_points = remaining_break_points;
|
||||
this.break_points_ = [];
|
||||
};
|
||||
|
||||
|
||||
Debug.setListener = function(listener, opt_data) {
|
||||
if (!IS_FUNCTION(listener) && !IS_UNDEFINED(listener) && !IS_NULL(listener)) {
|
||||
throw %make_type_error(kDebuggerType);
|
||||
}
|
||||
%SetDebugEventListener(listener, opt_data);
|
||||
};
|
||||
|
||||
|
||||
// Returns a Script object. If the parameter is a function the return value
|
||||
// is the script in which the function is defined. If the parameter is a string
|
||||
// the return value is the script for which the script name has that string
|
||||
@ -475,246 +148,6 @@ Debug.findScriptSourcePosition = function(script, opt_line, opt_column) {
|
||||
return location ? location.position : null;
|
||||
};
|
||||
|
||||
|
||||
Debug.findBreakPoint = function(break_point_number, remove) {
|
||||
var break_point;
|
||||
for (var i = 0; i < break_points.length; i++) {
|
||||
if (break_points[i].number() == break_point_number) {
|
||||
break_point = break_points[i];
|
||||
// Remove the break point from the list if requested.
|
||||
if (remove) {
|
||||
break_points.splice(i, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (break_point) {
|
||||
return break_point;
|
||||
} else {
|
||||
return this.findScriptBreakPoint(break_point_number, remove);
|
||||
}
|
||||
};
|
||||
|
||||
Debug.findBreakPointActualLocations = function(break_point_number) {
|
||||
for (var i = 0; i < script_break_points.length; i++) {
|
||||
if (script_break_points[i].number() == break_point_number) {
|
||||
return script_break_points[i].actual_locations();
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < break_points.length; i++) {
|
||||
if (break_points[i].number() == break_point_number) {
|
||||
return [break_points[i].actual_location];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
|
||||
if (!IS_FUNCTION(func)) throw %make_type_error(kDebuggerType);
|
||||
// Break points in API functions are not supported.
|
||||
if (%FunctionIsAPIFunction(func)) {
|
||||
throw %make_error(kDebugger, 'Cannot set break point in native code.');
|
||||
}
|
||||
// Find source position.
|
||||
var source_position =
|
||||
this.findFunctionSourceLocation(func, opt_line, opt_column).position;
|
||||
// Find the script for the function.
|
||||
var script = %FunctionGetScript(func);
|
||||
// Break in builtin JavaScript code is not supported.
|
||||
if (script.type == Debug.ScriptType.Native) {
|
||||
throw %make_error(kDebugger, 'Cannot set break point in native code.');
|
||||
}
|
||||
// If the script for the function has a name convert this to a script break
|
||||
// point.
|
||||
if (script && script.id) {
|
||||
// Find line and column for the position in the script and set a script
|
||||
// break point from that.
|
||||
var location = script.locationFromPosition(source_position, false);
|
||||
return this.setScriptBreakPointById(script.id,
|
||||
location.line, location.column,
|
||||
opt_condition);
|
||||
} else {
|
||||
// Set a break point directly on the function.
|
||||
var break_point = MakeBreakPoint(source_position);
|
||||
var actual_position =
|
||||
%SetFunctionBreakPoint(func, source_position, break_point);
|
||||
var actual_location = script.locationFromPosition(actual_position, true);
|
||||
break_point.actual_location = { line: actual_location.line,
|
||||
column: actual_location.column,
|
||||
script_id: script.id };
|
||||
break_point.setCondition(opt_condition);
|
||||
return break_point.number();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Debug.setBreakPointByScriptIdAndPosition = function(script_id, position,
|
||||
condition, enabled)
|
||||
{
|
||||
var break_point = MakeBreakPoint(position);
|
||||
break_point.setCondition(condition);
|
||||
if (!enabled) {
|
||||
break_point.disable();
|
||||
}
|
||||
var script = scriptById(script_id);
|
||||
if (script) {
|
||||
break_point.actual_position = %SetScriptBreakPoint(script, position, break_point);
|
||||
}
|
||||
return break_point;
|
||||
};
|
||||
|
||||
|
||||
Debug.enableBreakPoint = function(break_point_number) {
|
||||
var break_point = this.findBreakPoint(break_point_number, false);
|
||||
// Only enable if the breakpoint hasn't been deleted:
|
||||
if (break_point) {
|
||||
break_point.enable();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Debug.disableBreakPoint = function(break_point_number) {
|
||||
var break_point = this.findBreakPoint(break_point_number, false);
|
||||
// Only enable if the breakpoint hasn't been deleted:
|
||||
if (break_point) {
|
||||
break_point.disable();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Debug.changeBreakPointCondition = function(break_point_number, condition) {
|
||||
var break_point = this.findBreakPoint(break_point_number, false);
|
||||
break_point.setCondition(condition);
|
||||
};
|
||||
|
||||
|
||||
Debug.clearBreakPoint = function(break_point_number) {
|
||||
var break_point = this.findBreakPoint(break_point_number, true);
|
||||
if (break_point) {
|
||||
return %ClearBreakPoint(break_point);
|
||||
} else {
|
||||
break_point = this.findScriptBreakPoint(break_point_number, true);
|
||||
if (!break_point) throw %make_error(kDebugger, 'Invalid breakpoint');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Debug.clearAllBreakPoints = function() {
|
||||
for (var i = 0; i < break_points.length; i++) {
|
||||
var break_point = break_points[i];
|
||||
%ClearBreakPoint(break_point);
|
||||
}
|
||||
break_points = [];
|
||||
};
|
||||
|
||||
|
||||
Debug.disableAllBreakPoints = function() {
|
||||
// Disable all user defined breakpoints:
|
||||
for (var i = 1; i < next_break_point_number; i++) {
|
||||
Debug.disableBreakPoint(i);
|
||||
}
|
||||
// Disable all exception breakpoints:
|
||||
%ChangeBreakOnException(Debug.ExceptionBreak.Caught, false);
|
||||
%ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, false);
|
||||
};
|
||||
|
||||
|
||||
Debug.findScriptBreakPoint = function(break_point_number, remove) {
|
||||
var script_break_point;
|
||||
for (var i = 0; i < script_break_points.length; i++) {
|
||||
if (script_break_points[i].number() == break_point_number) {
|
||||
script_break_point = script_break_points[i];
|
||||
// Remove the break point from the list if requested.
|
||||
if (remove) {
|
||||
script_break_point.clear();
|
||||
script_break_points.splice(i,1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return script_break_point;
|
||||
};
|
||||
|
||||
|
||||
// Sets a breakpoint in a script identified through id or name at the
|
||||
// specified source line and column within that line.
|
||||
Debug.setScriptBreakPoint = function(type, script_id_or_name,
|
||||
opt_line, opt_column, opt_condition,
|
||||
opt_groupId) {
|
||||
// Create script break point object.
|
||||
var script_break_point =
|
||||
new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
|
||||
opt_groupId);
|
||||
|
||||
// Assign number to the new script break point and add it.
|
||||
script_break_point.number_ = next_break_point_number++;
|
||||
script_break_point.setCondition(opt_condition);
|
||||
script_break_points.push(script_break_point);
|
||||
|
||||
// Run through all scripts to see if this script break point matches any
|
||||
// loaded scripts.
|
||||
var scripts = this.scripts();
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
if (script_break_point.matchesScript(scripts[i])) {
|
||||
script_break_point.set(scripts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return script_break_point.number();
|
||||
};
|
||||
|
||||
|
||||
Debug.setScriptBreakPointById = function(script_id,
|
||||
opt_line, opt_column,
|
||||
opt_condition, opt_groupId) {
|
||||
return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
|
||||
script_id, opt_line, opt_column,
|
||||
opt_condition, opt_groupId);
|
||||
};
|
||||
|
||||
|
||||
Debug.setScriptBreakPointByName = function(script_name,
|
||||
opt_line, opt_column,
|
||||
opt_condition, opt_groupId) {
|
||||
return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptName,
|
||||
script_name, opt_line, opt_column,
|
||||
opt_condition, opt_groupId);
|
||||
};
|
||||
|
||||
|
||||
Debug.setScriptBreakPointByRegExp = function(script_regexp,
|
||||
opt_line, opt_column,
|
||||
opt_condition, opt_groupId) {
|
||||
return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptRegExp,
|
||||
script_regexp, opt_line, opt_column,
|
||||
opt_condition, opt_groupId);
|
||||
};
|
||||
|
||||
|
||||
Debug.enableScriptBreakPoint = function(break_point_number) {
|
||||
var script_break_point = this.findScriptBreakPoint(break_point_number, false);
|
||||
script_break_point.enable();
|
||||
};
|
||||
|
||||
|
||||
Debug.disableScriptBreakPoint = function(break_point_number) {
|
||||
var script_break_point = this.findScriptBreakPoint(break_point_number, false);
|
||||
script_break_point.disable();
|
||||
};
|
||||
|
||||
|
||||
Debug.changeScriptBreakPointCondition = function(
|
||||
break_point_number, condition) {
|
||||
var script_break_point = this.findScriptBreakPoint(break_point_number, false);
|
||||
script_break_point.setCondition(condition);
|
||||
};
|
||||
|
||||
|
||||
Debug.scriptBreakPoints = function() {
|
||||
return script_break_points;
|
||||
};
|
||||
|
||||
|
||||
Debug.clearStepping = function() {
|
||||
%ClearStepping();
|
||||
};
|
||||
@ -743,28 +176,6 @@ Debug.isBreakOnUncaughtException = function() {
|
||||
return !!%IsBreakOnException(Debug.ExceptionBreak.Uncaught);
|
||||
};
|
||||
|
||||
Debug.showBreakPoints = function(f, full) {
|
||||
if (!IS_FUNCTION(f)) throw %make_error(kDebuggerType);
|
||||
var source = full ? this.scriptSource(f) : this.source(f);
|
||||
var offset = full ? 0 : this.sourcePosition(f);
|
||||
var locations = %GetBreakLocations(f);
|
||||
if (!locations) return source;
|
||||
locations.sort(function(x, y) { return x - y; });
|
||||
var result = "";
|
||||
var prev_pos = 0;
|
||||
var pos;
|
||||
for (var i = 0; i < locations.length; i++) {
|
||||
pos = locations[i] - offset;
|
||||
result += source.slice(prev_pos, pos);
|
||||
result += "[B" + i + "]";
|
||||
prev_pos = pos;
|
||||
}
|
||||
pos = source.length;
|
||||
result += source.substring(prev_pos, pos);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// Get all the scripts currently loaded. Locating all the scripts is based on
|
||||
// scanning the heap.
|
||||
Debug.scripts = function() {
|
||||
@ -837,46 +248,6 @@ ExecutionState.prototype.selectedFrame = function() {
|
||||
return this.selected_frame;
|
||||
};
|
||||
|
||||
function MakeBreakEvent(break_id, break_points_hit) {
|
||||
return new BreakEvent(break_id, break_points_hit);
|
||||
}
|
||||
|
||||
|
||||
function BreakEvent(break_id, break_points_hit) {
|
||||
this.frame_ = new FrameMirror(break_id, 0);
|
||||
this.break_points_hit_ = break_points_hit;
|
||||
}
|
||||
|
||||
|
||||
BreakEvent.prototype.eventType = function() {
|
||||
return Debug.DebugEvent.Break;
|
||||
};
|
||||
|
||||
|
||||
BreakEvent.prototype.func = function() {
|
||||
return this.frame_.func();
|
||||
};
|
||||
|
||||
|
||||
BreakEvent.prototype.sourceLine = function() {
|
||||
return this.frame_.sourceLine();
|
||||
};
|
||||
|
||||
|
||||
BreakEvent.prototype.sourceColumn = function() {
|
||||
return this.frame_.sourceColumn();
|
||||
};
|
||||
|
||||
|
||||
BreakEvent.prototype.sourceLineText = function() {
|
||||
return this.frame_.sourceLineText();
|
||||
};
|
||||
|
||||
|
||||
BreakEvent.prototype.breakPointsHit = function() {
|
||||
return this.break_points_hit_;
|
||||
};
|
||||
|
||||
|
||||
function MakeExceptionEvent(break_id, exception, uncaught, promise) {
|
||||
return new ExceptionEvent(break_id, exception, uncaught, promise);
|
||||
@ -994,19 +365,15 @@ AsyncTaskEvent.prototype.id = function() {
|
||||
|
||||
utils.InstallConstants(global, [
|
||||
"Debug", Debug,
|
||||
"BreakEvent", BreakEvent,
|
||||
"CompileEvent", CompileEvent,
|
||||
"BreakPoint", BreakPoint,
|
||||
]);
|
||||
|
||||
// Functions needed by the debugger runtime.
|
||||
utils.InstallConstants(utils, [
|
||||
"MakeExecutionState", MakeExecutionState,
|
||||
"MakeExceptionEvent", MakeExceptionEvent,
|
||||
"MakeBreakEvent", MakeBreakEvent,
|
||||
"MakeCompileEvent", MakeCompileEvent,
|
||||
"MakeAsyncTaskEvent", MakeAsyncTaskEvent,
|
||||
"IsBreakPointTriggered", IsBreakPointTriggered,
|
||||
]);
|
||||
|
||||
})
|
||||
|
@ -2717,7 +2717,7 @@ Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
|
||||
Handle<BreakPointInfo> new_break_point_info =
|
||||
Handle<BreakPointInfo>::cast(NewStruct(TUPLE2_TYPE, TENURED));
|
||||
new_break_point_info->set_source_position(source_position);
|
||||
new_break_point_info->set_break_point_objects(*undefined_value());
|
||||
new_break_point_info->set_break_points(*undefined_value());
|
||||
return new_break_point_info;
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,6 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
|
||||
|
||||
void V8Debugger::BreakProgramRequested(
|
||||
v8::Local<v8::Context> pausedContext, v8::Local<v8::Object>,
|
||||
v8::Local<v8::Value>,
|
||||
const std::vector<v8::debug::BreakpointId>& break_points_hit) {
|
||||
handleProgramBreak(pausedContext, v8::Local<v8::Value>(), break_points_hit);
|
||||
}
|
||||
|
@ -169,7 +169,6 @@ class V8Debugger : public v8::debug::DebugDelegate {
|
||||
bool has_compile_error) override;
|
||||
void BreakProgramRequested(
|
||||
v8::Local<v8::Context> paused_context, v8::Local<v8::Object>,
|
||||
v8::Local<v8::Value>,
|
||||
const std::vector<v8::debug::BreakpointId>& break_points_hit) override;
|
||||
void ExceptionThrown(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object>, v8::Local<v8::Value> exception,
|
||||
|
@ -28,7 +28,7 @@ ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateOffset)
|
||||
ACCESSORS(DebugInfo, coverage_info, Object, kCoverageInfoOffset)
|
||||
|
||||
SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionOffset)
|
||||
ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsOffset)
|
||||
ACCESSORS(BreakPointInfo, break_points, Object, kBreakPointsOffset)
|
||||
|
||||
SMI_ACCESSORS(BreakPoint, id, kIdOffset)
|
||||
ACCESSORS(BreakPoint, condition, String, kConditionOffset)
|
||||
|
@ -76,7 +76,7 @@ Object* DebugInfo::GetBreakPointInfo(int source_position) {
|
||||
}
|
||||
|
||||
bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Handle<BreakPoint> break_point) {
|
||||
DCHECK(debug_info->HasBreakInfo());
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
|
||||
@ -84,9 +84,8 @@ bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue;
|
||||
Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
|
||||
BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
|
||||
if (BreakPointInfo::HasBreakPointObject(break_point_info,
|
||||
break_point_object)) {
|
||||
BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object);
|
||||
if (BreakPointInfo::HasBreakPoint(break_point_info, break_point)) {
|
||||
BreakPointInfo::ClearBreakPoint(break_point_info, break_point);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -94,14 +93,14 @@ bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
}
|
||||
|
||||
void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
Handle<Object> break_point_object) {
|
||||
Handle<BreakPoint> break_point) {
|
||||
DCHECK(debug_info->HasBreakInfo());
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
Handle<Object> break_point_info(
|
||||
debug_info->GetBreakPointInfo(source_position), isolate);
|
||||
if (!break_point_info->IsUndefined(isolate)) {
|
||||
BreakPointInfo::SetBreakPoint(
|
||||
Handle<BreakPointInfo>::cast(break_point_info), break_point_object);
|
||||
Handle<BreakPointInfo>::cast(break_point_info), break_point);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -117,8 +116,8 @@ void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
}
|
||||
if (index == kNoBreakPointInfo) {
|
||||
// No free slot - extend break point info array.
|
||||
Handle<FixedArray> old_break_points = Handle<FixedArray>(
|
||||
FixedArray::cast(debug_info->break_points()), isolate);
|
||||
Handle<FixedArray> old_break_points =
|
||||
Handle<FixedArray>(debug_info->break_points(), isolate);
|
||||
Handle<FixedArray> new_break_points = isolate->factory()->NewFixedArray(
|
||||
old_break_points->length() +
|
||||
DebugInfo::kEstimatedNofBreakPointsInFunction);
|
||||
@ -134,20 +133,20 @@ void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
// Allocate new BreakPointInfo object and set the break point.
|
||||
Handle<BreakPointInfo> new_break_point_info =
|
||||
isolate->factory()->NewBreakPointInfo(source_position);
|
||||
BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
|
||||
BreakPointInfo::SetBreakPoint(new_break_point_info, break_point);
|
||||
debug_info->break_points()->set(index, *new_break_point_info);
|
||||
}
|
||||
|
||||
// Get the break point objects for a source position.
|
||||
Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) {
|
||||
Handle<Object> DebugInfo::GetBreakPoints(int source_position) {
|
||||
DCHECK(HasBreakInfo());
|
||||
Object* break_point_info = GetBreakPointInfo(source_position);
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (break_point_info->IsUndefined(isolate)) {
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
return Handle<Object>(
|
||||
BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate);
|
||||
return Handle<Object>(BreakPointInfo::cast(break_point_info)->break_points(),
|
||||
isolate);
|
||||
}
|
||||
|
||||
// Get the total number of break points.
|
||||
@ -165,16 +164,15 @@ int DebugInfo::GetBreakPointCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
Handle<Object> DebugInfo::FindBreakPointInfo(
|
||||
Handle<DebugInfo> debug_info, Handle<Object> break_point_object) {
|
||||
Handle<Object> DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info,
|
||||
Handle<BreakPoint> break_point) {
|
||||
DCHECK(debug_info->HasBreakInfo());
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
|
||||
Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
|
||||
BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
|
||||
if (BreakPointInfo::HasBreakPointObject(break_point_info,
|
||||
break_point_object)) {
|
||||
if (BreakPointInfo::HasBreakPoint(break_point_info, break_point)) {
|
||||
return break_point_info;
|
||||
}
|
||||
}
|
||||
@ -199,40 +197,34 @@ bool DebugInfo::ClearCoverageInfo() {
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool IsEqual(Object* break_point1, Object* break_point2) {
|
||||
// TODO(kozyatinskiy): remove non-BreakPoint logic once the JS debug API has
|
||||
// been removed.
|
||||
if (break_point1->IsBreakPoint() != break_point2->IsBreakPoint())
|
||||
return false;
|
||||
if (!break_point1->IsBreakPoint()) return break_point1 == break_point2;
|
||||
return BreakPoint::cast(break_point1)->id() ==
|
||||
BreakPoint::cast(break_point2)->id();
|
||||
bool IsEqual(BreakPoint* break_point1, BreakPoint* break_point2) {
|
||||
return break_point1->id() == break_point2->id();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Remove the specified break point object.
|
||||
void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Handle<BreakPoint> break_point) {
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
// If there are no break points just ignore.
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) return;
|
||||
if (break_point_info->break_points()->IsUndefined(isolate)) return;
|
||||
// If there is a single break point clear it if it is the same.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
if (IsEqual(break_point_info->break_point_objects(), *break_point_object)) {
|
||||
break_point_info->set_break_point_objects(
|
||||
isolate->heap()->undefined_value());
|
||||
if (!break_point_info->break_points()->IsFixedArray()) {
|
||||
if (IsEqual(BreakPoint::cast(break_point_info->break_points()),
|
||||
*break_point)) {
|
||||
break_point_info->set_break_points(isolate->heap()->undefined_value());
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If there are multiple break points shrink the array
|
||||
DCHECK(break_point_info->break_point_objects()->IsFixedArray());
|
||||
Handle<FixedArray> old_array = Handle<FixedArray>(
|
||||
FixedArray::cast(break_point_info->break_point_objects()));
|
||||
DCHECK(break_point_info->break_points()->IsFixedArray());
|
||||
Handle<FixedArray> old_array =
|
||||
Handle<FixedArray>(FixedArray::cast(break_point_info->break_points()));
|
||||
Handle<FixedArray> new_array =
|
||||
isolate->factory()->NewFixedArray(old_array->length() - 1);
|
||||
int found_count = 0;
|
||||
for (int i = 0; i < old_array->length(); i++) {
|
||||
if (IsEqual(old_array->get(i), *break_point_object)) {
|
||||
if (IsEqual(BreakPoint::cast(old_array->get(i)), *break_point)) {
|
||||
DCHECK_EQ(found_count, 0);
|
||||
found_count++;
|
||||
} else {
|
||||
@ -240,61 +232,60 @@ void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
}
|
||||
}
|
||||
// If the break point was found in the list change it.
|
||||
if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
|
||||
if (found_count > 0) break_point_info->set_break_points(*new_array);
|
||||
}
|
||||
|
||||
// Add the specified break point object.
|
||||
void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Handle<BreakPoint> break_point) {
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
|
||||
// If there was no break point objects before just set it.
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
|
||||
break_point_info->set_break_point_objects(*break_point_object);
|
||||
if (break_point_info->break_points()->IsUndefined(isolate)) {
|
||||
break_point_info->set_break_points(*break_point);
|
||||
return;
|
||||
}
|
||||
// If the break point object is the same as before just ignore.
|
||||
if (break_point_info->break_point_objects() == *break_point_object) return;
|
||||
if (break_point_info->break_points() == *break_point) return;
|
||||
// If there was one break point object before replace with array.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
if (!break_point_info->break_points()->IsFixedArray()) {
|
||||
Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
|
||||
array->set(0, break_point_info->break_point_objects());
|
||||
array->set(1, *break_point_object);
|
||||
break_point_info->set_break_point_objects(*array);
|
||||
array->set(0, break_point_info->break_points());
|
||||
array->set(1, *break_point);
|
||||
break_point_info->set_break_points(*array);
|
||||
return;
|
||||
}
|
||||
// If there was more than one break point before extend array.
|
||||
Handle<FixedArray> old_array = Handle<FixedArray>(
|
||||
FixedArray::cast(break_point_info->break_point_objects()));
|
||||
Handle<FixedArray> old_array =
|
||||
Handle<FixedArray>(FixedArray::cast(break_point_info->break_points()));
|
||||
Handle<FixedArray> new_array =
|
||||
isolate->factory()->NewFixedArray(old_array->length() + 1);
|
||||
for (int i = 0; i < old_array->length(); i++) {
|
||||
// If the break point was there before just ignore.
|
||||
if (IsEqual(old_array->get(i), *break_point_object)) return;
|
||||
if (IsEqual(BreakPoint::cast(old_array->get(i)), *break_point)) return;
|
||||
new_array->set(i, old_array->get(i));
|
||||
}
|
||||
// Add the new break point.
|
||||
new_array->set(old_array->length(), *break_point_object);
|
||||
break_point_info->set_break_point_objects(*new_array);
|
||||
new_array->set(old_array->length(), *break_point);
|
||||
break_point_info->set_break_points(*new_array);
|
||||
}
|
||||
|
||||
bool BreakPointInfo::HasBreakPointObject(
|
||||
Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
bool BreakPointInfo::HasBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<BreakPoint> break_point) {
|
||||
// No break point.
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
|
||||
if (break_point_info->break_points()->IsUndefined(isolate)) {
|
||||
return false;
|
||||
}
|
||||
// Single break point.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
return IsEqual(break_point_info->break_point_objects(),
|
||||
*break_point_object);
|
||||
if (!break_point_info->break_points()->IsFixedArray()) {
|
||||
return IsEqual(BreakPoint::cast(break_point_info->break_points()),
|
||||
*break_point);
|
||||
}
|
||||
// Multiple break points.
|
||||
FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
|
||||
FixedArray* array = FixedArray::cast(break_point_info->break_points());
|
||||
for (int i = 0; i < array->length(); i++) {
|
||||
if (IsEqual(array->get(i), *break_point_object)) {
|
||||
if (IsEqual(BreakPoint::cast(array->get(i)), *break_point)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -304,11 +295,11 @@ bool BreakPointInfo::HasBreakPointObject(
|
||||
// Get the number of break points.
|
||||
int BreakPointInfo::GetBreakPointCount() {
|
||||
// No break point.
|
||||
if (break_point_objects()->IsUndefined(GetIsolate())) return 0;
|
||||
if (break_points()->IsUndefined(GetIsolate())) return 0;
|
||||
// Single break point.
|
||||
if (!break_point_objects()->IsFixedArray()) return 1;
|
||||
if (!break_points()->IsFixedArray()) return 1;
|
||||
// Multiple break points.
|
||||
return FixedArray::cast(break_point_objects())->length();
|
||||
return FixedArray::cast(break_points())->length();
|
||||
}
|
||||
|
||||
int CoverageInfo::SlotCount() const {
|
||||
|
@ -14,6 +14,7 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class BreakPoint;
|
||||
class BytecodeArray;
|
||||
|
||||
// The DebugInfo class holds additional information for a function being
|
||||
@ -69,15 +70,15 @@ class DebugInfo : public Struct {
|
||||
bool HasBreakPoint(int source_position);
|
||||
// Attempt to clear a break point. Return true if successful.
|
||||
static bool ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
// Set a break point.
|
||||
static void SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
// Get the break point objects for a source position.
|
||||
Handle<Object> GetBreakPointObjects(int source_position);
|
||||
Handle<Object> GetBreakPoints(int source_position);
|
||||
// Find the break point info holding this break point object.
|
||||
static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
// Get the number of break points for this function.
|
||||
int GetBreakPointCount();
|
||||
|
||||
@ -134,17 +135,17 @@ class BreakPointInfo : public Tuple2 {
|
||||
// The position in the source for the break position.
|
||||
DECL_INT_ACCESSORS(source_position)
|
||||
// List of related JavaScript break points.
|
||||
DECL_ACCESSORS(break_point_objects, Object)
|
||||
DECL_ACCESSORS(break_points, Object)
|
||||
|
||||
// Removes a break point.
|
||||
static void ClearBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
// Set a break point.
|
||||
static void SetBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Check if break point info has this break point object.
|
||||
static bool HasBreakPointObject(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
// Check if break point info has this break point.
|
||||
static bool HasBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<BreakPoint> break_point);
|
||||
// Get the number of break points for this code offset.
|
||||
int GetBreakPointCount();
|
||||
|
||||
@ -153,7 +154,7 @@ class BreakPointInfo : public Tuple2 {
|
||||
DECL_CAST(BreakPointInfo)
|
||||
|
||||
static const int kSourcePositionOffset = kValue1Offset;
|
||||
static const int kBreakPointObjectsOffset = kValue2Offset;
|
||||
static const int kBreakPointsOffset = kValue2Offset;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
|
||||
|
@ -85,27 +85,6 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
|
||||
}
|
||||
|
||||
|
||||
// Adds a JavaScript function as a debug event listener.
|
||||
// args[0]: debug event listener function to set or null or undefined for
|
||||
// clearing the event listener function
|
||||
// args[1]: object supplied during callback
|
||||
RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(2, args.length());
|
||||
CHECK(args[0]->IsJSFunction() || args[0]->IsNullOrUndefined(isolate));
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
|
||||
if (callback->IsJSFunction()) {
|
||||
JavaScriptDebugDelegate* delegate = new JavaScriptDebugDelegate(
|
||||
isolate, Handle<JSFunction>::cast(callback), data);
|
||||
isolate->debug()->SetDebugDelegate(delegate, true);
|
||||
} else {
|
||||
isolate->debug()->SetDebugDelegate(nullptr, false);
|
||||
}
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ScheduleBreak) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(0, args.length());
|
||||
@ -1041,16 +1020,6 @@ RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
|
||||
return isolate->heap()->ToBoolean(res);
|
||||
}
|
||||
|
||||
// Sets the disable break state
|
||||
// args[0]: disable break state
|
||||
RUNTIME_FUNCTION(Runtime_SetBreakPointsActive) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_BOOLEAN_ARG_CHECKED(active, 0);
|
||||
isolate->debug()->set_break_points_active(active);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
|
||||
HandleScope scope(isolate);
|
||||
@ -1070,71 +1039,6 @@ RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
|
||||
}
|
||||
|
||||
|
||||
// Set a break point in a function.
|
||||
// args[0]: function
|
||||
// args[1]: number: break source position (within the function source)
|
||||
// args[2]: number: break point object
|
||||
RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(3, args.length());
|
||||
CHECK(isolate->debug()->is_active());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
||||
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
|
||||
CHECK(source_position >= function->shared()->start_position() &&
|
||||
source_position <= function->shared()->end_position());
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
|
||||
|
||||
// Set break point.
|
||||
CHECK(isolate->debug()->SetBreakPoint(function, break_point_object_arg,
|
||||
&source_position));
|
||||
|
||||
return Smi::FromInt(source_position);
|
||||
}
|
||||
|
||||
// Changes the state of a break point in a script and returns source position
|
||||
// where break point was set. NOTE: Regarding performance see the NOTE for
|
||||
// GetScriptFromScriptData.
|
||||
// args[0]: script to set break point in
|
||||
// args[1]: number: break source position (within the script source)
|
||||
// args[2]: number: break point object
|
||||
RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(3, args.length());
|
||||
CHECK(isolate->debug()->is_active());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
|
||||
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
|
||||
CHECK_GE(source_position, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
|
||||
|
||||
// Get the script from the script wrapper.
|
||||
CHECK(wrapper->value()->IsScript());
|
||||
Handle<Script> script(Script::cast(wrapper->value()));
|
||||
|
||||
// Set break point.
|
||||
if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
|
||||
&source_position)) {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
return Smi::FromInt(source_position);
|
||||
}
|
||||
|
||||
|
||||
// Clear a break point
|
||||
// args[0]: number: break point object
|
||||
RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CHECK(isolate->debug()->is_active());
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
|
||||
|
||||
// Clear break point.
|
||||
isolate->debug()->ClearBreakPoint(break_point_object_arg);
|
||||
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
// Change the state of break on exceptions.
|
||||
// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
|
||||
// args[1]: Boolean indicating on/off.
|
||||
@ -1720,44 +1624,6 @@ RUNTIME_FUNCTION(Runtime_ScriptPositionInfo2) {
|
||||
return *GetJSPositionInfo(script, position, offset_flag, isolate);
|
||||
}
|
||||
|
||||
// Returns the given line as a string, or null if line is out of bounds.
|
||||
// The parameter line is expected to include the script's line offset.
|
||||
// TODO(5530): Remove once uses in debug.js are gone.
|
||||
RUNTIME_FUNCTION(Runtime_ScriptSourceLine) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(2, args.length());
|
||||
CONVERT_ARG_CHECKED(JSValue, script, 0);
|
||||
CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]);
|
||||
|
||||
CHECK(script->value()->IsScript());
|
||||
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
|
||||
|
||||
if (script_handle->type() == Script::TYPE_WASM) {
|
||||
// Return null for now; this function will disappear soon anyway.
|
||||
return isolate->heap()->null_value();
|
||||
}
|
||||
|
||||
Script::InitLineEnds(script_handle);
|
||||
|
||||
FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
|
||||
const int line_count = line_ends_array->length();
|
||||
|
||||
line -= script_handle->line_offset();
|
||||
if (line < 0 || line_count <= line) {
|
||||
return isolate->heap()->null_value();
|
||||
}
|
||||
|
||||
const int start =
|
||||
(line == 0) ? 0 : Smi::ToInt(line_ends_array->get(line - 1)) + 1;
|
||||
const int end = Smi::ToInt(line_ends_array->get(line));
|
||||
|
||||
Handle<String> source =
|
||||
handle(String::cast(script_handle->source()), isolate);
|
||||
Handle<String> str = isolate->factory()->NewSubString(source, start, end);
|
||||
|
||||
return *str;
|
||||
}
|
||||
|
||||
// On function call, depending on circumstances, prepare for stepping in,
|
||||
// or perform a side effect check.
|
||||
RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) {
|
||||
|
@ -128,7 +128,6 @@ namespace internal {
|
||||
|
||||
#define FOR_EACH_INTRINSIC_DEBUG(F) \
|
||||
F(HandleDebuggerStatement, 0, 1) \
|
||||
F(SetDebugEventListener, 2, 1) \
|
||||
F(ScheduleBreak, 0, 1) \
|
||||
F(DebugGetInternalProperties, 1, 1) \
|
||||
F(DebugGetPropertyDetails, 2, 1) \
|
||||
@ -146,11 +145,7 @@ namespace internal {
|
||||
F(GetGeneratorScopeCount, 1, 1) \
|
||||
F(GetGeneratorScopeDetails, 2, 1) \
|
||||
F(SetScopeVariableValue, 6, 1) \
|
||||
F(SetBreakPointsActive, 1, 1) \
|
||||
F(GetBreakLocations, 1, 1) \
|
||||
F(SetFunctionBreakPoint, 3, 1) \
|
||||
F(SetScriptBreakPoint, 3, 1) \
|
||||
F(ClearBreakPoint, 1, 1) \
|
||||
F(ChangeBreakOnException, 2, 1) \
|
||||
F(IsBreakOnException, 1, 1) \
|
||||
F(PrepareStep, 2, 1) \
|
||||
@ -173,7 +168,6 @@ namespace internal {
|
||||
F(ScriptLocationFromLine2, 4, 1) \
|
||||
F(ScriptPositionInfo, 3, 1) \
|
||||
F(ScriptPositionInfo2, 3, 1) \
|
||||
F(ScriptSourceLine, 2, 1) \
|
||||
F(DebugOnFunctionCall, 1, 1) \
|
||||
F(DebugPrepareStepInSuspendedGenerator, 0, 1) \
|
||||
F(DebugPushPromise, 1, 1) \
|
||||
|
@ -1049,7 +1049,7 @@ int FindBreakpointInfoInsertPos(Isolate* isolate,
|
||||
|
||||
void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared,
|
||||
int position,
|
||||
Handle<Object> break_point_object) {
|
||||
Handle<BreakPoint> break_point) {
|
||||
Isolate* isolate = shared->GetIsolate();
|
||||
Handle<FixedArray> breakpoint_infos;
|
||||
if (shared->has_breakpoint_infos()) {
|
||||
@ -1069,7 +1069,7 @@ void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared,
|
||||
position) {
|
||||
Handle<BreakPointInfo> old_info(
|
||||
BreakPointInfo::cast(breakpoint_infos->get(insert_pos)), isolate);
|
||||
BreakPointInfo::SetBreakPoint(old_info, break_point_object);
|
||||
BreakPointInfo::SetBreakPoint(old_info, break_point);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1096,7 +1096,7 @@ void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared,
|
||||
// Generate new BreakpointInfo.
|
||||
Handle<BreakPointInfo> breakpoint_info =
|
||||
isolate->factory()->NewBreakPointInfo(position);
|
||||
BreakPointInfo::SetBreakPoint(breakpoint_info, break_point_object);
|
||||
BreakPointInfo::SetBreakPoint(breakpoint_info, break_point);
|
||||
|
||||
// Now insert new position at insert_pos.
|
||||
new_breakpoint_infos->set(insert_pos, *breakpoint_info);
|
||||
@ -1368,9 +1368,8 @@ MaybeHandle<FixedArray> WasmSharedModuleData::CheckBreakPoints(
|
||||
Handle<BreakPointInfo>::cast(maybe_breakpoint_info);
|
||||
if (breakpoint_info->source_position() != position) return {};
|
||||
|
||||
Handle<Object> breakpoint_objects(breakpoint_info->break_point_objects(),
|
||||
isolate);
|
||||
return isolate->debug()->GetHitBreakPointObjects(breakpoint_objects);
|
||||
Handle<Object> break_points(breakpoint_info->break_points(), isolate);
|
||||
return isolate->debug()->GetHitBreakPoints(break_points);
|
||||
}
|
||||
|
||||
Handle<WasmCompiledModule> WasmCompiledModule::New(
|
||||
@ -1809,10 +1808,9 @@ bool WasmSharedModuleData::GetPositionInfo(uint32_t position,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WasmCompiledModule::SetBreakPoint(
|
||||
Handle<WasmCompiledModule> compiled_module, int* position,
|
||||
Handle<Object> break_point_object) {
|
||||
Handle<BreakPoint> break_point) {
|
||||
Isolate* isolate = compiled_module->GetIsolate();
|
||||
Handle<WasmSharedModuleData> shared(compiled_module->shared(), isolate);
|
||||
|
||||
@ -1827,7 +1825,7 @@ bool WasmCompiledModule::SetBreakPoint(
|
||||
DCHECK(IsBreakablePosition(*shared, func_index, offset_in_func));
|
||||
|
||||
// Insert new break point into break_positions of shared module data.
|
||||
WasmSharedModuleData::AddBreakpoint(shared, *position, break_point_object);
|
||||
WasmSharedModuleData::AddBreakpoint(shared, *position, break_point);
|
||||
|
||||
// Iterate over all instances of this module and tell them to set this new
|
||||
// breakpoint.
|
||||
|
@ -337,7 +337,7 @@ class WasmSharedModuleData : public FixedArray {
|
||||
Handle<WasmSharedModuleData>);
|
||||
|
||||
static void AddBreakpoint(Handle<WasmSharedModuleData>, int position,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
|
||||
static void SetBreakpointsOnNewInstance(Handle<WasmSharedModuleData>,
|
||||
Handle<WasmInstanceObject>);
|
||||
@ -569,7 +569,7 @@ class WasmCompiledModule : public FixedArray {
|
||||
// If it points outside a function, or behind the last breakable location,
|
||||
// this function returns false and does not set any breakpoint.
|
||||
static bool SetBreakPoint(Handle<WasmCompiledModule>, int* position,
|
||||
Handle<Object> break_point_object);
|
||||
Handle<BreakPoint> break_point);
|
||||
|
||||
inline void ReplaceCodeTableForTesting(
|
||||
std::vector<wasm::WasmCode*>&& testing_table);
|
||||
|
@ -2971,7 +2971,6 @@ class CountBreakDebugDelegate : public v8::debug::DebugDelegate {
|
||||
public:
|
||||
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
v8::Local<v8::Value> break_points_hit,
|
||||
const std::vector<int>&) override {
|
||||
debug_break_count++;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -88,7 +88,6 @@ class BreakHandler : public debug::DebugDelegate {
|
||||
|
||||
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
v8::Local<v8::Value> break_points_hit,
|
||||
const std::vector<int>&) override {
|
||||
printf("Break #%d\n", count_);
|
||||
CHECK_GT(expected_breaks_.size(), count_);
|
||||
@ -114,26 +113,6 @@ class BreakHandler : public debug::DebugDelegate {
|
||||
}
|
||||
};
|
||||
|
||||
Handle<JSObject> MakeFakeBreakpoint(Isolate* isolate, int position) {
|
||||
Handle<JSObject> obj =
|
||||
isolate->factory()->NewJSObject(isolate->object_function());
|
||||
// Generate an "isTriggered" method that always returns true.
|
||||
// This can/must be refactored once we remove remaining JS parts from the
|
||||
// debugger (bug 5530).
|
||||
Handle<String> source = isolate->factory()->NewStringFromStaticChars("true");
|
||||
Handle<Context> context(isolate->context(), isolate);
|
||||
Handle<JSFunction> triggered_fun =
|
||||
Compiler::GetFunctionFromString(context, source, NO_PARSE_RESTRICTION,
|
||||
kNoSourcePosition)
|
||||
.ToHandleChecked();
|
||||
PropertyDescriptor desc;
|
||||
desc.set_value(triggered_fun);
|
||||
Handle<String> name =
|
||||
isolate->factory()->InternalizeUtf8String(CStrVector("isTriggered"));
|
||||
CHECK(JSObject::DefineOwnProperty(isolate, obj, name, &desc, kDontThrow)
|
||||
.FromMaybe(false));
|
||||
return obj;
|
||||
}
|
||||
|
||||
void SetBreakpoint(WasmRunnerBase& runner, int function_index, int byte_offset,
|
||||
int expected_set_byte_offset = -1) {
|
||||
@ -143,10 +122,12 @@ void SetBreakpoint(WasmRunnerBase& runner, int function_index, int byte_offset,
|
||||
if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset;
|
||||
Handle<WasmInstanceObject> instance = runner.builder().instance_object();
|
||||
Handle<WasmCompiledModule> compiled_module(instance->compiled_module());
|
||||
Handle<JSObject> fake_breakpoint_object =
|
||||
MakeFakeBreakpoint(runner.main_isolate(), code_offset);
|
||||
static int break_index = 0;
|
||||
Handle<BreakPoint> break_point =
|
||||
runner.main_isolate()->factory()->NewBreakPoint(
|
||||
break_index++, runner.main_isolate()->factory()->empty_string());
|
||||
CHECK(WasmCompiledModule::SetBreakPoint(compiled_module, &code_offset,
|
||||
fake_breakpoint_object));
|
||||
break_point));
|
||||
int set_byte_offset = code_offset - func_offset;
|
||||
CHECK_EQ(expected_set_byte_offset, set_byte_offset);
|
||||
// Also set breakpoint on the debug info of the instance directly, since the
|
||||
@ -212,7 +193,6 @@ class CollectValuesBreakHandler : public debug::DebugDelegate {
|
||||
|
||||
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
|
||||
v8::Local<v8::Object> exec_state,
|
||||
v8::Local<v8::Value> break_points_hit,
|
||||
const std::vector<int>&) override {
|
||||
printf("Break #%d\n", count_);
|
||||
CHECK_GT(expected_values_.size(), count_);
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Flags: --allow-natives-syntax --cache=code
|
||||
// Test that script ids are unique and we found the correct ones.
|
||||
|
||||
var Debug = %GetDebugContext().Debug;
|
||||
var Debug = debug.Debug;
|
||||
Debug.setListener(function(){});
|
||||
|
||||
var scripts = %DebugGetLoadedScripts();
|
@ -1,35 +0,0 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
// Test that setting break point works correctly when the debugger is
|
||||
// activated late, which leads to duplicate shared function infos.
|
||||
|
||||
(function() {
|
||||
var Debug = %GetDebugContext().Debug;
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
if (event != Debug.DebugEvent.Break) return;
|
||||
try {
|
||||
assertTrue(/foo/.test(exec_state.frame(0).sourceLineText()));
|
||||
break_count++;
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var foo = function() { a = 1; }
|
||||
var exception = null;
|
||||
var break_count = 0;
|
||||
Debug.setListener(listener);
|
||||
if (i < 2) Debug.setBreakPoint(foo, 0, 0);
|
||||
assertTrue(/\[B\d\]a = 1/.test(Debug.showBreakPoints(foo)));
|
||||
foo();
|
||||
assertEquals(1, break_count);
|
||||
assertNull(exception);
|
||||
}
|
||||
|
||||
Debug.setListener(null);
|
||||
})();
|
@ -7,7 +7,7 @@
|
||||
try { } catch(e) { }
|
||||
try { try { } catch (e) { } } catch(e) { }
|
||||
try {
|
||||
var Debug = %GetDebugContext().Debug;
|
||||
var Debug = debug.Debug;
|
||||
Debug.setListener(function(){});
|
||||
} catch(e) { }
|
||||
(function() {
|
Loading…
Reference in New Issue
Block a user