/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <memory>
#include <string>

#include "atomic.h"
#include "base/hex_dump.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/stringprintf.h"
#include "debugger.h"
#include "jdwp/jdwp_constants.h"
#include "jdwp/jdwp_event.h"
#include "jdwp/jdwp_expand_buf.h"
#include "jdwp/jdwp_priv.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
#include "utils.h"

namespace art {

namespace JDWP {

std::string DescribeField(const FieldId& field_id) {
  return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
}

std::string DescribeMethod(const MethodId& method_id) {
  return StringPrintf("%#" PRIx64 " (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
}

std::string DescribeRefTypeId(const RefTypeId& ref_type_id) {
  std::string signature("unknown");
  Dbg::GetSignature(ref_type_id, &signature);
  return StringPrintf("%#" PRIx64 " (%s)", ref_type_id, signature.c_str());
}

static JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  uint8_t tag;
  JdwpError rc = Dbg::GetObjectTag(object_id, &tag);
  if (rc == ERR_NONE) {
    expandBufAdd1(reply, tag);
    expandBufAddObjectId(reply, object_id);
  }
  return rc;
}

static JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<ObjectId>& objects)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  expandBufAdd4BE(reply, objects.size());
  for (size_t i = 0; i < objects.size(); ++i) {
    JdwpError rc = WriteTaggedObject(reply, objects[i]);
    if (rc != ERR_NONE) {
      return rc;
    }
  }
  return ERR_NONE;
}

/*
 * Common code for *_InvokeMethod requests.
 *
 * If "is_constructor" is set, this returns "object_id" rather than the
 * expected-to-be-void return value of the called function.
 */
static JdwpError RequestInvoke(JdwpState*, Request* request,
                               ObjectId thread_id, ObjectId object_id,
                               RefTypeId class_id, MethodId method_id, bool is_constructor)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  CHECK(!is_constructor || object_id != 0);

  int32_t arg_count = request->ReadSigned32("argument count");

  VLOG(jdwp) << StringPrintf("    --> thread_id=%#" PRIx64 " object_id=%#" PRIx64,
                             thread_id, object_id);
  VLOG(jdwp) << StringPrintf("        class_id=%#" PRIx64 " method_id=%#" PRIx64 " %s.%s",
                             class_id, method_id, Dbg::GetClassName(class_id).c_str(),
                             Dbg::GetMethodName(method_id).c_str());
  VLOG(jdwp) << StringPrintf("        %d args:", arg_count);

  std::unique_ptr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : nullptr);
  std::unique_ptr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : nullptr);
  for (int32_t i = 0; i < arg_count; ++i) {
    argTypes[i] = request->ReadTag();
    size_t width = Dbg::GetTagWidth(argTypes[i]);
    argValues[i] = request->ReadValue(width);
    VLOG(jdwp) << "          " << argTypes[i] << StringPrintf("(%zd): %#" PRIx64, width,
                                                              argValues[i]);
  }

  uint32_t options = request->ReadUnsigned32("InvokeOptions bit flags");
  VLOG(jdwp) << StringPrintf("        options=0x%04x%s%s", options,
                             (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
                             (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");

  JDWP::JdwpError error =  Dbg::PrepareInvokeMethod(request->GetId(), thread_id, object_id,
                                                    class_id, method_id, arg_count,
                                                    argValues.get(), argTypes.get(), options);
  if (error == JDWP::ERR_NONE) {
    // We successfully requested the invoke. The event thread now owns the arguments array in its
    // DebugInvokeReq mailbox.
    argValues.release();
  }
  return error;
}

static JdwpError VM_Version(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  // Text information on runtime version.
  std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
  expandBufAddUtf8String(pReply, version);

  // JDWP version numbers, major and minor.
  expandBufAdd4BE(pReply, 1);
  expandBufAdd4BE(pReply, 6);

  // "java.version".
  expandBufAddUtf8String(pReply, "1.6.0");

  // "java.vm.name".
  expandBufAddUtf8String(pReply, "Dalvik");

  return ERR_NONE;
}

/*
 * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
 * referenceTypeID.  We need to send back more than one if the class has
 * been loaded by multiple class loaders.
 */
static JdwpError VM_ClassesBySignature(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  std::string classDescriptor(request->ReadUtf8String());

  std::vector<RefTypeId> ids;
  Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), &ids);

  expandBufAdd4BE(pReply, ids.size());

  for (size_t i = 0; i < ids.size(); ++i) {
    // Get class vs. interface and status flags.
    JDWP::JdwpTypeTag type_tag;
    uint32_t class_status;
    JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, nullptr);
    if (status != ERR_NONE) {
      return status;
    }

    expandBufAdd1(pReply, type_tag);
    expandBufAddRefTypeId(pReply, ids[i]);
    expandBufAdd4BE(pReply, class_status);
  }

  return ERR_NONE;
}

/*
 * Handle request for the thread IDs of all running threads.
 *
 * We exclude ourselves from the list, because we don't allow ourselves
 * to be suspended, and that violates some JDWP expectations.
 */
static JdwpError VM_AllThreads(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  std::vector<ObjectId> thread_ids;
  Dbg::GetThreads(nullptr /* all thread groups */, &thread_ids);

  expandBufAdd4BE(pReply, thread_ids.size());
  for (uint32_t i = 0; i < thread_ids.size(); ++i) {
    expandBufAddObjectId(pReply, thread_ids[i]);
  }

  return ERR_NONE;
}

/*
 * List all thread groups that do not have a parent.
 */
static JdwpError VM_TopLevelThreadGroups(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  /*
   * TODO: maintain a list of parentless thread groups in the VM.
   *
   * For now, just return "system".  Application threads are created
   * in "main", which is a child of "system".
   */
  uint32_t groups = 1;
  expandBufAdd4BE(pReply, groups);
  ObjectId thread_group_id = Dbg::GetSystemThreadGroupId();
  expandBufAddObjectId(pReply, thread_group_id);

  return ERR_NONE;
}

/*
 * Respond with the sizes of the basic debugger types.
 */
static JdwpError VM_IDSizes(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  expandBufAdd4BE(pReply, sizeof(FieldId));
  expandBufAdd4BE(pReply, sizeof(MethodId));
  expandBufAdd4BE(pReply, sizeof(ObjectId));
  expandBufAdd4BE(pReply, sizeof(RefTypeId));
  expandBufAdd4BE(pReply, sizeof(FrameId));
  return ERR_NONE;
}

static JdwpError VM_Dispose(JdwpState*, Request*, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  Dbg::Dispose();
  return ERR_NONE;
}

