/* Scheme interface to stack frames.

   Copyright (C) 2008-2016 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 "frame.h"
#include "inferior.h"
#include "objfiles.h"
#include "symfile.h"
#include "symtab.h"
#include "stack.h"
#include "user-regs.h"
#include "value.h"
#include "guile-internal.h"

/* The <gdb:frame> smob.
   The typedef for this struct is in guile-internal.h.  */

struct _frame_smob
{
  /* This always appears first.  */
  eqable_gdb_smob base;

  struct frame_id frame_id;
  struct gdbarch *gdbarch;

  /* Frames are tracked by inferior.
     We need some place to put the eq?-able hash table, and this feels as
     good a place as any.  Frames in one inferior shouldn't be considered
     equal to frames in a different inferior.  The frame becomes invalid if
     this becomes NULL (the inferior has been deleted from gdb).
     It's easier to relax restrictions than impose them after the fact.
     N.B. It is an outstanding question whether a frame survives reruns of
     the inferior.  Intuitively the answer is "No", but currently a frame
     also survives, e.g., multiple invocations of the same function from
     the same point.  Even different threads can have the same frame, e.g.,
     if a thread dies and a new thread gets the same stack.  */
  struct inferior *inferior;

  /* Marks that the FRAME_ID member actually holds the ID of the frame next
     to this, and not this frame's ID itself.  This is a hack to permit Scheme
     frame objects which represent invalid frames (i.e., the last frame_info
     in a corrupt stack).  The problem arises from the fact that this code
     relies on FRAME_ID to uniquely identify a frame, which is not always true
     for the last "frame" in a corrupt stack (it can have a null ID, or the
     same ID as the  previous frame).  Whenever get_prev_frame returns NULL, we
     record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1.  */
  int frame_id_is_next;
};

static const char frame_smob_name[] = "gdb:frame";

/* The tag Guile knows the frame smob by.  */
static scm_t_bits frame_smob_tag;

/* Keywords used in argument passing.  */
static SCM block_keyword;

static const struct inferior_data *frscm_inferior_data_key;

/* Administrivia for frame smobs.  */

/* Helper function to hash a frame_smob.  */

static hashval_t
frscm_hash_frame_smob (const void *p)
{
  const frame_smob *f_smob = (const frame_smob *) p;
  const struct frame_id *fid = &f_smob->frame_id;
  hashval_t hash = htab_hash_pointer (f_smob->inferior);

  if (fid->stack_status == FID_STACK_VALID)
    hash = iterative_hash (&fid->stack_addr, sizeof (fid->stack_addr), hash);
  if (fid->code_addr_p)
    hash = iterative_hash (&fid->code_addr, sizeof (fid->code_addr), hash);
  if (fid->special_addr_p)
    hash = iterative_hash (&fid->special_addr, sizeof (fid->special_addr),
			   hash);

  return hash;
}

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

static int
frscm_eq_frame_smob (const void *ap, const void *bp)
{
  const frame_smob *a = (const frame_smob *) ap;
  const frame_smob *b = (const frame_smob *) bp;

  return (frame_id_eq (a->frame_id, b->frame_id)
	  && a->inferior == b->inferior
	  && a->inferior != NULL);
}

/* Return the frame -> SCM mapping table.
   It is created if necessary.  */

static htab_t
frscm_inferior_frame_map (struct inferior *inferior)
{
  htab_t htab = (htab_t) inferior_data (inferior, frscm_inferior_data_key);

  if (htab == NULL)
    {
      htab = gdbscm_create_eqable_gsmob_ptr_map (frscm_hash_frame_smob,
						 frscm_eq_frame_smob);
      set_inferior_data (inferior, frscm_inferior_data_key, htab);
    }

  return htab;
}

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

static size_t
frscm_free_frame_smob (SCM self)
{
  frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);

  if (f_smob->inferior != NULL)
    {
      htab_t htab = frscm_inferior_frame_map (f_smob->inferior);

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

  /* Not necessary, done to catch bugs.  */
  f_smob->inferior = NULL;

  return 0;
}

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

