/* Scheme interface to blocks.

   Copyright (C) 2008-2022 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/>.  */

/* See README file in this directory for implementation notes, coding
   conventions, et.al.  */

#include "defs.h"
#include "block.h"
#include "dictionary.h"
#include "objfiles.h"
#include "source.h"
#include "symtab.h"
#include "guile-internal.h"

/* A smob describing a gdb block.  */

struct block_smob
{
  /* This always appears first.
     We want blocks to be eq?-able.  And we need to be able to invalidate
     blocks when the associated objfile is deleted.  */
  eqable_gdb_smob base;

  /* The GDB block structure that represents a frame's code block.  */
  const struct block *block;

  /* The backing object file.  There is no direct relationship in GDB
     between a block and an object file.  When a block is created also
     store a pointer to the object file for later use.  */
  struct objfile *objfile;
};

/* To iterate over block symbols from Scheme we need to store
   struct block_iterator somewhere.  This is stored in the "progress" field
   of <gdb:iterator>.  We store the block object in iterator_smob.object,
   so we don't store it here.

   Remember: While iterating over block symbols, you must continually check
   whether the block is still valid.  */

struct block_syms_progress_smob
{
  /* This always appears first.  */
  gdb_smob base;

  /* The iterator for that block.  */
  struct block_iterator iter;

  /* Has the iterator been initialized flag.  */
  int initialized_p;
};

static const char block_smob_name[] = "gdb:block";
static const char block_syms_progress_smob_name[] = "gdb:block-symbols-iterator";

/* The tag Guile knows the block smobs by.  */
static scm_t_bits block_smob_tag;
static scm_t_bits block_syms_progress_smob_tag;

/* The "next!" block syms iterator method.  */
static SCM bkscm_next_symbol_x_proc;

/* This is called when an objfile is about to be freed.
   Invalidate the block as further actions on the block would result
   in bad data.  All access to b_smob->block should be gated by
   checks to ensure the block is (still) valid.  */
struct bkscm_deleter
{
  /* Helper function for bkscm_del_objfile_blocks to mark the block
     as invalid.  */

  static int
  bkscm_mark_block_invalid (void **slot, void *info)
  {
    block_smob *b_smob = (block_smob *) *slot;

    b_smob->block = NULL;
    b_smob->objfile = NULL;
    return 1;
  }

  void operator() (htab_t htab)
  {
    gdb_assert (htab != nullptr);
    htab_traverse_noresize (htab, bkscm_mark_block_invalid, NULL);
    htab_delete (htab);
  }
};

static const registry<objfile>::key<htab, bkscm_deleter>
     bkscm_objfile_data_key;

/* Administrivia for block smobs.  */

/* Helper function to hash a block_smob.  */

static hashval_t
bkscm_hash_block_smob (const void *p)
{
  const block_smob *b_smob = (const block_smob *) p;

  return htab_hash_pointer (b_smob->block);
}

/* Helper function to compute equality of block_smobs.  */

static int
bkscm_eq_block_smob (const void *ap, const void *bp)
{
  const block_smob *a = (const block_smob *) ap;
  const block_smob *b = (const block_smob *) bp;

  return (a->block == b->block
	  && a->block != NULL);
}

/* Return the struct block pointer -> SCM mapping table.
   It is created if necessary.  */

static htab_t
bkscm_objfile_block_map (struct objfile *objfile)
{
  htab_t htab = bkscm_objfile_data_key.get (objfile);

  if (htab == NULL)
    {
      htab = gdbscm_create_eqable_gsmob_ptr_map (bkscm_hash_block_smob,
						 bkscm_eq_block_smob);
      bkscm_objfile_data_key.set (objfile, htab);
    }

  return htab;
}

/* The smob "free" function for <gdb:block>.  */

static size_t
bkscm_free_block_smob (SCM self)
{
  block_smob *b_smob = (block_smob *) SCM_SMOB_DATA (self);

  if (b_smob->block != NULL)
    {
      htab_t htab = bkscm_objfile_block_map (b_smob->objfile);

      gdbscm_clear_eqable_gsmob_ptr_slot (htab, &b_smob->base);
    }

  /* Not necessary, done to catch bugs.  */
  b_smob->block = NULL;
  b_smob->objfile = NULL;

  return 0;
}

