/*
 * 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 "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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Thread* self = Thread::Current();
  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
  Dbg::SuspendVM();
  self->TransitionFromSuspendedToRunnable();
  return ERR_NONE;
}

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

static JdwpError VM_Exit(JdwpState* state, Request* request, ExpandBuf*)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return VM_AllClassesImpl(pReply, true, false);
}

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

static JdwpError VM_InstanceCounts(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  /* referenceTypeId in, string out */
  return ERR_ABSENT_INFORMATION;
}

static JdwpError RT_Signature(JdwpState*, Request* request, ExpandBuf* pReply, bool with_generic)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return RT_Signature(state, request, pReply, false);
}

static JdwpError RT_SignatureWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  RefTypeId refTypeId = request->ReadRefTypeId();
  return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
}

static JdwpError RT_Instances(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return M_VariableTable(state, request, pReply, false);
}

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

static JdwpError M_Bytecodes(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_LOCKS_REQUIRED(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;
}

/*
 * 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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  ObjectId object_id = request->ReadObjectId();
  return Dbg::DisableCollection(object_id);
}

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

static JdwpError OR_IsCollected(JdwpState*, Request* request, ExpandBuf* pReply)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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();
  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
  JdwpError result = Dbg::SuspendThread(thread_id);
  self->TransitionFromSuspendedToRunnable();
  return result;
}

/*
 * Resume the specified thread.
 */
static JdwpError TR_Resume(JdwpState*, Request* request, ExpandBuf*)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return TR_OwnedMonitors(request, reply, false);
}

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

static JdwpError TR_CurrentContendedMonitor(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_LOCKS_REQUIRED(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)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  UNUSED(reply);
  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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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);
}

/*
 * Set an event trigger.
 *
 * Reply with a requestID.
 */
static JdwpError ER_Set(JdwpState* state, Request* request, ExpandBuf* pReply)
    SHARED_LOCKS_REQUIRED(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 */

  JdwpEvent* 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;
      // Free allocated event to avoid leak before leaving.
      EventFree(pEvent);
      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);
  if (err != ERR_NONE) {
    /* registration failed, probably because event is bogus */
    EventFree(pEvent);
    LOG(WARNING) << "WARNING: event request rejected";
  }
  return err;
}

static JdwpError ER_Clear(JdwpState* state, Request* request, ExpandBuf*)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return Dbg::SetLocalValues(request);
}

static JdwpError SF_ThisObject(JdwpState*, Request* request, ExpandBuf* reply)
    SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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);
    free(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,  nullptr,                    "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();
  ThreadState old_state = self->TransitionFromSuspendedToRunnable();

  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());
  }

  /* tell the VM that GC is okay again */
  self->TransitionFromRunnableToSuspended(old_state);

  return replyLength;
}

}  // namespace JDWP

}  // namespace art