static int
frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
{
  frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
  struct ui_file *strfile;

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

  strfile = mem_fileopen ();
  fprint_frame_id (strfile, f_smob->frame_id);
  std::string s = ui_file_as_string (strfile);
  gdbscm_printf (port, "%s", s.c_str ());
  ui_file_delete (strfile);

  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

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

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

static SCM
frscm_make_frame_smob (void)
{
  frame_smob *f_smob = (frame_smob *)
    scm_gc_malloc (sizeof (frame_smob), frame_smob_name);
  SCM f_scm;

  f_smob->frame_id = null_frame_id;
  f_smob->gdbarch = NULL;
  f_smob->inferior = NULL;
  f_smob->frame_id_is_next = 0;
  f_scm = scm_new_smob (frame_smob_tag, (scm_t_bits) f_smob);
  gdbscm_init_eqable_gsmob (&f_smob->base, f_scm);

  return f_scm;
}

/* Return non-zero if SCM is a <gdb:frame> object.  */

int
frscm_is_frame (SCM scm)
{
  return SCM_SMOB_PREDICATE (frame_smob_tag, scm);
}

/* (frame? object) -> boolean */

static SCM
gdbscm_frame_p (SCM scm)
{
  return scm_from_bool (frscm_is_frame (scm));
}

/* Create a new <gdb:frame> object that encapsulates FRAME.
   Returns a <gdb:exception> object if there is an error.  */

static SCM
frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior)
{
  frame_smob *f_smob, f_smob_for_lookup;
  SCM f_scm;
  htab_t htab;
  eqable_gdb_smob **slot;
  struct frame_id frame_id = null_frame_id;
  struct gdbarch *gdbarch = NULL;
  int frame_id_is_next = 0;

  /* If we've already created a gsmob for this frame, return it.
     This makes frames eq?-able.  */
  htab = frscm_inferior_frame_map (inferior);
  f_smob_for_lookup.frame_id = get_frame_id (frame);
  f_smob_for_lookup.inferior = inferior;
  slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &f_smob_for_lookup.base);
  if (*slot != NULL)
    return (*slot)->containing_scm;

  TRY
    {
      /* Try to get the previous frame, to determine if this is the last frame
	 in a corrupt stack.  If so, we need to store the frame_id of the next
	 frame and not of this one (which is possibly invalid).  */
      if (get_prev_frame (frame) == NULL
	  && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
	  && get_next_frame (frame) != NULL)
	{
	  frame_id = get_frame_id (get_next_frame (frame));
	  frame_id_is_next = 1;
	}
      else
	{
	  frame_id = get_frame_id (frame);
	  frame_id_is_next = 0;
	}
      gdbarch = get_frame_arch (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      return gdbscm_scm_from_gdb_exception (except);
    }
  END_CATCH

  f_scm = frscm_make_frame_smob ();
  f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);
  f_smob->frame_id = frame_id;
  f_smob->gdbarch = gdbarch;
  f_smob->inferior = inferior;
  f_smob->frame_id_is_next = frame_id_is_next;

  gdbscm_fill_eqable_gsmob_ptr_slot (slot, &f_smob->base);

  return f_scm;
}

/* Create a new <gdb:frame> object that encapsulates FRAME.
   A Scheme exception is thrown if there is an error.  */

static SCM
frscm_scm_from_frame_unsafe (struct frame_info *frame,
			     struct inferior *inferior)
{
  SCM f_scm = frscm_scm_from_frame (frame, inferior);

  if (gdbscm_is_exception (f_scm))
    gdbscm_throw (f_scm);

  return f_scm;
}

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

static SCM
frscm_get_frame_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (frscm_is_frame (self), self, arg_pos, func_name,
		   frame_smob_name);

  return self;
}