/* The smob "print" function for <gdb:block>.  */

static int
bkscm_print_block_smob (SCM self, SCM port, scm_print_state *pstate)
{
  block_smob *b_smob = (block_smob *) SCM_SMOB_DATA (self);
  const struct block *b = b_smob->block;

  gdbscm_printf (port, "#<%s", block_smob_name);

  if (b->superblock () == NULL)
    gdbscm_printf (port, " global");
  else if (b->superblock ()->superblock () == NULL)
    gdbscm_printf (port, " static");

  if (b->function () != NULL)
    gdbscm_printf (port, " %s", b->function ()->print_name ());

  gdbscm_printf (port, " %s-%s",
		 hex_string (b->start ()), hex_string (b->end ()));

  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

  /* Non-zero means success.  */
  return 1;
}

/* Low level routine to create a <gdb:block> object.  */

static SCM
bkscm_make_block_smob (void)
{
  block_smob *b_smob = (block_smob *)
    scm_gc_malloc (sizeof (block_smob), block_smob_name);
  SCM b_scm;

  b_smob->block = NULL;
  b_smob->objfile = NULL;
  b_scm = scm_new_smob (block_smob_tag, (scm_t_bits) b_smob);
  gdbscm_init_eqable_gsmob (&b_smob->base, b_scm);

  return b_scm;
}

/* Returns non-zero if SCM is a <gdb:block> object.  */

static int
bkscm_is_block (SCM scm)
{
  return SCM_SMOB_PREDICATE (block_smob_tag, scm);
}

/* (block? scm) -> boolean */

static SCM
gdbscm_block_p (SCM scm)
{
  return scm_from_bool (bkscm_is_block (scm));
}

/* Return the existing object that encapsulates BLOCK, or create a new
   <gdb:block> object.  */

SCM
bkscm_scm_from_block (const struct block *block, struct objfile *objfile)
{
  htab_t htab;
  eqable_gdb_smob **slot;
  block_smob *b_smob, b_smob_for_lookup;
  SCM b_scm;

  /* If we've already created a gsmob for this block, return it.
     This makes blocks eq?-able.  */
  htab = bkscm_objfile_block_map (objfile);
  b_smob_for_lookup.block = block;
  slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &b_smob_for_lookup.base);
  if (*slot != NULL)
    return (*slot)->containing_scm;

  b_scm = bkscm_make_block_smob ();
  b_smob = (block_smob *) SCM_SMOB_DATA (b_scm);
  b_smob->block = block;
  b_smob->objfile = objfile;
  gdbscm_fill_eqable_gsmob_ptr_slot (slot, &b_smob->base);

  return b_scm;
}

/* Returns the <gdb:block> object in SELF.
   Throws an exception if SELF is not a <gdb:block> object.  */

static SCM
bkscm_get_block_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (bkscm_is_block (self), self, arg_pos, func_name,
		   block_smob_name);

  return self;
}

/* Returns a pointer to the block smob of SELF.
   Throws an exception if SELF is not a <gdb:block> object.  */

static block_smob *
bkscm_get_block_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM b_scm = bkscm_get_block_arg_unsafe (self, arg_pos, func_name);
  block_smob *b_smob = (block_smob *) SCM_SMOB_DATA (b_scm);

  return b_smob;
}

/* Returns non-zero if block B_SMOB is valid.  */

static int
bkscm_is_valid (block_smob *b_smob)
{
  return b_smob->block != NULL;
}

/* Returns the block smob in SELF, verifying it's valid.
   Throws an exception if SELF is not a <gdb:block> object or is invalid.  */

static block_smob *
bkscm_get_valid_block_smob_arg_unsafe (SCM self, int arg_pos,
				       const char *func_name)
{
  block_smob *b_smob
    = bkscm_get_block_smob_arg_unsafe (self, arg_pos, func_name);

  if (!bkscm_is_valid (b_smob))
    {
      gdbscm_invalid_object_error (func_name, arg_pos, self,
				   _("<gdb:block>"));
    }

  return b_smob;
}