/*
 * Suspend the execution of the application running in the VM (i.e. suspend
 * all threads).
 *
 * This needs to increment the "suspend count" on all threads.
 */
static JdwpError VM_Suspend(JdwpState*, Request*, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  Thread* self = Thread::Current();
  ScopedThreadSuspension sts(self, kWaitingForDebuggerSuspension);
  Dbg::SuspendVM();
  return ERR_NONE;
}

/*
 * Resume execution.  Decrements the "suspend count" of all threads.
 */
static JdwpError VM_Resume(JdwpState*, Request*, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  Dbg::ResumeVM();
  return ERR_NONE;
}

static JdwpError VM_Exit(JdwpState* state, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  uint32_t exit_status = request->ReadUnsigned32("exit_status");
  state->ExitAfterReplying(exit_status);
  return ERR_NONE;
}

/*
 * Create a new string in the VM and return its ID.
 *
 * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
 * string "java.util.Arrays".)
 */
static JdwpError VM_CreateString(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  std::string str(request->ReadUtf8String());
  ObjectId string_id;
  JdwpError status = Dbg::CreateString(str, &string_id);
  if (status != ERR_NONE) {
    return status;
  }
  expandBufAddObjectId(pReply, string_id);
  return ERR_NONE;
}

static JdwpError VM_ClassPaths(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  expandBufAddUtf8String(pReply, "/");

  std::vector<std::string> class_path;
  Split(Runtime::Current()->GetClassPathString(), ':', &class_path);
  expandBufAdd4BE(pReply, class_path.size());
  for (const std::string& str : class_path) {
    expandBufAddUtf8String(pReply, str);
  }

  std::vector<std::string> boot_class_path;
  Split(Runtime::Current()->GetBootClassPathString(), ':', &boot_class_path);
  expandBufAdd4BE(pReply, boot_class_path.size());
  for (const std::string& str : boot_class_path) {
    expandBufAddUtf8String(pReply, str);
  }

  return ERR_NONE;
}

static JdwpError VM_DisposeObjects(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  size_t object_count = request->ReadUnsigned32("object_count");
  for (size_t i = 0; i < object_count; ++i) {
    ObjectId object_id = request->ReadObjectId();
    uint32_t reference_count = request->ReadUnsigned32("reference_count");
    Dbg::DisposeObject(object_id, reference_count);
  }
  return ERR_NONE;
}

static JdwpError VM_Capabilities(JdwpState*, Request*, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  expandBufAdd1(reply, true);    // canWatchFieldModification
  expandBufAdd1(reply, true);    // canWatchFieldAccess
  expandBufAdd1(reply, true);    // canGetBytecodes
  expandBufAdd1(reply, true);    // canGetSyntheticAttribute
  expandBufAdd1(reply, true);    // canGetOwnedMonitorInfo
  expandBufAdd1(reply, true);    // canGetCurrentContendedMonitor
  expandBufAdd1(reply, true);    // canGetMonitorInfo
  return ERR_NONE;
}

static JdwpError VM_CapabilitiesNew(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  // The first few capabilities are the same as those reported by the older call.
  VM_Capabilities(nullptr, request, reply);

  expandBufAdd1(reply, false);   // canRedefineClasses
  expandBufAdd1(reply, false);   // canAddMethod
  expandBufAdd1(reply, false);   // canUnrestrictedlyRedefineClasses
  expandBufAdd1(reply, false);   // canPopFrames
  expandBufAdd1(reply, true);    // canUseInstanceFilters
  expandBufAdd1(reply, false);   // canGetSourceDebugExtension
  expandBufAdd1(reply, false);   // canRequestVMDeathEvent
  expandBufAdd1(reply, false);   // canSetDefaultStratum
  expandBufAdd1(reply, true);    // 1.6: canGetInstanceInfo
  expandBufAdd1(reply, false);   // 1.6: canRequestMonitorEvents
  expandBufAdd1(reply, true);    // 1.6: canGetMonitorFrameInfo
  expandBufAdd1(reply, false);   // 1.6: canUseSourceNameFilters
  expandBufAdd1(reply, false);   // 1.6: canGetConstantPool
  expandBufAdd1(reply, false);   // 1.6: canForceEarlyReturn

  // Fill in reserved22 through reserved32; note count started at 1.
  for (size_t i = 22; i <= 32; ++i) {
    expandBufAdd1(reply, false);
  }
  return ERR_NONE;
}

static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  std::vector<JDWP::RefTypeId> classes;
  Dbg::GetClassList(&classes);

  expandBufAdd4BE(pReply, classes.size());

  for (size_t i = 0; i < classes.size(); ++i) {
    static const char genericSignature[1] = "";
    JDWP::JdwpTypeTag type_tag;
    std::string descriptor;
    uint32_t class_status;
    JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor);
    if (status != ERR_NONE) {
      return status;
    }

    expandBufAdd1(pReply, type_tag);
    expandBufAddRefTypeId(pReply, classes[i]);
    if (descriptor_and_status) {
      expandBufAddUtf8String(pReply, descriptor);
      if (generic) {
        expandBufAddUtf8String(pReply, genericSignature);
      }
      expandBufAdd4BE(pReply, class_status);
    }
  }

  return ERR_NONE;
}

static JdwpError VM_AllClasses(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return VM_AllClassesImpl(pReply, true, false);
}

static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request*, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return VM_AllClassesImpl(pReply, true, true);
}

static JdwpError VM_InstanceCounts(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  int32_t class_count = request->ReadSigned32("class count");
  if (class_count < 0) {
    return ERR_ILLEGAL_ARGUMENT;
  }
  std::vector<RefTypeId> class_ids;
  for (int32_t i = 0; i < class_count; ++i) {
    class_ids.push_back(request->ReadRefTypeId());
  }

  std::vector<uint64_t> counts;
  JdwpError rc = Dbg::GetInstanceCounts(class_ids, &counts);
  if (rc != ERR_NONE) {
    return rc;
  }

  expandBufAdd4BE(pReply, counts.size());
  for (size_t i = 0; i < counts.size(); ++i) {
    expandBufAdd8BE(pReply, counts[i]);
  }
  return ERR_NONE;
}

static JdwpError RT_Modifiers(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::GetModifiers(refTypeId, pReply);
}

/*
 * Get values from static fields in a reference type.
 */
static JdwpError RT_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  int32_t field_count = request->ReadSigned32("field count");
  expandBufAdd4BE(pReply, field_count);
  for (int32_t i = 0; i < field_count; ++i) {
    FieldId fieldId = request->ReadFieldId();
    JdwpError status = Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
    if (status != ERR_NONE) {
      return status;
    }
  }
  return ERR_NONE;
}

