| Index: runtime/vm/debugger.cc
|
| ===================================================================
|
| --- runtime/vm/debugger.cc (revision 22155)
|
| +++ runtime/vm/debugger.cc (working copy)
|
| @@ -339,13 +339,15 @@
|
| }
|
|
|
|
|
| -RawContext* ActivationFrame::GetSavedContext(const Context& ctx) {
|
| +// Get the caller's context, or return ctx if the function does not
|
| +// save the caller's context on entry.
|
| +RawContext* ActivationFrame::GetSavedCallerContext(const Context& ctx) {
|
| GetVarDescriptors();
|
| intptr_t var_desc_len = var_descriptors_.Length();
|
| for (int i = 0; i < var_desc_len; i++) {
|
| RawLocalVarDescriptors::VarInfo var_info;
|
| var_descriptors_.GetInfo(i, &var_info);
|
| - if (var_info.kind == RawLocalVarDescriptors::kContextChain) {
|
| + if (var_info.kind == RawLocalVarDescriptors::kSavedCallerContext) {
|
| return reinterpret_cast<RawContext*>(GetLocalVarValue(var_info.index));
|
| }
|
| }
|
| @@ -353,6 +355,23 @@
|
| }
|
|
|
|
|
| +// Get the saved context if the callee of this activation frame is a
|
| +// closure function.
|
| +RawContext* ActivationFrame::GetSavedCurrentContext() {
|
| + GetVarDescriptors();
|
| + intptr_t var_desc_len = var_descriptors_.Length();
|
| + for (int i = 0; i < var_desc_len; i++) {
|
| + RawLocalVarDescriptors::VarInfo var_info;
|
| + var_descriptors_.GetInfo(i, &var_info);
|
| + if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) {
|
| + return reinterpret_cast<RawContext*>(GetLocalVarValue(var_info.index));
|
| + }
|
| + }
|
| + UNREACHABLE();
|
| + return Context::null();
|
| +}
|
| +
|
| +
|
| ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
|
| const Instance& exc_obj) const {
|
| ExceptionHandlers& handlers = ExceptionHandlers::Handle();
|
| @@ -891,15 +910,25 @@
|
| frame->fp(),
|
| frame->sp(),
|
| code);
|
| + // If this activation frame called a closure, the function has
|
| + // saved its context before the call.
|
| + if (stack_trace->Length() > 0) {
|
| + ActivationFrame* callee_frame =
|
| + stack_trace->ActivationFrameAt(stack_trace->Length() - 1);
|
| + if (callee_frame->function().IsClosureFunction()) {
|
| + ctx = activation->GetSavedCurrentContext();
|
| + }
|
| + }
|
| if (optimized_frame_found || code.is_optimized()) {
|
| // Set context to null, to avoid returning bad context variable values.
|
| activation->SetContext(Context::Handle());
|
| optimized_frame_found = true;
|
| } else {
|
| activation->SetContext(ctx);
|
| - ctx = activation->GetSavedContext(ctx);
|
| }
|
| stack_trace->AddActivation(activation);
|
| + // Get caller's context if this function saved it on entry.
|
| + ctx = activation->GetSavedCallerContext(ctx);
|
| } else if (frame->IsEntryFrame()) {
|
| ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext();
|
| }
|
|
|