/* Returns the block smob contained in SCM or NULL if SCM is not a
   <gdb:block> object.
   If there is an error a <gdb:exception> object is stored in *EXCP.  */

static block_smob *
bkscm_get_valid_block (SCM scm, int arg_pos, const char *func_name, SCM *excp)
{
  block_smob *b_smob;

  if (!bkscm_is_block (scm))
    {
      *excp = gdbscm_make_type_error (func_name, arg_pos, scm,
				      block_smob_name);
      return NULL;
    }

  b_smob = (block_smob *) SCM_SMOB_DATA (scm);
  if (!bkscm_is_valid (b_smob))
    {
      *excp = gdbscm_make_invalid_object_error (func_name, arg_pos, scm,
						_("<gdb:block>"));
      return NULL;
    }

  return b_smob;
}

/* Returns the struct block that is wrapped by BLOCK_SCM.
   If BLOCK_SCM is not a block, or is an invalid block, then NULL is returned
   and a <gdb:exception> object is stored in *EXCP.  */

const struct block *
bkscm_scm_to_block (SCM block_scm, int arg_pos, const char *func_name,
		    SCM *excp)
{
  block_smob *b_smob;

  b_smob = bkscm_get_valid_block (block_scm, arg_pos, func_name, excp);

  if (b_smob != NULL)
    return b_smob->block;
  return NULL;
}


/* Block methods.  */

/* (block-valid? <gdb:block>) -> boolean
   Returns #t if SELF still exists in GDB.  */

static SCM
gdbscm_block_valid_p (SCM self)
{
  block_smob *b_smob
    = bkscm_get_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (bkscm_is_valid (b_smob));
}

/* (block-start <gdb:block>) -> address */

static SCM
gdbscm_block_start (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;

  return gdbscm_scm_from_ulongest (block->start ());
}

/* (block-end <gdb:block>) -> address */

static SCM
gdbscm_block_end (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;

  return gdbscm_scm_from_ulongest (block->end ());
}

/* (block-function <gdb:block>) -> <gdb:symbol> */

static SCM
gdbscm_block_function (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;
  struct symbol *sym;

  sym = block->function ();

  if (sym != NULL)
    return syscm_scm_from_symbol (sym);
  return SCM_BOOL_F;
}

/* (block-superblock <gdb:block>) -> <gdb:block> */

static SCM
gdbscm_block_superblock (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;
  const struct block *super_block;

  super_block = block->superblock ();

  if (super_block)
    return bkscm_scm_from_block (super_block, b_smob->objfile);
  return SCM_BOOL_F;
}

/* (block-global-block <gdb:block>) -> <gdb:block>
   Returns the global block associated to this block.  */

static SCM
gdbscm_block_global_block (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;
  const struct block *global_block;

  global_block = block_global_block (block);

  return bkscm_scm_from_block (global_block, b_smob->objfile);
}

/* (block-static-block <gdb:block>) -> <gdb:block>
   Returns the static block associated to this block.
   Returns #f if we cannot get the static block (this is the global block).  */

static SCM
gdbscm_block_static_block (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;
  const struct block *static_block;

  if (block->superblock () == NULL)
    return SCM_BOOL_F;

  static_block = block_static_block (block);

  return bkscm_scm_from_block (static_block, b_smob->objfile);
}

/* (block-global? <gdb:block>) -> boolean
   Returns #t if this block object is a global block.  */

static SCM
gdbscm_block_global_p (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;

  return scm_from_bool (block->superblock () == NULL);
}

/* (block-static? <gdb:block>) -> boolean
   Returns #t if this block object is a static block.  */

static SCM
gdbscm_block_static_p (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;

  if (block->superblock () != NULL
      && block->superblock ()->superblock () == NULL)
    return SCM_BOOL_T;
  return SCM_BOOL_F;
}

/* (block-symbols <gdb:block>) -> list of <gdb:symbol objects
   Returns a list of symbols of the block.  */

static SCM
gdbscm_block_symbols (SCM self)
{
  block_smob *b_smob
    = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct block *block = b_smob->block;
  struct block_iterator iter;
  struct symbol *sym;
  SCM result;

  result = SCM_EOL;

  sym = block_iterator_first (block, &iter);

  while (sym != NULL)
    {
      SCM s_scm = syscm_scm_from_symbol (sym);

      result = scm_cons (s_scm, result);
      sym = block_iterator_next (&iter);
    }

  return scm_reverse_x (result, SCM_EOL);
}

