Commit 8ab945f2 authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Translate locations to positions properly

... at least for the function which will remain after restructuring of
the debug interface. For some methods that will be removed anyway, we
just return zero / null for now.

I also refactored the ScriptLocationFromLine method to make it more
readable and reuse parts in other files (like ScriptLinePosition).

BUG=5655
R=titzer@chromium.org, jgruber@chromium.org

Review-Url: https://codereview.chromium.org/2512833003
Cr-Commit-Position: refs/heads/master@{#41115}
parent eefe11a1
......@@ -13423,15 +13423,7 @@ bool Script::GetPositionInfo(Handle<Script> script, int position,
PositionInfo* info, OffsetFlag offset_flag) {
// For wasm, we do not create an artificial line_ends array, but do the
// translation directly.
if (script->type() == Script::TYPE_WASM) {
Handle<WasmCompiledModule> compiled_module(
WasmCompiledModule::cast(script->wasm_compiled_module()));
DCHECK_LE(0, position);
return wasm::GetPositionInfo(compiled_module,
static_cast<uint32_t>(position), info);
}
InitLineEnds(script);
if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
return script->GetPositionInfo(position, info, offset_flag);
}
......@@ -13467,6 +13459,16 @@ bool Script::GetPositionInfo(int position, PositionInfo* info,
OffsetFlag offset_flag) const {
DisallowHeapAllocation no_allocation;
// For wasm, we do not rely on the line_ends array, but do the translation
// directly.
if (type() == Script::TYPE_WASM) {
Handle<WasmCompiledModule> compiled_module(
WasmCompiledModule::cast(wasm_compiled_module()));
DCHECK_LE(0, position);
return wasm::GetPositionInfo(compiled_module,
static_cast<uint32_t>(position), info);
}
if (line_ends()->IsUndefined(GetIsolate())) {
// Slow mode: we do not have line_ends. We have to iterate through source.
if (!GetPositionInfoSlow(this, position, info)) return false;
......
......@@ -1595,12 +1595,41 @@ RUNTIME_FUNCTION(Runtime_ScriptLineCount) {
CHECK(script->value()->IsScript());
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
if (script_handle->type() == Script::TYPE_WASM) {
// Return 0 for now; this function will disappear soon anyway.
return Smi::FromInt(0);
}
Script::InitLineEnds(script_handle);
FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
return Smi::FromInt(line_ends_array->length());
}
namespace {
int ScriptLinePosition(Handle<Script> script, int line) {
if (line < 0) return -1;
if (script->type() == Script::TYPE_WASM) {
return WasmCompiledModule::cast(script->wasm_compiled_module())
->GetFunctionOffset(line);
}
Script::InitLineEnds(script);
FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
const int line_count = line_ends_array->length();
DCHECK_LT(0, line_count);
if (line == 0) return 0;
// If line == line_count, we return the first position beyond the last line.
if (line > line_count) return -1;
return Smi::cast(line_ends_array->get(line - 1))->value() + 1;
}
} // namespace
// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) {
HandleScope scope(isolate);
......@@ -1611,21 +1640,7 @@ RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) {
CHECK(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();
// If line == line_count, we return the first position beyond the last line.
if (line < 0 || line > line_count) {
return Smi::FromInt(-1);
} else if (line == 0) {
return Smi::kZero;
} else {
DCHECK(0 < line && line <= line_count);
const int pos = Smi::cast(line_ends_array->get(line - 1))->value() + 1;
return Smi::FromInt(pos);
}
return Smi::FromInt(ScriptLinePosition(script_handle, line));
}
// TODO(5530): Remove once uses in debug.js are gone.
......@@ -1638,6 +1653,11 @@ RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) {
CHECK(script->value()->IsScript());
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
if (script_handle->type() == Script::TYPE_WASM) {
// Return zero for now; this function will disappear soon anyway.
return Smi::FromInt(0);
}
Script::InitLineEnds(script_handle);
FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
......@@ -1683,6 +1703,20 @@ static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
namespace {
int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) {
if (line < 0 || offset < 0) return -1;
if (line == 0) return ScriptLinePosition(script, line) + offset;
Script::PositionInfo info;
if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) {
return -1;
}
const int total_line = info.line + line;
return ScriptLinePosition(script, total_line);
}
Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script,
Handle<Object> opt_line,
Handle<Object> opt_column,
......@@ -1690,51 +1724,24 @@ Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script,
// Line and column are possibly undefined and we need to handle these cases,
// additionally subtracting corresponding offsets.
int32_t line;
if (opt_line->IsNull(isolate) || opt_line->IsUndefined(isolate)) {
line = 0;
} else {
int32_t line = 0;
if (!opt_line->IsNull(isolate) && !opt_line->IsUndefined(isolate)) {
CHECK(opt_line->IsNumber());
line = NumberToInt32(*opt_line) - script->line_offset();
}
int32_t column;
if (opt_column->IsNull(isolate) || opt_column->IsUndefined(isolate)) {
column = 0;
} else {
int32_t column = 0;
if (!opt_column->IsNull(isolate) && !opt_column->IsUndefined(isolate)) {
CHECK(opt_column->IsNumber());
column = NumberToInt32(*opt_column);
if (line == 0) column -= script->column_offset();
}
if (line < 0 || column < 0 || offset < 0) {
return isolate->factory()->null_value();
}
Script::InitLineEnds(script);
int line_position = ScriptLinePositionWithOffset(script, line, offset);
if (line_position < 0 || column < 0) return isolate->factory()->null_value();
FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
const int line_count = line_ends_array->length();
int position;
if (line == 0) {
position = offset + column;
} else {
Script::PositionInfo info;
if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET) ||
info.line + line >= line_count) {
return isolate->factory()->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, position, Script::NO_OFFSET, isolate);
return GetJSPositionInfo(script, line_position + column, Script::NO_OFFSET,
isolate);
}
// Slow traversal over all scripts on the heap.
......@@ -1820,6 +1827,11 @@ RUNTIME_FUNCTION(Runtime_ScriptSourceLine) {
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());
......
......@@ -377,3 +377,11 @@ Vector<const uint8_t> WasmCompiledModule::GetRawFunctionName(
return Vector<const uint8_t>(bytes->GetCharsAddress() + function.name_offset,
function.name_length);
}
int WasmCompiledModule::GetFunctionOffset(uint32_t func_index) const {
std::vector<WasmFunction>& functions = module()->functions;
if (static_cast<uint32_t>(func_index) >= functions.size()) return -1;
DCHECK_GE(static_cast<uint32_t>(kMaxInt),
functions[func_index].code_start_offset);
return static_cast<int>(functions[func_index].code_start_offset);
}
......@@ -271,6 +271,11 @@ class WasmCompiledModule : public FixedArray {
// Does not allocate, hence gc-safe.
Vector<const uint8_t> GetRawFunctionName(uint32_t func_index);
// Return the byte offset of the function identified by the given index.
// The offset will be relative to the start of the module bytes.
// Returns -1 if the function index is invalid.
int GetFunctionOffset(uint32_t func_index) const;
private:
void InitId();
......
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