/* Python interface to instruction disassembly.

   Copyright (C) 2021-2026 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "python-internal.h"
#include "language.h"
#include "dis-asm.h"
#include "arch-utils.h"
#include "charset.h"
#include "disasm.h"
#include "progspace.h"

/* Implement gdb.disassembler.DisassembleInfo type.  An object of this type
   represents a single disassembler request from GDB.  */

struct disasm_info_object : public PyObject
{
  /* The architecture in which we are disassembling.  */
  struct gdbarch *gdbarch;

  /* The program_space in which we are disassembling.  */
  struct program_space *program_space;

  /* Address of the instruction to disassemble.  */
  bfd_vma address;

  /* The disassemble_info passed from core GDB, this contains the
     callbacks necessary to read the instruction from core GDB, and to
     print the disassembled instruction.  */
  disassemble_info *gdb_info;

  /* If copies of this object are created then they are chained together
     via this NEXT pointer, this allows all the copies to be invalidated at
     the same time as the parent object.  */
  struct disasm_info_object *next;
};

extern PyTypeObject disasm_info_object_type;

/* Implement gdb.disassembler.DisassembleAddressPart type.  An object of
   this type represents a small part of a disassembled instruction; a part
   that is an address that should be printed using a call to GDB's
   internal print_address function.  */

struct disasm_addr_part_object : public PyObject
{
  /* The address to be formatted.  */
  bfd_vma address;

  /* A gdbarch.  This is only needed in the case where the user asks for
     the DisassemblerAddressPart to be converted to a string.  When we
     return this part to GDB within a DisassemblerResult then GDB will use
     the gdbarch from the initial disassembly request.  */
  struct gdbarch *gdbarch;
};

extern PyTypeObject disasm_addr_part_object_type;

/* Implement gdb.disassembler.DisassembleTextPart type.  An object of
   this type represents a small part of a disassembled instruction; a part
   that is a piece of test along with an associated style.  */

struct disasm_text_part_object : public PyObject
{
  /* The string that is this part.  */
  std::string *string;

  /* The style to use when displaying this part.  */
  enum disassembler_style style;
};

extern PyTypeObject disasm_text_part_object_type;

extern PyTypeObject disasm_part_object_type;

/* Implement gdb.disassembler.DisassemblerResult type, an object that holds
   the result of calling the disassembler.  This is mostly the length of
   the disassembled instruction (in bytes), and the string representing the
   disassembled instruction.  */

struct disasm_result_object : public PyObject
{
  /* The length of the disassembled instruction in bytes.  */
  int length;

  /* A vector containing all the parts of the disassembled instruction.
     Each part will be a DisassemblerPart sub-class.  */
  std::vector<gdbpy_ref<>> *parts;
};

extern PyTypeObject disasm_result_object_type;

/* When this is false we fast path out of gdbpy_print_insn, which should
   keep the performance impact of the Python disassembler down.  This is
   set to true from Python by calling gdb.disassembler._set_enabled() when
   the user registers a disassembler.  */

static bool python_print_insn_enabled = false;

/* A sub-class of gdb_disassembler that holds a pointer to a Python
   DisassembleInfo object.  A pointer to an instance of this class is
   placed in the application_data field of the disassemble_info that is
   used when we call gdbarch_print_insn.  */

struct gdbpy_disassembler : public gdb_disassemble_info
{
  /* Constructor.  */
  gdbpy_disassembler (disasm_info_object *obj);

  /* Get the DisassembleInfo object pointer.  */
  disasm_info_object *
  py_disasm_info () const
  {
    return m_disasm_info_object;
  }

  /* Callbacks used by disassemble_info.  */
  static void memory_error_func (int status, bfd_vma memaddr,
				 struct disassemble_info *info) noexcept;
  static void print_address_func (bfd_vma addr,
				  struct disassemble_info *info) noexcept;
  static int read_memory_func (bfd_vma memaddr, gdb_byte *buff,
			       unsigned int len,
			       struct disassemble_info *info) noexcept;

  /* Callback used as the disassemble_info's fprintf_func callback.  The
     DIS_INFO pointer is a pointer to a gdbpy_disassembler object.  */
  static int fprintf_func (void *dis_info, const char *format, ...) noexcept
    ATTRIBUTE_PRINTF(2,3);

  /* Callback used as the disassemble_info's fprintf_styled_func callback.
     The DIS_INFO pointer is a pointer to a gdbpy_disassembler.  */
  static int fprintf_styled_func (void *dis_info,
				  enum disassembler_style style,
				  const char *format, ...) noexcept
    ATTRIBUTE_PRINTF(3,4);

  /* Helper used by fprintf_func and fprintf_styled_func.  This function
     creates a new DisassemblerTextPart and adds it to the disassembler's
     parts list.  The actual disassembler is accessed through DIS_INFO,
     which is a pointer to the gdbpy_disassembler object.  */
  static int vfprintf_styled_func (void *dis_info,
				   enum disassembler_style style,
				   const char *format, va_list args) noexcept
    ATTRIBUTE_PRINTF(3,0);

  /* Return a reference to an optional that contains the address at which a
     memory error occurred.  The optional will only have a value if a
     memory error actually occurred.  */
  const std::optional<CORE_ADDR> &memory_error_address () const
  { return m_memory_error_address; }

  /* Return the content of the disassembler as a string.  The contents are
     moved out of the disassembler, so after this call the disassembler
     contents have been reset back to empty.  */
  std::vector<gdbpy_ref<>> release ()
  {
    return std::move (m_parts);
  }

  /* If there is a Python exception stored in this disassembler then
     restore it (i.e. set the PyErr_* state), clear the exception within
     this disassembler, and return true.  There must be no current
     exception set (i.e. !PyErr_Occurred()) when this function is called,
     as any such exception might get lost.

     Otherwise, there is no exception stored in this disassembler, return
     false.  */
  bool restore_exception ()
  {
    gdb_assert (!PyErr_Occurred ());
    if (m_stored_exception.has_value ())
      {
	gdbpy_err_fetch ex = std::move (*m_stored_exception);
	m_stored_exception.reset ();
	ex.restore ();
	return true;
      }

    return false;
  }

private:

  /* The list of all the parts that make up this disassembled instruction.
     This is populated as a result of the callbacks from libopcodes as the
     instruction is disassembled.  */
  std::vector<gdbpy_ref<>> m_parts;

  /* The DisassembleInfo object we are disassembling for.  */
  disasm_info_object *m_disasm_info_object;

  /* When the user indicates that a memory error has occurred then the
     address of the memory error is stored in here.  */
  std::optional<CORE_ADDR> m_memory_error_address;

  /* Move the exception EX into this disassembler object.  */
  void store_exception (gdbpy_err_fetch &&ex)
  {
    /* The only calls to store_exception are from read_memory_func, which
       will return early if there's already an exception stored.  */
    gdb_assert (!m_stored_exception.has_value ());
    m_stored_exception.emplace (std::move (ex));
  }