/* The <gdb:block-symbols-iterator> object,
   for iterating over all symbols in a block.  */

/* The smob "print" function for <gdb:block-symbols-iterator>.  */

static int
bkscm_print_block_syms_progress_smob (SCM self, SCM port,
				      scm_print_state *pstate)
{
  block_syms_progress_smob *i_smob
    = (block_syms_progress_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s", block_syms_progress_smob_name);

  if (i_smob->initialized_p)
    {
      switch (i_smob->iter.which)
	{
	case GLOBAL_BLOCK:
	case STATIC_BLOCK:
	  {
	    struct compunit_symtab *cust;

	    gdbscm_printf (port, " %s", 
			   i_smob->iter.which == GLOBAL_BLOCK
			   ? "global" : "static");
	    if (i_smob->iter.idx != -1)
	      gdbscm_printf (port, " @%d", i_smob->iter.idx);
	    cust = (i_smob->iter.idx == -1
		    ? i_smob->iter.d.compunit_symtab
		    : i_smob->iter.d.compunit_symtab->includes[i_smob->iter.idx]);
	    gdbscm_printf (port, " %s",
			   symtab_to_filename_for_display
			     (cust->primary_filetab ()));
	    break;
	  }
	case FIRST_LOCAL_BLOCK:
	  gdbscm_printf (port, " single block");
	  break;
	}
    }
  else
    gdbscm_printf (port, " !initialized");

  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

  /* Non-zero means success.  */
  return 1;
}

/* Low level routine to create a <gdb:block-symbols-progress> object.  */

static SCM
bkscm_make_block_syms_progress_smob (void)
{
  block_syms_progress_smob *i_smob = (block_syms_progress_smob *)
    scm_gc_malloc (sizeof (block_syms_progress_smob),
		   block_syms_progress_smob_name);
  SCM smob;

  memset (&i_smob->iter, 0, sizeof (i_smob->iter));
  i_smob->initialized_p = 0;
  smob = scm_new_smob (block_syms_progress_smob_tag, (scm_t_bits) i_smob);
  gdbscm_init_gsmob (&i_smob->base);

  return smob;
}

/* Returns non-zero if SCM is a <gdb:block-symbols-progress> object.  */

static int
bkscm_is_block_syms_progress (SCM scm)
{
  return SCM_SMOB_PREDICATE (block_syms_progress_smob_tag, scm);
}

/* (block-symbols-progress? scm) -> boolean */

static SCM
bkscm_block_syms_progress_p (SCM scm)
{
  return scm_from_bool (bkscm_is_block_syms_progress (scm));
}

/* (make-block-symbols-iterator <gdb:block>) -> <gdb:iterator>
   Return a <gdb:iterator> object for iterating over the symbols of SELF.  */

static SCM
gdbscm_make_block_syms_iter (SCM self)
{
  /* Call for side effects.  */
  bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  SCM progress, iter;

  progress = bkscm_make_block_syms_progress_smob ();

  iter = gdbscm_make_iterator (self, progress, bkscm_next_symbol_x_proc);

  return iter;
}

/* Returns the next symbol in the iteration through the block's dictionary,
   or (end-of-iteration).
   This is the iterator_smob.next_x method.  */

static SCM
gdbscm_block_next_symbol_x (SCM self)
{
  SCM progress, iter_scm, block_scm;
  iterator_smob *iter_smob;
  block_smob *b_smob;
  const struct block *block;
  block_syms_progress_smob *p_smob;
  struct symbol *sym;

  iter_scm = itscm_get_iterator_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  iter_smob = (iterator_smob *) SCM_SMOB_DATA (iter_scm);

  block_scm = itscm_iterator_smob_object (iter_smob);
  b_smob = bkscm_get_valid_block_smob_arg_unsafe (block_scm,
						  SCM_ARG1, FUNC_NAME);
  block = b_smob->block;

  progress = itscm_iterator_smob_progress (iter_smob);

  SCM_ASSERT_TYPE (bkscm_is_block_syms_progress (progress),
		   progress, SCM_ARG1, FUNC_NAME,
		   block_syms_progress_smob_name);
  p_smob = (block_syms_progress_smob *) SCM_SMOB_DATA (progress);

  if (!p_smob->initialized_p)
    {
      sym = block_iterator_first (block, &p_smob->iter);
      p_smob->initialized_p = 1;
    }
  else
    sym = block_iterator_next (&p_smob->iter);

  if (sym == NULL)
    return gdbscm_end_of_iteration ();

  return syscm_scm_from_symbol (sym);
}

/* (lookup-block address) -> <gdb:block>
   Returns the innermost lexical block containing the specified pc value,
   or #f if there is none.  */

static SCM
gdbscm_lookup_block (SCM pc_scm)
{
  CORE_ADDR pc;
  const struct block *block = NULL;
  struct compunit_symtab *cust = NULL;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc);

  gdbscm_gdb_exception exc {};
  try
    {
      cust = find_pc_compunit_symtab (pc);

      if (cust != NULL && cust->objfile () != NULL)
	block = block_for_pc (pc);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  if (cust == NULL || cust->objfile () == NULL)
    {
      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, pc_scm,
				 _("cannot locate object file for block"));
    }

  if (block != NULL)
    return bkscm_scm_from_block (block, cust->objfile ());
  return SCM_BOOL_F;
}

