Version 2.12.0-159.0.dev
Merge commit '5021f7dc1950bd36ff77be515b2acdf653be9a06' into 'dev'
diff --git a/DEPS b/DEPS
index 37c7c81..4f282eb 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
# Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a
# cipd package used to run Dart scripts in the build and test infrastructure.
- "sdk_tag": "version:2.12.0-0.0.dev",
+ "sdk_tag": "version:2.12.0-133.2.beta",
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index 049e919..24d84ab 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -82,23 +82,25 @@
const Script& script = Script::Handle(FindScript(&iterator));
// Initialize argument 'failed_assertion' with source snippet.
- intptr_t from_line, from_column;
- script.GetTokenLocation(assertion_start, &from_line, &from_column);
- intptr_t to_line, to_column;
- script.GetTokenLocation(assertion_end, &to_line, &to_column);
+ auto& condition_text = String::Handle();
// Extract the assertion condition text (if source is available).
- auto& condition_text = String::Handle(
- script.GetSnippet(from_line, from_column, to_line, to_column));
+ intptr_t from_line = -1, from_column = -1;
+ if (script.GetTokenLocation(assertion_start, &from_line, &from_column)) {
+ // Extract the assertion condition text (if source is available).
+ intptr_t to_line, to_column;
+ script.GetTokenLocation(assertion_end, &to_line, &to_column);
+ condition_text =
+ script.GetSnippet(from_line, from_column, to_line, to_column);
+ }
if (condition_text.IsNull()) {
condition_text = Symbols::OptimizedOut().raw();
}
args.SetAt(0, condition_text);
// Initialize location arguments starting at position 1.
- // Do not set a column if the source has been generated as it will be wrong.
args.SetAt(1, String::Handle(script.url()));
args.SetAt(2, Smi::Handle(Smi::New(from_line)));
- args.SetAt(3, Smi::Handle(Smi::New(script.HasSource() ? from_column : -1)));
+ args.SetAt(3, Smi::Handle(Smi::New(from_column)));
args.SetAt(4, message);
Exceptions::ThrowByType(Exceptions::kAssertion, args);
@@ -181,8 +183,8 @@
iterator.NextFrame(); // Skip native call.
const Script& script = Script::Handle(Exceptions::GetCallerScript(&iterator));
args.SetAt(0, String::Handle(script.url()));
- intptr_t line;
- script.GetTokenLocation(fallthrough_pos, &line, NULL);
+ intptr_t line = -1;
+ script.GetTokenLocation(fallthrough_pos, &line);
args.SetAt(1, Smi::Handle(Smi::New(line)));
Exceptions::ThrowByType(Exceptions::kFallThrough, args);
@@ -208,8 +210,8 @@
const Script& script = Script::Handle(Exceptions::GetCallerScript(&iterator));
args.SetAt(0, class_name);
args.SetAt(1, String::Handle(script.url()));
- intptr_t line;
- script.GetTokenLocation(error_pos, &line, NULL);
+ intptr_t line = -1;
+ script.GetTokenLocation(error_pos, &line);
args.SetAt(2, Smi::Handle(Smi::New(line)));
Exceptions::ThrowByType(Exceptions::kAbstractClassInstantiation, args);
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index eddf299..a3ca6fe 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1628,17 +1628,8 @@
}
const String& uri = String::Handle(zone, script.url());
- intptr_t from_line = 0;
- intptr_t from_col = 0;
- if (script.HasSource()) {
- script.GetTokenLocation(token_pos, &from_line, &from_col);
- } else {
- // Avoid the slow path of printing the token stream when precise source
- // information is not available.
- script.GetTokenLocation(token_pos, &from_line, NULL);
- }
- // We should always have at least the line number.
- ASSERT(from_line != 0);
+ intptr_t from_line = 0, from_col = 0;
+ script.GetTokenLocation(token_pos, &from_line, &from_col);
return CreateSourceLocation(uri, from_line, from_col);
}
diff --git a/runtime/platform/assert.h b/runtime/platform/assert.h
index c31c1cc..64351b6 100644
--- a/runtime/platform/assert.h
+++ b/runtime/platform/assert.h
@@ -140,7 +140,12 @@
inline void Expect::StringEquals(const char* expected, const char* actual) {
if (strcmp(expected, actual) == 0) return;
- Fail("expected:\n<\"%s\">\nbut was:\n<\"%s\">", expected, actual);
+ if (actual == nullptr) {
+ Fail("expected:\n<\"%s\">\nbut was nullptr", expected);
+ } else {
+ if (strcmp(expected, actual) == 0) return;
+ Fail("expected:\n<\"%s\">\nbut was:\n<\"%s\">", expected, actual);
+ }
}
inline void Expect::IsSubstring(const char* needle, const char* haystack) {
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index e75d702..6d6ef31 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -437,7 +437,7 @@
int32_t current_pc_offset = 0;
function_stack->Add(&root_);
- token_positions->Add(CodeSourceMapBuilder::kInitialPosition);
+ token_positions->Add(InitialPosition());
while (stream.PendingBytes() > 0) {
uint8_t opcode = stream.Read<uint8_t>();
@@ -459,7 +459,7 @@
int32_t func = stream.Read<int32_t>();
function_stack->Add(
&Function::Handle(Function::RawCast(functions_.At(func))));
- token_positions->Add(CodeSourceMapBuilder::kInitialPosition);
+ token_positions->Add(InitialPosition());
break;
}
case CodeSourceMapBuilder::kPopFunction: {
@@ -603,7 +603,7 @@
int32_t current_pc_offset = 0;
function_stack.Add(&root_);
- token_positions.Add(CodeSourceMapBuilder::kInitialPosition);
+ token_positions.Add(InitialPosition());
THR_Print("Source positions for function '%s' {\n",
root_.ToFullyQualifiedCString());
@@ -630,7 +630,7 @@
int32_t func = stream.Read<int32_t>();
function_stack.Add(
&Function::Handle(Function::RawCast(functions_.At(func))));
- token_positions.Add(CodeSourceMapBuilder::kInitialPosition);
+ token_positions.Add(InitialPosition());
break;
}
case CodeSourceMapBuilder::kPopFunction: {
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index bb2f773..8bc6350 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -292,6 +292,16 @@
intptr_t GetNullCheckNameIndexAt(int32_t pc_offset);
private:
+ static const TokenPosition& InitialPosition() {
+ if (FLAG_precompiled_mode) {
+ // In precompiled mode, the CodeSourceMap stores lines instead of
+ // real token positions and uses kNoSourcePos for no line information.
+ return TokenPosition::kNoSource;
+ } else {
+ return CodeSourceMapBuilder::kInitialPosition;
+ }
+ }
+
// Reads a TokenPosition value from a CSM, handling the different encoding for
// when non-symbolic stack traces are enabled.
static TokenPosition ReadPosition(ReadStream* stream);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 13200a2..7962ff2 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -535,13 +535,13 @@
}
const Script& script =
Script::Handle(zone(), instr->env()->function().script());
- intptr_t line_nr;
- intptr_t column_nr;
- script.GetTokenLocation(instr->token_pos(), &line_nr, &column_nr);
- const String& line = String::Handle(zone(), script.GetLine(line_nr));
- assembler()->Comment("Line %" Pd " in '%s':\n %s", line_nr,
- instr->env()->function().ToFullyQualifiedCString(),
- line.ToCString());
+ intptr_t line_nr, column_nr;
+ if (script.GetTokenLocation(instr->token_pos(), &line_nr, &column_nr)) {
+ const String& line = String::Handle(zone(), script.GetLine(line_nr));
+ assembler()->Comment("Line %" Pd " in '%s':\n %s", line_nr,
+ instr->env()->function().ToFullyQualifiedCString(),
+ line.ToCString());
+ }
}
static bool IsPusher(Instruction* instr) {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 6120b67..5db0e49 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -567,7 +567,7 @@
const TokenPosition& token_pos = TokenPos();
if ((line_number_ < 0) && token_pos.IsReal()) {
const Script& script = Script::Handle(SourceScript());
- script.GetTokenLocation(token_pos, &line_number_, nullptr);
+ script.GetTokenLocation(token_pos, &line_number_, &column_number_);
}
return line_number_;
}
@@ -1465,7 +1465,7 @@
// Compute line number lazily since it causes scanning of the script.
if (line_number_ < 0) {
const Script& script = Script::Handle(SourceCode());
- script.GetTokenLocation(token_pos_, &line_number_, NULL);
+ script.GetTokenLocation(token_pos_, &line_number_);
}
return line_number_;
}
@@ -2241,7 +2241,8 @@
TokenPosition token_end_pos =
TokenPosition::Min(next_closest_token_position, end_of_line_pos);
- if ((exact_token_pos.IsReal() && (token_end_pos < exact_token_pos)) ||
+ if ((token_end_pos.IsReal() && exact_token_pos.IsReal() &&
+ (token_end_pos < exact_token_pos)) ||
(token_start_column > *best_column)) {
// Prefer the token with the lowest column number compatible
// with the requested column.
@@ -2386,8 +2387,8 @@
const TokenPosition begin_pos = best_fit_pos;
TokenPosition end_of_line_pos = TokenPosition::kNoSource;
- if (best_line == -1) {
- script.GetTokenLocation(begin_pos, &best_line, nullptr);
+ if (best_line < 0) {
+ script.GetTokenLocation(begin_pos, &best_line);
}
ASSERT(best_line > 0);
TokenPosition ignored = TokenPosition::kNoSource;
@@ -2754,8 +2755,8 @@
MakeCodeBreakpointAt(func, loc);
}
if (FLAG_verbose_debug) {
- intptr_t line_number;
- intptr_t column_number;
+ intptr_t line_number = -1;
+ intptr_t column_number = -1;
script.GetTokenLocation(breakpoint_pos, &line_number, &column_number);
OS::PrintErr("Resolved code breakpoint for function '%s' at line %" Pd
" col %" Pd "\n",
@@ -2818,8 +2819,8 @@
// initializer of a field at |token_pos|. Hence, Register an unresolved
// breakpoint.
if (FLAG_verbose_debug) {
- intptr_t line_number;
- intptr_t column_number;
+ intptr_t line_number = -1;
+ intptr_t column_number = -1;
script.GetTokenLocation(token_pos, &line_number, &column_number);
if (func.IsNull()) {
OS::PrintErr(
@@ -3855,12 +3856,11 @@
intptr_t column_number) {
intptr_t line;
intptr_t col;
- script.GetTokenLocation(start_of_line, &line, &col);
- if (line < 0) {
- return TokenPosition::kNoSource;
+ if (script.GetTokenLocation(start_of_line, &line, &col)) {
+ return TokenPosition::Deserialize(start_of_line.Pos() +
+ (column_number - col));
}
- return TokenPosition::Deserialize(start_of_line.Pos() +
- (column_number - col));
+ return TokenPosition::kNoSource;
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 54cac1a..f9e3662 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -382,14 +382,15 @@
const Function& top_function = Function::Handle(code.function());
const Script& script = Script::Handle(top_function.script());
const TokenPosition token_pos = code.GetTokenIndexOfPC(top_frame->pc());
- intptr_t line, column;
- script.GetTokenLocation(token_pos, &line, &column);
- String& line_string = String::Handle(script.GetLine(line));
THR_Print(" Function: %s\n", top_function.ToFullyQualifiedCString());
- char line_buffer[80];
- Utils::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'",
- line, line_string.ToCString());
- THR_Print("%s\n", line_buffer);
+ intptr_t line;
+ if (script.GetTokenLocation(token_pos, &line)) {
+ String& line_string = String::Handle(script.GetLine(line));
+ char line_buffer[80];
+ Utils::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'",
+ line, line_string.ToCString());
+ THR_Print("%s\n", line_buffer);
+ }
THR_Print(" Deopt args: %" Pd "\n", deopt_arg_count);
}
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 6cc253e..20edf4d 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -919,7 +919,7 @@
zone, script.IsNull() ? Symbols::OptimizedOut().raw() : script.url());
intptr_t line = -1;
intptr_t column = -1;
- if (!script.IsNull() && location.IsReal()) {
+ if (!script.IsNull()) {
script.GetTokenLocation(location, &line, &column);
}
// Initialize '_url', '_line', and '_column' arguments.
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 4a65c47..dea993b 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -35,7 +35,7 @@
}
}
-void KernelLineStartsReader::LocationForPosition(intptr_t position,
+bool KernelLineStartsReader::LocationForPosition(intptr_t position,
intptr_t* line,
intptr_t* col) const {
intptr_t line_count = line_starts_data_.Length();
@@ -45,46 +45,43 @@
current_start += helper_->At(line_starts_data_, i);
if (current_start > position) {
*line = i;
- if (col != NULL) {
+ if (col != nullptr) {
*col = position - previous_start + 1;
}
- return;
+ return true;
}
if (current_start == position) {
*line = i + 1;
- if (col != NULL) {
+ if (col != nullptr) {
*col = 1;
}
- return;
+ return true;
}
previous_start = current_start;
}
- // If the start of any of the lines did not cross |position|,
- // then it means the position falls on the last line.
- *line = line_count;
- if (col != NULL) {
- *col = position - current_start + 1;
- }
+ return false;
}
-void KernelLineStartsReader::TokenRangeAtLine(
- intptr_t source_length,
+bool KernelLineStartsReader::TokenRangeAtLine(
intptr_t line_number,
TokenPosition* first_token_index,
TokenPosition* last_token_index) const {
- ASSERT(line_number <= line_starts_data_.Length());
+ if (line_number < 0 || line_number > line_starts_data_.Length()) {
+ return false;
+ }
intptr_t cumulative = 0;
for (intptr_t i = 0; i < line_number; ++i) {
cumulative += helper_->At(line_starts_data_, i);
}
*first_token_index = dart::TokenPosition::Deserialize(cumulative);
if (line_number == line_starts_data_.Length()) {
- *last_token_index = dart::TokenPosition::Deserialize(source_length);
+ *last_token_index = *first_token_index;
} else {
*last_token_index = dart::TokenPosition::Deserialize(
cumulative + helper_->At(line_starts_data_, line_number) - 1);
}
+ return true;
}
int32_t KernelLineStartsReader::KernelInt8LineStartsHelper::At(
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 79c5670..b9a582f 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -140,14 +140,21 @@
return helper_->At(line_starts_data_, index);
}
- void LocationForPosition(intptr_t position,
- intptr_t* line,
- intptr_t* col) const;
+ // Returns whether the given offset corresponds to a valid source offset
+ // If it does, then *line and *column (if column is not nullptr) are set
+ // to the line and column the token starts at.
+ DART_WARN_UNUSED_RESULT bool LocationForPosition(
+ intptr_t position,
+ intptr_t* line,
+ intptr_t* col = nullptr) const;
- void TokenRangeAtLine(intptr_t source_length,
- intptr_t line_number,
- dart::TokenPosition* first_token_index,
- dart::TokenPosition* last_token_index) const;
+ // Returns whether any tokens were found for the given line. When found,
+ // *first_token_index and *last_token_index are set to the first and
+ // last token on the line, respectively.
+ DART_WARN_UNUSED_RESULT bool TokenRangeAtLine(
+ intptr_t line_number,
+ dart::TokenPosition* first_token_index,
+ dart::TokenPosition* last_token_index) const;
private:
class KernelLineStartsHelper {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6cb5b65..8b790ce 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -9378,13 +9378,18 @@
Zone* zone = Thread::Current()->zone();
const Script& func_script = Script::Handle(zone, script());
- intptr_t from_line;
- intptr_t from_col;
- intptr_t to_line;
- intptr_t to_col;
- intptr_t to_length;
- func_script.GetTokenLocation(token_pos(), &from_line, &from_col);
- func_script.GetTokenLocation(end_token_pos(), &to_line, &to_col, &to_length);
+ intptr_t from_line, from_col;
+ if (!func_script.GetTokenLocation(token_pos(), &from_line, &from_col)) {
+ return String::null();
+ }
+ intptr_t to_line, to_col;
+ if (!func_script.GetTokenLocation(end_token_pos(), &to_line, &to_col)) {
+ return String::null();
+ }
+ intptr_t to_length = func_script.GetTokenLength(end_token_pos());
+ if (to_length < 0) {
+ return String::null();
+ }
if (to_length == 1) {
// Handle special cases for end tokens of closures (where we exclude the
@@ -11269,70 +11274,79 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-void Script::GetTokenLocation(TokenPosition token_pos,
+bool Script::GetTokenLocation(const TokenPosition& token_pos,
intptr_t* line,
- intptr_t* column,
- intptr_t* token_len) const {
+ intptr_t* column) const {
ASSERT(line != nullptr);
- // Set up appropriate values for any early returns.
- *line = -1;
- if (column != nullptr) {
- *column = -1;
- }
- if (token_len != nullptr) {
- *token_len = 1;
- }
+#if defined(DART_PRECOMPILED_RUNTIME)
// Scripts in the AOT snapshot do not have a line starts array.
-#if !defined(DART_PRECOMPILED_RUNTIME)
- if (!token_pos.IsReal()) return;
+ return false;
+#else
+ if (!token_pos.IsReal()) return false;
auto const zone = Thread::Current()->zone();
LookupSourceAndLineStarts(zone);
const TypedData& line_starts_data = TypedData::Handle(zone, line_starts());
+ if (line_starts_data.IsNull()) return false;
kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone);
- const intptr_t pos = token_pos.Pos();
- line_starts_reader.LocationForPosition(pos, line, column);
- if (token_len == nullptr) return;
- *token_len = 1;
- // We don't explicitly save this data: Load the source
- // and find it from there.
- const String& source = String::Handle(zone, Source());
- if (!source.IsNull()) {
- intptr_t offset = pos;
- if (offset < source.Length() && IsIdentStartChar(source.CharAt(offset))) {
- for (intptr_t i = offset + 1;
- i < source.Length() && IsIdentChar(source.CharAt(i)); ++i) {
- ++*token_len;
- }
- }
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ return line_starts_reader.LocationForPosition(token_pos.Pos(), line, column);
+#endif // defined(DART_PRECOMPILED_RUNTIME)
}
-void Script::TokenRangeAtLine(intptr_t line_number,
+intptr_t Script::GetTokenLength(const TokenPosition& token_pos) const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ // Scripts in the AOT snapshot do not have their source.
+ return -1;
+#else
+ if (!HasSource() || !token_pos.IsReal()) return -1;
+ auto const zone = Thread::Current()->zone();
+ LookupSourceAndLineStarts(zone);
+ // We don't explicitly save this data: Load the source and find it from there.
+ const String& source = String::Handle(zone, Source());
+ const intptr_t start = token_pos.Pos();
+ if (start >= source.Length()) return -1; // Can't determine token_len.
+ intptr_t end = start;
+ if (IsIdentStartChar(source.CharAt(end++))) {
+ for (; end < source.Length(); ++end) {
+ if (!IsIdentChar(source.CharAt(end))) break;
+ }
+ }
+ return end - start;
+#endif
+}
+
+bool Script::TokenRangeAtLine(intptr_t line_number,
TokenPosition* first_token_index,
TokenPosition* last_token_index) const {
- ASSERT(first_token_index != NULL && last_token_index != NULL);
- ASSERT(line_number > 0);
-
+ ASSERT(first_token_index != nullptr && last_token_index != nullptr);
+#if defined(DART_PRECOMPILED_RUNTIME)
// Scripts in the AOT snapshot do not have a line starts array.
-#if !defined(DART_PRECOMPILED_RUNTIME)
+ return false;
+#else
+ // Line numbers are 1-indexed.
+ if (line_number <= 0) return false;
Zone* zone = Thread::Current()->zone();
LookupSourceAndLineStarts(zone);
- const String& source = String::Handle(zone, Source());
+ const TypedData& line_starts_data = TypedData::Handle(zone, line_starts());
+ kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone);
+ if (!line_starts_reader.TokenRangeAtLine(line_number, first_token_index,
+ last_token_index)) {
+ return false;
+ }
+#if defined(DEBUG)
intptr_t source_length;
- if (source.IsNull()) {
+ if (!HasSource()) {
Smi& value = Smi::Handle(zone);
const Array& debug_positions_array = Array::Handle(zone, debug_positions());
value ^= debug_positions_array.At(debug_positions_array.Length() - 1);
source_length = value.Value();
} else {
+ const String& source = String::Handle(zone, Source());
source_length = source.Length();
}
- const TypedData& line_starts_data = TypedData::Handle(zone, line_starts());
- kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone);
- line_starts_reader.TokenRangeAtLine(source_length, line_number,
- first_token_index, last_token_index);
+ ASSERT(last_token_index->Serialize() <= source_length);
+#endif
+ return true;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
@@ -11349,7 +11363,8 @@
intptr_t column = 1,
intptr_t column_offset = 0,
intptr_t starting_index = 0) {
- if (starting_index < 0 || line < 1 || column < 1) {
+ if (starting_index < 0 || line < 1 || column < 1 || line <= line_offset ||
+ (line == line_offset + 1 && column <= column_offset)) {
return -1;
}
intptr_t len = src.Length();
@@ -11391,10 +11406,10 @@
}
StringPtr Script::GetLine(intptr_t line_number, Heap::Space space) const {
- const String& src = String::Handle(Source());
- if (src.IsNull()) {
+ if (!HasSource()) {
return Symbols::OptimizedOut().raw();
}
+ const String& src = String::Handle(Source());
const intptr_t start =
GetRelativeSourceIndex(src, line_number, line_offset());
if (start < 0) {
@@ -11414,11 +11429,10 @@
intptr_t from_column,
intptr_t to_line,
intptr_t to_column) const {
- const String& src = String::Handle(Source());
- if (src.IsNull()) {
+ if (!HasSource()) {
return Symbols::OptimizedOut().raw();
}
-
+ const String& src = String::Handle(Source());
const intptr_t start = GetRelativeSourceIndex(src, from_line, line_offset(),
from_column, col_offset());
// Lines and columns are 1-based, so need to subtract one to get offsets.
@@ -24209,8 +24223,9 @@
static void PrintSymbolicStackFrame(Zone* zone,
BaseTextBuffer* buffer,
const Function& function,
- TokenPosition token_pos,
- intptr_t frame_index) {
+ TokenPosition token_pos_or_line,
+ intptr_t frame_index,
+ bool is_line = false) {
ASSERT(!function.IsNull());
const auto& script = Script::Handle(zone, function.script());
const char* function_name = function.QualifiedUserVisibleNameCString();
@@ -24226,13 +24241,14 @@
intptr_t line = -1;
intptr_t column = -1;
- if (token_pos.IsReal()) {
- if (FLAG_precompiled_mode) {
- line = token_pos.Pos();
- } else {
- ASSERT(!script.IsNull());
- script.GetTokenLocation(token_pos, &line, &column);
+ if (is_line) {
+ ASSERT(token_pos_or_line.IsNoSource() || token_pos_or_line.IsReal());
+ if (token_pos_or_line.IsReal()) {
+ line = token_pos_or_line.Pos();
}
+ } else {
+ ASSERT(!script.IsNull());
+ script.GetTokenLocation(token_pos_or_line, &line, &column);
}
PrintSymbolicStackFrameIndex(buffer, frame_index);
PrintSymbolicStackFrameBody(buffer, function_name, url, line, column);
@@ -24386,7 +24402,8 @@
for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
const auto& inlined = *inlined_functions[j];
auto const pos = inlined_token_positions[j];
- PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index);
+ PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index,
+ /*is_line=*/FLAG_precompiled_mode);
frame_index++;
}
continue;
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index b94c5a3..3fe0d69 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4543,16 +4543,20 @@
void SetLocationOffset(intptr_t line_offset, intptr_t col_offset) const;
- void GetTokenLocation(TokenPosition token_pos,
+ // Returns whether a line and column could be computed for the given token
+ // position and, if so, sets *line and *column (if not nullptr).
+ bool GetTokenLocation(const TokenPosition& token_pos,
intptr_t* line,
- intptr_t* column,
- intptr_t* token_len = NULL) const;
+ intptr_t* column = nullptr) const;
- // Returns index of first and last token on the given line. Returns both
- // indices < 0 if no token exists on or after the line. If a token exists
- // after, but not on given line, returns in *first_token_index the index of
- // the first token after the line, and a negative value in *last_token_index.
- void TokenRangeAtLine(intptr_t line_number,
+ // Returns the length of the token at the given position. If the length cannot
+ // be determined, returns a negative value.
+ intptr_t GetTokenLength(const TokenPosition& token_pos) const;
+
+ // Returns whether any tokens were found for the given line. When found,
+ // *first_token_index and *last_token_index are set to the first and
+ // last token on the line, respectively.
+ bool TokenRangeAtLine(intptr_t line_number,
TokenPosition* first_token_index,
TokenPosition* last_token_index) const;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index fdd6784..5b280f2 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -292,7 +292,7 @@
const Script& scr = Script::Handle(cls.script());
intptr_t line;
intptr_t col;
- scr.GetTokenLocation(end_token_pos, &line, &col);
+ EXPECT(scr.GetTokenLocation(end_token_pos, &line, &col));
EXPECT_EQ(9, line);
EXPECT_EQ(1, col);
}
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 048a8bf..612e81a 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -262,36 +262,36 @@
const char* CurrentToken() {
if (!as_functions_) {
- return NULL;
+ return nullptr;
}
ProfileFunction* func = GetFunction();
const Function& function = *(func->function());
if (function.IsNull()) {
// No function.
- return NULL;
+ return nullptr;
}
Zone* zone = Thread::Current()->zone();
const Script& script = Script::Handle(zone, function.script());
if (script.IsNull()) {
// No script.
- return NULL;
+ return nullptr;
}
ProfileFunctionSourcePosition pfsp(TokenPosition::kNoSource);
if (!func->GetSinglePosition(&pfsp)) {
// Not exactly one source position.
- return NULL;
- }
- TokenPosition token_pos = pfsp.token_pos();
- if (!token_pos.IsReal()) {
- // Not a location in a script.
- return NULL;
+ return nullptr;
}
- intptr_t line = 0, column = 0, token_len = 0;
- script.GetTokenLocation(token_pos, &line, &column, &token_len);
- const auto& str = String::Handle(
- zone, script.GetSnippet(line, column, line, column + token_len));
- return str.IsNull() ? NULL : str.ToCString();
+ const TokenPosition& token_pos = pfsp.token_pos();
+ intptr_t line, column;
+ if (script.GetTokenLocation(token_pos, &line, &column)) {
+ const intptr_t token_len = script.GetTokenLength(token_pos);
+ const auto& str = String::Handle(
+ zone, script.GetSnippet(line, column, line, column + token_len));
+ if (!str.IsNull()) return str.ToCString();
+ }
+ // Couldn't get line/number information.
+ return nullptr;
}
intptr_t CurrentInclusiveTicks() {
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index ded367d6..069b3be 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -38,29 +38,20 @@
UNREACHABLE();
}
String& result = String::Handle();
- if (!script.IsNull() && !String::Handle(script.Source()).IsNull()) {
+ if (!script.IsNull() && script.HasSource()) {
const String& script_url = String::Handle(script.url());
- if (token_pos.IsReal()) {
- intptr_t line, column, token_len;
- script.GetTokenLocation(token_pos, &line, &column, &token_len);
+ intptr_t line, column;
+ if (script.GetTokenLocation(token_pos, &line, &column)) {
+ const intptr_t token_len = script.GetTokenLength(token_pos);
if (report_after_token) {
- column += token_len;
+ column += token_len < 0 ? 1 : token_len;
}
- // Only report the line position if we have the original source. We still
- // need to get a valid column so that we can report the ^ mark below the
- // snippet.
// Allocate formatted strings in old space as they may be created during
// optimizing compilation. Those strings are created rarely and should not
// polute old space.
- if (script.HasSource()) {
- result = String::NewFormatted(
- Heap::kOld, "'%s': %s: line %" Pd " pos %" Pd ": ",
- script_url.ToCString(), message_header, line, column);
- } else {
- result =
- String::NewFormatted(Heap::kOld, "'%s': %s: line %" Pd ": ",
- script_url.ToCString(), message_header, line);
- }
+ result = String::NewFormatted(
+ Heap::kOld, "'%s': %s: line %" Pd " pos %" Pd ": ",
+ script_url.ToCString(), message_header, line, column);
// Append the formatted error or warning message.
const Array& strs = Array::Handle(Array::New(6, Heap::kOld));
strs.SetAt(0, result);
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 020839e..67c7cbb 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -281,15 +281,18 @@
const Script& script = Script::Handle(function.script());
const String& func_name = String::Handle(function.QualifiedScrubbedName());
const String& url = String::Handle(script.url());
- intptr_t line = -1;
- intptr_t column = -1;
- if (token_pos.IsReal()) {
- script.GetTokenLocation(token_pos, &line, &column);
+ intptr_t line, column;
+ if (script.GetTokenLocation(token_pos, &line, &column)) {
+ OS::PrintErr(
+ "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")", pc,
+ fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
+ func_name.ToCString(), url.ToCString(), line, column);
+
+ } else {
+ OS::PrintErr("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s)", pc, fp, sp,
+ is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
+ func_name.ToCString(), url.ToCString());
}
- OS::PrintErr(
- "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")", pc,
- fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
- func_name.ToCString(), url.ToCString(), line, column);
#if defined(DART_PRECOMPILED_RUNTIME)
intptr_t offset;
auto const symbol_name =
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 24936ec..b39c371 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -309,15 +309,17 @@
const Script& script = Script::Handle(function.script());
const String& func_name = String::Handle(function.QualifiedScrubbedName());
const String& url = String::Handle(script.url());
- intptr_t line = -1;
- intptr_t column = -1;
- if (token_pos.IsReal()) {
- script.GetTokenLocation(token_pos, &line, &column);
+ intptr_t line, column;
+ if (script.GetTokenLocation(token_pos, &line, &column)) {
+ OS::PrintErr(
+ "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")", pc,
+ fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
+ func_name.ToCString(), url.ToCString(), line, column);
+ } else {
+ OS::PrintErr("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s)", pc, fp, sp,
+ is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
+ func_name.ToCString(), url.ToCString());
}
- OS::PrintErr(
- "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")", pc,
- fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
- func_name.ToCString(), url.ToCString(), line, column);
#if defined(DART_PRECOMPILED_RUNTIME)
intptr_t offset;
auto const symbol_name =
diff --git a/tools/VERSION b/tools/VERSION
index c912081..5e98251 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 158
+PRERELEASE 159
PRERELEASE_PATCH 0
\ No newline at end of file