/* GDB/Scheme smobs (gsmob is pronounced "jee smob")

   Copyright (C) 2014-2021 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.  */

/* Smobs are Guile's "small object".
   They are used to export C structs to Scheme.

   Note: There's only room in the encoding space for 256, and while we won't
   come close to that, mixed with other libraries maybe someday we could.
   We don't worry about it now, except to be aware of the issue.
   We could allocate just a few smobs and use the unused smob flags field to
   specify the gdb smob kind, that is left for another day if it ever is
   needed.

   Some GDB smobs are "chained gsmobs".  They are used to assist with life-time
   tracking of GDB objects vs Scheme objects.  Gsmobs can "subclass"
   chained_gdb_smob, which contains a doubly-linked list to assist with
   life-time tracking.

   Some other GDB smobs are "eqable gsmobs".  Gsmob implementations can
   "subclass" eqable_gdb_smob to make gsmobs eq?-able.  This is done by
   recording all gsmobs in a hash table and before creating a gsmob first
   seeing if it's already in the table.  Eqable gsmobs can also be used where
   lifetime-tracking is required.  */

#include "defs.h"
#include "hashtab.h"
#include "objfiles.h"
#include "guile-internal.h"

/* We need to call this.  Undo our hack to prevent others from calling it.  */
#undef scm_make_smob_type

static htab_t registered_gsmobs;

/* Hash function for registered_gsmobs hash table.  */

static hashval_t
hash_scm_t_bits (const void *item)
{
  uintptr_t v = (uintptr_t) item;

  return v;
}

/* Equality function for registered_gsmobs hash table.  */

static int
eq_scm_t_bits (const void *item_lhs, const void *item_rhs)
{
  return item_lhs == item_rhs;
}

/* Record GSMOB_CODE as being a gdb smob.
   GSMOB_CODE is the result of scm_make_smob_type.  */

static void
register_gsmob (scm_t_bits gsmob_code)
{
  void **slot;

  slot = htab_find_slot (registered_gsmobs, (void *) gsmob_code, INSERT);
  gdb_assert (*slot == NULL);
  *slot = (void *) gsmob_code;
}

/* Return non-zero if SCM is any registered gdb smob object.  */

static int
gdbscm_is_gsmob (SCM scm)
{
  void **slot;

  if (SCM_IMP (scm))
    return 0;
  slot = htab_find_slot (registered_gsmobs, (void *) SCM_TYP16 (scm),
			 NO_INSERT);
  return slot != NULL;
}

/* Call this to register a smob, instead of scm_make_smob_type.
   Exports the created smob type from the current module.  */

scm_t_bits
gdbscm_make_smob_type (const char *name, size_t size)
{
  scm_t_bits result = scm_make_smob_type (name, size);

  register_gsmob (result);

#if SCM_MAJOR_VERSION == 2 && SCM_MINOR_VERSION == 0
  /* Prior to Guile 2.1.0, smob classes were only exposed via exports
     from the (oop goops) module.  */
  SCM bound_name = scm_string_append (scm_list_3 (scm_from_latin1_string ("<"),
						  scm_from_latin1_string (name),
						  scm_from_latin1_string (">")));
  bound_name = scm_string_to_symbol (bound_name);
  SCM smob_type = scm_public_ref (scm_list_2 (scm_from_latin1_symbol ("oop"),
					      scm_from_latin1_symbol ("goops")),
				  bound_name);
#elif SCM_MAJOR_VERSION == 2 && SCM_MINOR_VERSION == 1 && SCM_MICRO_VERSION == 0
  /* Guile 2.1.0 doesn't provide any API for looking up smob classes.
     We could try allocating a fake instance and using scm_class_of,
     but it's probably not worth the trouble for the sake of a single
     development release.  */
#  error "Unsupported Guile version"
#else
  /* Guile 2.1.1 and above provides scm_smob_type_class.  */
  SCM smob_type = scm_smob_type_class (result);
#endif

  SCM smob_type_name = scm_class_name (smob_type);
  scm_define (smob_type_name, smob_type);
  scm_module_export (scm_current_module (), scm_list_1 (smob_type_name));

  return result;
}

/* Initialize a gsmob.  */

void
gdbscm_init_gsmob (gdb_smob *base)
{
  base->empty_base_class = 0;
}

/* Initialize a chained_gdb_smob.
   This is the same as gdbscm_init_gsmob except that it also sets prev,next
   to NULL.  */

void
gdbscm_init_chained_gsmob (chained_gdb_smob *base)
{
  gdbscm_init_gsmob ((gdb_smob *) base);
  base->prev = NULL;
  base->next = NULL;
}

/* Initialize an eqable_gdb_smob.
   This is the same as gdbscm_init_gsmob except that it also sets
   BASE->containing_scm to CONTAINING_SCM.  */

void
gdbscm_init_eqable_gsmob (eqable_gdb_smob *base, SCM containing_scm)
{
  gdbscm_init_gsmob ((gdb_smob *) base);
  base->containing_scm = containing_scm;
}


