* Runs the script returning the resulting value.
*/
Local<Value> Run();
+
+ /**
+ * Returns the script id value.
+ */
+ Local<Value> Id();
};
//
+// 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
//
V(StringLength) \
V(ScriptSource) \
V(ScriptName) \
+ V(ScriptId) \
V(ScriptLineOffset) \
V(ScriptColumnOffset) \
V(ScriptType) \
static Object* ArrayGetLength(Object* object, void*);
static Object* StringGetLength(Object* object, void*);
static Object* ScriptGetName(Object* object, void*);
+ static Object* ScriptGetId(Object* object, void*);
static Object* ScriptGetSource(Object* object, void*);
static Object* ScriptGetLineOffset(Object* object, void*);
static Object* ScriptGetColumnOffset(Object* object, void*);
}
+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 ---
Factory::LookupAsciiSymbol("source"),
proxy_source,
common_attributes);
- Handle<Proxy> proxy_data = Factory::NewProxy(&Accessors::ScriptName);
+ Handle<Proxy> proxy_name = Factory::NewProxy(&Accessors::ScriptName);
script_descriptors =
Factory::CopyAppendProxyDescriptor(
script_descriptors,
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);
Handle<Proxy> proxy_line_offset =
Factory::NewProxy(&Accessors::ScriptLineOffset);
var result = '';
for (i = 0; i < body.length; i++) {
if (i != 0) result += '\n';
+ if (body[i].id) {
+ result += body[i].id;
+ } else {
+ result += '[no id]';
+ }
+ result += ', ';
if (body[i].name) {
result += body[i].name;
} else {
result += '[unnamed] ';
- var sourceStart = body[i].sourceStart;
- if (sourceStart.length > 40) {
- sourceStart = sourceStart.substring(0, 37) + '...';
- }
- result += sourceStart;
}
result += ' (lines: ';
- result += body[i].sourceLines;
+ result += body[i].lineCount;
result += ', length: ';
result += body[i].sourceLength;
if (body[i].type == Debug.ScriptType.Native) {
} else if (body[i].type == Debug.ScriptType.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;
break;
Extension: 1,
Normal: 2 };
+// The different script break point types.
+Debug.ScriptBreakPointType = { ScriptId: 0,
+ ScriptName: 1 };
+
function ScriptTypeFlag(type) {
return (1 << type);
}
// Object representing a script break point. The script is referenced by its
-// script name and the break point is represented as line and column.
-function ScriptBreakPoint(script_name, opt_line, opt_column) {
- this.script_name_ = script_name;
+// 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) {
+ 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.column_ = opt_column;
this.hit_count_ = 0;
};
+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_;
};
// Check whether a script matches this script break point. Currently this is
// only based on script name.
ScriptBreakPoint.prototype.matchesScript = function(script) {
- return this.script_name_ == script.name &&
- script.line_offset <= this.line_ &&
- this.line_ < script.line_offset + script.lineCount();
+ if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
+ return this.script_id_ == script.id;
+ } else { // this.type_ == Debug.ScriptBreakPointType.ScriptName
+ return this.script_name_ == script.name &&
+ script.line_offset <= this.line_ &&
+ this.line_ < script.line_offset + script.lineCount();
+ }
};
// break points set in this script.
function UpdateScriptBreakPoints(script) {
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);
}
}
}
// If the script for the function has a name convert this to a script break
// point.
- if (script && script.name) {
+ if (script && script.id) {
// Adjust the source position to be script relative.
source_position += %FunctionGetScriptSourcePosition(func);
// Find line and column for the position in the script and set a script
// break point from that.
var location = script.locationFromPosition(source_position);
- return this.setScriptBreakPoint(script.name,
- location.line, location.column,
- opt_condition);
+ 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, opt_line, opt_column);
}
-// 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.
-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.
- 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.
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 it this script break point matches any
+ // 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++) {
}
+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) {
var script_break_point = this.findScriptBreakPoint(break_point_number, false);
script_break_point.enable();
o.body.sourceLine = this.sourceLine(),
o.body.sourceColumn = this.sourceColumn(),
o.body.sourceLineText = this.sourceLineText(),
- o.body.script = { name: script.name(),
- lineOffset: script.lineOffset(),
- columnOffset: script.columnOffset(),
- lineCount: script.lineCount()
- };
+ o.body.script = MakeScriptObject_(script, false);
}
// Add an Array of break points hit if any.
// Add script information to the event if available.
var script = this.func().script();
if (script) {
- o.body.script = { name: script.name(),
- lineOffset: script.lineOffset(),
- columnOffset: script.columnOffset(),
- lineCount: script.lineCount()
- };
+ o.body.script = MakeScriptObject_(script, false);
}
} else {
o.body.sourceLine = -1;
o.event = "afterCompile";
}
o.body = {};
- o.body.script = { name: this.script_.name(),
- lineOffset: this.script_.lineOffset(),
- columnOffset: this.script_.columnOffset(),
- lineCount: this.script_.lineCount(),
- source: this.script_.source()
- };
+ o.body.script = MakeScriptObject_(this.script_, true);
return o.toJSONProtocol();
}
};
+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) {
this.exec_state_ = exec_state;
this.running_ = false;
response.failed('Missing argument "type" or "target"');
return;
}
- if (type != 'function' && type != 'script') {
+ if (type != 'function' && type != 'script' && type != 'scriptId') {
response.failed('Illegal type "' + type + '"');
return;
}
// Set function break point.
break_point_number = Debug.setBreakPoint(f, line, column, condition);
- } else {
+ } else if (type == 'script') {
// set script break point.
- break_point_number = Debug.setScriptBreakPoint(target,
- line, column,
- condition);
+ break_point_number =
+ Debug.setScriptBreakPointByName(target, line, column, condition);
+ } else { // type == 'scriptId.
+ break_point_number =
+ Debug.setScriptBreakPointById(target, line, column, condition);
}
// Set additional break point properties.
// Add break point information to the response.
if (break_point instanceof ScriptBreakPoint) {
- response.body.type = 'script';
- response.body.script_name = break_point.script_name();
+ if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
+ 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.column = break_point.column();
} else {
if (scripts[i].name) {
script.name = scripts[i].name;
}
+ script.id = scripts[i].id;
script.lineOffset = scripts[i].line_offset;
script.columnOffset = scripts[i].column_offset;
script.lineCount = scripts[i].lineCount();
Handle<Script> Factory::NewScript(Handle<String> source) {
+ static uint32_t next_id = 1;
+
Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
script->set_source(*source);
script->set_name(Heap::undefined_value());
+ script->set_id(*Factory::NewNumberFromUint(next_id++));
script->set_line_offset(Smi::FromInt(0));
script->set_column_offset(Smi::FromInt(0));
script->set_type(Smi::FromInt(SCRIPT_TYPE_NORMAL));
}
+Handle<Object> Factory::NewNumberFromUint(uint32_t value) {
+ CALL_HEAP_FUNCTION(Heap::NumberFromUint32(value), Object);
+}
+
+
Handle<JSObject> Factory::NewNeanderObject() {
CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(Heap::neander_map()),
JSObject);
PretenureFlag pretenure = NOT_TENURED);
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
// structures in the heap.
FrameMirror.prototype.sourceLocation = function() {
if (this.func().resolved() && this.func().script()) {
- return this.func().script().locationFromPosition(this.sourcePosition());
+ return this.func().script().locationFromPosition(this.sourcePosition(),
+ true);
}
};
};
+ScriptMirror.prototype.id = function() {
+ return this.script_.id;
+};
+
+
ScriptMirror.prototype.source = function() {
return this.script_.source;
};
ACCESSORS(Script, source, Object, kSourceOffset)
ACCESSORS(Script, name, Object, kNameOffset)
+ACCESSORS(Script, id, Object, kIdOffset)
ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
// [name]: the script name.
DECL_ACCESSORS(name, Object)
+ // [id]: the script id.
+ DECL_ACCESSORS(id, Object)
+
// [line_offset]: script line offset in resource from where it was extracted.
DECL_ACCESSORS(line_offset, Smi)
static const int kWrapperOffset = kColumnOffsetOffset + kPointerSize;
static const int kTypeOffset = kWrapperOffset + 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:
DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
}
-// Set a break point in a script using the global Debug object.
-static int SetScriptBreakPointFromJS(const char* script_data,
- int line, int column) {
+// Set a break point in a script identified by id using the global Debug object.
+static int SetScriptBreakPointByIdFromJS(int script_id, 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.setScriptBreakPoint(\"%s\",%d,%d)",
- script_data, line, column);
+ "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
+ script_id, line, column);
} else {
// Column not specified set script break point on line.
OS::SNPrintF(buffer,
- "debug.Debug.setScriptBreakPoint(\"%s\",%d)",
- script_data, line);
+ "debug.Debug.setScriptBreakPointById(%d,%d)",
+ 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';
{
}
-// Test that break points can be set using the global Debug object.
-TEST(ScriptBreakPointThroughJavaScript) {
+// Test that break points on scripts identified by name can be set using the
+// global Debug object.
+TEST(ScriptBreakPointByNameThroughJavaScript) {
break_point_hit_count = 0;
v8::HandleScope scope;
DebugLocalContext env;
v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
v8::Undefined());
- v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run();
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
CHECK_EQ(0, break_point_hit_count);
// 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;
f->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
CHECK_EQ(0, break_point_hit_count);
// 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;
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, 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 = SetScriptBreakPointFromJS("test", 4, 0);
- int sbp4 = SetScriptBreakPointFromJS("test", 12, 0);
- int sbp5 = SetScriptBreakPointFromJS("test", 14, 0);
- int sbp6 = SetScriptBreakPointFromJS("test", 15, 0);
+ int sbp3 = SetScriptBreakPointByNameFromJS("test", 4, 0);
+ int sbp4 = SetScriptBreakPointByNameFromJS("test", 12, 0);
+ int sbp5 = SetScriptBreakPointByNameFromJS("test", 14, 0);
+ int sbp6 = SetScriptBreakPointByNameFromJS("test", 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 the all the break points again.
+ // Remove all the break points again.
break_point_hit_count = 0;
ClearBreakPointFromJS(sbp2);
ClearBreakPointFromJS(sbp3);
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- // Now set a function break point
- int bp7 = SetBreakPointFromJS("g", 0, 0);
+ v8::Debug::SetDebugEventListener(NULL);
+ 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);
CHECK_EQ(1, break_point_hit_count);
- // Reload the script and get g again checking that the break point survives.
- // This tests that the function break point was converted to a script break
- // point.
- v8::Script::Compile(script, &origin)->Run();
- g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
+ // Remove the break point again.
+ break_point_hit_count = 0;
+ ClearBreakPointFromJS(sbp1);
+ 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 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);
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);
CheckDebuggerUnloaded();
CHECK_EQ(4, sbp4);
CHECK_EQ(5, sbp5);
CHECK_EQ(6, sbp6);
- CHECK_EQ(7, bp7);
}
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("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.
break_point_hit_count = 0;
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
// 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.
break_point_hit_count = 0;
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("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.
break_point_hit_count = 0;
v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8::String::New("2"));
// 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.
v8::Script::Compile(script, &origin_1)->Run();
v8::ScriptOrigin(v8::String::New("test"));
// 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.
v8::Script::Compile(script_f, &origin)->Run();
CHECK_EQ(0, break_point_hit_count);
// 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.
break_point_hit_count = 0;
v8::Integer::New(7));
// Set two script break points before the script is loaded.
- int sbp1 = SetScriptBreakPointFromJS("test.html", 8, 0);
- int sbp2 = SetScriptBreakPointFromJS("test.html", 9, 0);
+ int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 8, 0);
+ int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 9, 0);
// Compile the script and get the function.
v8::Script::Compile(script, &origin)->Run();
CHECK_EQ(0, break_point_hit_count);
// 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.
break_point_hit_count = 0;
" a=5; // line 12");
// Set a couple script break point before the script is loaded.
- int sbp1 = SetScriptBreakPointFromJS("test.html", 0, -1);
- int sbp2 = SetScriptBreakPointFromJS("test.html", 1, -1);
- int sbp3 = SetScriptBreakPointFromJS("test.html", 5, -1);
+ int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 0, -1);
+ int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 1, -1);
+ int sbp3 = SetScriptBreakPointByNameFromJS("test.html", 5, -1);
// Compile the script and get the function.
break_point_hit_count = 0;
// Clear the script break point on g and set one on h.
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.
g->Call(env->Global(), 0, NULL);
// more.
ClearBreakPointFromJS(sbp2);
ClearBreakPointFromJS(sbp4);
- int sbp5 = SetScriptBreakPointFromJS("test.html", 4, -1);
+ int sbp5 = SetScriptBreakPointByNameFromJS("test.html", 4, -1);
break_point_hit_count = 0;
f->Call(env->Global(), 0, NULL);
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, strlen(last_function_hit));
// 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.
break_point_hit_count = 0;
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
-// Set and remove a script break point.
-var sbp = Debug.setScriptBreakPoint("1", 2, 3);
+// Set and remove a script break point for a named script.
+var sbp = Debug.setScriptBreakPointByName("1", 2, 3);
assertEquals(1, Debug.scriptBreakPoints().length);
assertEquals("1", Debug.scriptBreakPoints()[0].script_name());
assertEquals(2, Debug.scriptBreakPoints()[0].line());
Debug.clearBreakPoint(sbp);
assertEquals(0, Debug.scriptBreakPoints().length);
-// Set three script break points.
-var sbp1 = Debug.setScriptBreakPoint("1", 2, 3);
-var sbp2 = Debug.setScriptBreakPoint("2", 3, 4);
-var sbp3 = Debug.setScriptBreakPoint("3", 4, 5);
+// Set three script break points for named scripts.
+var sbp1 = Debug.setScriptBreakPointByName("1", 2, 3);
+var sbp2 = Debug.setScriptBreakPointByName("2", 3, 4);
+var sbp3 = Debug.setScriptBreakPointByName("3", 4, 5);
// Check the content of the script break points.
assertEquals(3, Debug.scriptBreakPoints().length);
assertEquals(4, x.line());
assertEquals(5, x.column());
} 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());
}
}
Debug = debug.Debug
// Simple function which stores the last debug event.
-listenerComplete = false;
-exception = false;
+var listenerComplete = 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"'
}
}
-function testArguments(dcp, arguments, success, type) {
+function testArguments(dcp, arguments, success, is_script) {
var request = '{' + base_request + ',"arguments":' + arguments + '}'
var json_response = dcp.processDebugJSONRequest(request);
var response = safeEval(json_response);
if (success) {
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 {
assertFalse(response.success, json_response);
}
testArguments(dcp, '{"type":"function","target":"f","ignoreCount":-1}', false);
// Test some legal setbreakpoint requests.
- testArguments(dcp, '{"type":"function","target":"f"}', true);
- testArguments(dcp, '{"type":"function","target":"h"}', true, 'function');
- testArguments(dcp, '{"type":"function","target":"f","line":1}', true);
- testArguments(dcp, '{"type":"function","target":"f","position":1}', true);
- testArguments(dcp, '{"type":"function","target":"f","condition":"i == 1"}', true);
- testArguments(dcp, '{"type":"function","target":"f","enabled":true}', true);
- testArguments(dcp, '{"type":"function","target":"f","enabled":false}', true);
- testArguments(dcp, '{"type":"function","target":"f","ignoreCount":7}', true);
- testArguments(dcp, '{"type":"script","target":"test"}', true);
- testArguments(dcp, '{"type":"script","target":"test"}', true);
- testArguments(dcp, '{"type":"script","target":"test","line":1}', true);
- testArguments(dcp, '{"type":"script","target":"test","column":1}', true);
+ testArguments(dcp, '{"type":"function","target":"f"}', true, false);
+ testArguments(dcp, '{"type":"function","target":"h"}', true, false);
+ testArguments(dcp, '{"type":"function","target":"f","line":1}', true, false);
+ testArguments(dcp, '{"type":"function","target":"f","position":1}', true, false);
+ testArguments(dcp, '{"type":"function","target":"f","condition":"i == 1"}', true, false);
+ testArguments(dcp, '{"type":"function","target":"f","enabled":true}', true, false);
+ testArguments(dcp, '{"type":"function","target":"f","enabled":false}', true, false);
+ testArguments(dcp, '{"type":"function","target":"f","ignoreCount":7}', true, false);
+
+ testArguments(dcp, '{"type":"script","target":"test"}', true, true);
+ testArguments(dcp, '{"type":"script","target":"test"}', true, 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.
listenerComplete = true;
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.
Debug.setBreakPoint(g, 0, 0);
g();
// Make sure that the debug event listener vas invoked.
-assertTrue(listenerComplete, "listener did not run to completion");
-assertFalse(exception, "exception in listener")
+assertTrue(listenerComplete, "listener did not run to completion: " + exception);