  /* Return true if there is an exception stored in this disassembler.  */
  bool has_stored_exception () const
  {
    return m_stored_exception.has_value ();
  }

  /* Store a single exception.  This is used to pass Python exceptions back
     from ::memory_read to disasmpy_builtin_disassemble.  */
  std::optional<gdbpy_err_fetch> m_stored_exception;
};

/* Return true if OBJ is still valid, otherwise, return false.  A valid OBJ
   will have a non-nullptr gdb_info field.  */

static bool
disasm_info_object_is_valid (disasm_info_object *obj)
{
  return obj->gdb_info != nullptr;
}

/* Fill in OBJ with all the other arguments.  */

static void
disasm_info_fill (disasm_info_object &obj, struct gdbarch *gdbarch,
		  program_space *progspace, bfd_vma address,
		  disassemble_info *di, disasm_info_object *next)
{
  obj.gdbarch = gdbarch;
  obj.program_space = progspace;
  obj.address = address;
  obj.gdb_info = di;
  obj.next = next;
}

/* Implement DisassembleInfo.__init__.  Takes a single argument that must
   be another DisassembleInfo object and copies the contents from the
   argument into this new object.  */

static int
disasm_info_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static const char *keywords[] = { "info", NULL };
  PyObject *info_obj;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "O!", keywords,
					&disasm_info_object_type,
					&info_obj))
    return -1;

  disasm_info_object *other = (disasm_info_object *) info_obj;
  disasm_info_object *info = (disasm_info_object *) self;
  disasm_info_fill (*info, other->gdbarch, other->program_space,
		    other->address, other->gdb_info, other->next);
  other->next = info;

  /* As the OTHER object now holds a pointer to INFO we inc the ref count
     on INFO.  This stops INFO being deleted until OTHER has gone away.  */
  Py_INCREF ((PyObject *) info);
  return 0;
}

/* The tp_dealloc callback for the DisassembleInfo type.  */

static void
disasm_info_dealloc (PyObject *self)
{
  disasm_info_object *obj = (disasm_info_object *) self;

  /* We no longer care about the object our NEXT pointer points at, so we
     can decrement its reference count.  This macro handles the case when
     NEXT is nullptr.  */
  Py_XDECREF ((PyObject *) obj->next);

  /* Now core deallocation behavior.  */
  Py_TYPE (self)->tp_free (self);
}

/* Implement __repr__ for the DisassembleInfo type.  */

static PyObject *
disasmpy_info_repr (PyObject *self)
{
  disasm_info_object *obj = (disasm_info_object *) self;

  const char *arch_name
    = (gdbarch_bfd_arch_info (obj->gdbarch))->printable_name;
  return PyUnicode_FromFormat ("<%s address=%s architecture=%s>",
			       gdbpy_py_obj_tp_name (self),
			       core_addr_to_string_nz (obj->address),
			       arch_name);
}

/* Implement DisassembleInfo.is_valid(), really just a wrapper around the
   disasm_info_object_is_valid function above.  */

static PyObject *
disasmpy_info_is_valid (PyObject *self, PyObject *args)
{
  disasm_info_object *disasm_obj = (disasm_info_object *) self;

  if (disasm_info_object_is_valid (disasm_obj))
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Set the Python exception to be a gdb.MemoryError object, with ADDRESS
   as its payload.  */

static void
disasmpy_set_memory_error_for_address (CORE_ADDR address)
{
  PyObject *address_obj = gdb_py_object_from_longest (address).release ();
  PyErr_SetObject (gdbpy_gdb_memory_error, address_obj);
}

/* Create a new DisassemblerTextPart and return a gdbpy_ref wrapper for
   the new object.  STR is the string content of the part and STYLE is the
   style to be used when GDB displays this part.  */

static gdbpy_ref<>
make_disasm_text_part (std::string &&str, enum disassembler_style style)
{
  PyTypeObject *type = &disasm_text_part_object_type;
  disasm_text_part_object *text_part
    = (disasm_text_part_object *) type->tp_alloc (type, 0);
  text_part->string = new std::string (str);
  text_part->style = style;

  return gdbpy_ref<> ((PyObject *) text_part);
}

/* Create a new DisassemblerAddressPart and return a gdbpy_ref wrapper for
   the new object.  GDBARCH is the architecture used when formatting the
   address, and ADDRESS is the numerical address to be displayed.  */

static gdbpy_ref<>
make_disasm_addr_part (struct gdbarch *gdbarch, CORE_ADDR address)
{
  PyTypeObject *type = &disasm_addr_part_object_type;
  disasm_addr_part_object *addr_part
    = (disasm_addr_part_object *) type->tp_alloc (type, 0);
  addr_part->address = address;
  addr_part->gdbarch = gdbarch;

  return gdbpy_ref<> ((PyObject *) addr_part);
}

/* Ensure that a gdb.disassembler.DisassembleInfo is valid.  */

#define DISASMPY_DISASM_INFO_REQUIRE_VALID(Info)			\
  do {									\
    if (!disasm_info_object_is_valid (Info))				\
      {									\
	PyErr_SetString (PyExc_RuntimeError,				\
			 _("DisassembleInfo is no longer valid."));	\
	return nullptr;							\
      }									\
  } while (0)

/* Implement DisassembleInfo.text_part method.  Creates and returns a new
   DisassemblerTextPart object.  */

static PyObject *
disasmpy_info_make_text_part (PyObject *self, PyObject *args,
			      PyObject *kwargs)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);

  static const char *keywords[] = { "style", "string", NULL };
  int style_num;
  const char *string;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "is", keywords,
					&style_num, &string))
    return nullptr;

  if (style_num < 0 || style_num > ((int) dis_style_comment_start))
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Invalid disassembler style."));
      return nullptr;
    }

  if (strlen (string) == 0)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("String must not be empty."));
      return nullptr;
    }

  gdbpy_ref<> text_part
    = make_disasm_text_part (std::string (string),
			     (enum disassembler_style) style_num);
  return text_part.release ();
}

/* Implement DisassembleInfo.address_part method.  Creates and returns a
   new DisassemblerAddressPart object.  */

static PyObject *
disasmpy_info_make_address_part (PyObject *self, PyObject *args,
				 PyObject *kwargs)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);

  static const char *keywords[] = { "address", NULL };
  CORE_ADDR address;
  PyObject *address_object;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "O", keywords,
					&address_object))
    return nullptr;

  if (get_addr_from_python (address_object, &address) < 0)
    return nullptr;

  return make_disasm_addr_part (obj->gdbarch, address).release ();
}

/* Return a string representation of TEXT_PART.  The returned string does
   not include any styling.  */

static std::string
disasmpy_part_to_string (const disasm_text_part_object *text_part)
{
  gdb_assert (text_part->string != nullptr);
  return *(text_part->string);
}

/* Return a string representation of ADDR_PART.  The returned string does
   not include any styling.  */

