| Index: runtime/vm/dart_api_impl.cc
|
| diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
|
| index 74117cc890c7626dfab5cecd7e978bde797cb284..53a650da1c86c2b1104cea09578c84dae59b14da 100644
|
| --- a/runtime/vm/dart_api_impl.cc
|
| +++ b/runtime/vm/dart_api_impl.cc
|
| @@ -15,6 +15,7 @@
|
| #include "vm/dart_api_message.h"
|
| #include "vm/dart_api_state.h"
|
| #include "vm/dart_entry.h"
|
| +#include "vm/debugger.h"
|
| #include "vm/debuginfo.h"
|
| #include "vm/exceptions.h"
|
| #include "vm/flags.h"
|
| @@ -375,19 +376,95 @@ DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle) {
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ErrorGetStacktrace(Dart_Handle handle) {
|
| +DART_EXPORT Dart_Handle Dart_ErrorGetStacktrace(
|
| + Dart_Handle handle,
|
| + Dart_ExceptionStackTrace *trace) {
|
| Isolate* isolate = Isolate::Current();
|
| DARTSCOPE(isolate);
|
| const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle));
|
| if (obj.IsUnhandledException()) {
|
| const UnhandledException& error = UnhandledException::Cast(obj);
|
| - return Api::NewHandle(isolate, error.stacktrace());
|
| + Stacktrace& dart_stacktrace = Stacktrace::Handle(isolate);
|
| + dart_stacktrace ^= error.stacktrace();
|
| + if (dart_stacktrace.IsNull()) {
|
| + *trace = NULL;
|
| + } else {
|
| + ExceptionStackTrace* cpp_stacktrace =
|
| + dart_stacktrace.BuildExceptionStackTrace();
|
| + *trace = reinterpret_cast<Dart_ExceptionStackTrace>(cpp_stacktrace);
|
| + }
|
| + return Api::Success();
|
| } else if (obj.IsError()) {
|
| return Api::NewError("This error is not an unhandled exception error.");
|
| } else {
|
| return Api::NewError("Can only get stacktraces from error handles.");
|
| }
|
| }
|
| +DART_EXPORT Dart_Handle Dart_CurrentStacktrace(
|
| + Dart_ExceptionStackTrace *trace) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + ExceptionStackTrace* cpp_stacktrace =
|
| + isolate->debugger()->BuildExceptionStackTrace();
|
| + *trace = reinterpret_cast<Dart_ExceptionStackTrace>(cpp_stacktrace);
|
| + return Api::Success();
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_StacktraceLength(Dart_ExceptionStackTrace trace,
|
| + intptr_t* length) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + if (trace == NULL) {
|
| + return Api::NewError("%s expects argument 'trace' to be non-null.",
|
| + CURRENT_FUNC);
|
| + }
|
| + ExceptionStackTrace *stack_trace =
|
| + reinterpret_cast<ExceptionStackTrace*>(trace);
|
| + if (length == NULL) {
|
| + return Api::NewError("%s expects argument 'length' to be non-null.",
|
| + CURRENT_FUNC);
|
| + }
|
| + *length = stack_trace->Length();
|
| + return Api::Success();
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_StacktraceFrameInfo(
|
| + Dart_ExceptionStackTrace trace,
|
| + intptr_t frame_index,
|
| + Dart_Handle* function_name,
|
| + Dart_Handle* script_url,
|
| + intptr_t* line_number,
|
| + intptr_t* col_number) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + if (trace == NULL) {
|
| + return Api::NewError("%s expects argument 'trace' to be non-null.",
|
| + CURRENT_FUNC);
|
| + }
|
| + ExceptionStackTrace *stack_trace =
|
| + reinterpret_cast<ExceptionStackTrace*>(trace);
|
| + if (frame_index < 0 || frame_index >= stack_trace->Length()) {
|
| + return Api::NewError(
|
| + "%s: frame index was out of bounds (%" Pd ")",
|
| + CURRENT_FUNC, frame_index);
|
| + }
|
| + ExceptionStackFrame *frame = stack_trace->FrameAt(frame_index);
|
| + if (function_name != NULL) {
|
| + *function_name = Api::NewHandle(isolate, frame->function_name());
|
| + }
|
| + if (script_url != NULL) {
|
| + *script_url = Api::NewHandle(isolate, frame->script_uri());
|
| + }
|
| + if (line_number != NULL) {
|
| + *line_number = frame->line_number();
|
| + }
|
| + if (col_number != NULL) {
|
| + *col_number = frame->column_number();
|
| + }
|
| + return Api::Success();
|
| +}
|
|
|
|
|
| // TODO(turnidge): This clones Api::NewError. I need to use va_copy to
|
|
|