/* gsmob accessors */

/* Return the gsmob in SELF.
   Throws an exception if SELF is not a gsmob.  */

static SCM
gsscm_get_gsmob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (gdbscm_is_gsmob (self), self, arg_pos, func_name,
		   _("any gdb smob"));

  return self;
}

/* (gdb-object-kind gsmob) -> symbol

   Note: While one might want to name this gdb-object-class-name, it is named
   "-kind" because smobs aren't real GOOPS classes.  */

static SCM
gdbscm_gsmob_kind (SCM self)
{
  SCM smob, result;
  scm_t_bits smobnum;
  const char *name;
  char *kind;

  smob = gsscm_get_gsmob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  smobnum = SCM_SMOBNUM (smob);
  name = SCM_SMOBNAME (smobnum);
  kind = xstrprintf ("<%s>", name);
  result = scm_from_latin1_symbol (kind);
  xfree (kind);

  return result;
}


/* When underlying gdb data structures are deleted, we need to update any
   smobs with references to them.  There are several smobs that reference
   objfile-based data, so we provide helpers to manage this.  */

/* Add G_SMOB to the reference chain for OBJFILE specified by DATA_KEY.
   OBJFILE may be NULL, in which case just set prev,next to NULL.  */

void
gdbscm_add_objfile_ref (struct objfile *objfile,
			const struct objfile_data *data_key,
			chained_gdb_smob *g_smob)
{
  g_smob->prev = NULL;
  if (objfile != NULL)
    {
      g_smob->next = (chained_gdb_smob *) objfile_data (objfile, data_key);
      if (g_smob->next)
	g_smob->next->prev = g_smob;
      set_objfile_data (objfile, data_key, g_smob);
    }
  else
    g_smob->next = NULL;
}

/* Remove G_SMOB from the reference chain for OBJFILE specified
   by DATA_KEY.  OBJFILE may be NULL.  */

void
gdbscm_remove_objfile_ref (struct objfile *objfile,
			   const struct objfile_data *data_key,
			   chained_gdb_smob *g_smob)
{
  if (g_smob->prev)
    g_smob->prev->next = g_smob->next;
  else if (objfile != NULL)
    set_objfile_data (objfile, data_key, g_smob->next);
  if (g_smob->next)
    g_smob->next->prev = g_smob->prev;
}

/* Create a hash table for mapping a pointer to a gdb data structure to the
   gsmob that wraps it.  */

htab_t
gdbscm_create_eqable_gsmob_ptr_map (htab_hash hash_fn, htab_eq eq_fn)
{
  htab_t htab = htab_create_alloc (7, hash_fn, eq_fn,
				   NULL, xcalloc, xfree);

  return htab;
}

/* Return a pointer to the htab entry for the eq?-able gsmob BASE.
   If the entry is found, *SLOT is non-NULL.
   Otherwise *slot is NULL.  */

eqable_gdb_smob **
gdbscm_find_eqable_gsmob_ptr_slot (htab_t htab, eqable_gdb_smob *base)
{
  void **slot = htab_find_slot (htab, base, INSERT);

  return (eqable_gdb_smob **) slot;
}

/* Record BASE in SLOT.  SLOT must be the result of calling
   gdbscm_find_eqable_gsmob_ptr_slot on BASE (or equivalent for lookup).  */

void
gdbscm_fill_eqable_gsmob_ptr_slot (eqable_gdb_smob **slot,
				   eqable_gdb_smob *base)
{
  *slot = base;
}

/* Remove BASE from HTAB.
   BASE is a pointer to a gsmob that wraps a pointer to a GDB datum.
   This is used, for example, when an object is freed.

   It is an error to call this if PTR is not in HTAB (only because it allows
   for some consistency checking).  */

void
gdbscm_clear_eqable_gsmob_ptr_slot (htab_t htab, eqable_gdb_smob *base)
{
  void **slot = htab_find_slot (htab, base, NO_INSERT);

  gdb_assert (slot != NULL);
  htab_clear_slot (htab, slot);
}

/* Initialize the Scheme gsmobs code.  */

static const scheme_function gsmob_functions[] =
{
  /* N.B. There is a general rule of not naming symbols in gdb-guile with a
     "gdb" prefix.  This symbol does not violate this rule because it is to
     be read as "gdb-object-foo", not "gdb-foo".  */
  { "gdb-object-kind", 1, 0, 0, as_a_scm_t_subr (gdbscm_gsmob_kind),
    "\
Return the kind of the GDB object, e.g., <gdb:breakpoint>, as a symbol." },

  END_FUNCTIONS
};

void
gdbscm_initialize_smobs (void)
{
  registered_gsmobs = htab_create_alloc (10,
					 hash_scm_t_bits, eq_scm_t_bits,
					 NULL, xcalloc, xfree);

  gdbscm_define_functions (gsmob_functions, 1);
}