/*
 * Get the name of the source file in which a reference type was declared.
 */
static JdwpError RT_SourceFile(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  std::string source_file;
  JdwpError status = Dbg::GetSourceFile(refTypeId, &source_file);
  if (status != ERR_NONE) {
    return status;
  }
  expandBufAddUtf8String(pReply, source_file);
  return ERR_NONE;
}

/*
 * Return the current status of the reference type.
 */
static JdwpError RT_Status(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  JDWP::JdwpTypeTag type_tag;
  uint32_t class_status;
  JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, nullptr);
  if (status != ERR_NONE) {
    return status;
  }
  expandBufAdd4BE(pReply, class_status);
  return ERR_NONE;
}

/*
 * Return interfaces implemented directly by this class.
 */
static JdwpError RT_Interfaces(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
}

/*
 * Return the class object corresponding to this type.
 */
static JdwpError RT_ClassObject(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  ObjectId class_object_id;
  JdwpError status = Dbg::GetClassObject(refTypeId, &class_object_id);
  if (status != ERR_NONE) {
    return status;
  }
  VLOG(jdwp) << StringPrintf("    --> ObjectId %#" PRIx64, class_object_id);
  expandBufAddObjectId(pReply, class_object_id);
  return ERR_NONE;
}

/*
 * Returns the value of the SourceDebugExtension attribute.
 *
 * JDB seems interested, but DEX files don't currently support this.
 */
static JdwpError RT_SourceDebugExtension(JdwpState*, Request*, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  /* referenceTypeId in, string out */
  return ERR_ABSENT_INFORMATION;
}

static JdwpError RT_Signature(JdwpState*, Request* request, ExpandBuf* pReply, bool with_generic)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();

  std::string signature;
  JdwpError status = Dbg::GetSignature(refTypeId, &signature);
  if (status != ERR_NONE) {
    return status;
  }
  expandBufAddUtf8String(pReply, signature);
  if (with_generic) {
    expandBufAddUtf8String(pReply, "");
  }
  return ERR_NONE;
}

static JdwpError RT_Signature(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return RT_Signature(state, request, pReply, false);
}

static JdwpError RT_SignatureWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return RT_Signature(state, request, pReply, true);
}

/*
 * Return the instance of java.lang.ClassLoader that loaded the specified
 * reference type, or null if it was loaded by the system loader.
 */
static JdwpError RT_ClassLoader(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::GetClassLoader(refTypeId, pReply);
}

/*
 * Given a referenceTypeId, return a block of stuff that describes the
 * fields declared by a class.
 */
static JdwpError RT_FieldsWithGeneric(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
}

// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
static JdwpError RT_Fields(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
}

/*
 * Given a referenceTypeID, return a block of goodies describing the
 * methods declared by a class.
 */
static JdwpError RT_MethodsWithGeneric(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
}

// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
static JdwpError RT_Methods(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
}

static JdwpError RT_Instances(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  int32_t max_count = request->ReadSigned32("max count");
  if (max_count < 0) {
    return ERR_ILLEGAL_ARGUMENT;
  }

  std::vector<ObjectId> instances;
  JdwpError rc = Dbg::GetInstances(class_id, max_count, &instances);
  if (rc != ERR_NONE) {
    return rc;
  }

  return WriteTaggedObjectList(reply, instances);
}

/*
 * Return the immediate superclass of a class.
 */
static JdwpError CT_Superclass(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  RefTypeId superClassId;
  JdwpError status = Dbg::GetSuperclass(class_id, &superClassId);
  if (status != ERR_NONE) {
    return status;
  }
  expandBufAddRefTypeId(pReply, superClassId);
  return ERR_NONE;
}

/*
 * Set static class values.
 */
static JdwpError CT_SetValues(JdwpState* , Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  int32_t values_count = request->ReadSigned32("values count");

  UNUSED(class_id);

  for (int32_t i = 0; i < values_count; ++i) {
    FieldId fieldId = request->ReadFieldId();
    JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId);
    size_t width = Dbg::GetTagWidth(fieldTag);
    uint64_t value = request->ReadValue(width);

    VLOG(jdwp) << "    --> field=" << fieldId << " tag=" << fieldTag << " --> " << value;
    JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width);
    if (status != ERR_NONE) {
      return status;
    }
  }

  return ERR_NONE;
}

/*
 * Invoke a static method.
 *
 * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
 * values in the "variables" display.
 */
static JdwpError CT_InvokeMethod(JdwpState* state, Request* request,
                                 ExpandBuf* pReply ATTRIBUTE_UNUSED)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  ObjectId thread_id = request->ReadThreadId();
  MethodId method_id = request->ReadMethodId();

  return RequestInvoke(state, request, thread_id, 0, class_id, method_id, false);
}

/*
 * Create a new object of the requested type, and invoke the specified
 * constructor.
 *
 * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
 * see the contents of a byte[] as a string.
 */
static JdwpError CT_NewInstance(JdwpState* state, Request* request,
                                ExpandBuf* pReply ATTRIBUTE_UNUSED)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  ObjectId thread_id = request->ReadThreadId();
  MethodId method_id = request->ReadMethodId();

  ObjectId object_id;
  JdwpError status = Dbg::CreateObject(class_id, &object_id);
  if (status != ERR_NONE) {
    return status;
  }
  return RequestInvoke(state, request, thread_id, object_id, class_id, method_id, true);
}

/*
 * Create a new array object of the requested type and length.
 */
static JdwpError AT_newInstance(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId arrayTypeId = request->ReadRefTypeId();
  int32_t length = request->ReadSigned32("length");

  ObjectId object_id;
  JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, &object_id);
  if (status != ERR_NONE) {
    return status;
  }
  expandBufAdd1(pReply, JT_ARRAY);
  expandBufAddObjectId(pReply, object_id);
  return ERR_NONE;
}

/*
 * Return line number information for the method, if present.
 */
static JdwpError M_LineTable(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  MethodId method_id = request->ReadMethodId();

  Dbg::OutputLineTable(refTypeId, method_id, pReply);

  return ERR_NONE;
}

static JdwpError M_VariableTable(JdwpState*, Request* request, ExpandBuf* pReply,
                                 bool generic)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  MethodId method_id = request->ReadMethodId();

  // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
  // information. That will cause Eclipse to make a best-effort attempt at displaying local
  // variables anonymously. However, the attempt isn't very good, so we're probably better off just
  // not showing anything.
  Dbg::OutputVariableTable(class_id, method_id, generic, pReply);
  return ERR_NONE;
}

