| Index: runtime/vm/service.cc | 
| diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc | 
| index 5e34b4a9a4b17984245b32efc0db562261a07ba0..deedaed5e3fc3d01f6b51d43cf9b2ea79e716060 100644 | 
| --- a/runtime/vm/service.cc | 
| +++ b/runtime/vm/service.cc | 
| @@ -2988,18 +2988,57 @@ static bool GetVMTimeline(Thread* thread, JSONStream* js) { | 
| } | 
|  | 
|  | 
| +static const char* const step_enum_names[] = { | 
| +    "None", "Into", "Over", "Out", "Rewind", "OverAsyncSuspension", NULL, | 
| +}; | 
| + | 
| + | 
| +static const Debugger::ResumeAction step_enum_values[] = { | 
| +    Debugger::kContinue,   Debugger::kStepInto, | 
| +    Debugger::kStepOver,   Debugger::kStepOut, | 
| +    Debugger::kStepRewind, Debugger::kStepOverAsyncSuspension, | 
| +    Debugger::kContinue,  // Default value | 
| +}; | 
| + | 
| + | 
| static const MethodParameter* resume_params[] = { | 
| -    RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| +    RUNNABLE_ISOLATE_PARAMETER, | 
| +    new EnumParameter("step", false, step_enum_names), | 
| +    new UIntParameter("frameIndex", false), NULL, | 
| }; | 
|  | 
|  | 
| static bool Resume(Thread* thread, JSONStream* js) { | 
| const char* step_param = js->LookupParam("step"); | 
| +  Debugger::ResumeAction step = Debugger::kContinue; | 
| +  if (step_param != NULL) { | 
| +    step = EnumMapper(step_param, step_enum_names, step_enum_values); | 
| +  } | 
| +#if defined(TARGET_ARCH_DBC) | 
| +  if (step == Debugger::kStepRewind) { | 
| +    js->PrintError(kCannotResume, | 
| +                   "Rewind not yet implemented on this architecture"); | 
| +    return true; | 
| +  } | 
| +#endif | 
| +  intptr_t frame_index = 1; | 
| +  const char* frame_index_param = js->LookupParam("frameIndex"); | 
| +  if (frame_index_param != NULL) { | 
| +    if (step != Debugger::kStepRewind) { | 
| +      // Only rewind supports the frameIndex parameter. | 
| +      js->PrintError( | 
| +          kInvalidParams, | 
| +          "%s: the 'frameIndex' parameter can only be used when rewinding", | 
| +          js->method()); | 
| +      return true; | 
| +    } | 
| +    frame_index = UIntParameter::Parse(js->LookupParam("frameIndex")); | 
| +  } | 
| Isolate* isolate = thread->isolate(); | 
| if (isolate->message_handler()->is_paused_on_start()) { | 
| // If the user is issuing a 'Over' or an 'Out' step, that is the | 
| // same as a regular resume request. | 
| -    if ((step_param != NULL) && (strcmp(step_param, "Into") == 0)) { | 
| +    if (step == Debugger::kStepInto) { | 
| isolate->debugger()->EnterSingleStepMode(); | 
| } | 
| isolate->message_handler()->set_should_pause_on_start(false); | 
| @@ -3028,31 +3067,18 @@ static bool Resume(Thread* thread, JSONStream* js) { | 
| PrintSuccess(js); | 
| return true; | 
| } | 
| -  if (isolate->debugger()->PauseEvent() != NULL) { | 
| -    if (step_param != NULL) { | 
| -      if (strcmp(step_param, "Into") == 0) { | 
| -        isolate->debugger()->SetSingleStep(); | 
| -      } else if (strcmp(step_param, "Over") == 0) { | 
| -        isolate->debugger()->SetStepOver(); | 
| -      } else if (strcmp(step_param, "Out") == 0) { | 
| -        isolate->debugger()->SetStepOut(); | 
| -      } else if (strcmp(step_param, "OverAsyncSuspension") == 0) { | 
| -        if (!isolate->debugger()->SetupStepOverAsyncSuspension()) { | 
| -          js->PrintError(kInvalidParams, | 
| -                         "Isolate must be paused at an async suspension point"); | 
| -          return true; | 
| -        } | 
| -      } else { | 
| -        PrintInvalidParamError(js, "step"); | 
| -        return true; | 
| -      } | 
| -    } | 
| -    isolate->SetResumeRequest(); | 
| -    PrintSuccess(js); | 
| +  if (isolate->debugger()->PauseEvent() == NULL) { | 
| +    js->PrintError(kIsolateMustBePaused, NULL); | 
| return true; | 
| } | 
|  | 
| -  js->PrintError(kIsolateMustBePaused, NULL); | 
| +  const char* error = NULL; | 
| +  if (!isolate->debugger()->SetResumeAction(step, frame_index, &error)) { | 
| +    js->PrintError(kCannotResume, error); | 
| +    return true; | 
| +  } | 
| +  isolate->SetResumeRequest(); | 
| +  PrintSuccess(js); | 
| return true; | 
| } | 
|  | 
|  |