static std::string
disasmpy_part_to_string (const disasm_addr_part_object *addr_part)
{
  string_file buf;
  print_address (addr_part->gdbarch, addr_part->address, &buf);
  return buf.release ();
}

/* PARTS is a vector of Python objects, each is a sub-class of
   DisassemblerPart.  Create a string by concatenating the string
   representation of each part, and return this new string.

   Converting an address part requires that we call back into GDB core,
   which could throw an exception.  As such, calls to this function should
   be wrapped with a try/catch.  */

static std::string
disasmpy_parts_list_to_string (const std::vector<gdbpy_ref<>> &parts)
{
  std::string str;
  for (auto p : parts)
    {
      if (Py_TYPE (p.get ()) == &disasm_text_part_object_type)
	{
	  disasm_text_part_object *text_part
	    = (disasm_text_part_object *) p.get ();
	  str += disasmpy_part_to_string (text_part);
	}
      else
	{
	  gdb_assert (Py_TYPE (p.get ()) == &disasm_addr_part_object_type);

	  disasm_addr_part_object *addr_part
	    = (disasm_addr_part_object *) p.get ();
	  str += disasmpy_part_to_string (addr_part);
	}
    }

  return str;
}

/* Initialise OBJ, a DisassemblerResult object with LENGTH and PARTS.
   OBJ might already have been initialised, in which case any existing
   content should be discarded before the new PARTS are moved in.  */

static void
disasmpy_init_disassembler_result (disasm_result_object *obj, int length,
				   std::vector<gdbpy_ref<>> &&parts)
{
  if (obj->parts == nullptr)
    obj->parts = new std::vector<gdbpy_ref<>>;
  else
    obj->parts->clear ();

  obj->length = length;
  *(obj->parts) = std::move (parts);
}

/* Implement gdb.disassembler.builtin_disassemble().  Calls back into GDB's
   builtin disassembler.  The first argument is a DisassembleInfo object
   describing what to disassemble.  The second argument is optional and
   provides a mechanism to modify the memory contents that the builtin
   disassembler will actually disassemble.

   Returns an instance of gdb.disassembler.DisassemblerResult, an object
   that wraps a disassembled instruction, or it raises a
   gdb.MemoryError.  */

static PyObject *
disasmpy_builtin_disassemble (PyObject *self, PyObject *args, PyObject *kw)
{
  PyObject *info_obj;
  static const char *keywords[] = { "info", nullptr };
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O!", keywords,
					&disasm_info_object_type, &info_obj))
    return nullptr;

  disasm_info_object *disasm_info = (disasm_info_object *) info_obj;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (disasm_info);

  /* Where the result will be written.  */
  gdbpy_disassembler disassembler (disasm_info);

  /* Now actually perform the disassembly.  LENGTH is set to the length of
     the disassembled instruction, or -1 if there was a memory-error
     encountered while disassembling.  See below more more details on
     handling of -1 return value.  */
  int length = gdbarch_print_insn (disasm_info->gdbarch, disasm_info->address,
				   disassembler.disasm_info ());

  /* It is possible that, while calling a user overridden memory read
     function, a Python exception was raised that couldn't be
     translated into a standard memory-error.  In this case the first such
     exception is stored in the disassembler and restored here.  */
  if (disassembler.restore_exception ())
    return nullptr;

  if (length == -1)
    {

      /* In an ideal world, every disassembler should always call the
	 memory error function before returning a status of -1 as the only
	 error a disassembler should encounter is a failure to read
	 memory.  Unfortunately, there are some disassemblers who don't
	 follow this rule, and will return -1 without calling the memory
	 error function.

	 To make the Python API simpler, we just classify everything as a
	 memory error, but the message has to be modified for the case
	 where the disassembler didn't call the memory error function.  */
      if (disassembler.memory_error_address ().has_value ())
	{
	  CORE_ADDR addr = *disassembler.memory_error_address ();
	  disasmpy_set_memory_error_for_address (addr);
	}
      else
	{
	  auto content = disassembler.release ();
	  std::string str;

	  try
	    {
	      str = disasmpy_parts_list_to_string (content);
	    }
	  catch (const gdb_exception &except)
	    {
	      return gdbpy_handle_gdb_exception (nullptr, except);
	    }
	  if (!str.empty ())
	    PyErr_SetString (gdbpy_gdberror_exc, str.c_str ());
	  else
	    PyErr_SetString (gdbpy_gdberror_exc,
			     _("Unknown disassembly error."));
	}
      return nullptr;
    }

  /* Instructions are either non-zero in length, or we got an error,
     indicated by a length of -1, which we handled above.  */
  gdb_assert (length > 0);

  /* We should not have seen a memory error in this case.  */
  gdb_assert (!disassembler.memory_error_address ().has_value ());

  /* Create a DisassemblerResult containing the results.  */
  PyTypeObject *type = &disasm_result_object_type;
  gdbpy_ref<disasm_result_object> res
    ((disasm_result_object *) type->tp_alloc (type, 0));
  auto content = disassembler.release ();
  disasmpy_init_disassembler_result (res.get (), length, std::move (content));
  return reinterpret_cast<PyObject *> (res.release ());
}

/* Implement gdb._set_enabled function.  Takes a boolean parameter, and
   sets whether GDB should enter the Python disassembler code or not.

   This is called from within the Python code when a new disassembler is
   registered.  When no disassemblers are registered the global C++ flag
   is set to false, and GDB never even enters the Python environment to
   check for a disassembler.

   When the user registers a new Python disassembler, the global C++ flag
   is set to true, and now GDB will enter the Python environment to check
   if there's a disassembler registered for the current architecture.  */

static PyObject *
disasmpy_set_enabled (PyObject *self, PyObject *args, PyObject *kw)
{
  PyObject *newstate;
  static const char *keywords[] = { "state", nullptr };
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O!", keywords,
					&PyBool_Type, &newstate))
    return nullptr;

  python_print_insn_enabled = newstate == Py_True;
  Py_RETURN_NONE;
}

/* Implement DisassembleInfo.read_memory(LENGTH, OFFSET).  Read LENGTH
   bytes at OFFSET from the start of the instruction currently being
   disassembled, and return a memory buffer containing the bytes.

   OFFSET defaults to zero if it is not provided.  LENGTH is required.  If
   the read fails then this will raise a gdb.MemoryError exception.  */