static JdwpError M_VariableTable(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return M_VariableTable(state, request, pReply, false);
}

static JdwpError M_VariableTableWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return M_VariableTable(state, request, pReply, true);
}

static JdwpError M_Bytecodes(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_id = request->ReadRefTypeId();
  MethodId method_id = request->ReadMethodId();

  std::vector<uint8_t> bytecodes;
  JdwpError rc = Dbg::GetBytecodes(class_id, method_id, &bytecodes);
  if (rc != ERR_NONE) {
    return rc;
  }

  expandBufAdd4BE(reply, bytecodes.size());
  for (size_t i = 0; i < bytecodes.size(); ++i) {
    expandBufAdd1(reply, bytecodes[i]);
  }

  return ERR_NONE;
}

// Default implementation for IDEs relying on this command.
static JdwpError M_IsObsolete(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  request->ReadRefTypeId();  // unused reference type ID
  request->ReadMethodId();   // unused method ID
  expandBufAdd1(reply, false);  // a method is never obsolete.
  return ERR_NONE;
}

/*
 * Given an object reference, return the runtime type of the object
 * (class or array).
 *
 * This can get called on different things, e.g. thread_id gets
 * passed in here.
 */
static JdwpError OR_ReferenceType(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  return Dbg::GetReferenceType(object_id, pReply);
}

/*
 * Get values from the fields of an object.
 */
static JdwpError OR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  int32_t field_count = request->ReadSigned32("field count");

  expandBufAdd4BE(pReply, field_count);
  for (int32_t i = 0; i < field_count; ++i) {
    FieldId fieldId = request->ReadFieldId();
    JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply);
    if (status != ERR_NONE) {
      return status;
    }
  }

  return ERR_NONE;
}

/*
 * Set values in the fields of an object.
 */
static JdwpError OR_SetValues(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  int32_t field_count = request->ReadSigned32("field count");

  for (int32_t i = 0; i < field_count; ++i) {
    FieldId fieldId = request->ReadFieldId();

    JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
    size_t width = Dbg::GetTagWidth(fieldTag);
    uint64_t value = request->ReadValue(width);

    VLOG(jdwp) << "    --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value;
    JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width);
    if (status != ERR_NONE) {
      return status;
    }
  }

  return ERR_NONE;
}

static JdwpError OR_MonitorInfo(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  return Dbg::GetMonitorInfo(object_id, reply);
}

/*
 * Invoke an instance method.  The invocation must occur in the specified
 * thread, which must have been suspended by an event.
 *
 * The call is synchronous.  All threads in the VM are resumed, unless the
 * SINGLE_THREADED flag is set.
 *
 * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
 * object), it will try to invoke the object's toString() function.  This
 * feature becomes crucial when examining ArrayLists with Eclipse.
 */
static JdwpError OR_InvokeMethod(JdwpState* state, Request* request,
                                 ExpandBuf* pReply ATTRIBUTE_UNUSED)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  ObjectId thread_id = request->ReadThreadId();
  RefTypeId class_id = request->ReadRefTypeId();
  MethodId method_id = request->ReadMethodId();

  return RequestInvoke(state, request, thread_id, object_id, class_id, method_id, false);
}

static JdwpError OR_DisableCollection(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  return Dbg::DisableCollection(object_id);
}

static JdwpError OR_EnableCollection(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  return Dbg::EnableCollection(object_id);
}

static JdwpError OR_IsCollected(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  bool is_collected;
  JdwpError rc = Dbg::IsCollected(object_id, &is_collected);
  expandBufAdd1(pReply, is_collected ? 1 : 0);
  return rc;
}

static JdwpError OR_ReferringObjects(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  int32_t max_count = request->ReadSigned32("max count");
  if (max_count < 0) {
    return ERR_ILLEGAL_ARGUMENT;
  }

  std::vector<ObjectId> referring_objects;
  JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, &referring_objects);
  if (rc != ERR_NONE) {
    return rc;
  }

  return WriteTaggedObjectList(reply, referring_objects);
}

/*
 * Return the string value in a string object.
 */
static JdwpError SR_Value(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId stringObject = request->ReadObjectId();
  std::string str;
  JDWP::JdwpError error = Dbg::StringToUtf8(stringObject, &str);
  if (error != JDWP::ERR_NONE) {
    return error;
  }

  VLOG(jdwp) << StringPrintf("    --> %s", PrintableString(str.c_str()).c_str());

  expandBufAddUtf8String(pReply, str);

  return ERR_NONE;
}

/*
 * Return a thread's name.
 */
static JdwpError TR_Name(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  std::string name;
  JdwpError error = Dbg::GetThreadName(thread_id, &name);
  if (error != ERR_NONE) {
    return error;
  }
  VLOG(jdwp) << StringPrintf("  Name of thread %#" PRIx64 " is \"%s\"", thread_id, name.c_str());
  expandBufAddUtf8String(pReply, name);

  return ERR_NONE;
}

/*
 * Suspend the specified thread.
 *
 * It's supposed to remain suspended even if interpreted code wants to
 * resume it; only the JDI is allowed to resume it.
 */
static JdwpError TR_Suspend(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  if (thread_id == Dbg::GetThreadSelfId()) {
    LOG(INFO) << "  Warning: ignoring request to suspend self";
    return ERR_THREAD_NOT_SUSPENDED;
  }

  Thread* self = Thread::Current();
  ScopedThreadSuspension sts(self, kWaitingForDebuggerSend);
  JdwpError result = Dbg::SuspendThread(thread_id);
  return result;
}

/*
 * Resume the specified thread.
 */
static JdwpError TR_Resume(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  if (thread_id == Dbg::GetThreadSelfId()) {
    LOG(INFO) << "  Warning: ignoring request to resume self";
    return ERR_NONE;
  }

  Dbg::ResumeThread(thread_id);
  return ERR_NONE;
}

/*
 * Return status of specified thread.
 */
static JdwpError TR_Status(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  JDWP::JdwpThreadStatus threadStatus;
  JDWP::JdwpSuspendStatus suspendStatus;
  JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus);
  if (error != ERR_NONE) {
    return error;
  }

  VLOG(jdwp) << "    --> " << threadStatus << ", " << suspendStatus;

  expandBufAdd4BE(pReply, threadStatus);
  expandBufAdd4BE(pReply, suspendStatus);

  return ERR_NONE;
}

/*
 * Return the thread group that the specified thread is a member of.
 */
