Chromium Code Reviews| 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); | |
|
siva
2011/12/09 02:20:04
We are handing out these C++ VM object pointers an
hausner
2011/12/13 00:14:59
As we discussed in person, we have type safety thr
| |
| 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); | |
|
siva
2011/12/09 02:20:04
can bp_handler be NULL? Do we need a non NULL chec
hausner
2011/12/13 00:14:59
It can be NULL. Cf. other comment.
| |
| 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, | |
|
siva
2011/12/09 02:20:04
I presume the library URL is also needed to fully
hausner
2011/12/13 00:14:59
I think the names would become very unreadable if
| |
| 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) { |
| 70 *breakpoint = reinterpret_cast<Dart_Breakpoint>(bpt); | 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); | |
| 71 } | 155 } |
| 156 *breakpoint = reinterpret_cast<Dart_Breakpoint>(bpt); | |
|
siva
2011/12/09 02:20:04
Should the setting of *breakpoint be under an else
hausner
2011/12/13 00:14:59
Yes, that's cleaner. Done.
| |
| 72 } else { | 157 } else { |
| 73 SetupErrorResult(&result); | 158 SetupErrorResult(&result); |
| 74 } | 159 } |
| 75 isolate->set_long_jump_base(base); | 160 isolate->set_long_jump_base(base); |
| 76 return result; | 161 return result; |
| 77 } | 162 } |
| 78 | 163 |
| 79 | 164 |
| 80 } // namespace dart | 165 } // namespace dart |
| OLD | NEW |