/* There is no gdbscm_scm_to_frame function because translating
   a frame SCM object to a struct frame_info * can throw a GDB error.
   Thus code working with frames has to handle both Scheme errors (e.g., the
   object is not a frame) and GDB errors (e.g., the frame lookup failed).

   To help keep things clear we split what would be gdbscm_scm_to_frame
   into two:

   frscm_get_frame_smob_arg_unsafe
     - throws a Scheme error if object is not a frame,
       or if the inferior is gone or is no longer current

   frscm_frame_smob_to_frame
     - may throw a gdb error if the conversion fails
     - it's not clear when it will and won't throw a GDB error,
       but for robustness' sake we assume that whenever we call out to GDB
       a GDB error may get thrown (and thus the call must be wrapped in a
       TRY_CATCH)  */

/* Returns the frame_smob for the object wrapped by FRAME_SCM.
   A Scheme error is thrown if FRAME_SCM is not a frame.  */

frame_smob *
frscm_get_frame_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM f_scm = frscm_get_frame_arg_unsafe (self, arg_pos, func_name);
  frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);

  if (f_smob->inferior == NULL)
    {
      gdbscm_invalid_object_error (func_name, arg_pos, self,
				   _("inferior"));
    }
  if (f_smob->inferior != current_inferior ())
    scm_misc_error (func_name, _("inferior has changed"), SCM_EOL);

  return f_smob;
}

/* Returns the frame_info object wrapped by F_SMOB.
   If the frame doesn't exist anymore (the frame id doesn't
   correspond to any frame in the inferior), returns NULL.
   This function calls GDB routines, so don't assume a GDB error will
   not be thrown.  */

struct frame_info *
frscm_frame_smob_to_frame (frame_smob *f_smob)
{
  struct frame_info *frame;

  frame = frame_find_by_id (f_smob->frame_id);
  if (frame == NULL)
    return NULL;

  if (f_smob->frame_id_is_next)
    frame = get_prev_frame (frame);

  return frame;
}

/* Helper function for frscm_del_inferior_frames to mark the frame
   as invalid.  */

static int
frscm_mark_frame_invalid (void **slot, void *info)
{
  frame_smob *f_smob = (frame_smob *) *slot;

  f_smob->inferior = NULL;
  return 1;
}

/* This function is called when an inferior is about to be freed.
   Invalidate the frame as further actions on the frame could result
   in bad data.  All access to the frame should be gated by
   frscm_get_frame_smob_arg_unsafe which will raise an exception on
   invalid frames.  */

static void
frscm_del_inferior_frames (struct inferior *inferior, void *datum)
{
  htab_t htab = (htab_t) datum;

  if (htab != NULL)
    {
      htab_traverse_noresize (htab, frscm_mark_frame_invalid, NULL);
      htab_delete (htab);
    }
}

/* Frame methods.  */

/* (frame-valid? <gdb:frame>) -> bool
   Returns #t if the frame corresponding to the frame_id of this
   object still exists in the inferior.  */

static SCM
gdbscm_frame_valid_p (SCM self)
{
  frame_smob *f_smob;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return scm_from_bool (frame != NULL);
}

/* (frame-name <gdb:frame>) -> string
   Returns the name of the function corresponding to this frame,
   or #f if there is no function.  */

static SCM
gdbscm_frame_name (SCM self)
{
  frame_smob *f_smob;
  char *name = NULL;
  enum language lang = language_minimal;
  struct frame_info *frame = NULL;
  SCM result;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	find_frame_funname (frame, &name, &lang, NULL);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      xfree (name);
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  if (name != NULL)
    {
      result = gdbscm_scm_from_c_string (name);
      xfree (name);
    }
  else
    result = SCM_BOOL_F;

  return result;
}

/* (frame-type <gdb:frame>) -> integer
   Returns the frame type, namely one of the gdb:*_FRAME constants.  */