static JdwpError TR_ThreadGroup(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();
  return Dbg::GetThreadGroup(thread_id, pReply);
}

/*
 * Return the current call stack of a suspended thread.
 *
 * If the thread isn't suspended, the error code isn't defined, but should
 * be THREAD_NOT_SUSPENDED.
 */
static JdwpError TR_Frames(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();
  uint32_t start_frame = request->ReadUnsigned32("start frame");
  uint32_t length = request->ReadUnsigned32("length");

  size_t actual_frame_count;
  JdwpError error = Dbg::GetThreadFrameCount(thread_id, &actual_frame_count);
  if (error != ERR_NONE) {
    return error;
  }

  if (actual_frame_count <= 0) {
    return ERR_THREAD_NOT_SUSPENDED;  // 0 means no managed frames (which means "in native").
  }

  if (start_frame > actual_frame_count) {
    return ERR_INVALID_INDEX;
  }
  if (length == static_cast<uint32_t>(-1)) {
    length = actual_frame_count - start_frame;
  }
  if (start_frame + length > actual_frame_count) {
    return ERR_INVALID_LENGTH;
  }

  return Dbg::GetThreadFrames(thread_id, start_frame, length, pReply);
}

/*
 * Returns the #of frames on the specified thread, which must be suspended.
 */
static JdwpError TR_FrameCount(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  size_t frame_count;
  JdwpError rc = Dbg::GetThreadFrameCount(thread_id, &frame_count);
  if (rc != ERR_NONE) {
    return rc;
  }
  expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count));

  return ERR_NONE;
}

static JdwpError TR_OwnedMonitors(Request* request, ExpandBuf* reply, bool with_stack_depths)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  std::vector<ObjectId> monitors;
  std::vector<uint32_t> stack_depths;
  JdwpError rc = Dbg::GetOwnedMonitors(thread_id, &monitors, &stack_depths);
  if (rc != ERR_NONE) {
    return rc;
  }

  expandBufAdd4BE(reply, monitors.size());
  for (size_t i = 0; i < monitors.size(); ++i) {
    rc = WriteTaggedObject(reply, monitors[i]);
    if (rc != ERR_NONE) {
      return rc;
    }
    if (with_stack_depths) {
      expandBufAdd4BE(reply, stack_depths[i]);
    }
  }
  return ERR_NONE;
}

static JdwpError TR_OwnedMonitors(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return TR_OwnedMonitors(request, reply, false);
}

static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return TR_OwnedMonitors(request, reply, true);
}

static JdwpError TR_CurrentContendedMonitor(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();

  ObjectId contended_monitor;
  JdwpError rc = Dbg::GetContendedMonitor(thread_id, &contended_monitor);
  if (rc != ERR_NONE) {
    return rc;
  }
  return WriteTaggedObject(reply, contended_monitor);
}

static JdwpError TR_Interrupt(JdwpState*, Request* request, ExpandBuf* reply ATTRIBUTE_UNUSED)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();
  return Dbg::Interrupt(thread_id);
}

/*
 * Return the debug suspend count for the specified thread.
 *
 * (The thread *might* still be running -- it might not have examined
 * its suspend count recently.)
 */
static JdwpError TR_DebugSuspendCount(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();
  return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
}

/*
 * Return the name of a thread group.
 *
 * The Eclipse debugger recognizes "main" and "system" as special.
 */
static JdwpError TGR_Name(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_group_id = request->ReadThreadGroupId();
  return Dbg::GetThreadGroupName(thread_group_id, pReply);
}

/*
 * Returns the thread group -- if any -- that contains the specified
 * thread group.
 */
static JdwpError TGR_Parent(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_group_id = request->ReadThreadGroupId();
  return Dbg::GetThreadGroupParent(thread_group_id, pReply);
}

/*
 * Return the active threads and thread groups that are part of the
 * specified thread group.
 */
static JdwpError TGR_Children(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_group_id = request->ReadThreadGroupId();
  return Dbg::GetThreadGroupChildren(thread_group_id, pReply);
}

/*
 * Return the #of components in the array.
 */
static JdwpError AR_Length(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId array_id = request->ReadArrayId();

  int32_t length;
  JdwpError status = Dbg::GetArrayLength(array_id, &length);
  if (status != ERR_NONE) {
    return status;
  }
  VLOG(jdwp) << "    --> " << length;

  expandBufAdd4BE(pReply, length);

  return ERR_NONE;
}

/*
 * Return the values from an array.
 */
static JdwpError AR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId array_id = request->ReadArrayId();
  uint32_t offset = request->ReadUnsigned32("offset");
  uint32_t length = request->ReadUnsigned32("length");
  return Dbg::OutputArray(array_id, offset, length, pReply);
}

/*
 * Set values in an array.
 */
static JdwpError AR_SetValues(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId array_id = request->ReadArrayId();
  uint32_t offset = request->ReadUnsigned32("offset");
  uint32_t count = request->ReadUnsigned32("count");
  return Dbg::SetArrayElements(array_id, offset, count, request);
}

static JdwpError CLR_VisibleClasses(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  request->ReadObjectId();  // classLoaderObject
  // TODO: we should only return classes which have the given class loader as a defining or
  // initiating loader. The former would be easy; the latter is hard, because we don't have
  // any such notion.
  return VM_AllClassesImpl(pReply, false, false);
}

// Delete function class to use std::unique_ptr with JdwpEvent.
struct JdwpEventDeleter {
  void operator()(JdwpEvent* event) {
    EventFree(event);
  }
};

/*
 * Set an event trigger.
 *
 * Reply with a requestID.
 */