static PyObject *
disasmpy_info_read_memory (PyObject *self, PyObject *args, PyObject *kw)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);

  gdb_py_longest length, offset = 0;
  gdb::unique_xmalloc_ptr<gdb_byte> buffer;
  static const char *keywords[] = { "length", "offset", nullptr };

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw,
					GDB_PY_LL_ARG "|" GDB_PY_LL_ARG,
					keywords, &length, &offset))
    return nullptr;

  /* The apparent address from which we are reading memory.  Note that in
     some cases GDB actually disassembles instructions from a buffer, so
     we might not actually be reading this information directly from the
     inferior memory.  This is all hidden behind the read_memory_func API
     within the disassemble_info structure.  */
  CORE_ADDR address = obj->address + offset;

  /* Setup a buffer to hold the result.  */
  buffer.reset ((gdb_byte *) xmalloc (length));

  /* Read content into BUFFER.  If the read fails then raise a memory
     error, otherwise, convert BUFFER to a Python memory buffer, and return
     it to the user.  */
  disassemble_info *info = obj->gdb_info;
  if (info->read_memory_func ((bfd_vma) address, buffer.get (),
			      (unsigned int) length, info) != 0)
    {
      disasmpy_set_memory_error_for_address (address);
      return nullptr;
    }
  return gdbpy_buffer_to_membuf (std::move (buffer), address, length);
}

/* Implement DisassembleInfo.address attribute, return the address at which
   GDB would like an instruction disassembled.  */

static PyObject *
disasmpy_info_address (PyObject *self, void *closure)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
  return gdb_py_object_from_longest (obj->address).release ();
}

/* Implement DisassembleInfo.architecture attribute.  Return the
   gdb.Architecture in which we are disassembling.  */

static PyObject *
disasmpy_info_architecture (PyObject *self, void *closure)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
  return gdbarch_to_arch_object (obj->gdbarch).release ();
}

/* Implement DisassembleInfo.progspace attribute.  Return the
   gdb.Progspace in which we are disassembling.  */

static PyObject *
disasmpy_info_progspace (PyObject *self, void *closure)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
  return pspace_to_pspace_object (obj->program_space).release ();
}

/* Helper function called when the libopcodes disassembler produces some
   output.  FORMAT and ARGS are used to create a string which GDB will
   display using STYLE.  The string is either added as a new
   DisassemblerTextPart to the list of parts being built in the current
   gdbpy_disassembler object (accessed through DIS_INFO).  Or, if the last
   part in the gdbpy_disassembler is a text part in the same STYLE, then
   the new string is appended to the previous part.

   The merging behavior make the Python API a little more user friendly,
   some disassemblers produce their output character at a time, there's no
   particular reason for this, it's just how they are implemented.  By
   merging parts with the same style we make it easier for the user to
   analyse the disassembler output.  */

int
gdbpy_disassembler::vfprintf_styled_func (void *dis_info,
					  enum disassembler_style style,
					  const char *format,
					  va_list args) noexcept
{
  gdb_disassemble_info *di = (gdb_disassemble_info *) dis_info;
  gdbpy_disassembler *dis
    = gdb::checked_static_cast<gdbpy_disassembler *> (di);

  if (!dis->m_parts.empty ()
      && Py_TYPE (dis->m_parts.back ().get ()) == &disasm_text_part_object_type
      && (((disasm_text_part_object *) dis->m_parts.back ().get ())->style
	  == style))
    {
      std::string *string
	= ((disasm_text_part_object *) dis->m_parts.back ().get ())->string;
      string_vappendf (*string, format, args);
    }
  else
    {
      std::string str = string_vprintf (format, args);
      if (str.size () > 0)
	{
	  gdbpy_ref<> text_part
	    = make_disasm_text_part (std::move (str), style);
	  dis->m_parts.emplace_back (std::move (text_part));
	}
    }

  /* Something non -ve.  */
  return 0;
}

/* Disassembler callback for architectures where libopcodes doesn't
   created styled output.  In these cases we format all the output using
   the (default) text style.  */

int
gdbpy_disassembler::fprintf_func (void *dis_info,
				  const char *format, ...) noexcept
{
  va_list args;
  va_start (args, format);
  vfprintf_styled_func (dis_info, dis_style_text, format, args);
  va_end (args);

  /* Something non -ve.  */
  return 0;
}

/* Disassembler callback for architectures where libopcodes does create
   styled output.  Just creates a new text part with the given STYLE.  */

int
gdbpy_disassembler::fprintf_styled_func (void *dis_info,
					 enum disassembler_style style,
					 const char *format, ...) noexcept
{
  va_list args;
  va_start (args, format);
  vfprintf_styled_func (dis_info, style, format, args);
  va_end (args);

  /* Something non -ve.  */
  return 0;
}

/* This implements the disassemble_info read_memory_func callback and is
   called from the libopcodes disassembler when the disassembler wants to
   read memory.

   From the INFO argument we can find the gdbpy_disassembler object for
   which we are disassembling, and from that object we can find the
   DisassembleInfo for the current disassembly call.

   This function reads the instruction bytes by calling the read_memory
   method on the DisassembleInfo object.  This method might have been
   overridden by user code.

   Read LEN bytes from MEMADDR and place them into BUFF.  Return 0 on
   success (in which case BUFF has been filled), or -1 on error, in which
   case the contents of BUFF are undefined.  */

int
gdbpy_disassembler::read_memory_func (bfd_vma memaddr, gdb_byte *buff,
				      unsigned int len,
				      struct disassemble_info *info) noexcept
{
  gdbpy_disassembler *dis
    = static_cast<gdbpy_disassembler *> (info->application_data);
  disasm_info_object *obj = dis->py_disasm_info ();

  /* If a previous read attempt resulted in an exception, then we don't
     allow any further reads to succeed.  We only do this check for the
     read_memory_func as this is the only one the user can hook into,
     thus, this check prevents us calling back into user code if a
     previous call has already thrown an error.  */
  if (dis->has_stored_exception ())
    return -1;

  /* The DisassembleInfo.read_memory method expects an offset from the
     address stored within the DisassembleInfo object; calculate that
     offset here.  */
  gdb_py_longest offset
    = (gdb_py_longest) memaddr - (gdb_py_longest) obj->address;

  /* Now call the DisassembleInfo.read_memory method.  This might have been
     overridden by the user.  */
  gdbpy_ref<> result_obj = gdbpy_call_method ((PyObject *) obj, "read_memory",
					      len, offset);

  /* Handle any exceptions.  */
  if (result_obj == nullptr)
    {
      /* If we got a gdb.MemoryError then we ignore this and just report
	 that the read failed to the caller.  The caller is then
	 responsible for calling the memory_error_func if it wants to.
	 Remember, the disassembler might just be probing to see if these
	 bytes can be read, if we automatically call the memory error
	 function, we can end up registering an error prematurely.  */
      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
	{
	  PyErr_Clear ();
	  return -1;
	}

      /* For any other exception type we capture the value of the Python
	 exception and throw it, this will then be caught in
	 disasmpy_builtin_disassemble, at which point the exception will be
	 restored.  */
      dis->store_exception (gdbpy_err_fetch ());
      return -1;
    }

  /* Convert the result to a buffer.  */
  Py_buffer py_buff;
  if (!PyObject_CheckBuffer (result_obj.get ())
      || PyObject_GetBuffer (result_obj.get(), &py_buff, PyBUF_CONTIG_RO) < 0)
    {
      PyErr_Format (PyExc_TypeError,
		    _("Result from read_memory is not a buffer"));
      dis->store_exception (gdbpy_err_fetch ());
      return -1;
    }

