| Index: runtime/vm/debugger.cc
 | 
| ===================================================================
 | 
| --- runtime/vm/debugger.cc	(revision 22595)
 | 
| +++ runtime/vm/debugger.cc	(working copy)
 | 
| @@ -603,6 +603,7 @@
 | 
|    breakpoint_kind_ = desc.DescriptorKind(pc_desc_index);
 | 
|    ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) ||
 | 
|           (breakpoint_kind_ == PcDescriptors::kFuncCall) ||
 | 
| +         (breakpoint_kind_ == PcDescriptors::kClosureCall) ||
 | 
|           (breakpoint_kind_ == PcDescriptors::kReturn));
 | 
|  }
 | 
|  
 | 
| @@ -665,6 +666,15 @@
 | 
|                                       StubCode::BreakpointStaticEntryPoint());
 | 
|        break;
 | 
|      }
 | 
| +    case PcDescriptors::kClosureCall: {
 | 
| +      const Code& code =
 | 
| +          Code::Handle(Function::Handle(function_).unoptimized_code());
 | 
| +      saved_bytes_.target_address_ =
 | 
| +          CodePatcher::GetStaticCallTargetAt(pc_, code);
 | 
| +      CodePatcher::PatchStaticCallAt(pc_, code,
 | 
| +                                     StubCode::BreakpointClosureEntryPoint());
 | 
| +      break;
 | 
| +    }
 | 
|      case PcDescriptors::kReturn:
 | 
|        PatchFunctionReturn();
 | 
|        break;
 | 
| @@ -685,7 +695,8 @@
 | 
|                                         saved_bytes_.target_address_);
 | 
|        break;
 | 
|      }
 | 
| -    case PcDescriptors::kFuncCall: {
 | 
| +    case PcDescriptors::kFuncCall:
 | 
| +    case PcDescriptors::kClosureCall: {
 | 
|        const Code& code =
 | 
|            Code::Handle(Function::Handle(function_).unoptimized_code());
 | 
|        CodePatcher::PatchStaticCallAt(pc_, code,
 | 
| @@ -874,6 +885,7 @@
 | 
|      PcDescriptors::Kind kind = desc.DescriptorKind(i);
 | 
|      if ((kind == PcDescriptors::kIcCall) ||
 | 
|          (kind == PcDescriptors::kFuncCall) ||
 | 
| +        (kind == PcDescriptors::kClosureCall) ||
 | 
|          (kind == PcDescriptors::kReturn)) {
 | 
|        bpt = new CodeBreakpoint(target_function, i);
 | 
|        RegisterCodeBreakpoint(bpt);
 | 
| @@ -1041,6 +1053,7 @@
 | 
|      PcDescriptors::Kind kind = desc.DescriptorKind(i);
 | 
|      if ((kind == PcDescriptors::kIcCall) ||
 | 
|          (kind == PcDescriptors::kFuncCall) ||
 | 
| +        (kind == PcDescriptors::kClosureCall) ||
 | 
|          (kind == PcDescriptors::kReturn)) {
 | 
|        if ((desc_token_pos - first_token_pos) < best_fit) {
 | 
|          best_fit = desc_token_pos - first_token_pos;
 | 
| @@ -1573,6 +1586,25 @@
 | 
|        if (IsDebuggable(callee)) {
 | 
|          func_to_instrument = callee.raw();
 | 
|        }
 | 
| +    } else if (bpt->breakpoint_kind_ == PcDescriptors::kClosureCall) {
 | 
| +      func_to_instrument = bpt->function();
 | 
| +      const Code& code = Code::Handle(func_to_instrument.CurrentCode());
 | 
| +      ArgumentsDescriptor args_desc(Array::Handle(
 | 
| +          CodePatcher::GetClosureArgDescAt(bpt->pc_, code)));
 | 
| +      ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0);
 | 
| +      const Object& receiver =
 | 
| +          Object::Handle(top_frame->GetClosureObject(args_desc.Count()));
 | 
| +      if (!receiver.IsNull()) {
 | 
| +        // Verify that the class of receiver is a closure class
 | 
| +        // by checking that signature_function() is not null.
 | 
| +        const Class& receiver_class = Class::Handle(receiver.clazz());
 | 
| +        if (receiver_class.IsSignatureClass()) {
 | 
| +          func_to_instrument = Closure::function(Instance::Cast(receiver));
 | 
| +        }
 | 
| +        // If the receiver is not a closure, then the runtime will attempt
 | 
| +        // to invoke the "call" method on the object if one exists.
 | 
| +        // TODO(hausner): find call method and intrument it for stepping.
 | 
| +      }
 | 
|      } else {
 | 
|        ASSERT(bpt->breakpoint_kind_ == PcDescriptors::kReturn);
 | 
|        // Treat like stepping out to caller.
 | 
| 
 |