Chromium Code Reviews| Index: src/runtime/runtime-debug.cc |
| diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc |
| index b65324fb8fc076a968fc926dbca95705bfb1af10..a9c2bc0cfe71d55bfdff08c0de64744c8287fea2 100644 |
| --- a/src/runtime/runtime-debug.cc |
| +++ b/src/runtime/runtime-debug.cc |
| @@ -1562,33 +1562,23 @@ RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) { |
| } |
| } |
| -RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { |
| - HandleScope scope(isolate); |
| - DCHECK(args.length() == 3); |
| - CONVERT_ARG_CHECKED(JSValue, script, 0); |
| - CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]); |
| - CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2); |
| - |
| - RUNTIME_ASSERT(script->value()->IsScript()); |
| - Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| - |
| +static Object* GetJSPositionInfo(Handle<Script> script, int position, |
|
Yang
2016/05/24 07:54:31
Let's return a handle and let the call site derefe
jgruber
2016/05/24 10:52:55
Done.
|
| + Script::OffsetFlag offset_flag, |
| + Isolate* isolate) { |
| Script::PositionInfo info; |
| - const Script::OffsetFlag offset_flag = |
| - with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET; |
| - if (!script_handle->GetPositionInfo(position, &info, offset_flag)) { |
| + if (!script->GetPositionInfo(position, &info, offset_flag)) { |
| return isolate->heap()->null_value(); |
| } |
| - Handle<String> source = |
| - handle(String::cast(script_handle->source()), isolate); |
| + Handle<String> source = handle(String::cast(script->source()), isolate); |
| Handle<String> sourceText = |
| isolate->factory()->NewSubString(source, info.line_start, info.line_end); |
| Handle<JSObject> jsinfo = |
| isolate->factory()->NewJSObject(isolate->object_function()); |
| - JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), |
| - script_handle, NONE); |
| + JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script, |
| + NONE); |
| JSObject::AddProperty(jsinfo, isolate->factory()->position_string(), |
| handle(Smi::FromInt(position), isolate), NONE); |
| JSObject::AddProperty(jsinfo, isolate->factory()->line_string(), |
| @@ -1601,6 +1591,107 @@ RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { |
| return *jsinfo; |
| } |
| +// Get information on a specific source line and column possibly offset by a |
| +// fixed source position. This function is used to find a source position from |
| +// a line and column position. The fixed source position offset is typically |
| +// used to find a source position in a function based on a line and column in |
| +// the source for the function alone. The offset passed will then be the |
| +// start position of the source for the function within the full script source. |
| +// Note that incoming line and column parameters are assumed to be passed *with* |
| +// offsets. |
| +RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) { |
| + HandleScope scope(isolate); |
| + DCHECK(args.length() == 4); |
| + CONVERT_ARG_CHECKED(JSValue, script, 0); |
| + CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); |
| + CONVERT_NUMBER_CHECKED(int32_t, column, Int32, args[2]); |
| + CONVERT_NUMBER_CHECKED(int32_t, offset_position, Int32, args[3]); |
| + |
| + RUNTIME_ASSERT(script->value()->IsScript()); |
| + Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| + |
| + // Subtract any offsets from line and column. |
| + line -= script_handle->line_offset(); |
| + if (line == 0) column -= script_handle->column_offset(); |
| + |
| + if (line < 0 || column < 0 || offset_position < 0) { |
| + 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(); |
| + |
| + int position; |
| + if (line == 0) { |
| + position = offset_position + column; |
| + } else { |
| + Script::PositionInfo info; |
| + if (!script_handle->GetPositionInfo(offset_position, &info, |
| + Script::NO_OFFSET) || |
| + info.line + line >= line_count) { |
| + return isolate->heap()->null_value(); |
| + } |
| + |
| + const int offset_line = info.line + line; |
| + const int offset_line_position = |
| + (offset_line == 0) |
| + ? 0 |
| + : Smi::cast(line_ends_array->get(offset_line - 1))->value() + 1; |
| + position = offset_line_position + column; |
| + } |
| + |
| + return GetJSPositionInfo(script_handle, position, Script::NO_OFFSET, isolate); |
| +} |
| + |
| +RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { |
| + HandleScope scope(isolate); |
| + DCHECK(args.length() == 3); |
| + CONVERT_ARG_CHECKED(JSValue, script, 0); |
| + CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]); |
| + CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2); |
| + |
| + RUNTIME_ASSERT(script->value()->IsScript()); |
| + Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| + |
| + const Script::OffsetFlag offset_flag = |
| + with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET; |
| + return GetJSPositionInfo(script_handle, 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. |
| +RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { |
| + HandleScope scope(isolate); |
| + DCHECK(args.length() == 2); |
| + CONVERT_ARG_CHECKED(JSValue, script, 0); |
| + CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); |
| + |
| + RUNTIME_ASSERT(script->value()->IsScript()); |
| + Handle<Script> script_handle = Handle<Script>(Script::cast(script->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::cast(line_ends_array->get(line - 1))->value() + 1; |
| + const int end = Smi::cast(line_ends_array->get(line))->value(); |
| + |
| + Handle<String> source = |
| + handle(String::cast(script_handle->source()), isolate); |
| + Handle<String> str = isolate->factory()->NewSubString(source, start, end); |
| + |
| + return *str; |
| +} |
| + |
| // Set one shot breakpoints for the callback function that is passed to a |
| // built-in function such as Array.forEach to enable stepping into the callback, |
| // if we are indeed stepping and the callback is subject to debugging. |