  /* Wrap PY_BUFF so that it is cleaned up correctly at the end of this
     scope.  */
  Py_buffer_up buffer_up (&py_buff);

  /* Validate that the buffer is the correct length.  */
  if (py_buff.len != len)
    {
      PyErr_Format (PyExc_ValueError,
		    _("Buffer returned from read_memory is sized %d instead of the expected %d"),
		    py_buff.len, len);
      dis->store_exception (gdbpy_err_fetch ());
      return -1;
    }

  /* Copy the data out of the Python buffer and return success.  */
  const gdb_byte *buffer = (const gdb_byte *) py_buff.buf;
  memcpy (buff, buffer, len);
  return 0;
}

/* Implement __str__ for the DisassemblerResult type.  */

static PyObject *
disasmpy_result_str (PyObject *self)
{
  disasm_result_object *obj = (disasm_result_object *) self;

  /* These conditions are all enforced when the DisassemblerResult object
     is created.  */
  gdb_assert (obj->parts != nullptr);
  gdb_assert (obj->parts->size () > 0);
  gdb_assert (obj->length > 0);

  std::string str;

  try
    {
      str = disasmpy_parts_list_to_string (*obj->parts);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyUnicode_Decode (str.c_str (), str.size (),
			   host_charset (), nullptr);
}

/* Implement DisassemblerResult.length attribute, return the length of the
   disassembled instruction.  */

static PyObject *
disasmpy_result_length (PyObject *self, void *closure)
{
  disasm_result_object *obj = (disasm_result_object *) self;
  return gdb_py_object_from_longest (obj->length).release ();
}

/* Implement DisassemblerResult.string attribute, return the content string
   of the disassembled instruction.  */

static PyObject *
disasmpy_result_string (PyObject *self, void *closure)
{
  return disasmpy_result_str (self);
}

/* Implement DisassemblerResult.parts method.  Returns a list of all the
   parts that make up this result.  There should always be at least one
   part, so the returned list should never be empty.  */

static PyObject *
disasmpy_result_parts (PyObject *self, void *closure)
{
  disasm_result_object *obj = (disasm_result_object *) self;

  /* These conditions are all enforced when the DisassemblerResult object
     is created.  */
  gdb_assert (obj->parts != nullptr);
  gdb_assert (obj->parts->size () > 0);
  gdb_assert (obj->length > 0);

  gdbpy_ref<> result_list (PyList_New (obj->parts->size ()));
  if (result_list == nullptr)
    return nullptr;
  Py_ssize_t idx = 0;
  for (auto p : *obj->parts)
    {
      gdbpy_ref<> item = gdbpy_ref<>::new_reference (p.get ());
      PyList_SET_ITEM (result_list.get (), idx, item.release ());
      ++idx;
    }

  /* This should follow naturally from the obj->parts list being
     non-empty.  */
  gdb_assert (PyList_Size (result_list.get()) > 0);

  return result_list.release ();
}

/* Implement DisassemblerResult.__init__.  Takes two arguments, an
   integer, the length in bytes of the disassembled instruction, and a
   string, the disassembled content of the instruction.  */

static int
disasmpy_result_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static const char *keywords[] = { "length", "string", "parts", NULL };
  int length;
  const char *string = nullptr;
  PyObject *parts_list = nullptr;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "i|zO", keywords,
					&length, &string, &parts_list))
    return -1;

  if (length <= 0)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Length must be greater than 0."));
      return -1;
    }

  if (parts_list == Py_None)
    parts_list = nullptr;

  if (string != nullptr && parts_list != nullptr)
    {
      PyErr_Format (PyExc_ValueError,
		    _("Cannot use 'string' and 'parts' when creating %s."),
		    gdbpy_py_obj_tp_name (self));
      return -1;
    }

  if (string != nullptr)
    {
      if (strlen (string) == 0)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("String must not be empty."));
	  return -1;
	}

      disasm_result_object *obj = (disasm_result_object *) self;
      std::vector<gdbpy_ref<>> content;
      gdbpy_ref<> text_part
	= make_disasm_text_part (std::string (string), dis_style_text);
      content.emplace_back (text_part.release ());
      disasmpy_init_disassembler_result (obj, length, std::move (content));
    }
  else
    {
      if (!PySequence_Check (parts_list))
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("'parts' argument is not a sequence"));
	  return -1;
	}

      Py_ssize_t parts_count = PySequence_Size (parts_list);
      if (parts_count <= 0)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("'parts' list must not be empty."));
	  return -1;
	}

      disasm_result_object *obj = (disasm_result_object *) self;
      std::vector<gdbpy_ref<>> content (parts_count);

      struct gdbarch *gdbarch = nullptr;
      for (Py_ssize_t i = 0; i < parts_count; ++i)
	{
	  gdbpy_ref<> part (PySequence_GetItem (parts_list, i));

	  if (part == nullptr)
	    return -1;

	  if (Py_TYPE (part.get ()) == &disasm_addr_part_object_type)
	    {
	      disasm_addr_part_object *addr_part
		= (disasm_addr_part_object *) part.get ();
	      gdb_assert (addr_part->gdbarch != nullptr);
	      if (gdbarch == nullptr)
		gdbarch = addr_part->gdbarch;
	      else if (addr_part->gdbarch != gdbarch)
		{
		  PyErr_SetString (PyExc_ValueError,
				   _("Inconsistent gdb.Architectures used "
				     "in 'parts' sequence."));
		  return -1;
		}
	    }

	  content[i] = std::move (part);
	}

      disasmpy_init_disassembler_result (obj, length, std::move (content));
    }

  return 0;

}

/* Implement __repr__ for the DisassemblerResult type.  */

static PyObject *
disasmpy_result_repr (PyObject *self)
{
  disasm_result_object *obj = (disasm_result_object *) self;

  gdb_assert (obj->parts != nullptr);

  return PyUnicode_FromFormat ("<%s length=%d string=\"%U\">",
			       gdbpy_py_obj_tp_name (self),
			       obj->length,
			       disasmpy_result_str (self));
}

/* Implement memory_error_func callback for disassemble_info.  Extract the
   underlying DisassembleInfo Python object, and set a memory error on
   it.  */

void
gdbpy_disassembler::memory_error_func (int status, bfd_vma memaddr,
				       struct disassemble_info *info) noexcept
{
  gdbpy_disassembler *dis
    = static_cast<gdbpy_disassembler *> (info->application_data);
  dis->m_memory_error_address.emplace (memaddr);
}

/* Wrapper of print_address.  */

void
gdbpy_disassembler::print_address_func (bfd_vma addr,
					struct disassemble_info *info) noexcept
{
  gdbpy_disassembler *dis
    = static_cast<gdbpy_disassembler *> (info->application_data);

  gdbpy_ref<> addr_part
    = make_disasm_addr_part (dis->arch (), addr);
  dis->m_parts.emplace_back (std::move (addr_part));
}