static JdwpError ER_Set(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  JdwpEventKind event_kind = request->ReadEnum1<JdwpEventKind>("event kind");
  JdwpSuspendPolicy suspend_policy = request->ReadEnum1<JdwpSuspendPolicy>("suspend policy");
  int32_t modifier_count = request->ReadSigned32("modifier count");

  CHECK_LT(modifier_count, 256);    /* reasonableness check */

  std::unique_ptr<JDWP::JdwpEvent, JdwpEventDeleter> pEvent(EventAlloc(modifier_count));
  pEvent->eventKind = event_kind;
  pEvent->suspend_policy = suspend_policy;
  pEvent->modCount = modifier_count;

  /*
   * Read modifiers.  Ordering may be significant (see explanation of Count
   * mods in JDWP doc).
   */
  for (int32_t i = 0; i < modifier_count; ++i) {
    JdwpEventMod& mod = pEvent->mods[i];
    mod.modKind = request->ReadModKind();
    switch (mod.modKind) {
    case MK_COUNT:
      {
        // Report once, when "--count" reaches 0.
        uint32_t count = request->ReadUnsigned32("count");
        if (count == 0) {
          return ERR_INVALID_COUNT;
        }
        mod.count.count = count;
      }
      break;
    case MK_CONDITIONAL:
      {
        // Conditional on expression.
        uint32_t exprId = request->ReadUnsigned32("expr id");
        mod.conditional.exprId = exprId;
      }
      break;
    case MK_THREAD_ONLY:
      {
        // Only report events in specified thread.
        ObjectId thread_id = request->ReadThreadId();
        mod.threadOnly.threadId = thread_id;
      }
      break;
    case MK_CLASS_ONLY:
      {
        // For ClassPrepare, MethodEntry.
        RefTypeId class_id = request->ReadRefTypeId();
        mod.classOnly.refTypeId = class_id;
      }
      break;
    case MK_CLASS_MATCH:
      {
        // Restrict events to matching classes.
        // pattern is "java.foo.*", we want "java/foo/*".
        std::string pattern(request->ReadUtf8String());
        std::replace(pattern.begin(), pattern.end(), '.', '/');
        mod.classMatch.classPattern = strdup(pattern.c_str());
      }
      break;
    case MK_CLASS_EXCLUDE:
      {
        // Restrict events to non-matching classes.
        // pattern is "java.foo.*", we want "java/foo/*".
        std::string pattern(request->ReadUtf8String());
        std::replace(pattern.begin(), pattern.end(), '.', '/');
        mod.classExclude.classPattern = strdup(pattern.c_str());
      }
      break;
    case MK_LOCATION_ONLY:
      {
        // Restrict certain events based on location.
        JdwpLocation location = request->ReadLocation();
        mod.locationOnly.loc = location;
      }
      break;
    case MK_EXCEPTION_ONLY:
      {
        // Modifies EK_EXCEPTION events,
        mod.exceptionOnly.refTypeId = request->ReadRefTypeId();  // null => all exceptions.
        mod.exceptionOnly.caught = request->ReadEnum1<uint8_t>("caught");
        mod.exceptionOnly.uncaught = request->ReadEnum1<uint8_t>("uncaught");
      }
      break;
    case MK_FIELD_ONLY:
      {
        // For field access/modification events.
        RefTypeId declaring = request->ReadRefTypeId();
        FieldId fieldId = request->ReadFieldId();
        mod.fieldOnly.refTypeId = declaring;
        mod.fieldOnly.fieldId = fieldId;
      }
      break;
    case MK_STEP:
      {
        // For use with EK_SINGLE_STEP.
        ObjectId thread_id = request->ReadThreadId();
        uint32_t size = request->ReadUnsigned32("step size");
        uint32_t depth = request->ReadUnsigned32("step depth");
        VLOG(jdwp) << StringPrintf("    Step: thread=%#" PRIx64, thread_id)
                     << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);

        mod.step.threadId = thread_id;
        mod.step.size = size;
        mod.step.depth = depth;
      }
      break;
    case MK_INSTANCE_ONLY:
      {
        // Report events related to a specific object.
        ObjectId instance = request->ReadObjectId();
        mod.instanceOnly.objectId = instance;
      }
      break;
    default:
      LOG(WARNING) << "Unsupported modifier " << mod.modKind << " for event " << pEvent->eventKind;
      return JDWP::ERR_NOT_IMPLEMENTED;
    }
  }

  /*
   * We reply with an integer "requestID".
   */
  uint32_t requestId = state->NextEventSerial();
  expandBufAdd4BE(pReply, requestId);

  pEvent->requestId = requestId;

  VLOG(jdwp) << StringPrintf("    --> event requestId=%#x", requestId);

  /* add it to the list */
  JdwpError err = state->RegisterEvent(pEvent.get());
  if (err != ERR_NONE) {
    /* registration failed, probably because event is bogus */
    LOG(WARNING) << "WARNING: event request rejected";
    return err;
  }
  pEvent.release();
  return ERR_NONE;
}

static JdwpError ER_Clear(JdwpState* state, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  request->ReadEnum1<JdwpEventKind>("event kind");
  uint32_t requestId = request->ReadUnsigned32("request id");

  // Failure to find an event with a matching ID is a no-op
  // and does not return an error.
  state->UnregisterEventById(requestId);
  return ERR_NONE;
}

/*
 * Return the values of arguments and local variables.
 */
static JdwpError SF_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return Dbg::GetLocalValues(request, pReply);
}

/*
 * Set the values of arguments and local variables.
 */
static JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  return Dbg::SetLocalValues(request);
}

static JdwpError SF_ThisObject(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  ObjectId thread_id = request->ReadThreadId();
  FrameId frame_id = request->ReadFrameId();

  ObjectId object_id;
  JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
  if (rc != ERR_NONE) {
    return rc;
  }

  return WriteTaggedObject(reply, object_id);
}

/*
 * Return the reference type reflected by this class object.
 *
 * This appears to be required because ReferenceTypeId values are NEVER
 * reused, whereas ClassIds can be recycled like any other object.  (Either
 * that, or I have no idea what this is for.)
 */
static JdwpError COR_ReflectedType(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  RefTypeId class_object_id = request->ReadRefTypeId();
  return Dbg::GetReflectedType(class_object_id, pReply);
}

/*
 * Handle a DDM packet with a single chunk in it.
 */
static JdwpError DDM_Chunk(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_REQUIRES(Locks::mutator_lock_) {
  state->NotifyDdmsActive();
  uint8_t* replyBuf = nullptr;
  int replyLen = -1;
  if (Dbg::DdmHandlePacket(request, &replyBuf, &replyLen)) {
    // If they want to send something back, we copy it into the buffer.
    // TODO: consider altering the JDWP stuff to hold the packet header
    // in a separate buffer.  That would allow us to writev() DDM traffic
    // instead of copying it into the expanding buffer.  The reduction in
    // heap requirements is probably more valuable than the efficiency.
    CHECK_GT(replyLen, 0);
    memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
    delete[] replyBuf;
  }
  return ERR_NONE;
}

/*
 * Handler map decl.
 */
typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request* request, ExpandBuf* reply);

struct JdwpHandlerMap {
  uint8_t cmdSet;
  uint8_t cmd;
  JdwpRequestHandler func;
  const char* name;
};

/*
 * Map commands to functions.
 *
 * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
 * and 128-256 are vendor-defined.
 */