static SCM
gdbscm_frame_type (SCM self)
{
  frame_smob *f_smob;
  enum frame_type type = NORMAL_FRAME;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	type = get_frame_type (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  return scm_from_int (type);
}

/* (frame-arch <gdb:frame>) -> <gdb:architecture>
   Returns the frame's architecture as a gdb:architecture object.  */

static SCM
gdbscm_frame_arch (SCM self)
{
  frame_smob *f_smob;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  return arscm_scm_from_arch (f_smob->gdbarch);
}

/* (frame-unwind-stop-reason <gdb:frame>) -> integer
   Returns one of the gdb:FRAME_UNWIND_* constants.  */

static SCM
gdbscm_frame_unwind_stop_reason (SCM self)
{
  frame_smob *f_smob;
  struct frame_info *frame = NULL;
  enum unwind_stop_reason stop_reason;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  stop_reason = get_frame_unwind_stop_reason (frame);

  return scm_from_int (stop_reason);
}

/* (frame-pc <gdb:frame>) -> integer
   Returns the frame's resume address.  */

static SCM
gdbscm_frame_pc (SCM self)
{
  frame_smob *f_smob;
  CORE_ADDR pc = 0;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	pc = get_frame_pc (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  return gdbscm_scm_from_ulongest (pc);
}

/* (frame-block <gdb:frame>) -> <gdb:block>
   Returns the frame's code block, or #f if one cannot be found.  */

static SCM
gdbscm_frame_block (SCM self)
{
  frame_smob *f_smob;
  const struct block *block = NULL, *fn_block;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	block = get_frame_block (frame, NULL);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  for (fn_block = block;
       fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
       fn_block = BLOCK_SUPERBLOCK (fn_block))
    continue;

  if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
    {
      scm_misc_error (FUNC_NAME, _("cannot find block for frame"),
		      scm_list_1 (self));
    }

  if (block != NULL)
    {
      return bkscm_scm_from_block
	(block, symbol_objfile (BLOCK_FUNCTION (fn_block)));
    }

  return SCM_BOOL_F;
}

/* (frame-function <gdb:frame>) -> <gdb:symbol>
   Returns the symbol for the function corresponding to this frame,
   or #f if there isn't one.  */

static SCM
gdbscm_frame_function (SCM self)
{
  frame_smob *f_smob;
  struct symbol *sym = NULL;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	sym = find_pc_function (get_frame_address_in_block (frame));
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

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

  return SCM_BOOL_F;
}

/* (frame-older <gdb:frame>) -> <gdb:frame>
   Returns the frame immediately older (outer) to this frame,
   or #f if there isn't one.  */

static SCM
gdbscm_frame_older (SCM self)
{
  frame_smob *f_smob;
  struct frame_info *prev = NULL;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	prev = get_prev_frame (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  if (prev != NULL)
    return frscm_scm_from_frame_unsafe (prev, f_smob->inferior);

  return SCM_BOOL_F;
}

/* (frame-newer <gdb:frame>) -> <gdb:frame>
   Returns the frame immediately newer (inner) to this frame,
   or #f if there isn't one.  */

static SCM
gdbscm_frame_newer (SCM self)
{
  frame_smob *f_smob;
  struct frame_info *next = NULL;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	next = get_next_frame (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  if (next != NULL)
    return frscm_scm_from_frame_unsafe (next, f_smob->inferior);

  return SCM_BOOL_F;
}

/* (frame-sal <gdb:frame>) -> <gdb:sal>
   Returns the frame's symtab and line.  */

static SCM
gdbscm_frame_sal (SCM self)
{
  frame_smob *f_smob;
  struct symtab_and_line sal;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	find_frame_sal (frame, &sal);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  return stscm_scm_from_sal (sal);
}

/* (frame-read-register <gdb:frame> string) -> <gdb:value>
   The register argument must be a string.  */

static SCM
gdbscm_frame_read_register (SCM self, SCM register_scm)
{
  char *register_str;
  struct value *value = NULL;
  struct frame_info *frame = NULL;
  struct cleanup *cleanup;
  frame_smob *f_smob;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s",
			      register_scm, &register_str);
  cleanup = make_cleanup (xfree, register_str);

  TRY
    {
      int regnum;

      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame)
	{
	  regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
						register_str,
						strlen (register_str));
	  if (regnum >= 0)
	    value = value_of_register (regnum, frame);
	}
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  do_cleanups (cleanup);

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  if (value == NULL)
    {
      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, register_scm,
				 _("unknown register"));
    }

  return vlscm_scm_from_value (value);
}

/* (frame-read-var <gdb:frame> <gdb:symbol>) -> <gdb:value>
   (frame-read-var <gdb:frame> string [#:block <gdb:block>]) -> <gdb:value>
   If the optional block argument is provided start the search from that block,
   otherwise search from the frame's current block (determined by examining
   the resume address of the frame).  The variable argument must be a string
   or an instance of a <gdb:symbol>.  The block argument must be an instance of
   <gdb:block>.  */

static SCM
gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
{
  SCM keywords[] = { block_keyword, SCM_BOOL_F };
  int rc;
  frame_smob *f_smob;
  int block_arg_pos = -1;
  SCM block_scm = SCM_UNDEFINED;
  struct frame_info *frame = NULL;
  struct symbol *var = NULL;
  const struct block *block = NULL;
  struct value *value = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG3, keywords, "#O",
			      rest, &block_arg_pos, &block_scm);

  if (syscm_is_symbol (symbol_scm))
    {
      var = syscm_get_valid_symbol_arg_unsafe (symbol_scm, SCM_ARG2,
					       FUNC_NAME);
      SCM_ASSERT (SCM_UNBNDP (block_scm), block_scm, SCM_ARG3, FUNC_NAME);
    }
  else if (scm_is_string (symbol_scm))
    {
      char *var_name;
      const struct block *block = NULL;
      struct cleanup *cleanup;
      struct gdb_exception except = exception_none;

      if (! SCM_UNBNDP (block_scm))
	{
	  SCM except_scm;

	  gdb_assert (block_arg_pos > 0);
	  block = bkscm_scm_to_block (block_scm, block_arg_pos, FUNC_NAME,
				      &except_scm);
	  if (block == NULL)
	    gdbscm_throw (except_scm);
	}

      var_name = gdbscm_scm_to_c_string (symbol_scm);
      cleanup = make_cleanup (xfree, var_name);
      /* N.B. Between here and the call to do_cleanups, don't do anything
	 to cause a Scheme exception without performing the cleanup.  */

      TRY
	{
	  struct block_symbol lookup_sym;

	  if (block == NULL)
	    block = get_frame_block (frame, NULL);
	  lookup_sym = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
	  var = lookup_sym.symbol;
	  block = lookup_sym.block;
	}
      CATCH (ex, RETURN_MASK_ALL)
	{
	  except = ex;
	}
      END_CATCH

      do_cleanups (cleanup);
      GDBSCM_HANDLE_GDB_EXCEPTION (except);

      if (var == NULL)
	{
	  do_cleanups (cleanup);
	  gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm,
				     _("variable not found"));
	}

      do_cleanups (cleanup);
    }
  else
    {
      /* Use SCM_ASSERT_TYPE for more consistent error messages.  */
      SCM_ASSERT_TYPE (0, symbol_scm, SCM_ARG1, FUNC_NAME,
		       _("gdb:symbol or string"));
    }

  TRY
    {
      value = read_var_value (var, block, frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return vlscm_scm_from_value (value);
}

/* (frame-select <gdb:frame>) -> unspecified
   Select this frame.  */

static SCM
gdbscm_frame_select (SCM self)
{
  frame_smob *f_smob;
  struct frame_info *frame = NULL;

  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  TRY
    {
      frame = frscm_frame_smob_to_frame (f_smob);
      if (frame != NULL)
	select_frame (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  if (frame == NULL)
    {
      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
				   _("<gdb:frame>"));
    }

  return SCM_UNSPECIFIED;
}

/* (newest-frame) -> <gdb:frame>
   Returns the newest frame.  */

static SCM
gdbscm_newest_frame (void)
{
  struct frame_info *frame = NULL;

  TRY
    {
      frame = get_current_frame ();
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return frscm_scm_from_frame_unsafe (frame, current_inferior ());
}

/* (selected-frame) -> <gdb:frame>
   Returns the selected frame.  */

static SCM
gdbscm_selected_frame (void)
{
  struct frame_info *frame = NULL;

  TRY
    {
      frame = get_selected_frame (_("No frame is currently selected"));
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return frscm_scm_from_frame_unsafe (frame, current_inferior ());
}

/* (unwind-stop-reason-string integer) -> string
   Return a string explaining the unwind stop reason.  */

static SCM
gdbscm_unwind_stop_reason_string (SCM reason_scm)
{
  int reason;
  const char *str;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "i",
			      reason_scm, &reason);

  if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
    scm_out_of_range (FUNC_NAME, reason_scm);

  str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
  return gdbscm_scm_from_c_string (str);
}

/* Initialize the Scheme frame support.  */

static const scheme_integer_constant frame_integer_constants[] =
{
#define ENTRY(X) { #X, X }

  ENTRY (NORMAL_FRAME),
  ENTRY (DUMMY_FRAME),
  ENTRY (INLINE_FRAME),
  ENTRY (TAILCALL_FRAME),
  ENTRY (SIGTRAMP_FRAME),
  ENTRY (ARCH_FRAME),
  ENTRY (SENTINEL_FRAME),

#undef ENTRY

#define SET(name, description) \
  { "FRAME_" #name, name },
#include "unwind_stop_reasons.def"
#undef SET

  END_INTEGER_CONSTANTS
};

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

  { "frame-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_valid_p),
    "\
Return #t if the object is a valid <gdb:frame> object.\n\
Frames become invalid when the inferior returns to its caller." },

  { "frame-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_name),
    "\
Return the name of the function corresponding to this frame,\n\
or #f if there is no function." },

  { "frame-arch", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_arch),
    "\
Return the frame's architecture as a <gdb:arch> object." },

  { "frame-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_type),
    "\
Return the frame type, namely one of the gdb:*_FRAME constants." },

  { "frame-unwind-stop-reason", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_frame_unwind_stop_reason),
    "\
Return one of the gdb:FRAME_UNWIND_* constants explaining why\n\
it's not possible to find frames older than this." },

  { "frame-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_pc),
    "\
Return the frame's resume address." },

  { "frame-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_block),
    "\
Return the frame's code block, or #f if one cannot be found." },

  { "frame-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_function),
    "\
Return the <gdb:symbol> for the function corresponding to this frame,\n\
or #f if there isn't one." },

  { "frame-older", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_older),
    "\
Return the frame immediately older (outer) to this frame,\n\
or #f if there isn't one." },

  { "frame-newer", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_newer),
    "\
Return the frame immediately newer (inner) to this frame,\n\
or #f if there isn't one." },

  { "frame-sal", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_sal),
    "\
Return the frame's symtab-and-line <gdb:sal> object." },

  { "frame-read-var", 2, 0, 1, as_a_scm_t_subr (gdbscm_frame_read_var),
    "\
Return the value of the symbol in the frame.\n\
\n\
  Arguments: <gdb:frame> <gdb:symbol>\n\
         Or: <gdb:frame> string [#:block <gdb:block>]" },

  { "frame-read-register", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_frame_read_register),
    "\
Return the value of the register in the frame.\n\
\n\
  Arguments: <gdb:frame> string" },

  { "frame-select", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_select),
    "\
Select this frame." },

  { "newest-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_newest_frame),
    "\
Return the newest frame." },

  { "selected-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_selected_frame),
    "\
Return the selected frame." },

  { "unwind-stop-reason-string", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_unwind_stop_reason_string),
    "\
Return a string explaining the unwind stop reason.\n\
\n\
  Arguments: integer (the result of frame-unwind-stop-reason)" },

  END_FUNCTIONS
};

void
gdbscm_initialize_frames (void)
{
  frame_smob_tag
    = gdbscm_make_smob_type (frame_smob_name, sizeof (frame_smob));
  scm_set_smob_free (frame_smob_tag, frscm_free_frame_smob);
  scm_set_smob_print (frame_smob_tag, frscm_print_frame_smob);

  gdbscm_define_integer_constants (frame_integer_constants, 1);
  gdbscm_define_functions (frame_functions, 1);

  block_keyword = scm_from_latin1_keyword ("block");

  /* Register an inferior "free" callback so we can properly
     invalidate frames when an inferior file is about to be deleted.  */
  frscm_inferior_data_key
    = register_inferior_data_with_cleanup (NULL, frscm_del_inferior_frames);
}