/* constructor.  */

gdbpy_disassembler::gdbpy_disassembler (disasm_info_object *obj)
  : gdb_disassemble_info (obj->gdbarch,
			  read_memory_func,
			  memory_error_func,
			  print_address_func,
			  fprintf_func,
			  fprintf_styled_func),
    m_disasm_info_object (obj)
{ /* Nothing.  */ }

/* A wrapper around a reference to a Python DisassembleInfo object, which
   ensures that the object is marked as invalid when we leave the enclosing
   scope.

   Each DisassembleInfo is created in gdbpy_print_insn, and is done with by
   the time that function returns.  However, there's nothing to stop a user
   caching a reference to the DisassembleInfo, and thus keeping the object
   around.

   We therefore have the notion of a DisassembleInfo becoming invalid, this
   happens when gdbpy_print_insn returns.  This class is responsible for
   marking the DisassembleInfo as invalid in its destructor.  */

struct scoped_invalidate_disasm_info
{
  /* Constructor.  Just cache DISASM_INFO for use in the destructor.  */
  scoped_invalidate_disasm_info
    (gdbpy_ref<disasm_info_object> disasm_info)
      : m_disasm_info (std::move (disasm_info))
  {
    /* Nothing.  */
  }

  /* Upon destruction mark m_disasm_info as invalid.  */
  ~scoped_invalidate_disasm_info ()
  {
    /* Invalidate the original DisassembleInfo object as well as any copies
       that the user might have made.  */
    for (disasm_info_object *obj = m_disasm_info.get ();
	 obj != nullptr;
	 obj = obj->next)
      obj->gdb_info = nullptr;
  }

private:

  /* A reference to a gdb.disassembler.DisassembleInfo object.  When this
     object goes out of scope this reference is released, however, the user
     might be holding other references to the DisassembleInfo (either
     directly, or via copies of this object), in which case the underlying
     object will not be deleted.  The destructor of this class ensures
     that this DisassembleInfo object, and any copies, are all marked
     invalid.  */
  gdbpy_ref<disasm_info_object> m_disasm_info;
};

/* See python-internal.h.  */

