OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_DEBUGGER_H_ | 5 #ifndef VM_DEBUGGER_H_ |
6 #define VM_DEBUGGER_H_ | 6 #define VM_DEBUGGER_H_ |
7 | 7 |
8 #include "include/dart_tools_api.h" | 8 #include "include/dart_tools_api.h" |
9 | 9 |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 | 23 |
24 // A user-defined breakpoint, which either fires once, for a particular closure, | 24 // A user-defined breakpoint, which either fires once, for a particular closure, |
25 // or always. The API's notion of a breakpoint corresponds to this object. | 25 // or always. The API's notion of a breakpoint corresponds to this object. |
26 class Breakpoint { | 26 class Breakpoint { |
27 public: | 27 public: |
28 Breakpoint(intptr_t id, BreakpointLocation* bpt_location) | 28 Breakpoint(intptr_t id, BreakpointLocation* bpt_location) |
29 : id_(id), | 29 : id_(id), |
30 kind_(Breakpoint::kNone), | 30 kind_(Breakpoint::kNone), |
31 next_(NULL), | 31 next_(NULL), |
32 closure_(Instance::null()), | 32 closure_(Instance::null()), |
33 bpt_location_(bpt_location) {} | 33 bpt_location_(bpt_location), |
| 34 is_synthetic_async_(false) {} |
34 | 35 |
35 intptr_t id() const { return id_; } | 36 intptr_t id() const { return id_; } |
36 Breakpoint* next() const { return next_; } | 37 Breakpoint* next() const { return next_; } |
37 void set_next(Breakpoint* n) { next_ = n; } | 38 void set_next(Breakpoint* n) { next_ = n; } |
38 | 39 |
39 BreakpointLocation* bpt_location() const { return bpt_location_; } | 40 BreakpointLocation* bpt_location() const { return bpt_location_; } |
40 void set_bpt_location(BreakpointLocation* new_bpt_location); | 41 void set_bpt_location(BreakpointLocation* new_bpt_location); |
41 | 42 |
42 bool IsRepeated() const { return kind_ == kRepeated; } | 43 bool IsRepeated() const { return kind_ == kRepeated; } |
43 bool IsSingleShot() const { return kind_ == kSingleShot; } | 44 bool IsSingleShot() const { return kind_ == kSingleShot; } |
44 bool IsPerClosure() const { return kind_ == kPerClosure; } | 45 bool IsPerClosure() const { return kind_ == kPerClosure; } |
45 RawInstance* closure() const { return closure_; } | 46 RawInstance* closure() const { return closure_; } |
46 | 47 |
47 void SetIsRepeated() { | 48 void SetIsRepeated() { |
48 ASSERT(kind_ == kNone); | 49 ASSERT(kind_ == kNone); |
49 kind_ = kRepeated; | 50 kind_ = kRepeated; |
50 } | 51 } |
51 | 52 |
52 void SetIsSingleShot() { | 53 void SetIsSingleShot() { |
53 ASSERT(kind_ == kNone); | 54 ASSERT(kind_ == kNone); |
54 kind_ = kSingleShot; | 55 kind_ = kSingleShot; |
55 } | 56 } |
56 | 57 |
57 void SetIsPerClosure(const Instance& closure) { | 58 void SetIsPerClosure(const Instance& closure) { |
58 ASSERT(kind_ == kNone); | 59 ASSERT(kind_ == kNone); |
59 kind_ = kPerClosure; | 60 kind_ = kPerClosure; |
60 closure_ = closure.raw(); | 61 closure_ = closure.raw(); |
61 } | 62 } |
62 | 63 |
| 64 // Mark that this breakpoint is a result of a step OverAwait request. |
| 65 void set_is_synthetic_async(bool is_synthetic_async) { |
| 66 is_synthetic_async_ = is_synthetic_async; |
| 67 } |
| 68 bool is_synthetic_async() const { |
| 69 return is_synthetic_async_; |
| 70 } |
| 71 |
63 void PrintJSON(JSONStream* stream); | 72 void PrintJSON(JSONStream* stream); |
64 | 73 |
65 private: | 74 private: |
66 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 75 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
67 | 76 |
68 enum ConditionKind { | 77 enum ConditionKind { |
69 kNone, | 78 kNone, |
70 kRepeated, | 79 kRepeated, |
71 kSingleShot, | 80 kSingleShot, |
72 kPerClosure, | 81 kPerClosure, |
73 }; | 82 }; |
74 | 83 |
75 intptr_t id_; | 84 intptr_t id_; |
76 ConditionKind kind_; | 85 ConditionKind kind_; |
77 Breakpoint* next_; | 86 Breakpoint* next_; |
78 RawInstance* closure_; | 87 RawInstance* closure_; |
79 BreakpointLocation* bpt_location_; | 88 BreakpointLocation* bpt_location_; |
| 89 bool is_synthetic_async_; |
80 | 90 |
81 friend class BreakpointLocation; | 91 friend class BreakpointLocation; |
82 DISALLOW_COPY_AND_ASSIGN(Breakpoint); | 92 DISALLOW_COPY_AND_ASSIGN(Breakpoint); |
83 }; | 93 }; |
84 | 94 |
85 | 95 |
86 // BreakpointLocation represents a collection of breakpoint conditions at the | 96 // BreakpointLocation represents a collection of breakpoint conditions at the |
87 // same token position in Dart source. There may be more than one CodeBreakpoint | 97 // same token position in Dart source. There may be more than one CodeBreakpoint |
88 // object per BreakpointLocation. | 98 // object per BreakpointLocation. |
89 // An unresolved breakpoint is one where the underlying code has not | 99 // An unresolved breakpoint is one where the underlying code has not |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 131 |
122 intptr_t LineNumber(); | 132 intptr_t LineNumber(); |
123 intptr_t ColumnNumber(); | 133 intptr_t ColumnNumber(); |
124 | 134 |
125 void GetCodeLocation(Library* lib, | 135 void GetCodeLocation(Library* lib, |
126 Script* script, | 136 Script* script, |
127 TokenPosition* token_pos) const; | 137 TokenPosition* token_pos) const; |
128 | 138 |
129 Breakpoint* AddRepeated(Debugger* dbg); | 139 Breakpoint* AddRepeated(Debugger* dbg); |
130 Breakpoint* AddSingleShot(Debugger* dbg); | 140 Breakpoint* AddSingleShot(Debugger* dbg); |
131 Breakpoint* AddPerClosure(Debugger* dbg, const Instance& closure); | 141 Breakpoint* AddPerClosure(Debugger* dbg, |
| 142 const Instance& closure, |
| 143 bool for_over_await); |
132 | 144 |
133 bool AnyEnabled() const; | 145 bool AnyEnabled() const; |
134 bool IsResolved() const { return is_resolved_; } | 146 bool IsResolved() const { return is_resolved_; } |
135 bool IsLatent() const { return !token_pos_.IsReal(); } | 147 bool IsLatent() const { return !token_pos_.IsReal(); } |
136 | 148 |
137 private: | 149 private: |
138 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 150 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
139 | 151 |
140 void SetResolved(const Function& func, TokenPosition token_pos); | 152 void SetResolved(const Function& func, TokenPosition token_pos); |
141 | 153 |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 void NotifyCompilation(const Function& func); | 472 void NotifyCompilation(const Function& func); |
461 void NotifyDoneLoading(); | 473 void NotifyDoneLoading(); |
462 | 474 |
463 RawFunction* ResolveFunction(const Library& library, | 475 RawFunction* ResolveFunction(const Library& library, |
464 const String& class_name, | 476 const String& class_name, |
465 const String& function_name); | 477 const String& function_name); |
466 | 478 |
467 // Set breakpoint at closest location to function entry. | 479 // Set breakpoint at closest location to function entry. |
468 Breakpoint* SetBreakpointAtEntry(const Function& target_function, | 480 Breakpoint* SetBreakpointAtEntry(const Function& target_function, |
469 bool single_shot); | 481 bool single_shot); |
470 Breakpoint* SetBreakpointAtActivation(const Instance& closure); | 482 Breakpoint* SetBreakpointAtActivation(const Instance& closure, |
| 483 bool for_over_await); |
471 Breakpoint* BreakpointAtActivation(const Instance& closure); | 484 Breakpoint* BreakpointAtActivation(const Instance& closure); |
472 | 485 |
473 // TODO(turnidge): script_url may no longer be specific enough. | 486 // TODO(turnidge): script_url may no longer be specific enough. |
474 Breakpoint* SetBreakpointAtLine(const String& script_url, | 487 Breakpoint* SetBreakpointAtLine(const String& script_url, |
475 intptr_t line_number); | 488 intptr_t line_number); |
476 Breakpoint* SetBreakpointAtLineCol(const String& script_url, | 489 Breakpoint* SetBreakpointAtLineCol(const String& script_url, |
477 intptr_t line_number, | 490 intptr_t line_number, |
478 intptr_t column_number); | 491 intptr_t column_number); |
479 RawError* OneTimeBreakAtEntry(const Function& target_function); | 492 RawError* OneTimeBreakAtEntry(const Function& target_function); |
480 | 493 |
481 BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url, | 494 BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url, |
482 intptr_t line_number, | 495 intptr_t line_number, |
483 intptr_t column_number); | 496 intptr_t column_number); |
484 | 497 |
485 | 498 |
486 void RemoveBreakpoint(intptr_t bp_id); | 499 void RemoveBreakpoint(intptr_t bp_id); |
487 Breakpoint* GetBreakpointById(intptr_t id); | 500 Breakpoint* GetBreakpointById(intptr_t id); |
488 | 501 |
| 502 // Will return false if we are not at an await. |
| 503 bool SetupStepOverAsyncSuspension(); |
489 void SetStepOver(); | 504 void SetStepOver(); |
490 void SetSingleStep(); | 505 void SetSingleStep(); |
491 void SetStepOut(); | 506 void SetStepOut(); |
492 bool IsStepping() const { return resume_action_ != kContinue; } | 507 bool IsStepping() const { return resume_action_ != kContinue; } |
493 | 508 |
494 bool IsPaused() const { return pause_event_ != NULL; } | 509 bool IsPaused() const { return pause_event_ != NULL; } |
495 | 510 |
496 // Put the isolate into single stepping mode when Dart code next runs. | 511 // Put the isolate into single stepping mode when Dart code next runs. |
497 // | 512 // |
498 // This is used by the vm service to allow the user to step while | 513 // This is used by the vm service to allow the user to step while |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 enum ResumeAction { | 595 enum ResumeAction { |
581 kContinue, | 596 kContinue, |
582 kStepOver, | 597 kStepOver, |
583 kStepOut, | 598 kStepOut, |
584 kSingleStep | 599 kSingleStep |
585 }; | 600 }; |
586 | 601 |
587 static bool HasAnyEventHandler(); | 602 static bool HasAnyEventHandler(); |
588 static bool HasDebugEventHandler(); | 603 static bool HasDebugEventHandler(); |
589 void InvokeEventHandler(DebuggerEvent* event); | 604 void InvokeEventHandler(DebuggerEvent* event); |
590 | 605 bool IsAtAsyncJump(ActivationFrame* top_frame); |
591 void FindCompiledFunctions(const Script& script, | 606 void FindCompiledFunctions(const Script& script, |
592 TokenPosition start_pos, | 607 TokenPosition start_pos, |
593 TokenPosition end_pos, | 608 TokenPosition end_pos, |
594 GrowableObjectArray* function_list); | 609 GrowableObjectArray* function_list); |
595 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); | 610 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); |
596 RawFunction* FindInnermostClosure(const Function& function, | 611 RawFunction* FindInnermostClosure(const Function& function, |
597 TokenPosition token_pos); | 612 TokenPosition token_pos); |
598 TokenPosition ResolveBreakpointPos(const Function& func, | 613 TokenPosition ResolveBreakpointPos(const Function& func, |
599 TokenPosition requested_token_pos, | 614 TokenPosition requested_token_pos, |
600 TokenPosition last_token_pos, | 615 TokenPosition last_token_pos, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // When stepping through code, only pause the program if the top | 704 // When stepping through code, only pause the program if the top |
690 // frame corresponds to this fp value, or if the top frame is | 705 // frame corresponds to this fp value, or if the top frame is |
691 // lower on the stack. | 706 // lower on the stack. |
692 uword stepping_fp_; | 707 uword stepping_fp_; |
693 | 708 |
694 // If we step while at a breakpoint, we would hit the same pc twice. | 709 // If we step while at a breakpoint, we would hit the same pc twice. |
695 // We use this field to let us skip the next single-step after a | 710 // We use this field to let us skip the next single-step after a |
696 // breakpoint. | 711 // breakpoint. |
697 bool skip_next_step_; | 712 bool skip_next_step_; |
698 | 713 |
| 714 // We keep this breakpoint alive until after the debugger does the step over |
| 715 // async continuation machinery so that we can report that we've stopped |
| 716 // at the breakpoint. |
| 717 Breakpoint* synthetic_async_breakpoint_; |
| 718 |
699 Dart_ExceptionPauseInfo exc_pause_info_; | 719 Dart_ExceptionPauseInfo exc_pause_info_; |
700 | 720 |
701 static EventHandler* event_handler_; | 721 static EventHandler* event_handler_; |
702 | 722 |
703 friend class Isolate; | 723 friend class Isolate; |
704 friend class BreakpointLocation; | 724 friend class BreakpointLocation; |
705 DISALLOW_COPY_AND_ASSIGN(Debugger); | 725 DISALLOW_COPY_AND_ASSIGN(Debugger); |
706 }; | 726 }; |
707 | 727 |
708 | 728 |
709 } // namespace dart | 729 } // namespace dart |
710 | 730 |
711 #endif // VM_DEBUGGER_H_ | 731 #endif // VM_DEBUGGER_H_ |
OLD | NEW |