| 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 |