/* Initialize the Scheme block support.  */

static const scheme_function block_functions[] =
{
  { "block?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_p),
    "\
Return #t if the object is a <gdb:block> object." },

  { "block-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_valid_p),
    "\
Return #t if the block is valid.\n\
A block becomes invalid when its objfile is freed." },

  { "block-start", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_start),
    "\
Return the start address of the block." },

  { "block-end", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_end),
    "\
Return the end address of the block." },

  { "block-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_function),
    "\
Return the gdb:symbol object of the function containing the block\n\
or #f if the block does not live in any function." },

  { "block-superblock", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_superblock),
    "\
Return the superblock (parent block) of the block." },

  { "block-global-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_global_block),
    "\
Return the global block of the block." },

  { "block-static-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_static_block),
    "\
Return the static block of the block." },

  { "block-global?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_global_p),
    "\
Return #t if block is a global block." },

  { "block-static?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_static_p),
    "\
Return #t if block is a static block." },

  { "block-symbols", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_symbols),
    "\
Return a list of all symbols (as <gdb:symbol> objects) in the block." },

  { "make-block-symbols-iterator", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_make_block_syms_iter),
    "\
Return a <gdb:iterator> object for iterating over all symbols in the block." },

  { "block-symbols-progress?", 1, 0, 0,
    as_a_scm_t_subr (bkscm_block_syms_progress_p),
    "\
Return #t if the object is a <gdb:block-symbols-progress> object." },

  { "lookup-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_lookup_block),
    "\
Return the innermost GDB block containing the address or #f if none found.\n\
\n\
  Arguments:\n\
    address: the address to lookup" },

  END_FUNCTIONS
};

void
gdbscm_initialize_blocks (void)
{
  block_smob_tag
    = gdbscm_make_smob_type (block_smob_name, sizeof (block_smob));
  scm_set_smob_free (block_smob_tag, bkscm_free_block_smob);
  scm_set_smob_print (block_smob_tag, bkscm_print_block_smob);

  block_syms_progress_smob_tag
    = gdbscm_make_smob_type (block_syms_progress_smob_name,
			     sizeof (block_syms_progress_smob));
  scm_set_smob_print (block_syms_progress_smob_tag,
		      bkscm_print_block_syms_progress_smob);

  gdbscm_define_functions (block_functions, 1);

  /* This function is "private".  */
  bkscm_next_symbol_x_proc
    = scm_c_define_gsubr ("%block-next-symbol!", 1, 0, 0,
			  as_a_scm_t_subr (gdbscm_block_next_symbol_x));
  scm_set_procedure_property_x (bkscm_next_symbol_x_proc,
				gdbscm_documentation_symbol,
				gdbscm_scm_from_c_string ("\
Internal function to assist the block symbols iterator."));
}