static const JdwpHandlerMap gHandlers[] = {
  /* VirtualMachine command set (1) */
  { 1,    1,  VM_Version,               "VirtualMachine.Version" },
  { 1,    2,  VM_ClassesBySignature,    "VirtualMachine.ClassesBySignature" },
  { 1,    3,  VM_AllClasses,            "VirtualMachine.AllClasses" },
  { 1,    4,  VM_AllThreads,            "VirtualMachine.AllThreads" },
  { 1,    5,  VM_TopLevelThreadGroups,  "VirtualMachine.TopLevelThreadGroups" },
  { 1,    6,  VM_Dispose,               "VirtualMachine.Dispose" },
  { 1,    7,  VM_IDSizes,               "VirtualMachine.IDSizes" },
  { 1,    8,  VM_Suspend,               "VirtualMachine.Suspend" },
  { 1,    9,  VM_Resume,                "VirtualMachine.Resume" },
  { 1,    10, VM_Exit,                  "VirtualMachine.Exit" },
  { 1,    11, VM_CreateString,          "VirtualMachine.CreateString" },
  { 1,    12, VM_Capabilities,          "VirtualMachine.Capabilities" },
  { 1,    13, VM_ClassPaths,            "VirtualMachine.ClassPaths" },
  { 1,    14, VM_DisposeObjects,        "VirtualMachine.DisposeObjects" },
  { 1,    15, nullptr,                  "VirtualMachine.HoldEvents" },
  { 1,    16, nullptr,                  "VirtualMachine.ReleaseEvents" },
  { 1,    17, VM_CapabilitiesNew,       "VirtualMachine.CapabilitiesNew" },
  { 1,    18, nullptr,                  "VirtualMachine.RedefineClasses" },
  { 1,    19, nullptr,                  "VirtualMachine.SetDefaultStratum" },
  { 1,    20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
  { 1,    21, VM_InstanceCounts,        "VirtualMachine.InstanceCounts" },

  /* ReferenceType command set (2) */
  { 2,    1,  RT_Signature,            "ReferenceType.Signature" },
  { 2,    2,  RT_ClassLoader,          "ReferenceType.ClassLoader" },
  { 2,    3,  RT_Modifiers,            "ReferenceType.Modifiers" },
  { 2,    4,  RT_Fields,               "ReferenceType.Fields" },
  { 2,    5,  RT_Methods,              "ReferenceType.Methods" },
  { 2,    6,  RT_GetValues,            "ReferenceType.GetValues" },
  { 2,    7,  RT_SourceFile,           "ReferenceType.SourceFile" },
  { 2,    8,  nullptr,                 "ReferenceType.NestedTypes" },
  { 2,    9,  RT_Status,               "ReferenceType.Status" },
  { 2,    10, RT_Interfaces,           "ReferenceType.Interfaces" },
  { 2,    11, RT_ClassObject,          "ReferenceType.ClassObject" },
  { 2,    12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
  { 2,    13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
  { 2,    14, RT_FieldsWithGeneric,    "ReferenceType.FieldsWithGeneric" },
  { 2,    15, RT_MethodsWithGeneric,   "ReferenceType.MethodsWithGeneric" },
  { 2,    16, RT_Instances,            "ReferenceType.Instances" },
  { 2,    17, nullptr,                 "ReferenceType.ClassFileVersion" },
  { 2,    18, nullptr,                 "ReferenceType.ConstantPool" },

  /* ClassType command set (3) */
  { 3,    1,  CT_Superclass,    "ClassType.Superclass" },
  { 3,    2,  CT_SetValues,     "ClassType.SetValues" },
  { 3,    3,  CT_InvokeMethod,  "ClassType.InvokeMethod" },
  { 3,    4,  CT_NewInstance,   "ClassType.NewInstance" },

  /* ArrayType command set (4) */
  { 4,    1,  AT_newInstance,   "ArrayType.NewInstance" },

  /* InterfaceType command set (5) */

  /* Method command set (6) */
  { 6,    1,  M_LineTable,                "Method.LineTable" },
  { 6,    2,  M_VariableTable,            "Method.VariableTable" },
  { 6,    3,  M_Bytecodes,                "Method.Bytecodes" },
  { 6,    4,  M_IsObsolete,               "Method.IsObsolete" },
  { 6,    5,  M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },

  /* Field command set (8) */

  /* ObjectReference command set (9) */
  { 9,    1,  OR_ReferenceType,     "ObjectReference.ReferenceType" },
  { 9,    2,  OR_GetValues,         "ObjectReference.GetValues" },
  { 9,    3,  OR_SetValues,         "ObjectReference.SetValues" },
  { 9,    4,  nullptr,              "ObjectReference.UNUSED" },
  { 9,    5,  OR_MonitorInfo,       "ObjectReference.MonitorInfo" },
  { 9,    6,  OR_InvokeMethod,      "ObjectReference.InvokeMethod" },
  { 9,    7,  OR_DisableCollection, "ObjectReference.DisableCollection" },
  { 9,    8,  OR_EnableCollection,  "ObjectReference.EnableCollection" },
  { 9,    9,  OR_IsCollected,       "ObjectReference.IsCollected" },
  { 9,    10, OR_ReferringObjects,  "ObjectReference.ReferringObjects" },

  /* StringReference command set (10) */
  { 10,   1,  SR_Value,         "StringReference.Value" },

  /* ThreadReference command set (11) */
  { 11,   1,  TR_Name,                        "ThreadReference.Name" },
  { 11,   2,  TR_Suspend,                     "ThreadReference.Suspend" },
  { 11,   3,  TR_Resume,                      "ThreadReference.Resume" },
  { 11,   4,  TR_Status,                      "ThreadReference.Status" },
  { 11,   5,  TR_ThreadGroup,                 "ThreadReference.ThreadGroup" },
  { 11,   6,  TR_Frames,                      "ThreadReference.Frames" },
  { 11,   7,  TR_FrameCount,                  "ThreadReference.FrameCount" },
  { 11,   8,  TR_OwnedMonitors,               "ThreadReference.OwnedMonitors" },
  { 11,   9,  TR_CurrentContendedMonitor,     "ThreadReference.CurrentContendedMonitor" },
  { 11,   10, nullptr,                        "ThreadReference.Stop" },
  { 11,   11, TR_Interrupt,                   "ThreadReference.Interrupt" },
  { 11,   12, TR_DebugSuspendCount,           "ThreadReference.SuspendCount" },
  { 11,   13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
  { 11,   14, nullptr,                        "ThreadReference.ForceEarlyReturn" },

  /* ThreadGroupReference command set (12) */
  { 12,   1,  TGR_Name,         "ThreadGroupReference.Name" },
  { 12,   2,  TGR_Parent,       "ThreadGroupReference.Parent" },
  { 12,   3,  TGR_Children,     "ThreadGroupReference.Children" },

  /* ArrayReference command set (13) */
  { 13,   1,  AR_Length,        "ArrayReference.Length" },
  { 13,   2,  AR_GetValues,     "ArrayReference.GetValues" },
  { 13,   3,  AR_SetValues,     "ArrayReference.SetValues" },

  /* ClassLoaderReference command set (14) */
  { 14,   1,  CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },

  /* EventRequest command set (15) */
  { 15,   1,  ER_Set,           "EventRequest.Set" },
  { 15,   2,  ER_Clear,         "EventRequest.Clear" },
  { 15,   3,  nullptr,          "EventRequest.ClearAllBreakpoints" },

  /* StackFrame command set (16) */
  { 16,   1,  SF_GetValues,     "StackFrame.GetValues" },
  { 16,   2,  SF_SetValues,     "StackFrame.SetValues" },
  { 16,   3,  SF_ThisObject,    "StackFrame.ThisObject" },
  { 16,   4,  nullptr,          "StackFrame.PopFrames" },

  /* ClassObjectReference command set (17) */
  { 17,   1,  COR_ReflectedType, "ClassObjectReference.ReflectedType" },

  /* Event command set (64) */
  { 64, 100,  nullptr, "Event.Composite" },  // sent from VM to debugger, never received by VM

  { 199,  1,  DDM_Chunk,        "DDM.Chunk" },
};

static const char* GetCommandName(Request* request) {
  for (size_t i = 0; i < arraysize(gHandlers); ++i) {
    if (gHandlers[i].cmdSet == request->GetCommandSet() &&
        gHandlers[i].cmd == request->GetCommand()) {
      return gHandlers[i].name;
    }
  }
  return "?UNKNOWN?";
}

static std::string DescribeCommand(Request* request) {
  std::string result;
  result += "REQUEST: ";
  result += GetCommandName(request);
  result += StringPrintf(" (length=%zu id=0x%06x)", request->GetLength(), request->GetId());
  return result;
}

// Returns true if the given command_set and command identify an "invoke" command.
static bool IsInvokeCommand(uint8_t command_set, uint8_t command) {
  if (command_set == kJDWPClassTypeCmdSet) {
    return command == kJDWPClassTypeInvokeMethodCmd || command == kJDWPClassTypeNewInstanceCmd;
  } else if (command_set == kJDWPObjectReferenceCmdSet) {
    return command == kJDWPObjectReferenceInvokeCmd;
  } else {
    return false;
  }
}

/*
 * Process a request from the debugger. The skip_reply flag is set to true to indicate to the
 * caller the reply must not be sent to the debugger. This is used for invoke commands where the
 * reply is sent by the event thread after completing the invoke.
 *
 * On entry, the JDWP thread is in VMWAIT.
 */
size_t JdwpState::ProcessRequest(Request* request, ExpandBuf* pReply, bool* skip_reply) {
  JdwpError result = ERR_NONE;
  *skip_reply = false;

  if (request->GetCommandSet() != kJDWPDdmCmdSet) {
    /*
     * Activity from a debugger, not merely ddms.  Mark us as having an
     * active debugger session, and zero out the last-activity timestamp
     * so waitForDebugger() doesn't return if we stall for a bit here.
     */
    Dbg::GoActive();
    last_activity_time_ms_.StoreSequentiallyConsistent(0);
  }

  /*
   * If a debugger event has fired in another thread, wait until the
   * initiating thread has suspended itself before processing commands
   * from the debugger.  Otherwise we (the JDWP thread) could be told to
   * resume the thread before it has suspended.
   *
   * Note that we MUST clear the event token before waking the event
   * thread up, or risk waiting for the thread to suspend after we've
   * told it to resume.
   */
  AcquireJdwpTokenForCommand();

  /*
   * Tell the VM that we're running and shouldn't be interrupted by GC.
   * Do this after anything that can stall indefinitely.
   */
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  expandBufAddSpace(pReply, kJDWPHeaderLen);

  size_t i;
  for (i = 0; i < arraysize(gHandlers); ++i) {
    if (gHandlers[i].cmdSet == request->GetCommandSet() &&
        gHandlers[i].cmd == request->GetCommand() &&
        gHandlers[i].func != nullptr) {
      VLOG(jdwp) << DescribeCommand(request);
      result = (*gHandlers[i].func)(this, request, pReply);
      if (result == ERR_NONE) {
        request->CheckConsumed();
      }
      self->AssertNoPendingException();
      break;
    }
  }
  if (i == arraysize(gHandlers)) {
    LOG(ERROR) << "Command not implemented: " << DescribeCommand(request);
    LOG(ERROR) << HexDump(request->data(), request->size(), false, "");
    result = ERR_NOT_IMPLEMENTED;
  }

  size_t replyLength = 0U;
  if (result == ERR_NONE && IsInvokeCommand(request->GetCommandSet(), request->GetCommand())) {
    // We successfully request an invoke in the event thread. It will send the reply once the
    // invoke completes so we must not send it now.
    *skip_reply = true;
  } else {
    /*
     * Set up the reply header.
     *
     * If we encountered an error, only send the header back.
     */
    uint8_t* replyBuf = expandBufGetBuffer(pReply);
    replyLength = (result == ERR_NONE) ? expandBufGetLength(pReply) : kJDWPHeaderLen;
    Set4BE(replyBuf + kJDWPHeaderSizeOffset, replyLength);
    Set4BE(replyBuf + kJDWPHeaderIdOffset, request->GetId());
    Set1(replyBuf + kJDWPHeaderFlagsOffset, kJDWPFlagReply);
    Set2BE(replyBuf + kJDWPHeaderErrorCodeOffset, result);

    CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request->GetId();

    size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
    VLOG(jdwp) << "REPLY: " << GetCommandName(request) << " " << result << " (length=" << respLen << ")";
    if (false) {
      VLOG(jdwp) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen, false, "");
    }
  }

  VLOG(jdwp) << "----------";

  /*
   * Update last-activity timestamp.  We really only need this during
   * the initial setup.  Only update if this is a non-DDMS packet.
   */
  if (request->GetCommandSet() != kJDWPDdmCmdSet) {
    last_activity_time_ms_.StoreSequentiallyConsistent(MilliTime());
  }

  return replyLength;
}

}  // namespace JDWP

}  // namespace art