std::optional<int>
gdbpy_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
		  disassemble_info *info)
{
  /* Early exit case.  This must be done as early as possible, and
     definitely before we enter Python environment.  The
     python_print_insn_enabled flag is set (from Python) only when the user
     has installed one (or more) Python disassemblers.  So in the common
     case (no custom disassembler installed) this flag will be false,
     allowing for a quick return.  */
  if (!gdb_python_initialized || !python_print_insn_enabled)
    return {};

  gdbpy_enter enter_py (get_current_arch (), current_language);

  /* Import the gdb.disassembler module.  */
  gdbpy_ref<> gdb_python_disassembler_module
    (PyImport_ImportModule ("gdb.disassembler"));
  if (gdb_python_disassembler_module == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Get the _print_insn attribute from the module, this should be the
     function we are going to call to actually perform the disassembly.  */
  gdbpy_ref<> hook
    (PyObject_GetAttrString (gdb_python_disassembler_module.get (),
			     "_print_insn"));
  if (hook == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Create the new DisassembleInfo object we will pass into Python.  */
  gdbpy_ref<disasm_info_object> disasm_info
    ((disasm_info_object *) PyObject_New (disasm_info_object,
					  &disasm_info_object_type));
  if (disasm_info == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Initialise the DisassembleInfo object.  */
  disasm_info_fill (*disasm_info.get (), gdbarch, current_program_space,
		    memaddr, info, nullptr);

  /* Ensure the DisassembleInfo, along with any copies the user makes, are
     marked as invalid when we leave this scope.  */
  scoped_invalidate_disasm_info invalidate_disasm (disasm_info);

  /* Call into the registered disassembler to (possibly) perform the
     disassembly.  */
  gdbpy_ref<> result
    (PyObject_CallFunctionObjArgs (hook.get (),
				   (PyObject *) disasm_info.get (),
				   nullptr));

  if (result == nullptr)
    {
      /* The call into Python code resulted in an exception.  If this was a
	 gdb.MemoryError, then we can figure out an address and call the
	 disassemble_info::memory_error_func to report the error back to
	 core GDB.  Any other exception type we report back to core GDB as
	 an unknown error (return -1 without first calling the
	 memory_error_func callback).  */

      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
	{
	  /* A gdb.MemoryError might have an address attribute which
	     contains the address at which the memory error occurred.  If
	     this is the case then use this address, otherwise, fallback to
	     just using the address of the instruction we were asked to
	     disassemble.  */
	  gdbpy_err_fetch err;
	  PyErr_Clear ();

	  CORE_ADDR addr;
	  if (err.value () != nullptr
	      && PyObject_HasAttrString (err.value ().get (), "address"))
	    {
	      PyObject *addr_obj
		= PyObject_GetAttrString (err.value ().get (), "address");
	      if (get_addr_from_python (addr_obj, &addr) < 0)
		addr = disasm_info->address;
	    }
	  else
	    addr = disasm_info->address;

	  info->memory_error_func (-1, addr, info);
	  return std::optional<int> (-1);
	}
      else if (PyErr_ExceptionMatches (gdbpy_gdberror_exc))
	{
	  gdbpy_err_fetch err;
	  gdb::unique_xmalloc_ptr<char> msg = err.to_string ();

	  info->fprintf_func (info->stream, "%s", msg.get ());
	  return std::optional<int> (-1);
	}
      else
	{
	  gdbpy_print_stack_or_quit ();
	  return std::optional<int> (-1);
	}

    }
  else if (result == Py_None)
    {
      /* A return value of None indicates that the Python code could not,
	 or doesn't want to, disassemble this instruction.  Just return an
	 empty result and core GDB will try to disassemble this for us.  */
      return {};
    }

  /* Check the result is a DisassemblerResult.  */
  if (!PyObject_TypeCheck (result.get (), &disasm_result_object_type))
    {
      PyErr_Format
	(PyExc_TypeError,
	 _("Result from Disassembler must be gdb.DisassemblerResult, not %s."),
	 gdbpy_py_obj_tp_name (result.get ()));
      gdbpy_print_stack ();
      return std::optional<int> (-1);
    }

  /* The result from the Python disassembler has the correct type.  Convert
     this back to the underlying C++ object and read the state directly
     from this object.  */
  struct disasm_result_object *result_obj
    = (struct disasm_result_object *) result.get ();

  /* Validate the length of the disassembled instruction.  */
  long length = result_obj->length;
  long max_insn_length = (gdbarch_max_insn_length_p (gdbarch) ?
			  gdbarch_max_insn_length (gdbarch) : INT_MAX);
  if (length <= 0)
    {
      PyErr_SetString
	(PyExc_ValueError,
	 _("Invalid length attribute: length must be greater than 0."));
      gdbpy_print_stack ();
      return std::optional<int> (-1);
    }
  if (length > max_insn_length)
    {
      PyErr_Format
	(PyExc_ValueError,
	 _("Invalid length attribute: length %d greater than architecture maximum of %d"),
	 length, max_insn_length);
      gdbpy_print_stack ();
      return std::optional<int> (-1);
    }

  /* It is impossible to create a DisassemblerResult object with an empty
     parts list.  We know that each part results in a non-empty string, so
     we know that the instruction disassembly will not be the empty
     string.  */
  gdb_assert (result_obj->parts->size () > 0);

  /* Now print out the parts that make up this instruction.  */
  for (auto &p : *result_obj->parts)
    {
      if (Py_TYPE (p.get ()) == &disasm_text_part_object_type)
	{
	  disasm_text_part_object *text_part
	    = (disasm_text_part_object *) p.get ();
	  gdb_assert (text_part->string != nullptr);
	  info->fprintf_styled_func (info->stream, text_part->style,
				     "%s", text_part->string->c_str ());
	}
      else
	{
	  gdb_assert (Py_TYPE (p.get ()) == &disasm_addr_part_object_type);
	  disasm_addr_part_object *addr_part
	    = (disasm_addr_part_object *) p.get ();
	  /* A DisassemblerAddressPart can only be created by calling a
	     method on DisassembleInfo, and the gdbarch is copied from the
	     DisassembleInfo into the DisassemblerAddressPart.  As the
	     DisassembleInfo has its gdbarch initialised from GDBARCH in
	     this scope, and this architecture can't be changed, then the
	     following assert should hold.  */
	  gdb_assert (addr_part->gdbarch == gdbarch);
	  info->print_address_func (addr_part->address, info);
	}
    }

  return std::optional<int> (length);
}

/* The tp_dealloc callback for the DisassemblerResult type.  Takes care of
   deallocating the content buffer.  */

static void
disasmpy_dealloc_result (PyObject *self)
{
  disasm_result_object *obj = (disasm_result_object *) self;
  delete obj->parts;
  Py_TYPE (self)->tp_free (self);
}

/* The tp_init callback for the DisassemblerPart type.  This just raises an
   exception, which prevents the user from creating objects of this type.
   Instead the user should create instances of a sub-class.  */

static int
disasmpy_part_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  PyErr_Format (PyExc_RuntimeError,
		_("Cannot create instances of %s."),
		gdbpy_py_obj_tp_name (self));
  return -1;
}

/* Return a string representing STYLE.  The returned string is used as a
   constant defined in the gdb.disassembler module.  */

static const char *
get_style_name (enum disassembler_style style)
{
  switch (style)
    {
    case dis_style_text: return "STYLE_TEXT";
    case dis_style_mnemonic: return "STYLE_MNEMONIC";
    case dis_style_sub_mnemonic: return "STYLE_SUB_MNEMONIC";
    case dis_style_assembler_directive: return "STYLE_ASSEMBLER_DIRECTIVE";
    case dis_style_register: return "STYLE_REGISTER";
    case dis_style_immediate: return "STYLE_IMMEDIATE";
    case dis_style_address: return "STYLE_ADDRESS";
    case dis_style_address_offset: return "STYLE_ADDRESS_OFFSET";
    case dis_style_symbol: return "STYLE_SYMBOL";
    case dis_style_comment_start: return "STYLE_COMMENT_START";
    }

  gdb_assert_not_reached ("unknown disassembler style");
}

/* Implement DisassemblerTextPart.__repr__ method.  */

static PyObject *
disasmpy_text_part_repr (PyObject *self)
{
  disasm_text_part_object *obj = (disasm_text_part_object *) self;

  gdb_assert (obj->string != nullptr);

  return PyUnicode_FromFormat ("<%s string='%s', style='%s'>",
			       gdbpy_py_obj_tp_name (self),
			       obj->string->c_str (),
			       get_style_name (obj->style));
}

/* Implement DisassemblerTextPart.__str__ attribute.  */

static PyObject *
disasmpy_text_part_str (PyObject *self)
{
  disasm_text_part_object *obj = (disasm_text_part_object *) self;

  return PyUnicode_Decode (obj->string->c_str (), obj->string->size (),
			   host_charset (), nullptr);
}

/* Implement DisassemblerTextPart.string attribute.  */

static PyObject *
disasmpy_text_part_string (PyObject *self, void *closure)
{
  return disasmpy_text_part_str (self);
}

/* Implement DisassemblerTextPart.style attribute.   */

static PyObject *
disasmpy_text_part_style (PyObject *self, void *closure)
{
  disasm_text_part_object *obj = (disasm_text_part_object *) self;

  LONGEST style_val = (LONGEST) obj->style;
  return gdb_py_object_from_longest (style_val).release ();
}

/* Implement DisassemblerAddressPart.__repr__ method.  */

static PyObject *
disasmpy_addr_part_repr (PyObject *self)
{
  disasm_addr_part_object *obj = (disasm_addr_part_object *) self;

  return PyUnicode_FromFormat ("<%s address='%s'>",
			       gdbpy_py_obj_tp_name (self),
			       core_addr_to_string_nz (obj->address));
}

/* Implement DisassemblerAddressPart.__str__ attribute.  */

static PyObject *
disasmpy_addr_part_str (PyObject *self)
{
  disasm_addr_part_object *obj = (disasm_addr_part_object *) self;

  std::string str;
  try
    {
      string_file buf;
      print_address (obj->gdbarch, obj->address, &buf);
      str = buf.release ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyUnicode_Decode (str.c_str (), str.size (),
			   host_charset (), nullptr);
}

/* Implement DisassemblerAddressPart.string attribute.  */

static PyObject *
disasmpy_addr_part_string (PyObject *self, void *closure)
{
  return disasmpy_addr_part_str (self);
}

/* Implement DisassemblerAddressPart.address attribute.  */

static PyObject *
disasmpy_addr_part_address (PyObject *self, void *closure)
{
  disasm_addr_part_object *obj = (disasm_addr_part_object *) self;

  return gdb_py_object_from_longest (obj->address).release ();
}

/* The get/set attributes of the gdb.disassembler.DisassembleInfo type.  */

static gdb_PyGetSetDef disasm_info_object_getset[] = {
  { "address", disasmpy_info_address, nullptr,
    "Start address of the instruction to disassemble.", nullptr },
  { "architecture", disasmpy_info_architecture, nullptr,
    "Architecture to disassemble in", nullptr },
  { "progspace", disasmpy_info_progspace, nullptr,
    "Program space to disassemble in", nullptr },
  { nullptr }   /* Sentinel */
};

/* The methods of the gdb.disassembler.DisassembleInfo type.  */

static PyMethodDef disasm_info_object_methods[] = {
  { "read_memory", (PyCFunction) disasmpy_info_read_memory,
    METH_VARARGS | METH_KEYWORDS,
    "read_memory (LEN, OFFSET = 0) -> Octets[]\n\
Read LEN octets for the instruction to disassemble." },
  { "is_valid", disasmpy_info_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this DisassembleInfo is valid, false if not." },
  { "text_part", (PyCFunction) disasmpy_info_make_text_part,
    METH_VARARGS | METH_KEYWORDS,
    "text_part (STRING, STYLE) -> DisassemblerTextPart\n\
Create a new text part, with contents STRING styled with STYLE." },
  { "address_part", (PyCFunction) disasmpy_info_make_address_part,
    METH_VARARGS | METH_KEYWORDS,
    "address_part (ADDRESS) -> DisassemblerAddressPart\n\
Create a new address part representing ADDRESS." },
  {nullptr}  /* Sentinel */
};

/* The get/set attributes of the gdb.disassembler.DisassemblerResult type.  */

static gdb_PyGetSetDef disasm_result_object_getset[] = {
  { "length", disasmpy_result_length, nullptr,
    "Length of the disassembled instruction.", nullptr },
  { "string", disasmpy_result_string, nullptr,
    "String representing the disassembled instruction.", nullptr },
  { "parts", disasmpy_result_parts, nullptr,
    "List of all the separate disassembly parts", nullptr },
  { nullptr }   /* Sentinel */
};

/* The get/set attributes of the gdb.disassembler.DisassemblerTextPart type.  */

static gdb_PyGetSetDef disasmpy_text_part_getset[] = {
  { "string", disasmpy_text_part_string, nullptr,
    "String representing a text part.", nullptr },
  { "style", disasmpy_text_part_style, nullptr,
    "The style of this text part.", nullptr },
  { nullptr }   /* Sentinel */
};

/* The get/set attributes of the gdb.disassembler.DisassemblerAddressPart type.  */

static gdb_PyGetSetDef disasmpy_addr_part_getset[] = {
  { "string", disasmpy_addr_part_string, nullptr,
    "String representing an address part.", nullptr },
  { "address", disasmpy_addr_part_address, nullptr,
    "The address of this address part.", nullptr },
  { nullptr }   /* Sentinel */
};

/* These are the methods we add into the _gdb.disassembler module, which
   are then imported into the gdb.disassembler module.  These are global
   functions that support performing disassembly.  */

PyMethodDef python_disassembler_methods[] =
{
  { "builtin_disassemble", (PyCFunction) disasmpy_builtin_disassemble,
    METH_VARARGS | METH_KEYWORDS,
    "builtin_disassemble (INFO) -> None\n\
Disassemble using GDB's builtin disassembler.  INFO is an instance of\n\
gdb.disassembler.DisassembleInfo." },
  { "_set_enabled", (PyCFunction) disasmpy_set_enabled,
    METH_VARARGS | METH_KEYWORDS,
    "_set_enabled (STATE) -> None\n\
Set whether GDB should call into the Python _print_insn code or not." },
  {nullptr, nullptr, 0, nullptr}
};

/* Structure to define the _gdb.disassembler module.  */

static struct PyModuleDef python_disassembler_module_def =
{
  PyModuleDef_HEAD_INIT,
  "_gdb.disassembler",
  nullptr,
  -1,
  python_disassembler_methods,
  nullptr,
  nullptr,
  nullptr,
  nullptr
};

/* Called to initialize the Python structures in this file.  */

static int
gdbpy_initialize_disasm ()
{
  /* Create the _gdb.disassembler module, and add it to the _gdb module.  */

  PyObject *gdb_disassembler_module;
  gdb_disassembler_module = PyModule_Create (&python_disassembler_module_def);
  if (gdb_disassembler_module == nullptr)
    return -1;
  if (gdb_pymodule_addobject (gdb_module, "disassembler",
			      gdb_disassembler_module) < 0)
    return -1;

  /* This is needed so that 'import _gdb.disassembler' will work.  */
  PyObject *dict = PyImport_GetModuleDict ();
  if (PyDict_SetItemString (dict, "_gdb.disassembler",
			    gdb_disassembler_module) < 0)
    return -1;

  for (int i = 0; i <= (int) dis_style_comment_start; ++i)
    {
      const char *style_name = get_style_name ((enum disassembler_style) i);
      if (PyModule_AddIntConstant (gdb_disassembler_module, style_name, i) < 0)
	return -1;
    }

  disasm_info_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_info_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_result_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_result_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_part_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_part_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_addr_part_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_addr_part_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_text_part_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_text_part_object_type, gdb_disassembler_module) < 0)
    return -1;

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_disasm);



/* Describe the gdb.disassembler.DisassembleInfo type.  */

PyTypeObject disasm_info_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassembleInfo",		/*tp_name*/
  sizeof (disasm_info_object),			/*tp_basicsize*/
  0,						/*tp_itemsize*/
  disasm_info_dealloc,				/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_info_repr,				/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  0,						/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/*tp_flags*/
  "GDB instruction disassembler object",	/* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  disasm_info_object_methods,			/* tp_methods */
  0,						/* tp_members */
  disasm_info_object_getset,			/* tp_getset */
  0,						/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  disasm_info_init,				/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerResult type.  */

PyTypeObject disasm_result_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerResult",	/*tp_name*/
  sizeof (disasm_result_object),		/*tp_basicsize*/
  0,						/*tp_itemsize*/
  disasmpy_dealloc_result,			/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_result_repr,				/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  disasmpy_result_str,				/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing a disassembler result",	/* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  disasm_result_object_getset,			/* tp_getset */
  0,						/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  disasmpy_result_init,				/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerPart type.  This type exists
   only as an abstract base-class for the various part sub-types.  The
   init method for this type throws an error.  As such we don't both to
   provide a tp_repr method for this parent class.  */

PyTypeObject disasm_part_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerPart",		/*tp_name*/
  sizeof (PyObject),				/*tp_basicsize*/
  0,						/*tp_itemsize*/
  0,						/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  0,						/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  0,						/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing part of a disassembled instruction",  /* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  0,						/* tp_getset */
  0,						/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  disasmpy_part_init,				/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerTextPart type.  */

PyTypeObject disasm_text_part_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerTextPart",	/*tp_name*/
  sizeof (disasm_text_part_object_type),	/*tp_basicsize*/
  0,						/*tp_itemsize*/
  0,						/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_text_part_repr,			/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  disasmpy_text_part_str,			/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing a text part of an instruction",  /* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  disasmpy_text_part_getset,			/* tp_getset */
  &disasm_part_object_type,			/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  0,						/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerAddressPart type.  */

PyTypeObject disasm_addr_part_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerAddressPart",	/*tp_name*/
  sizeof (disasm_addr_part_object),		/*tp_basicsize*/
  0,						/*tp_itemsize*/
  0,						/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_addr_part_repr,			/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  disasmpy_addr_part_str,			/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing an address part of an instruction",  /* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  disasmpy_addr_part_getset,						/* tp_getset */
  &disasm_part_object_type,			/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  0,						/* tp_init */
  0,						/* tp_alloc */
};
