Commit 9d17b0d4 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Whenever a script object is created it is assigned a unique id. Currently this...

Whenever a script object is created it is assigned a unique id. Currently this id is assigned from an 32 bit integer counter.

Changed the script break points to be able to handle both break points based on script names and script ids. When break points are set through a script id the position is relative to the script itself. This is different from the script break points set through script names where the line/coulmn offset is taken into account.

This has the side effect that function break points are not converted into script break points for named scripts.

Show the script id in the D8 shell debugger when listing all scripts using the 'scripts' command.
Review URL: http://codereview.chromium.org/40317

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1468 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bab4b3b2
...@@ -524,6 +524,11 @@ class EXPORT Script { ...@@ -524,6 +524,11 @@ class EXPORT Script {
* Runs the script returning the resulting value. * Runs the script returning the resulting value.
*/ */
Local<Value> Run(); Local<Value> Run();
/**
* Returns the script id value.
*/
Local<Value> Id();
}; };
......
...@@ -197,6 +197,24 @@ const AccessorDescriptor Accessors::ScriptName = { ...@@ -197,6 +197,24 @@ const AccessorDescriptor Accessors::ScriptName = {
}; };
//
// Accessors::ScriptId
//
Object* Accessors::ScriptGetId(Object* object, void*) {
Object* script = JSValue::cast(object)->value();
return Script::cast(script)->id();
}
const AccessorDescriptor Accessors::ScriptId = {
ScriptGetId,
IllegalSetter,
0
};
// //
// Accessors::ScriptLineOffset // Accessors::ScriptLineOffset
// //
......
...@@ -42,6 +42,7 @@ namespace v8 { namespace internal { ...@@ -42,6 +42,7 @@ namespace v8 { namespace internal {
V(StringLength) \ V(StringLength) \
V(ScriptSource) \ V(ScriptSource) \
V(ScriptName) \ V(ScriptName) \
V(ScriptId) \
V(ScriptLineOffset) \ V(ScriptLineOffset) \
V(ScriptColumnOffset) \ V(ScriptColumnOffset) \
V(ScriptType) \ V(ScriptType) \
...@@ -79,6 +80,7 @@ class Accessors : public AllStatic { ...@@ -79,6 +80,7 @@ class Accessors : public AllStatic {
static Object* ArrayGetLength(Object* object, void*); static Object* ArrayGetLength(Object* object, void*);
static Object* StringGetLength(Object* object, void*); static Object* StringGetLength(Object* object, void*);
static Object* ScriptGetName(Object* object, void*); static Object* ScriptGetName(Object* object, void*);
static Object* ScriptGetId(Object* object, void*);
static Object* ScriptGetSource(Object* object, void*); static Object* ScriptGetSource(Object* object, void*);
static Object* ScriptGetLineOffset(Object* object, void*); static Object* ScriptGetLineOffset(Object* object, void*);
static Object* ScriptGetColumnOffset(Object* object, void*); static Object* ScriptGetColumnOffset(Object* object, void*);
......
...@@ -1054,6 +1054,22 @@ Local<Value> Script::Run() { ...@@ -1054,6 +1054,22 @@ Local<Value> Script::Run() {
} }
Local<Value> Script::Id() {
ON_BAILOUT("v8::Script::Id()", return Local<Value>());
LOG_API("Script::Id");
i::Object* raw_id = NULL;
{
HandleScope scope;
i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
i::Handle<i::Script> script(i::Script::cast(fun->shared()->script()));
i::Handle<i::Object> id(script->id());
raw_id = *id;
}
i::Handle<i::Object> id(raw_id);
return Utils::ToLocal(id);
}
// --- E x c e p t i o n s --- // --- E x c e p t i o n s ---
......
...@@ -985,12 +985,19 @@ bool Genesis::InstallNatives() { ...@@ -985,12 +985,19 @@ bool Genesis::InstallNatives() {
Factory::LookupAsciiSymbol("source"), Factory::LookupAsciiSymbol("source"),
proxy_source, proxy_source,
common_attributes); common_attributes);
Handle<Proxy> proxy_data = Factory::NewProxy(&Accessors::ScriptName); Handle<Proxy> proxy_name = Factory::NewProxy(&Accessors::ScriptName);
script_descriptors = script_descriptors =
Factory::CopyAppendProxyDescriptor( Factory::CopyAppendProxyDescriptor(
script_descriptors, script_descriptors,
Factory::LookupAsciiSymbol("name"), Factory::LookupAsciiSymbol("name"),
proxy_data, proxy_name,
common_attributes);
Handle<Proxy> proxy_id = Factory::NewProxy(&Accessors::ScriptId);
script_descriptors =
Factory::CopyAppendProxyDescriptor(
script_descriptors,
Factory::LookupAsciiSymbol("id"),
proxy_id,
common_attributes); common_attributes);
Handle<Proxy> proxy_line_offset = Handle<Proxy> proxy_line_offset =
Factory::NewProxy(&Accessors::ScriptLineOffset); Factory::NewProxy(&Accessors::ScriptLineOffset);
......
...@@ -888,18 +888,19 @@ function DebugResponseDetails(response) { ...@@ -888,18 +888,19 @@ function DebugResponseDetails(response) {
var result = ''; var result = '';
for (i = 0; i < body.length; i++) { for (i = 0; i < body.length; i++) {
if (i != 0) result += '\n'; if (i != 0) result += '\n';
if (body[i].id) {
result += body[i].id;
} else {
result += '[no id]';
}
result += ', ';
if (body[i].name) { if (body[i].name) {
result += body[i].name; result += body[i].name;
} else { } else {
result += '[unnamed] '; result += '[unnamed] ';
var sourceStart = body[i].sourceStart;
if (sourceStart.length > 40) {
sourceStart = sourceStart.substring(0, 37) + '...';
}
result += sourceStart;
} }
result += ' (lines: '; result += ' (lines: ';
result += body[i].sourceLines; result += body[i].lineCount;
result += ', length: '; result += ', length: ';
result += body[i].sourceLength; result += body[i].sourceLength;
if (body[i].type == Debug.ScriptType.Native) { if (body[i].type == Debug.ScriptType.Native) {
...@@ -907,7 +908,13 @@ function DebugResponseDetails(response) { ...@@ -907,7 +908,13 @@ function DebugResponseDetails(response) {
} else if (body[i].type == Debug.ScriptType.Extension) { } else if (body[i].type == Debug.ScriptType.Extension) {
result += ', extension'; result += ', extension';
} }
result += ')'; result += '), [';
var sourceStart = body[i].sourceStart;
if (sourceStart.length > 40) {
sourceStart = sourceStart.substring(0, 37) + '...';
}
result += sourceStart;
result += ']';
} }
details.text = result; details.text = result;
break; break;
......
...@@ -61,6 +61,10 @@ Debug.ScriptType = { Native: 0, ...@@ -61,6 +61,10 @@ Debug.ScriptType = { Native: 0,
Extension: 1, Extension: 1,
Normal: 2 }; Normal: 2 };
// The different script break point types.
Debug.ScriptBreakPointType = { ScriptId: 0,
ScriptName: 1 };
function ScriptTypeFlag(type) { function ScriptTypeFlag(type) {
return (1 << type); return (1 << type);
} }
...@@ -210,9 +214,15 @@ function IsBreakPointTriggered(break_id, break_point) { ...@@ -210,9 +214,15 @@ function IsBreakPointTriggered(break_id, break_point) {
// Object representing a script break point. The script is referenced by its // Object representing a script break point. The script is referenced by its
// script name and the break point is represented as line and column. // script name or script id and the break point is represented as line and
function ScriptBreakPoint(script_name, opt_line, opt_column) { // column.
this.script_name_ = script_name; function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column) {
this.type_ = type;
if (type == Debug.ScriptBreakPointType.ScriptId) {
this.script_id_ = script_id_or_name;
} else { // type == Debug.ScriptBreakPointType.ScriptName
this.script_name_ = script_id_or_name;
}
this.line_ = opt_line || 0; this.line_ = opt_line || 0;
this.column_ = opt_column; this.column_ = opt_column;
this.hit_count_ = 0; this.hit_count_ = 0;
...@@ -227,6 +237,16 @@ ScriptBreakPoint.prototype.number = function() { ...@@ -227,6 +237,16 @@ ScriptBreakPoint.prototype.number = function() {
}; };
ScriptBreakPoint.prototype.type = function() {
return this.type_;
};
ScriptBreakPoint.prototype.script_id = function() {
return this.script_id_;
};
ScriptBreakPoint.prototype.script_name = function() { ScriptBreakPoint.prototype.script_name = function() {
return this.script_name_; return this.script_name_;
}; };
...@@ -292,9 +312,13 @@ ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) { ...@@ -292,9 +312,13 @@ ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
// Check whether a script matches this script break point. Currently this is // Check whether a script matches this script break point. Currently this is
// only based on script name. // only based on script name.
ScriptBreakPoint.prototype.matchesScript = function(script) { ScriptBreakPoint.prototype.matchesScript = function(script) {
return this.script_name_ == script.name && if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
script.line_offset <= this.line_ && return this.script_id_ == script.id;
this.line_ < script.line_offset + script.lineCount(); } else { // this.type_ == Debug.ScriptBreakPointType.ScriptName
return this.script_name_ == script.name &&
script.line_offset <= this.line_ &&
this.line_ < script.line_offset + script.lineCount();
}
}; };
...@@ -356,7 +380,8 @@ ScriptBreakPoint.prototype.clear = function () { ...@@ -356,7 +380,8 @@ ScriptBreakPoint.prototype.clear = function () {
// break points set in this script. // break points set in this script.
function UpdateScriptBreakPoints(script) { function UpdateScriptBreakPoints(script) {
for (var i = 0; i < script_break_points.length; i++) { for (var i = 0; i < script_break_points.length; i++) {
if (script_break_points[i].script_name() == script.name) { if (script_break_points[i].type() == Debug.ScriptBreakPointType.ScriptName &&
script_break_points[i].script_name() == script.name) {
script_break_points[i].set(script); script_break_points[i].set(script);
} }
} }
...@@ -491,15 +516,15 @@ Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) { ...@@ -491,15 +516,15 @@ Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
} }
// If the script for the function has a name convert this to a script break // If the script for the function has a name convert this to a script break
// point. // point.
if (script && script.name) { if (script && script.id) {
// Adjust the source position to be script relative. // Adjust the source position to be script relative.
source_position += %FunctionGetScriptSourcePosition(func); source_position += %FunctionGetScriptSourcePosition(func);
// Find line and column for the position in the script and set a script // Find line and column for the position in the script and set a script
// break point from that. // break point from that.
var location = script.locationFromPosition(source_position); var location = script.locationFromPosition(source_position);
return this.setScriptBreakPoint(script.name, return this.setScriptBreakPointById(script.id,
location.line, location.column, location.line, location.column,
opt_condition); opt_condition);
} else { } else {
// Set a break point directly on the function. // Set a break point directly on the function.
var break_point = MakeBreakPoint(source_position, opt_line, opt_column); var break_point = MakeBreakPoint(source_position, opt_line, opt_column);
...@@ -576,18 +601,20 @@ Debug.findScriptBreakPoint = function(break_point_number, remove) { ...@@ -576,18 +601,20 @@ Debug.findScriptBreakPoint = function(break_point_number, remove) {
} }
// Sets a breakpoint in a script identified through script name at the // Sets a breakpoint in a script identified through id or name at the
// specified source line and column within that line. // specified source line and column within that line.
Debug.setScriptBreakPoint = function(script_name, opt_line, opt_column, opt_condition) { Debug.setScriptBreakPoint = function(type, script_id_or_name,
opt_line, opt_column, opt_condition) {
// Create script break point object. // Create script break point object.
var script_break_point = new ScriptBreakPoint(script_name, opt_line, opt_column); var script_break_point =
new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column);
// Assign number to the new script break point and add it. // Assign number to the new script break point and add it.
script_break_point.number_ = next_break_point_number++; script_break_point.number_ = next_break_point_number++;
script_break_point.setCondition(opt_condition); script_break_point.setCondition(opt_condition);
script_break_points.push(script_break_point); script_break_points.push(script_break_point);
// Run through all scripts to see it this script break point matches any // Run through all scripts to see if this script break point matches any
// loaded scripts. // loaded scripts.
var scripts = this.scripts(); var scripts = this.scripts();
for (var i = 0; i < scripts.length; i++) { for (var i = 0; i < scripts.length; i++) {
...@@ -600,6 +627,24 @@ Debug.setScriptBreakPoint = function(script_name, opt_line, opt_column, opt_cond ...@@ -600,6 +627,24 @@ Debug.setScriptBreakPoint = function(script_name, opt_line, opt_column, opt_cond
} }
Debug.setScriptBreakPointById = function(script_id,
opt_line, opt_column,
opt_condition) {
return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
script_id, opt_line, opt_column,
opt_condition)
}
Debug.setScriptBreakPointByName = function(script_name,
opt_line, opt_column,
opt_condition) {
return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptName,
script_name, opt_line, opt_column,
opt_condition)
}
Debug.enableScriptBreakPoint = function(break_point_number) { Debug.enableScriptBreakPoint = function(break_point_number) {
var script_break_point = this.findScriptBreakPoint(break_point_number, false); var script_break_point = this.findScriptBreakPoint(break_point_number, false);
script_break_point.enable(); script_break_point.enable();
...@@ -792,11 +837,7 @@ BreakEvent.prototype.toJSONProtocol = function() { ...@@ -792,11 +837,7 @@ BreakEvent.prototype.toJSONProtocol = function() {
o.body.sourceLine = this.sourceLine(), o.body.sourceLine = this.sourceLine(),
o.body.sourceColumn = this.sourceColumn(), o.body.sourceColumn = this.sourceColumn(),
o.body.sourceLineText = this.sourceLineText(), o.body.sourceLineText = this.sourceLineText(),
o.body.script = { name: script.name(), o.body.script = MakeScriptObject_(script, false);
lineOffset: script.lineOffset(),
columnOffset: script.columnOffset(),
lineCount: script.lineCount()
};
} }
// Add an Array of break points hit if any. // Add an Array of break points hit if any.
...@@ -889,11 +930,7 @@ ExceptionEvent.prototype.toJSONProtocol = function() { ...@@ -889,11 +930,7 @@ ExceptionEvent.prototype.toJSONProtocol = function() {
// Add script information to the event if available. // Add script information to the event if available.
var script = this.func().script(); var script = this.func().script();
if (script) { if (script) {
o.body.script = { name: script.name(), o.body.script = MakeScriptObject_(script, false);
lineOffset: script.lineOffset(),
columnOffset: script.columnOffset(),
lineCount: script.lineCount()
};
} }
} else { } else {
o.body.sourceLine = -1; o.body.sourceLine = -1;
...@@ -942,12 +979,7 @@ CompileEvent.prototype.toJSONProtocol = function() { ...@@ -942,12 +979,7 @@ CompileEvent.prototype.toJSONProtocol = function() {
o.event = "afterCompile"; o.event = "afterCompile";
} }
o.body = {}; o.body = {};
o.body.script = { name: this.script_.name(), o.body.script = MakeScriptObject_(this.script_, true);
lineOffset: this.script_.lineOffset(),
columnOffset: this.script_.columnOffset(),
lineCount: this.script_.lineCount(),
source: this.script_.source()
};
return o.toJSONProtocol(); return o.toJSONProtocol();
} }
...@@ -978,6 +1010,20 @@ NewFunctionEvent.prototype.setBreakPoint = function(p) { ...@@ -978,6 +1010,20 @@ NewFunctionEvent.prototype.setBreakPoint = function(p) {
}; };
function MakeScriptObject_(script, include_source) {
var o = { id: script.id(),
name: script.name(),
lineOffset: script.lineOffset(),
columnOffset: script.columnOffset(),
lineCount: script.lineCount(),
};
if (include_source) {
o.source = script.source();
}
return o;
};
function DebugCommandProcessor(exec_state) { function DebugCommandProcessor(exec_state) {
this.exec_state_ = exec_state; this.exec_state_ = exec_state;
this.running_ = false; this.running_ = false;
...@@ -1222,7 +1268,7 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ = ...@@ -1222,7 +1268,7 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ =
response.failed('Missing argument "type" or "target"'); response.failed('Missing argument "type" or "target"');
return; return;
} }
if (type != 'function' && type != 'script') { if (type != 'function' && type != 'script' && type != 'scriptId') {
response.failed('Illegal type "' + type + '"'); response.failed('Illegal type "' + type + '"');
return; return;
} }
...@@ -1251,11 +1297,13 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ = ...@@ -1251,11 +1297,13 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ =
// Set function break point. // Set function break point.
break_point_number = Debug.setBreakPoint(f, line, column, condition); break_point_number = Debug.setBreakPoint(f, line, column, condition);
} else { } else if (type == 'script') {
// set script break point. // set script break point.
break_point_number = Debug.setScriptBreakPoint(target, break_point_number =
line, column, Debug.setScriptBreakPointByName(target, line, column, condition);
condition); } else { // type == 'scriptId.
break_point_number =
Debug.setScriptBreakPointById(target, line, column, condition);
} }
// Set additional break point properties. // Set additional break point properties.
...@@ -1273,8 +1321,13 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ = ...@@ -1273,8 +1321,13 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ =
// Add break point information to the response. // Add break point information to the response.
if (break_point instanceof ScriptBreakPoint) { if (break_point instanceof ScriptBreakPoint) {
response.body.type = 'script'; if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
response.body.script_name = break_point.script_name(); response.body.type = 'scriptId';
response.body.script_id = break_point.script_id();
} else {
response.body.type = 'scriptName';
response.body.script_name = break_point.script_name();
}
response.body.line = break_point.line(); response.body.line = break_point.line();
response.body.column = break_point.column(); response.body.column = break_point.column();
} else { } else {
...@@ -1607,6 +1660,7 @@ DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) { ...@@ -1607,6 +1660,7 @@ DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) {
if (scripts[i].name) { if (scripts[i].name) {
script.name = scripts[i].name; script.name = scripts[i].name;
} }
script.id = scripts[i].id;
script.lineOffset = scripts[i].line_offset; script.lineOffset = scripts[i].line_offset;
script.columnOffset = scripts[i].column_offset; script.columnOffset = scripts[i].column_offset;
script.lineCount = scripts[i].lineCount(); script.lineCount = scripts[i].lineCount();
......
...@@ -153,9 +153,12 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() { ...@@ -153,9 +153,12 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() {
Handle<Script> Factory::NewScript(Handle<String> source) { Handle<Script> Factory::NewScript(Handle<String> source) {
static uint32_t next_id = 1;
Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE)); Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
script->set_source(*source); script->set_source(*source);
script->set_name(Heap::undefined_value()); script->set_name(Heap::undefined_value());
script->set_id(*Factory::NewNumberFromUint(next_id++));
script->set_line_offset(Smi::FromInt(0)); script->set_line_offset(Smi::FromInt(0));
script->set_column_offset(Smi::FromInt(0)); script->set_column_offset(Smi::FromInt(0));
script->set_type(Smi::FromInt(SCRIPT_TYPE_NORMAL)); script->set_type(Smi::FromInt(SCRIPT_TYPE_NORMAL));
...@@ -277,6 +280,11 @@ Handle<Object> Factory::NewNumberFromInt(int value) { ...@@ -277,6 +280,11 @@ Handle<Object> Factory::NewNumberFromInt(int value) {
} }
Handle<Object> Factory::NewNumberFromUint(uint32_t value) {
CALL_HEAP_FUNCTION(Heap::NumberFromUint32(value), Object);
}
Handle<JSObject> Factory::NewNeanderObject() { Handle<JSObject> Factory::NewNeanderObject() {
CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(Heap::neander_map()), CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(Heap::neander_map()),
JSObject); JSObject);
......
...@@ -170,6 +170,7 @@ class Factory : public AllStatic { ...@@ -170,6 +170,7 @@ class Factory : public AllStatic {
PretenureFlag pretenure = NOT_TENURED); PretenureFlag pretenure = NOT_TENURED);
static Handle<Object> NewNumberFromInt(int value); static Handle<Object> NewNumberFromInt(int value);
static Handle<Object> NewNumberFromUint(uint32_t value);
// These objects are used by the api to create env-independent data // These objects are used by the api to create env-independent data
// structures in the heap. // structures in the heap.
......
...@@ -1359,7 +1359,8 @@ FrameMirror.prototype.sourcePosition = function() { ...@@ -1359,7 +1359,8 @@ FrameMirror.prototype.sourcePosition = function() {
FrameMirror.prototype.sourceLocation = function() { FrameMirror.prototype.sourceLocation = function() {
if (this.func().resolved() && this.func().script()) { if (this.func().resolved() && this.func().script()) {
return this.func().script().locationFromPosition(this.sourcePosition()); return this.func().script().locationFromPosition(this.sourcePosition(),
true);
} }
}; };
...@@ -1561,6 +1562,11 @@ ScriptMirror.prototype.name = function() { ...@@ -1561,6 +1562,11 @@ ScriptMirror.prototype.name = function() {
}; };
ScriptMirror.prototype.id = function() {
return this.script_.id;
};
ScriptMirror.prototype.source = function() { ScriptMirror.prototype.source = function() {
return this.script_.source; return this.script_.source;
}; };
......
...@@ -2041,6 +2041,7 @@ ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset) ...@@ -2041,6 +2041,7 @@ ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
ACCESSORS(Script, source, Object, kSourceOffset) ACCESSORS(Script, source, Object, kSourceOffset)
ACCESSORS(Script, name, Object, kNameOffset) ACCESSORS(Script, name, Object, kNameOffset)
ACCESSORS(Script, id, Object, kIdOffset)
ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset) ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset) ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ACCESSORS(Script, wrapper, Proxy, kWrapperOffset) ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
......
...@@ -2550,6 +2550,9 @@ class Script: public Struct { ...@@ -2550,6 +2550,9 @@ class Script: public Struct {
// [name]: the script name. // [name]: the script name.
DECL_ACCESSORS(name, Object) DECL_ACCESSORS(name, Object)
// [id]: the script id.
DECL_ACCESSORS(id, Object)
// [line_offset]: script line offset in resource from where it was extracted. // [line_offset]: script line offset in resource from where it was extracted.
DECL_ACCESSORS(line_offset, Smi) DECL_ACCESSORS(line_offset, Smi)
...@@ -2583,7 +2586,8 @@ class Script: public Struct { ...@@ -2583,7 +2586,8 @@ class Script: public Struct {
static const int kWrapperOffset = kColumnOffsetOffset + kPointerSize; static const int kWrapperOffset = kColumnOffsetOffset + kPointerSize;
static const int kTypeOffset = kWrapperOffset + kPointerSize; static const int kTypeOffset = kWrapperOffset + kPointerSize;
static const int kLineEndsOffset = kTypeOffset + kPointerSize; static const int kLineEndsOffset = kTypeOffset + kPointerSize;
static const int kSize = kLineEndsOffset + kPointerSize; static const int kIdOffset = kLineEndsOffset + kPointerSize;
static const int kSize = kIdOffset + kPointerSize;
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Script); DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
......
...@@ -210,20 +210,46 @@ static int SetBreakPointFromJS(const char* function_name, ...@@ -210,20 +210,46 @@ static int SetBreakPointFromJS(const char* function_name,
} }
// Set a break point in a script using the global Debug object. // Set a break point in a script identified by id using the global Debug object.
static int SetScriptBreakPointFromJS(const char* script_data, static int SetScriptBreakPointByIdFromJS(int script_id, int line, int column) {
int line, int column) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
if (column >= 0) { if (column >= 0) {
// Column specified set script break point on precise location. // Column specified set script break point on precise location.
OS::SNPrintF(buffer, OS::SNPrintF(buffer,
"debug.Debug.setScriptBreakPoint(\"%s\",%d,%d)", "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
script_data, line, column); script_id, line, column);
} else { } else {
// Column not specified set script break point on line. // Column not specified set script break point on line.
OS::SNPrintF(buffer, OS::SNPrintF(buffer,
"debug.Debug.setScriptBreakPoint(\"%s\",%d)", "debug.Debug.setScriptBreakPointById(%d,%d)",
script_data, line); script_id, line);
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
v8::TryCatch try_catch;
v8::Handle<v8::String> str = v8::String::New(buffer.start());
v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
ASSERT(!try_catch.HasCaught());
return value->Int32Value();
}
}
// Set a break point in a script identified by name using the global Debug
// object.
static int SetScriptBreakPointByNameFromJS(const char* script_name,
int line, int column) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
if (column >= 0) {
// Column specified set script break point on precise location.
OS::SNPrintF(buffer,
"debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
script_name, line, column);
} else {
// Column not specified set script break point on line.
OS::SNPrintF(buffer,
"debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
script_name, line);
} }
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{ {
...@@ -1166,8 +1192,9 @@ TEST(BreakPointThroughJavaScript) { ...@@ -1166,8 +1192,9 @@ TEST(BreakPointThroughJavaScript) {
} }
// Test that break points can be set using the global Debug object. // Test that break points on scripts identified by name can be set using the
TEST(ScriptBreakPointThroughJavaScript) { // global Debug object.
TEST(ScriptBreakPointByNameThroughJavaScript) {
break_point_hit_count = 0; break_point_hit_count = 0;
v8::HandleScope scope; v8::HandleScope scope;
DebugLocalContext env; DebugLocalContext env;
...@@ -1175,7 +1202,6 @@ TEST(ScriptBreakPointThroughJavaScript) { ...@@ -1175,7 +1202,6 @@ TEST(ScriptBreakPointThroughJavaScript) {
v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
v8::Undefined()); v8::Undefined());
v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run();
v8::Local<v8::String> script = v8::String::New( v8::Local<v8::String> script = v8::String::New(
"function f() {\n" "function f() {\n"
...@@ -1213,7 +1239,7 @@ TEST(ScriptBreakPointThroughJavaScript) { ...@@ -1213,7 +1239,7 @@ TEST(ScriptBreakPointThroughJavaScript) {
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
// Call f and g with break point on line 12. // Call f and g with break point on line 12.
int sbp1 = SetScriptBreakPointFromJS("test", 12, 0); int sbp1 = SetScriptBreakPointByNameFromJS("test", 12, 0);
break_point_hit_count = 0; break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL); f->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
...@@ -1229,7 +1255,7 @@ TEST(ScriptBreakPointThroughJavaScript) { ...@@ -1229,7 +1255,7 @@ TEST(ScriptBreakPointThroughJavaScript) {
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
// Call f and g with break point on line 2. // Call f and g with break point on line 2.
int sbp2 = SetScriptBreakPointFromJS("test", 2, 0); int sbp2 = SetScriptBreakPointByNameFromJS("test", 2, 0);
break_point_hit_count = 0; break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL); f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count); CHECK_EQ(1, break_point_hit_count);
...@@ -1237,17 +1263,17 @@ TEST(ScriptBreakPointThroughJavaScript) { ...@@ -1237,17 +1263,17 @@ TEST(ScriptBreakPointThroughJavaScript) {
CHECK_EQ(2, break_point_hit_count); CHECK_EQ(2, break_point_hit_count);
// Call f and g with break point on line 2, 4, 12, 14 and 15. // Call f and g with break point on line 2, 4, 12, 14 and 15.
int sbp3 = SetScriptBreakPointFromJS("test", 4, 0); int sbp3 = SetScriptBreakPointByNameFromJS("test", 4, 0);
int sbp4 = SetScriptBreakPointFromJS("test", 12, 0); int sbp4 = SetScriptBreakPointByNameFromJS("test", 12, 0);
int sbp5 = SetScriptBreakPointFromJS("test", 14, 0); int sbp5 = SetScriptBreakPointByNameFromJS("test", 14, 0);
int sbp6 = SetScriptBreakPointFromJS("test", 15, 0); int sbp6 = SetScriptBreakPointByNameFromJS("test", 15, 0);
break_point_hit_count = 0; break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL); f->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count); CHECK_EQ(2, break_point_hit_count);
g->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL);
CHECK_EQ(7, break_point_hit_count); CHECK_EQ(7, break_point_hit_count);
// Remove the all the break points again. // Remove all the break points again.
break_point_hit_count = 0; break_point_hit_count = 0;
ClearBreakPointFromJS(sbp2); ClearBreakPointFromJS(sbp2);
ClearBreakPointFromJS(sbp3); ClearBreakPointFromJS(sbp3);
...@@ -1259,19 +1285,114 @@ TEST(ScriptBreakPointThroughJavaScript) { ...@@ -1259,19 +1285,114 @@ TEST(ScriptBreakPointThroughJavaScript) {
g->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
// Now set a function break point v8::Debug::SetDebugEventListener(NULL);
int bp7 = SetBreakPointFromJS("g", 0, 0); CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
CHECK_EQ(1, sbp1);
CHECK_EQ(2, sbp2);
CHECK_EQ(3, sbp3);
CHECK_EQ(4, sbp4);
CHECK_EQ(5, sbp5);
CHECK_EQ(6, sbp6);
}
TEST(ScriptBreakPointByIdThroughJavaScript) {
break_point_hit_count = 0;
v8::HandleScope scope;
DebugLocalContext env;
env.ExposeDebug();
v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
v8::Undefined());
v8::Local<v8::String> source = v8::String::New(
"function f() {\n"
" function h() {\n"
" a = 0; // line 2\n"
" }\n"
" b = 1; // line 4\n"
" return h();\n"
"}\n"
"\n"
"function g() {\n"
" function h() {\n"
" a = 0;\n"
" }\n"
" b = 2; // line 12\n"
" h();\n"
" b = 3; // line 14\n"
" f(); // line 15\n"
"}");
// Compile the script and get the two functions.
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8::String::New("test"));
v8::Local<v8::Script> script = v8::Script::Compile(source, &origin);
script->Run();
v8::Local<v8::Function> f =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
v8::Local<v8::Function> g =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
// Get the script id knowing that internally it is a 32 integer.
uint32_t script_id = script->Id()->Uint32Value();
// Call f and g without break points.
break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
// Call f and g with break point on line 12.
int sbp1 = SetScriptBreakPointByIdFromJS(script_id, 12, 0);
break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
g->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count); CHECK_EQ(1, break_point_hit_count);
// Reload the script and get g again checking that the break point survives. // Remove the break point again.
// This tests that the function break point was converted to a script break break_point_hit_count = 0;
// point. ClearBreakPointFromJS(sbp1);
v8::Script::Compile(script, &origin)->Run(); f->Call(env->Global(), 0, NULL);
g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); CHECK_EQ(0, break_point_hit_count);
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
// Call f and g with break point on line 2.
int sbp2 = SetScriptBreakPointByIdFromJS(script_id, 2, 0);
break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
g->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count); CHECK_EQ(2, break_point_hit_count);
// Call f and g with break point on line 2, 4, 12, 14 and 15.
int sbp3 = SetScriptBreakPointByIdFromJS(script_id, 4, 0);
int sbp4 = SetScriptBreakPointByIdFromJS(script_id, 12, 0);
int sbp5 = SetScriptBreakPointByIdFromJS(script_id, 14, 0);
int sbp6 = SetScriptBreakPointByIdFromJS(script_id, 15, 0);
break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
g->Call(env->Global(), 0, NULL);
CHECK_EQ(7, break_point_hit_count);
// Remove all the break points again.
break_point_hit_count = 0;
ClearBreakPointFromJS(sbp2);
ClearBreakPointFromJS(sbp3);
ClearBreakPointFromJS(sbp4);
ClearBreakPointFromJS(sbp5);
ClearBreakPointFromJS(sbp6);
f->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
v8::Debug::SetDebugEventListener(NULL); v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded(); CheckDebuggerUnloaded();
...@@ -1282,7 +1403,6 @@ TEST(ScriptBreakPointThroughJavaScript) { ...@@ -1282,7 +1403,6 @@ TEST(ScriptBreakPointThroughJavaScript) {
CHECK_EQ(4, sbp4); CHECK_EQ(4, sbp4);
CHECK_EQ(5, sbp5); CHECK_EQ(5, sbp5);
CHECK_EQ(6, sbp6); CHECK_EQ(6, sbp6);
CHECK_EQ(7, bp7);
} }
...@@ -1309,7 +1429,7 @@ TEST(EnableDisableScriptBreakPoint) { ...@@ -1309,7 +1429,7 @@ TEST(EnableDisableScriptBreakPoint) {
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
// Set script break point on line 1 (in function f). // Set script break point on line 1 (in function f).
int sbp = SetScriptBreakPointFromJS("test", 1, 0); int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
// Call f while enabeling and disabling the script break point. // Call f while enabeling and disabling the script break point.
break_point_hit_count = 0; break_point_hit_count = 0;
...@@ -1370,7 +1490,7 @@ TEST(ConditionalScriptBreakPoint) { ...@@ -1370,7 +1490,7 @@ TEST(ConditionalScriptBreakPoint) {
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
// Set script break point on line 5 (in function g). // Set script break point on line 5 (in function g).
int sbp1 = SetScriptBreakPointFromJS("test", 5, 0); int sbp1 = SetScriptBreakPointByNameFromJS("test", 5, 0);
// Call f with different conditions on the script break point. // Call f with different conditions on the script break point.
break_point_hit_count = 0; break_point_hit_count = 0;
...@@ -1428,7 +1548,7 @@ TEST(ScriptBreakPointIgnoreCount) { ...@@ -1428,7 +1548,7 @@ TEST(ScriptBreakPointIgnoreCount) {
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
// Set script break point on line 1 (in function f). // Set script break point on line 1 (in function f).
int sbp = SetScriptBreakPointFromJS("test", 1, 0); int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
// Call f with different ignores on the script break point. // Call f with different ignores on the script break point.
break_point_hit_count = 0; break_point_hit_count = 0;
...@@ -1484,7 +1604,7 @@ TEST(ScriptBreakPointReload) { ...@@ -1484,7 +1604,7 @@ TEST(ScriptBreakPointReload) {
v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8::String::New("2")); v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8::String::New("2"));
// Set a script break point before the script is loaded. // Set a script break point before the script is loaded.
SetScriptBreakPointFromJS("1", 2, 0); SetScriptBreakPointByNameFromJS("1", 2, 0);
// Compile the script and get the function. // Compile the script and get the function.
v8::Script::Compile(script, &origin_1)->Run(); v8::Script::Compile(script, &origin_1)->Run();
...@@ -1545,7 +1665,7 @@ TEST(ScriptBreakPointMultiple) { ...@@ -1545,7 +1665,7 @@ TEST(ScriptBreakPointMultiple) {
v8::ScriptOrigin(v8::String::New("test")); v8::ScriptOrigin(v8::String::New("test"));
// Set a script break point before the scripts are loaded. // Set a script break point before the scripts are loaded.
int sbp = SetScriptBreakPointFromJS("test", 1, 0); int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
// Compile the scripts with same script data and get the functions. // Compile the scripts with same script data and get the functions.
v8::Script::Compile(script_f, &origin)->Run(); v8::Script::Compile(script_f, &origin)->Run();
...@@ -1571,7 +1691,7 @@ TEST(ScriptBreakPointMultiple) { ...@@ -1571,7 +1691,7 @@ TEST(ScriptBreakPointMultiple) {
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
// Set script break point with the scripts loaded. // Set script break point with the scripts loaded.
sbp = SetScriptBreakPointFromJS("test", 1, 0); sbp = SetScriptBreakPointByNameFromJS("test", 1, 0);
// Call f and g and check that the script break point is active. // Call f and g and check that the script break point is active.
break_point_hit_count = 0; break_point_hit_count = 0;
...@@ -1607,8 +1727,8 @@ TEST(ScriptBreakPointLineOffset) { ...@@ -1607,8 +1727,8 @@ TEST(ScriptBreakPointLineOffset) {
v8::Integer::New(7)); v8::Integer::New(7));
// Set two script break points before the script is loaded. // Set two script break points before the script is loaded.
int sbp1 = SetScriptBreakPointFromJS("test.html", 8, 0); int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 8, 0);
int sbp2 = SetScriptBreakPointFromJS("test.html", 9, 0); int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 9, 0);
// Compile the script and get the function. // Compile the script and get the function.
v8::Script::Compile(script, &origin)->Run(); v8::Script::Compile(script, &origin)->Run();
...@@ -1629,7 +1749,7 @@ TEST(ScriptBreakPointLineOffset) { ...@@ -1629,7 +1749,7 @@ TEST(ScriptBreakPointLineOffset) {
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
// Set a script break point with the script loaded. // Set a script break point with the script loaded.
sbp1 = SetScriptBreakPointFromJS("test.html", 9, 0); sbp1 = SetScriptBreakPointByNameFromJS("test.html", 9, 0);
// Call f and check that the script break point is active. // Call f and check that the script break point is active.
break_point_hit_count = 0; break_point_hit_count = 0;
...@@ -1673,9 +1793,9 @@ TEST(ScriptBreakPointLine) { ...@@ -1673,9 +1793,9 @@ TEST(ScriptBreakPointLine) {
" a=5; // line 12"); " a=5; // line 12");
// Set a couple script break point before the script is loaded. // Set a couple script break point before the script is loaded.
int sbp1 = SetScriptBreakPointFromJS("test.html", 0, -1); int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 0, -1);
int sbp2 = SetScriptBreakPointFromJS("test.html", 1, -1); int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 1, -1);
int sbp3 = SetScriptBreakPointFromJS("test.html", 5, -1); int sbp3 = SetScriptBreakPointByNameFromJS("test.html", 5, -1);
// Compile the script and get the function. // Compile the script and get the function.
break_point_hit_count = 0; break_point_hit_count = 0;
...@@ -1700,7 +1820,7 @@ TEST(ScriptBreakPointLine) { ...@@ -1700,7 +1820,7 @@ TEST(ScriptBreakPointLine) {
// Clear the script break point on g and set one on h. // Clear the script break point on g and set one on h.
ClearBreakPointFromJS(sbp3); ClearBreakPointFromJS(sbp3);
int sbp4 = SetScriptBreakPointFromJS("test.html", 6, -1); int sbp4 = SetScriptBreakPointByNameFromJS("test.html", 6, -1);
// Call g and check that the script break point in h is hit. // Call g and check that the script break point in h is hit.
g->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL);
...@@ -1712,7 +1832,7 @@ TEST(ScriptBreakPointLine) { ...@@ -1712,7 +1832,7 @@ TEST(ScriptBreakPointLine) {
// more. // more.
ClearBreakPointFromJS(sbp2); ClearBreakPointFromJS(sbp2);
ClearBreakPointFromJS(sbp4); ClearBreakPointFromJS(sbp4);
int sbp5 = SetScriptBreakPointFromJS("test.html", 4, -1); int sbp5 = SetScriptBreakPointByNameFromJS("test.html", 4, -1);
break_point_hit_count = 0; break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL); f->Call(env->Global(), 0, NULL);
g->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL);
...@@ -1725,7 +1845,7 @@ TEST(ScriptBreakPointLine) { ...@@ -1725,7 +1845,7 @@ TEST(ScriptBreakPointLine) {
CHECK_EQ(0, strlen(last_function_hit)); CHECK_EQ(0, strlen(last_function_hit));
// Set a break point in the code after the last function decleration. // Set a break point in the code after the last function decleration.
int sbp6 = SetScriptBreakPointFromJS("test.html", 12, -1); int sbp6 = SetScriptBreakPointByNameFromJS("test.html", 12, -1);
// Reload the script which should hit three break points. // Reload the script which should hit three break points.
break_point_hit_count = 0; break_point_hit_count = 0;
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
// Get the Debug object exposed from the debug context global object. // Get the Debug object exposed from the debug context global object.
Debug = debug.Debug Debug = debug.Debug
// Set and remove a script break point. // Set and remove a script break point for a named script.
var sbp = Debug.setScriptBreakPoint("1", 2, 3); var sbp = Debug.setScriptBreakPointByName("1", 2, 3);
assertEquals(1, Debug.scriptBreakPoints().length); assertEquals(1, Debug.scriptBreakPoints().length);
assertEquals("1", Debug.scriptBreakPoints()[0].script_name()); assertEquals("1", Debug.scriptBreakPoints()[0].script_name());
assertEquals(2, Debug.scriptBreakPoints()[0].line()); assertEquals(2, Debug.scriptBreakPoints()[0].line());
...@@ -38,10 +38,10 @@ assertEquals(3, Debug.scriptBreakPoints()[0].column()); ...@@ -38,10 +38,10 @@ assertEquals(3, Debug.scriptBreakPoints()[0].column());
Debug.clearBreakPoint(sbp); Debug.clearBreakPoint(sbp);
assertEquals(0, Debug.scriptBreakPoints().length); assertEquals(0, Debug.scriptBreakPoints().length);
// Set three script break points. // Set three script break points for named scripts.
var sbp1 = Debug.setScriptBreakPoint("1", 2, 3); var sbp1 = Debug.setScriptBreakPointByName("1", 2, 3);
var sbp2 = Debug.setScriptBreakPoint("2", 3, 4); var sbp2 = Debug.setScriptBreakPointByName("2", 3, 4);
var sbp3 = Debug.setScriptBreakPoint("3", 4, 5); var sbp3 = Debug.setScriptBreakPointByName("3", 4, 5);
// Check the content of the script break points. // Check the content of the script break points.
assertEquals(3, Debug.scriptBreakPoints().length); assertEquals(3, Debug.scriptBreakPoints().length);
...@@ -57,7 +57,48 @@ for (var i = 0; i < Debug.scriptBreakPoints().length; i++) { ...@@ -57,7 +57,48 @@ for (var i = 0; i < Debug.scriptBreakPoints().length; i++) {
assertEquals(4, x.line()); assertEquals(4, x.line());
assertEquals(5, x.column()); assertEquals(5, x.column());
} else { } else {
assertUnreachable("unecpected script_data " + x.script_data()); assertUnreachable("unecpected script_name " + x.script_name());
}
}
// Remove script break points (in another order than they where added).
assertEquals(3, Debug.scriptBreakPoints().length);
Debug.clearBreakPoint(sbp1);
assertEquals(2, Debug.scriptBreakPoints().length);
Debug.clearBreakPoint(sbp3);
assertEquals(1, Debug.scriptBreakPoints().length);
Debug.clearBreakPoint(sbp2);
assertEquals(0, Debug.scriptBreakPoints().length);
// Set and remove a script break point for a script id.
var sbp = Debug.setScriptBreakPointById(1, 2, 3);
assertEquals(1, Debug.scriptBreakPoints().length);
assertEquals(1, Debug.scriptBreakPoints()[0].script_id());
assertEquals(2, Debug.scriptBreakPoints()[0].line());
assertEquals(3, Debug.scriptBreakPoints()[0].column());
Debug.clearBreakPoint(sbp);
assertEquals(0, Debug.scriptBreakPoints().length);
// Set three script break points for script ids.
var sbp1 = Debug.setScriptBreakPointById(1, 2, 3);
var sbp2 = Debug.setScriptBreakPointById(2, 3, 4);
var sbp3 = Debug.setScriptBreakPointById(3, 4, 5);
// Check the content of the script break points.
assertEquals(3, Debug.scriptBreakPoints().length);
for (var i = 0; i < Debug.scriptBreakPoints().length; i++) {
var x = Debug.scriptBreakPoints()[i];
if (1 == x.script_id()) {
assertEquals(2, x.line());
assertEquals(3, x.column());
} else if (2 == x.script_id()) {
assertEquals(3, x.line());
assertEquals(4, x.column());
} else if (3 == x.script_id()) {
assertEquals(4, x.line());
assertEquals(5, x.column());
} else {
assertUnreachable("unecpected script_id " + x.script_id());
} }
} }
......
...@@ -30,8 +30,13 @@ ...@@ -30,8 +30,13 @@
Debug = debug.Debug Debug = debug.Debug
// Simple function which stores the last debug event. // Simple function which stores the last debug event.
listenerComplete = false; var listenerComplete = false;
exception = false; var exception = false;
var f_script_id = 0;
var g_script_id = 0;
var h_script_id = 0;
var f_line = 0;
var g_line = 0;
var base_request = '"seq":0,"type":"request","command":"setbreakpoint"' var base_request = '"seq":0,"type":"request","command":"setbreakpoint"'
...@@ -44,13 +49,18 @@ function safeEval(code) { ...@@ -44,13 +49,18 @@ function safeEval(code) {
} }
} }
function testArguments(dcp, arguments, success, type) { function testArguments(dcp, arguments, success, is_script) {
var request = '{' + base_request + ',"arguments":' + arguments + '}' var request = '{' + base_request + ',"arguments":' + arguments + '}'
var json_response = dcp.processDebugJSONRequest(request); var json_response = dcp.processDebugJSONRequest(request);
var response = safeEval(json_response); var response = safeEval(json_response);
if (success) { if (success) {
assertTrue(response.success, json_response); assertTrue(response.success, json_response);
assertEquals(type ? type : 'script', response.body.type, json_response); if (is_script) {
assertEquals('scriptName', response.body.type, json_response);
} else {
assertEquals('scriptId', response.body.type, json_response);
print(response.body.script_id);
}
} else { } else {
assertFalse(response.success, json_response); assertFalse(response.success, json_response);
} }
...@@ -79,18 +89,23 @@ function listener(event, exec_state, event_data, data) { ...@@ -79,18 +89,23 @@ function listener(event, exec_state, event_data, data) {
testArguments(dcp, '{"type":"function","target":"f","ignoreCount":-1}', false); testArguments(dcp, '{"type":"function","target":"f","ignoreCount":-1}', false);
// Test some legal setbreakpoint requests. // Test some legal setbreakpoint requests.
testArguments(dcp, '{"type":"function","target":"f"}', true); testArguments(dcp, '{"type":"function","target":"f"}', true, false);
testArguments(dcp, '{"type":"function","target":"h"}', true, 'function'); testArguments(dcp, '{"type":"function","target":"h"}', true, false);
testArguments(dcp, '{"type":"function","target":"f","line":1}', true); testArguments(dcp, '{"type":"function","target":"f","line":1}', true, false);
testArguments(dcp, '{"type":"function","target":"f","position":1}', true); testArguments(dcp, '{"type":"function","target":"f","position":1}', true, false);
testArguments(dcp, '{"type":"function","target":"f","condition":"i == 1"}', true); testArguments(dcp, '{"type":"function","target":"f","condition":"i == 1"}', true, false);
testArguments(dcp, '{"type":"function","target":"f","enabled":true}', true); testArguments(dcp, '{"type":"function","target":"f","enabled":true}', true, false);
testArguments(dcp, '{"type":"function","target":"f","enabled":false}', true); testArguments(dcp, '{"type":"function","target":"f","enabled":false}', true, false);
testArguments(dcp, '{"type":"function","target":"f","ignoreCount":7}', true); testArguments(dcp, '{"type":"function","target":"f","ignoreCount":7}', true, false);
testArguments(dcp, '{"type":"script","target":"test"}', true);
testArguments(dcp, '{"type":"script","target":"test"}', true); testArguments(dcp, '{"type":"script","target":"test"}', true, true);
testArguments(dcp, '{"type":"script","target":"test","line":1}', true); testArguments(dcp, '{"type":"script","target":"test"}', true, true);
testArguments(dcp, '{"type":"script","target":"test","column":1}', true); testArguments(dcp, '{"type":"script","target":"test","line":1}', true, true);
testArguments(dcp, '{"type":"script","target":"test","column":1}', true, true);
testArguments(dcp, '{"type":"scriptId","target":' + f_script_id + ',"line":' + f_line + '}', true, false);
testArguments(dcp, '{"type":"scriptId","target":' + g_script_id + ',"line":' + g_line + '}', true, false);
testArguments(dcp, '{"type":"scriptId","target":' + h_script_id + ',"line":' + h_line + '}', true, false);
// Indicate that all was processed. // Indicate that all was processed.
listenerComplete = true; listenerComplete = true;
...@@ -113,10 +128,27 @@ function g() { ...@@ -113,10 +128,27 @@ function g() {
eval('function h(){}'); eval('function h(){}');
// Check the script ids for the test functions.
f_script_id = Debug.findScript(f).id;
g_script_id = Debug.findScript(g).id;
h_script_id = Debug.findScript(h).id;
assertTrue(f_script_id > 0, "invalid script id for f");
assertTrue(g_script_id > 0, "invalid script id for g");
assertTrue(h_script_id > 0, "invalid script id for h");
assertEquals(f_script_id, g_script_id);
// Get the source line for the test functions.
f_line = Debug.findFunctionSourceLocation(f).line;
g_line = Debug.findFunctionSourceLocation(g).line;
h_line = Debug.findFunctionSourceLocation(h).line;
assertTrue(f_line > 0, "invalid line for f");
assertTrue(g_line > 0, "invalid line for g");
assertTrue(f_line < g_line);
assertEquals(h_line, 0, "invalid line for h");
// Set a break point and call to invoke the debug event listener. // Set a break point and call to invoke the debug event listener.
Debug.setBreakPoint(g, 0, 0); Debug.setBreakPoint(g, 0, 0);
g(); g();
// Make sure that the debug event listener vas invoked. // Make sure that the debug event listener vas invoked.
assertTrue(listenerComplete, "listener did not run to completion"); assertTrue(listenerComplete, "listener did not run to completion: " + exception);
assertFalse(exception, "exception in listener")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment