Index: runtime/vm/debugger.cc |
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc |
index b978a73aa3a82c330b5bc0dfa30d707715162910..c9612493b4c66145dbd11f20b4aaacb065562cec 100644 |
--- a/runtime/vm/debugger.cc |
+++ b/runtime/vm/debugger.cc |
@@ -27,6 +27,7 @@ |
#include "vm/stub_code.h" |
#include "vm/symbols.h" |
#include "vm/thread_interrupter.h" |
+#include "vm/token_position.h" |
#include "vm/visitor.h" |
@@ -69,8 +70,8 @@ class RemoteObjectCache : public ZoneAllocated { |
// Create an unresolved breakpoint in given token range and script. |
BreakpointLocation::BreakpointLocation(const Script& script, |
- intptr_t token_pos, |
- intptr_t end_token_pos, |
+ TokenPosition token_pos, |
+ TokenPosition end_token_pos, |
intptr_t requested_line_number, |
intptr_t requested_column_number) |
: script_(script.raw()), |
@@ -86,7 +87,7 @@ BreakpointLocation::BreakpointLocation(const Script& script, |
line_number_(-1), |
column_number_(-1) { |
ASSERT(!script.IsNull()); |
- ASSERT(Token::IsReal(token_pos_)); |
+ ASSERT(token_pos_.IsReal()); |
} |
// Create a latent breakpoint at given url and line number. |
@@ -95,8 +96,8 @@ BreakpointLocation::BreakpointLocation(const String& url, |
intptr_t requested_column_number) |
: script_(Script::null()), |
url_(url.raw()), |
- token_pos_(Token::kNoSourcePos), |
- end_token_pos_(Token::kNoSourcePos), |
+ token_pos_(TokenPosition::kNoSource), |
+ end_token_pos_(TokenPosition::kNoSource), |
is_resolved_(false), |
next_(NULL), |
conditions_(NULL), |
@@ -124,7 +125,8 @@ bool BreakpointLocation::AnyEnabled() const { |
} |
-void BreakpointLocation::SetResolved(const Function& func, intptr_t token_pos) { |
+void BreakpointLocation::SetResolved(const Function& func, |
+ TokenPosition token_pos) { |
ASSERT(!IsLatent()); |
ASSERT(func.script() == script_); |
ASSERT((func.token_pos() <= token_pos) && |
@@ -142,11 +144,11 @@ void BreakpointLocation::SetResolved(const Function& func, intptr_t token_pos) { |
// in more than one library, e.g. the text location of mixin functions. |
void BreakpointLocation::GetCodeLocation(Library* lib, |
Script* script, |
- intptr_t* pos) const { |
+ TokenPosition* pos) const { |
if (IsLatent()) { |
*lib = Library::null(); |
*script = Script::null(); |
- *pos = -1; |
+ *pos = TokenPosition::kNoSource; |
} else { |
*script = this->script(); |
*pos = token_pos_; |
@@ -241,7 +243,7 @@ ActivationFrame::ActivationFrame( |
code_(Code::ZoneHandle(code.raw())), |
function_(Function::ZoneHandle(code.function())), |
token_pos_initialized_(false), |
- token_pos_(Token::kNoSourcePos), |
+ token_pos_(TokenPosition::kNoSource), |
try_index_(-1), |
line_number_(-1), |
column_number_(-1), |
@@ -457,7 +459,7 @@ const char* Debugger::QualifiedFunctionName(const Function& func) { |
// Returns true if function contains the token position in the given script. |
static bool FunctionContains(const Function& func, |
const Script& script, |
- intptr_t token_pos) { |
+ TokenPosition token_pos) { |
if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { |
// Check script equality second because it allocates |
// handles as a side effect. |
@@ -569,10 +571,10 @@ void ActivationFrame::GetPcDescriptors() { |
// Compute token_pos_ and try_index_ and token_pos_initialized_. |
-intptr_t ActivationFrame::TokenPos() { |
+TokenPosition ActivationFrame::TokenPos() { |
if (!token_pos_initialized_) { |
token_pos_initialized_ = true; |
- token_pos_ = Token::kNoSourcePos; |
+ token_pos_ = TokenPosition::kNoSource; |
GetPcDescriptors(); |
PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); |
uword pc_offset = pc_ - code().EntryPoint(); |
@@ -598,8 +600,8 @@ intptr_t ActivationFrame::TryIndex() { |
intptr_t ActivationFrame::LineNumber() { |
// Compute line number lazily since it causes scanning of the script. |
- if ((line_number_ < 0) && Token::IsReal(TokenPos())) { |
- const intptr_t token_pos = TokenPos(); |
+ if ((line_number_ < 0) && TokenPos().IsReal()) { |
+ const TokenPosition token_pos = TokenPos(); |
const Script& script = Script::Handle(SourceScript()); |
script.GetTokenLocation(token_pos, &line_number_, NULL); |
} |
@@ -609,8 +611,8 @@ intptr_t ActivationFrame::LineNumber() { |
intptr_t ActivationFrame::ColumnNumber() { |
// Compute column number lazily since it causes scanning of the script. |
- if ((column_number_ < 0) && Token::IsReal(TokenPos())) { |
- const intptr_t token_pos = TokenPos(); |
+ if ((column_number_ < 0) && TokenPos().IsReal()) { |
+ const TokenPosition token_pos = TokenPos(); |
const Script& script = Script::Handle(SourceScript()); |
if (script.HasSource()) { |
script.GetTokenLocation(token_pos, &line_number_, &column_number_); |
@@ -655,14 +657,14 @@ intptr_t ActivationFrame::ContextLevel() { |
// for the code position of the frame? For now say we are at context |
// level 0. |
TokenPos(); |
- if (token_pos_ == -1) { |
+ if (token_pos_ == TokenPosition::kNoSource) { |
// No PcDescriptor. |
return context_level_; |
} |
ASSERT(!pc_desc_.IsNull()); |
- intptr_t innermost_begin_pos = 0; |
- intptr_t activation_token_pos = TokenPos(); |
- ASSERT(Token::IsReal(activation_token_pos)); |
+ TokenPosition innermost_begin_pos = TokenPosition::kMinSource; |
+ TokenPosition activation_token_pos = TokenPos(); |
+ ASSERT(activation_token_pos.IsReal()); |
GetVarDescriptors(); |
intptr_t var_desc_len = var_descriptors_.Length(); |
for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
@@ -774,8 +776,8 @@ void ActivationFrame::GetDescIndices() { |
} |
GetVarDescriptors(); |
- intptr_t activation_token_pos = TokenPos(); |
- if (!Token::IsDebugPause(activation_token_pos)) { |
+ TokenPosition activation_token_pos = TokenPos(); |
+ if (!activation_token_pos.IsDebugPause()) { |
// We don't have a token position for this frame, so can't determine |
// which variables are visible. |
vars_initialized_ = true; |
@@ -935,8 +937,8 @@ void ActivationFrame::PrintContextMismatchError( |
void ActivationFrame::VariableAt(intptr_t i, |
String* name, |
- intptr_t* token_pos, |
- intptr_t* end_pos, |
+ TokenPosition* token_pos, |
+ TokenPosition* end_pos, |
Object* value) { |
GetDescIndices(); |
ASSERT(i < desc_indices_.length()); |
@@ -1004,7 +1006,7 @@ RawArray* ActivationFrame::GetLocalVariables() { |
Object& value = Instance::Handle(); |
const Array& list = Array::Handle(Array::New(2 * num_variables)); |
for (intptr_t i = 0; i < num_variables; i++) { |
- intptr_t ignore; |
+ TokenPosition ignore; |
VariableAt(i, &var_name, &ignore, &ignore, &value); |
list.SetAt(2 * i, var_name); |
list.SetAt((2 * i) + 1, value); |
@@ -1019,7 +1021,7 @@ RawObject* ActivationFrame::GetReceiver() { |
String& var_name = String::Handle(); |
Instance& value = Instance::Handle(); |
for (intptr_t i = 0; i < num_variables; i++) { |
- intptr_t ignore; |
+ TokenPosition ignore; |
VariableAt(i, &var_name, &ignore, &ignore, &value); |
if (var_name.Equals(Symbols::This())) { |
return value.raw(); |
@@ -1044,7 +1046,7 @@ RawObject* ActivationFrame::Evaluate(const String& expr) { |
Object& value = Instance::Handle(); |
intptr_t num_variables = desc_indices_.length(); |
for (intptr_t i = 0; i < num_variables; i++) { |
- intptr_t ignore; |
+ TokenPosition ignore; |
VariableAt(i, &name, &ignore, &ignore, &value); |
if (!name.Equals(Symbols::This())) { |
if (IsPrivateVariableName(name)) { |
@@ -1115,8 +1117,8 @@ void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, |
for (intptr_t v = 0; v < num_vars; v++) { |
String& var_name = String::Handle(); |
Instance& var_value = Instance::Handle(); |
- intptr_t token_pos; |
- intptr_t end_token_pos; |
+ TokenPosition token_pos; |
+ TokenPosition end_token_pos; |
VariableAt(v, &var_name, &token_pos, &end_token_pos, &var_value); |
if (var_name.raw() != Symbols::AsyncOperation().raw()) { |
JSONObject jsvar(&jsvars); |
@@ -1149,7 +1151,7 @@ const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
CodeBreakpoint::CodeBreakpoint(const Code& code, |
- intptr_t token_pos, |
+ TokenPosition token_pos, |
uword pc, |
RawPcDescriptors::Kind kind) |
: code_(code.raw()), |
@@ -1162,7 +1164,7 @@ CodeBreakpoint::CodeBreakpoint(const Code& code, |
breakpoint_kind_(kind), |
saved_value_(Code::null()) { |
ASSERT(!code.IsNull()); |
- ASSERT(token_pos_ > 0); |
+ ASSERT(token_pos_.IsReal()); |
ASSERT(pc_ != 0); |
ASSERT((breakpoint_kind_ & kSafepointKind) != 0); |
} |
@@ -1653,12 +1655,15 @@ void Debugger::SignalExceptionThrown(const Instance& exc) { |
} |
-static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) { |
- TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens); |
+static TokenPosition LastTokenOnLine(const TokenStream& tokens, |
+ TokenPosition pos) { |
+ TokenStream::Iterator iter(tokens, |
+ pos, |
+ TokenStream::Iterator::kAllTokens); |
ASSERT(iter.IsValid()); |
- intptr_t last_pos = pos; |
+ TokenPosition last_pos = pos; |
while ((iter.CurrentTokenKind() != Token::kNEWLINE) && |
- (iter.CurrentTokenKind() != Token::kEOS)) { |
+ (iter.CurrentTokenKind() != Token::kEOS)) { |
last_pos = iter.CurrentPosition(); |
iter.Advance(); |
} |
@@ -1722,10 +1727,11 @@ static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) { |
// algorithm, which would be simpler. I believe that it only needs |
// two passes to support the recursive try-the-whole-function case. |
// Rewrite this later, once there are more tests in place. |
-intptr_t Debugger::ResolveBreakpointPos(const Function& func, |
- intptr_t requested_token_pos, |
- intptr_t last_token_pos, |
- intptr_t requested_column) { |
+TokenPosition Debugger::ResolveBreakpointPos( |
+ const Function& func, |
+ TokenPosition requested_token_pos, |
+ TokenPosition last_token_pos, |
+ intptr_t requested_column) { |
ASSERT(func.HasCode()); |
ASSERT(!func.HasOptimizedCode()); |
@@ -1743,12 +1749,12 @@ intptr_t Debugger::ResolveBreakpointPos(const Function& func, |
// First pass: find the safe point which is closest to the beginning |
// of the given token range. |
- intptr_t best_fit_pos = INT_MAX; |
+ TokenPosition best_fit_pos = TokenPosition::kMaxSource; |
intptr_t best_column = INT_MAX; |
PcDescriptors::Iterator iter(desc, kSafepointKind); |
while (iter.MoveNext()) { |
- const intptr_t pos = iter.TokenPos(); |
- if ((!Token::IsReal(pos)) || |
+ const TokenPosition pos = iter.TokenPos(); |
+ if ((!pos.IsReal()) || |
(pos < requested_token_pos) || |
(pos > last_token_pos)) { |
// Token is not in the target range. |
@@ -1785,16 +1791,16 @@ intptr_t Debugger::ResolveBreakpointPos(const Function& func, |
// Second pass (if we found a safe point in the first pass). Find |
// the token on the line which is at the best fit column (if column |
// was specified) and has the lowest code address. |
- if (best_fit_pos != INT_MAX) { |
+ if (best_fit_pos != TokenPosition::kMaxSource) { |
const Script& script = Script::Handle(func.script()); |
const TokenStream& tokens = TokenStream::Handle(script.tokens()); |
- const intptr_t begin_pos = best_fit_pos; |
- const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos); |
+ const TokenPosition begin_pos = best_fit_pos; |
+ const TokenPosition end_of_line_pos = LastTokenOnLine(tokens, begin_pos); |
uword lowest_pc_offset = kUwordMax; |
PcDescriptors::Iterator iter(desc, kSafepointKind); |
while (iter.MoveNext()) { |
- const intptr_t pos = iter.TokenPos(); |
- if ((!Token::IsReal(pos)) || |
+ const TokenPosition pos = iter.TokenPos(); |
+ if (!pos.IsReal() || |
(pos < begin_pos) || |
(pos > end_of_line_pos)) { |
// Token is not on same line as best fit. |
@@ -1829,13 +1835,13 @@ intptr_t Debugger::ResolveBreakpointPos(const Function& func, |
return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), |
-1 /* no column */); |
} |
- return Token::kNoSourcePos; |
+ return TokenPosition::kNoSource; |
} |
void Debugger::MakeCodeBreakpointAt(const Function& func, |
BreakpointLocation* loc) { |
- ASSERT(Token::IsReal(loc->token_pos_)); |
+ ASSERT(loc->token_pos_.IsReal()); |
ASSERT((loc != NULL) && loc->IsResolved()); |
ASSERT(!func.HasOptimizedCode()); |
Code& code = Code::Handle(func.unoptimized_code()); |
@@ -1873,8 +1879,8 @@ void Debugger::MakeCodeBreakpointAt(const Function& func, |
void Debugger::FindCompiledFunctions(const Script& script, |
- intptr_t start_pos, |
- intptr_t end_pos, |
+ TokenPosition start_pos, |
+ TokenPosition end_pos, |
GrowableObjectArray* function_list) { |
Zone* zone = Thread::Current()->zone(); |
Class& cls = Class::Handle(zone); |
@@ -1958,7 +1964,7 @@ static void SelectBestFit(Function* best_fit, Function* func) { |
RawFunction* Debugger::FindBestFit(const Script& script, |
- intptr_t token_pos) { |
+ TokenPosition token_pos) { |
Zone* zone = Thread::Current()->zone(); |
Class& cls = Class::Handle(zone); |
Array& functions = Array::Handle(zone); |
@@ -2017,8 +2023,8 @@ RawFunction* Debugger::FindBestFit(const Script& script, |
BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
- intptr_t token_pos, |
- intptr_t last_token_pos, |
+ TokenPosition token_pos, |
+ TokenPosition last_token_pos, |
intptr_t requested_line, |
intptr_t requested_column) { |
Function& func = Function::Handle(); |
@@ -2043,9 +2049,9 @@ BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
// have already been compiled. We can resolve the breakpoint now. |
DeoptimizeWorld(); |
func ^= functions.At(0); |
- intptr_t breakpoint_pos = |
+ TokenPosition breakpoint_pos = |
ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column); |
- if (breakpoint_pos >= 0) { |
+ if (breakpoint_pos.IsReal()) { |
BreakpointLocation* bpt = |
GetBreakpointLocation(script, breakpoint_pos, requested_column); |
if (bpt != NULL) { |
@@ -2248,16 +2254,16 @@ BreakpointLocation* Debugger::BreakpointLocationAtLineCol( |
return NULL; |
} |
script ^= scripts.At(0); |
- intptr_t first_token_idx, last_token_idx; |
+ TokenPosition first_token_idx, last_token_idx; |
script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); |
- if (!Token::IsReal(first_token_idx)) { |
+ if (!first_token_idx.IsReal()) { |
// Script does not contain the given line number. |
if (FLAG_verbose_debug) { |
OS::Print("Script '%s' does not contain line number %" Pd "\n", |
script_url.ToCString(), line_number); |
} |
return NULL; |
- } else if (!Token::IsReal(last_token_idx)) { |
+ } else if (!last_token_idx.IsReal()) { |
// Line does not contain any tokens. |
if (FLAG_verbose_debug) { |
OS::Print("No executable code at line %" Pd " in '%s'\n", |
@@ -2271,7 +2277,7 @@ BreakpointLocation* Debugger::BreakpointLocationAtLineCol( |
while ((bpt == NULL) && (first_token_idx <= last_token_idx)) { |
bpt = SetBreakpoint(script, first_token_idx, last_token_idx, |
line_number, column_number); |
- first_token_idx++; |
+ first_token_idx.Next(); |
} |
if ((bpt == NULL) && FLAG_verbose_debug) { |
OS::Print("No executable code at line %" Pd " in '%s'\n", |
@@ -2665,7 +2671,7 @@ RawError* Debugger::DebuggerStepCallback() { |
if (!frame->IsDebuggable()) { |
return Error::null(); |
} |
- if (!Token::IsDebugPause(frame->TokenPos())) { |
+ if (!frame->TokenPos().IsDebugPause()) { |
return Error::null(); |
} |
@@ -2675,11 +2681,11 @@ RawError* Debugger::DebuggerStepCallback() { |
ASSERT(!HasActiveBreakpoint(frame->pc())); |
if (FLAG_verbose_debug) { |
- OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", |
+ OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", |
String::Handle(frame->SourceUrl()).ToCString(), |
frame->LineNumber(), |
String::Handle(frame->QualifiedFunctionName()).ToCString(), |
- frame->TokenPos()); |
+ frame->TokenPos().ToCString()); |
} |
ASSERT(stack_trace_ == NULL); |
@@ -2760,11 +2766,11 @@ RawError* Debugger::SignalBpReached() { |
if (FLAG_verbose_debug) { |
OS::Print(">>> hit %s breakpoint at %s:%" Pd " " |
- "(token %" Pd ") (address %#" Px ")\n", |
+ "(token %s) (address %#" Px ")\n", |
cbpt->IsInternal() ? "internal" : "user", |
String::Handle(cbpt->SourceUrl()).ToCString(), |
cbpt->LineNumber(), |
- cbpt->token_pos(), |
+ cbpt->token_pos().ToCString(), |
top_frame->pc()); |
} |
@@ -2843,7 +2849,7 @@ void Debugger::NotifyIsolateCreated() { |
// Return innermost closure contained in 'function' that contains |
// the given token position. |
RawFunction* Debugger::FindInnermostClosure(const Function& function, |
- intptr_t token_pos) { |
+ TokenPosition token_pos) { |
Zone* zone = Thread::Current()->zone(); |
const Script& outer_origin = Script::Handle(zone, function.script()); |
const GrowableObjectArray& closures = |
@@ -2908,33 +2914,33 @@ void Debugger::NotifyCompilation(const Function& func) { |
// and set the code breakpoints. |
if (!loc->IsResolved()) { |
// Resolve source breakpoint in the newly compiled function. |
- intptr_t bp_pos = |
+ TokenPosition bp_pos = |
ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), |
loc->requested_column_number()); |
- if (!Token::IsDebugPause(bp_pos)) { |
+ if (!bp_pos.IsDebugPause()) { |
if (FLAG_verbose_debug) { |
OS::Print("Failed resolving breakpoint for function '%s'\n", |
String::Handle(func.name()).ToCString()); |
} |
continue; |
} |
- intptr_t requested_pos = loc->token_pos(); |
- intptr_t requested_end_pos = loc->end_token_pos(); |
+ TokenPosition requested_pos = loc->token_pos(); |
+ TokenPosition requested_end_pos = loc->end_token_pos(); |
loc->SetResolved(func, bp_pos); |
Breakpoint* bpt = loc->breakpoints(); |
while (bpt != NULL) { |
if (FLAG_verbose_debug) { |
- OS::Print("Resolved BP %" Pd " to pos %" Pd ", " |
+ OS::Print("Resolved BP %" Pd " to pos %s, " |
"line %" Pd " col %" Pd ", " |
- "function '%s' (requested range %" Pd "-%" Pd ", " |
+ "function '%s' (requested range %s-%s, " |
"requested col %" Pd ")\n", |
bpt->id(), |
- loc->token_pos(), |
+ loc->token_pos().ToCString(), |
loc->LineNumber(), |
loc->ColumnNumber(), |
func.ToFullyQualifiedCString(), |
- requested_pos, |
- requested_end_pos, |
+ requested_pos.ToCString(), |
+ requested_end_pos.ToCString(), |
loc->requested_column_number()); |
} |
SignalBpResolved(bpt); |
@@ -2997,10 +3003,9 @@ void Debugger::NotifyDoneLoading() { |
intptr_t line_number = matched_loc->requested_line_number(); |
intptr_t column_number = matched_loc->requested_column_number(); |
ASSERT(line_number >= 0); |
- intptr_t first_token_pos, last_token_pos; |
+ TokenPosition first_token_pos, last_token_pos; |
script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); |
- if (!Token::IsDebugPause(first_token_pos) || |
- !Token::IsDebugPause(last_token_pos)) { |
+ if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) { |
// Script does not contain the given line number or there are no |
// tokens on the line. Drop the breakpoint silently. |
Breakpoint* bpt = matched_loc->breakpoints(); |
@@ -3208,7 +3213,7 @@ void Debugger::RemoveInternalBreakpoints() { |
BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, |
- intptr_t token_pos, |
+ TokenPosition token_pos, |
intptr_t requested_column) { |
BreakpointLocation* bpt = breakpoint_locations_; |
while (bpt != NULL) { |