OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/assembler-inl.h" | 5 #include "src/assembler-inl.h" |
6 #include "src/debug/debug-interface.h" | 6 #include "src/debug/debug-interface.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/property-descriptor.h" | 8 #include "src/property-descriptor.h" |
9 #include "src/utils.h" | 9 #include "src/utils.h" |
10 #include "src/wasm/wasm-macro-gen.h" | 10 #include "src/wasm/wasm-macro-gen.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 } | 47 } |
48 } | 48 } |
49 void CheckLocationsFail(WasmCompiledModule *compiled_module, | 49 void CheckLocationsFail(WasmCompiledModule *compiled_module, |
50 debug::Location start, debug::Location end) { | 50 debug::Location start, debug::Location end) { |
51 std::vector<debug::BreakLocation> locations; | 51 std::vector<debug::BreakLocation> locations; |
52 bool success = | 52 bool success = |
53 compiled_module->GetPossibleBreakpoints(start, end, &locations); | 53 compiled_module->GetPossibleBreakpoints(start, end, &locations); |
54 CHECK(!success); | 54 CHECK(!success); |
55 } | 55 } |
56 | 56 |
57 class BreakHandler { | 57 class BreakHandler : public debug::DebugDelegate { |
58 public: | 58 public: |
59 enum Action { | 59 enum Action { |
60 Continue = StepAction::LastStepAction + 1, | 60 Continue = StepAction::LastStepAction + 1, |
61 StepNext = StepAction::StepNext, | 61 StepNext = StepAction::StepNext, |
62 StepIn = StepAction::StepIn, | 62 StepIn = StepAction::StepIn, |
63 StepOut = StepAction::StepOut | 63 StepOut = StepAction::StepOut |
64 }; | 64 }; |
65 struct BreakPoint { | 65 struct BreakPoint { |
66 int position; | 66 int position; |
67 Action action; | 67 Action action; |
68 BreakPoint(int position, Action action) | 68 BreakPoint(int position, Action action) |
69 : position(position), action(action) {} | 69 : position(position), action(action) {} |
70 }; | 70 }; |
71 | 71 |
72 explicit BreakHandler(Isolate* isolate, | 72 explicit BreakHandler(Isolate* isolate, |
73 std::initializer_list<BreakPoint> expected_breaks) | 73 std::initializer_list<BreakPoint> expected_breaks) |
74 : isolate_(isolate), expected_breaks_(expected_breaks) { | 74 : isolate_(isolate), expected_breaks_(expected_breaks) { |
75 current_handler = this; | 75 v8::debug::SetDebugDelegate(reinterpret_cast<v8::Isolate*>(isolate_), this); |
76 v8::Debug::SetDebugEventListener(reinterpret_cast<v8::Isolate*>(isolate), | |
77 DebugEventListener); | |
78 } | 76 } |
79 ~BreakHandler() { | 77 ~BreakHandler() { |
80 // Check that all expected breakpoints have been hit. | 78 // Check that all expected breakpoints have been hit. |
81 CHECK_EQ(count_, expected_breaks_.size()); | 79 CHECK_EQ(count_, expected_breaks_.size()); |
82 // BreakHandlers must be correctly stacked. | 80 v8::debug::SetDebugDelegate(reinterpret_cast<v8::Isolate*>(isolate_), |
83 CHECK_EQ(this, current_handler); | 81 nullptr); |
84 current_handler = nullptr; | |
85 v8::Debug::SetDebugEventListener(reinterpret_cast<v8::Isolate*>(isolate_), | |
86 nullptr); | |
87 } | 82 } |
88 | 83 |
89 int count() const { return count_; } | 84 int count() const { return count_; } |
90 | 85 |
91 private: | 86 private: |
92 Isolate* isolate_; | 87 Isolate* isolate_; |
93 int count_ = 0; | 88 int count_ = 0; |
94 std::vector<BreakPoint> expected_breaks_; | 89 std::vector<BreakPoint> expected_breaks_; |
95 | 90 |
96 static BreakHandler* current_handler; | 91 void BreakProgramRequested(v8::Local<v8::Context> paused_context, |
97 | 92 v8::Local<v8::Object> exec_state, |
98 void HandleBreak() { | 93 v8::Local<v8::Value> break_points_hit) override { |
99 printf("Break #%d\n", count_); | 94 printf("Break #%d\n", count_); |
100 CHECK_GT(expected_breaks_.size(), count_); | 95 CHECK_GT(expected_breaks_.size(), count_); |
101 | 96 |
102 // Check the current position. | 97 // Check the current position. |
103 StackTraceFrameIterator frame_it(isolate_); | 98 StackTraceFrameIterator frame_it(isolate_); |
104 auto summ = FrameSummary::GetTop(frame_it.frame()).AsWasmInterpreted(); | 99 auto summ = FrameSummary::GetTop(frame_it.frame()).AsWasmInterpreted(); |
105 CHECK_EQ(expected_breaks_[count_].position, summ.byte_offset()); | 100 CHECK_EQ(expected_breaks_[count_].position, summ.byte_offset()); |
106 | 101 |
107 Action next_action = expected_breaks_[count_].action; | 102 Action next_action = expected_breaks_[count_].action; |
108 switch (next_action) { | 103 switch (next_action) { |
109 case Continue: | 104 case Continue: |
110 break; | 105 break; |
111 case StepNext: | 106 case StepNext: |
112 case StepIn: | 107 case StepIn: |
113 case StepOut: | 108 case StepOut: |
114 isolate_->debug()->PrepareStep(static_cast<StepAction>(next_action)); | 109 isolate_->debug()->PrepareStep(static_cast<StepAction>(next_action)); |
115 break; | 110 break; |
116 default: | 111 default: |
117 UNREACHABLE(); | 112 UNREACHABLE(); |
118 } | 113 } |
119 ++count_; | 114 ++count_; |
120 } | 115 } |
121 | |
122 static void DebugEventListener(const v8::Debug::EventDetails& event_details) { | |
123 if (event_details.GetEvent() != v8::DebugEvent::Break) return; | |
124 | |
125 CHECK_NOT_NULL(current_handler); | |
126 current_handler->HandleBreak(); | |
127 } | |
128 }; | 116 }; |
129 | 117 |
130 // static | |
131 BreakHandler* BreakHandler::current_handler = nullptr; | |
132 | |
133 Handle<JSObject> MakeFakeBreakpoint(Isolate* isolate, int position) { | 118 Handle<JSObject> MakeFakeBreakpoint(Isolate* isolate, int position) { |
134 Handle<JSObject> obj = | 119 Handle<JSObject> obj = |
135 isolate->factory()->NewJSObject(isolate->object_function()); | 120 isolate->factory()->NewJSObject(isolate->object_function()); |
136 // Generate an "isTriggered" method that always returns true. | 121 // Generate an "isTriggered" method that always returns true. |
137 // This can/must be refactored once we remove remaining JS parts from the | 122 // This can/must be refactored once we remove remaining JS parts from the |
138 // debugger (bug 5530). | 123 // debugger (bug 5530). |
139 Handle<String> source = isolate->factory()->NewStringFromStaticChars("true"); | 124 Handle<String> source = isolate->factory()->NewStringFromStaticChars("true"); |
140 Handle<Context> context(isolate->context(), isolate); | 125 Handle<Context> context(isolate->context(), isolate); |
141 Handle<JSFunction> triggered_fun = | 126 Handle<JSFunction> triggered_fun = |
142 Compiler::GetFunctionFromString(context, source, NO_PARSE_RESTRICTION, | 127 Compiler::GetFunctionFromString(context, source, NO_PARSE_RESTRICTION, |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 {19, BreakHandler::StepIn}, // GetLocal | 265 {19, BreakHandler::StepIn}, // GetLocal |
281 {21, BreakHandler::StepIn}, // Call | 266 {21, BreakHandler::StepIn}, // Call |
282 {1, BreakHandler::StepOut}, // in f2 | 267 {1, BreakHandler::StepOut}, // in f2 |
283 {23, BreakHandler::Continue} // After Call | 268 {23, BreakHandler::Continue} // After Call |
284 }); | 269 }); |
285 | 270 |
286 Handle<Object> global(isolate->context()->global_object(), isolate); | 271 Handle<Object> global(isolate->context()->global_object(), isolate); |
287 CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr) | 272 CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr) |
288 .is_null()); | 273 .is_null()); |
289 } | 274 } |
OLD | NEW |