| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include "include/dart_debugger_api.h" | 5 #include "include/dart_debugger_api.h" |
| 6 | 6 |
| 7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
| 9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 } else if (tmp.IsApiError()) { \ | 21 } else if (tmp.IsApiError()) { \ |
| 22 return param; \ | 22 return param; \ |
| 23 } else if (!tmp.Is##type()) { \ | 23 } else if (!tmp.Is##type()) { \ |
| 24 return Api::Error("%s expects argument '%s' to be of type %s.", \ | 24 return Api::Error("%s expects argument '%s' to be of type %s.", \ |
| 25 CURRENT_FUNC, #param, #type); \ | 25 CURRENT_FUNC, #param, #type); \ |
| 26 } \ | 26 } \ |
| 27 var ^= tmp.raw(); \ | 27 var ^= tmp.raw(); \ |
| 28 } while (0); | 28 } while (0); |
| 29 | 29 |
| 30 | 30 |
| 31 #define CHECK_AND_CAST(type, var, param) \ |
| 32 if (param == NULL) { \ |
| 33 return Api::Error("%s expects argument '%s' to be non-null.", \ |
| 34 CURRENT_FUNC, #param); \ |
| 35 } \ |
| 36 type* var = reinterpret_cast<type*>(param); |
| 37 |
| 38 |
| 39 #define CHECK_NOT_NULL(param) \ |
| 40 if (param == NULL) { \ |
| 41 return Api::Error("%s expects argument '%s' to be non-null.", \ |
| 42 CURRENT_FUNC, #param); \ |
| 43 } |
| 44 |
| 45 |
| 46 DART_EXPORT Dart_Handle Dart_StackTraceLength( |
| 47 Dart_StackTrace trace, |
| 48 intptr_t* length) { |
| 49 Isolate* isolate = Isolate::Current(); |
| 50 DARTSCOPE(isolate); |
| 51 CHECK_NOT_NULL(length); |
| 52 CHECK_AND_CAST(StackTrace, stack_trace, trace); |
| 53 *length = stack_trace->Length(); |
| 54 return Api::True(); |
| 55 } |
| 56 |
| 57 |
| 58 DART_EXPORT Dart_Handle Dart_GetActivationFrame( |
| 59 Dart_StackTrace trace, |
| 60 int frame_index, |
| 61 Dart_ActivationFrame* frame) { |
| 62 Isolate* isolate = Isolate::Current(); |
| 63 DARTSCOPE(isolate); |
| 64 CHECK_NOT_NULL(frame); |
| 65 CHECK_AND_CAST(StackTrace, stack_trace, trace); |
| 66 if ((frame_index < 0) || (frame_index >= stack_trace->Length())) { |
| 67 return Api::Error("argument 'frame_index' is out of range for %s", |
| 68 CURRENT_FUNC); |
| 69 } |
| 70 *frame = reinterpret_cast<Dart_ActivationFrame>( |
| 71 stack_trace->ActivationFrameAt(frame_index)); |
| 72 return Api::True(); |
| 73 } |
| 74 |
| 75 |
| 76 DART_EXPORT void Dart_SetBreakpointHandler( |
| 77 Dart_BreakpointHandler bp_handler) { |
| 78 Isolate* isolate = Isolate::Current(); |
| 79 DARTSCOPE(isolate); |
| 80 BreakpointHandler* handler = |
| 81 reinterpret_cast<BreakpointHandler*>(bp_handler); |
| 82 |
| 83 isolate->debugger()->SetBreakpointHandler(handler); |
| 84 } |
| 85 |
| 86 |
| 87 DART_EXPORT Dart_Handle Dart_ActivationFrameInfo( |
| 88 Dart_ActivationFrame activation_frame, |
| 89 Dart_Handle* function_name, |
| 90 Dart_Handle* script_url, |
| 91 intptr_t* line_number) { |
| 92 Isolate* isolate = Isolate::Current(); |
| 93 DARTSCOPE(isolate); |
| 94 CHECK_AND_CAST(ActivationFrame, frame, activation_frame); |
| 95 if (function_name != NULL) { |
| 96 const String& name = String::Handle(frame->QualifiedFunctionName()); |
| 97 *function_name = Api::NewLocalHandle(name); |
| 98 } |
| 99 if (script_url != NULL) { |
| 100 const String& url = String::Handle(frame->SourceUrl()); |
| 101 *script_url = Api::NewLocalHandle(url); |
| 102 } |
| 103 if (line_number != NULL) { |
| 104 *line_number = frame->LineNumber(); |
| 105 } |
| 106 return Api::True(); |
| 107 } |
| 108 |
| 109 |
| 31 DART_EXPORT Dart_Handle Dart_SetBreakpointAtEntry( | 110 DART_EXPORT Dart_Handle Dart_SetBreakpointAtEntry( |
| 32 Dart_Handle library_in, | 111 Dart_Handle library_in, |
| 33 Dart_Handle class_name_in, | 112 Dart_Handle class_name_in, |
| 34 Dart_Handle function_name_in, | 113 Dart_Handle function_name_in, |
| 35 Dart_Breakpoint* breakpoint) { | 114 Dart_Breakpoint* breakpoint) { |
| 36 Isolate* isolate = Isolate::Current(); | 115 Isolate* isolate = Isolate::Current(); |
| 37 DARTSCOPE(isolate); | 116 DARTSCOPE(isolate); |
| 38 | 117 |
| 39 Library& library = Library::Handle(); | 118 Library& library = Library::Handle(); |
| 40 String& class_name = String::Handle(); | 119 String& class_name = String::Handle(); |
| 41 String& function_name = String::Handle(); | 120 String& function_name = String::Handle(); |
| 42 UNWRAP_AND_CHECK_PARAM(Library, library, library_in); | 121 UNWRAP_AND_CHECK_PARAM(Library, library, library_in); |
| 43 UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in); | 122 UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in); |
| 44 UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in); | 123 UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in); |
| 124 CHECK_NOT_NULL(breakpoint); |
| 45 | 125 |
| 46 const char* msg = CheckIsolateState(isolate); | 126 const char* msg = CheckIsolateState(isolate); |
| 47 if (msg != NULL) { | 127 if (msg != NULL) { |
| 48 return Api::Error(msg); | 128 return Api::Error(msg); |
| 49 } | 129 } |
| 50 | 130 |
| 51 if (breakpoint != NULL) { | |
| 52 *breakpoint = NULL; | |
| 53 } | |
| 54 | |
| 55 // Resolve the breakpoint target function. | 131 // Resolve the breakpoint target function. |
| 56 Debugger* debugger = isolate->debugger(); | 132 Debugger* debugger = isolate->debugger(); |
| 57 const Function& bp_target = Function::Handle( | 133 const Function& bp_target = Function::Handle( |
| 58 debugger->ResolveFunction(library, class_name, function_name)); | 134 debugger->ResolveFunction(library, class_name, function_name)); |
| 59 if (bp_target.IsNull()) { | 135 if (bp_target.IsNull()) { |
| 60 return Api::Error("Breakpoint target function does not exist"); | 136 const bool toplevel = class_name.Length() == 0; |
| 137 return Api::Error("%s: could not find function '%s%s%s'", |
| 138 CURRENT_FUNC, |
| 139 toplevel ? "" : class_name.ToCString(), |
| 140 toplevel ? "" : ".", |
| 141 function_name.ToCString()); |
| 61 } | 142 } |
| 62 | 143 |
| 63 LongJump* base = isolate->long_jump_base(); | 144 LongJump* base = isolate->long_jump_base(); |
| 64 LongJump jump; | 145 LongJump jump; |
| 65 isolate->set_long_jump_base(&jump); | 146 isolate->set_long_jump_base(&jump); |
| 66 Dart_Handle result = Api::True(); | 147 Dart_Handle result = Api::True(); |
| 148 *breakpoint = NULL; |
| 67 if (setjmp(*jump.Set()) == 0) { | 149 if (setjmp(*jump.Set()) == 0) { |
| 68 Breakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target); | 150 Breakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target); |
| 69 if (breakpoint != NULL) { | 151 if (bpt == NULL) { |
| 152 const char* target_name = Debugger::QualifiedFunctionName(bp_target); |
| 153 result = Api::Error("%s: no breakpoint location found in '%s'", |
| 154 CURRENT_FUNC, target_name); |
| 155 } else { |
| 70 *breakpoint = reinterpret_cast<Dart_Breakpoint>(bpt); | 156 *breakpoint = reinterpret_cast<Dart_Breakpoint>(bpt); |
| 71 } | 157 } |
| 72 } else { | 158 } else { |
| 73 SetupErrorResult(&result); | 159 SetupErrorResult(&result); |
| 74 } | 160 } |
| 75 isolate->set_long_jump_base(base); | 161 isolate->set_long_jump_base(base); |
| 76 return result; | 162 return result; |
| 77 } | 163 } |
| 78 | 164 |
| 79 | 165 |
| 80 } // namespace dart | 166 } // namespace dart |
| OLD | NEW |