/* Scheme interface to values.

   Copyright (C) 2008-2023 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 "top.h"		/* For quit_force().  */
#include "arch-utils.h"
#include "charset.h"
#include "cp-abi.h"
#include "target-float.h"
#include "infcall.h"
#include "symtab.h" /* Needed by language.h.  */
#include "language.h"
#include "valprint.h"
#include "value.h"
#include "guile-internal.h"

/* The <gdb:value> smob.  */

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

  /* Doubly linked list of values in values_in_scheme.
     IWBN to use a chained_gdb_smob instead, which is doable, it just requires
     a bit more casting than normal.  */
  value_smob *next;
  value_smob *prev;

  struct value *value;

  /* These are cached here to avoid making multiple copies of them.
     Plus computing the dynamic_type can be a bit expensive.
     We use #f to indicate that the value doesn't exist (e.g. value doesn't
     have an address), so we need another value to indicate that we haven't
     computed the value yet.  For this we use SCM_UNDEFINED.  */
  SCM address;
  SCM type;
  SCM dynamic_type;
};

static const char value_smob_name[] = "gdb:value";

/* The tag Guile knows the value smob by.  */
static scm_t_bits value_smob_tag;

/* List of all values which are currently exposed to Scheme. It is
   maintained so that when an objfile is discarded, preserve_values
   can copy the values' types if needed.  */
static value_smob *values_in_scheme;

/* Keywords used by Scheme procedures in this file.  */
static SCM type_keyword;
static SCM encoding_keyword;
static SCM errors_keyword;
static SCM length_keyword;

/* Possible #:errors values.  */
static SCM error_symbol;
static SCM escape_symbol;
static SCM substitute_symbol;

/* Administrivia for value smobs.  */

/* Iterate over all the <gdb:value> objects, calling preserve_one_value on
   each.
   This is the extension_language_ops.preserve_values "method".  */

void
gdbscm_preserve_values (const struct extension_language_defn *extlang,
			struct objfile *objfile, htab_t copied_types)
{
  value_smob *iter;

  for (iter = values_in_scheme; iter; iter = iter->next)
    iter->value->preserve (objfile, copied_types);
}

/* Helper to add a value_smob to the global list.  */

static void
vlscm_remember_scheme_value (value_smob *v_smob)
{
  v_smob->next = values_in_scheme;
  if (v_smob->next)
    v_smob->next->prev = v_smob;
  v_smob->prev = NULL;
  values_in_scheme = v_smob;
}

/* Helper to remove a value_smob from the global list.  */

static void
vlscm_forget_value_smob (value_smob *v_smob)
{
  /* Remove SELF from the global list.  */
  if (v_smob->prev)
    v_smob->prev->next = v_smob->next;
  else
    {
      gdb_assert (values_in_scheme == v_smob);
      values_in_scheme = v_smob->next;
    }
  if (v_smob->next)
    v_smob->next->prev = v_smob->prev;
}

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

static size_t
vlscm_free_value_smob (SCM self)
{
  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (self);

  vlscm_forget_value_smob (v_smob);
  v_smob->value->decref ();

  return 0;
}

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

static int
vlscm_print_value_smob (SCM self, SCM port, scm_print_state *pstate)
{
  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (self);
  struct value_print_options opts;

  if (pstate->writingp)
    gdbscm_printf (port, "#<%s ", value_smob_name);

  get_user_print_options (&opts);
  opts.deref_ref = false;

  /* pstate->writingp = zero if invoked by display/~A, and nonzero if
     invoked by write/~S.  What to do here may need to evolve.
     IWBN if we could pass an argument to format that would we could use
     instead of writingp.  */
  opts.raw = !!pstate->writingp;

  gdbscm_gdb_exception exc {};
  try
    {
      string_file stb;

      common_val_print (v_smob->value, &stb, 0, &opts, current_language);
      scm_puts (stb.c_str (), port);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  if (pstate->writingp)
    scm_puts (">", port);

  scm_remember_upto_here_1 (self);

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

/* The smob "equalp" function for <gdb:value>.  */

static SCM
vlscm_equal_p_value_smob (SCM v1, SCM v2)
{
  const value_smob *v1_smob = (value_smob *) SCM_SMOB_DATA (v1);
  const value_smob *v2_smob = (value_smob *) SCM_SMOB_DATA (v2);
  int result = 0;

  gdbscm_gdb_exception exc {};
  try
    {
      result = value_equal (v1_smob->value, v2_smob->value);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return scm_from_bool (result);
}

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

static SCM
vlscm_make_value_smob (void)
{
  value_smob *v_smob = (value_smob *)
    scm_gc_malloc (sizeof (value_smob), value_smob_name);
  SCM v_scm;

  /* These must be filled in by the caller.  */
  v_smob->value = NULL;
  v_smob->prev = NULL;
  v_smob->next = NULL;

  /* These are lazily computed.  */
  v_smob->address = SCM_UNDEFINED;
  v_smob->type = SCM_UNDEFINED;
  v_smob->dynamic_type = SCM_UNDEFINED;

  v_scm = scm_new_smob (value_smob_tag, (scm_t_bits) v_smob);
  gdbscm_init_gsmob (&v_smob->base);

  return v_scm;
}

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

int
vlscm_is_value (SCM scm)
{
  return SCM_SMOB_PREDICATE (value_smob_tag, scm);
}

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

static SCM
gdbscm_value_p (SCM scm)
{
  return scm_from_bool (vlscm_is_value (scm));
}

/* Create a new <gdb:value> object that encapsulates VALUE.
   The value is released from the all_values chain so its lifetime is not
   bound to the execution of a command.  */

SCM
vlscm_scm_from_value (struct value *value)
{
  /* N.B. It's important to not cause any side-effects until we know the
     conversion worked.  */
  SCM v_scm = vlscm_make_value_smob ();
  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (v_scm);

  v_smob->value = release_value (value).release ();
  vlscm_remember_scheme_value (v_smob);

  return v_scm;
}

/* Create a new <gdb:value> object that encapsulates VALUE.
   The value is not released from the all_values chain.  */

SCM
vlscm_scm_from_value_no_release (struct value *value)
{
  /* N.B. It's important to not cause any side-effects until we know the
     conversion worked.  */
  SCM v_scm = vlscm_make_value_smob ();
  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (v_scm);

  value->incref ();
  v_smob->value = value;
  vlscm_remember_scheme_value (v_smob);

  return v_scm;
}

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

static SCM
vlscm_get_value_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (vlscm_is_value (self), self, arg_pos, func_name,
		   value_smob_name);

  return self;
}

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

static value_smob *
vlscm_get_value_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM v_scm = vlscm_get_value_arg_unsafe (self, arg_pos, func_name);
  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (v_scm);

  return v_smob;
}

/* Return the value field of V_SCM, an object of type <gdb:value>.
   This exists so that we don't have to export the struct's contents.  */

struct value *
vlscm_scm_to_value (SCM v_scm)
{
  value_smob *v_smob;

  gdb_assert (vlscm_is_value (v_scm));
  v_smob = (value_smob *) SCM_SMOB_DATA (v_scm);
  return v_smob->value;
}

/* Value methods.  */

/* (make-value x [#:type type]) -> <gdb:value> */

static SCM
gdbscm_make_value (SCM x, SCM rest)
{
  const SCM keywords[] = { type_keyword, SCM_BOOL_F };

  int type_arg_pos = -1;
  SCM type_scm = SCM_UNDEFINED;
  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "#O", rest,
			      &type_arg_pos, &type_scm);

  struct type *type = NULL;
  if (type_arg_pos > 0)
    {
      type_smob *t_smob = tyscm_get_type_smob_arg_unsafe (type_scm,
							  type_arg_pos,
							  FUNC_NAME);
      type = tyscm_type_smob_type (t_smob);
    }

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      SCM except_scm;
      struct value *value
	= vlscm_convert_typed_value_from_scheme (FUNC_NAME, SCM_ARG1, x,
						 type_arg_pos, type_scm, type,
						 &except_scm,
						 get_current_arch (),
						 current_language);
      if (value == NULL)
	return except_scm;

      return vlscm_scm_from_value (value);
    });
}

/* (make-lazy-value <gdb:type> address) -> <gdb:value> */

static SCM
gdbscm_make_lazy_value (SCM type_scm, SCM address_scm)
{
  type_smob *t_smob = tyscm_get_type_smob_arg_unsafe (type_scm,
						      SCM_ARG1, FUNC_NAME);
  struct type *type = tyscm_type_smob_type (t_smob);

  ULONGEST address;
  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "U",
			      address_scm, &address);

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      struct value *value = value_from_contents_and_address (type, NULL,
							     address);
      return vlscm_scm_from_value (value);
    });
}

/* (value-optimized-out? <gdb:value>) -> boolean */

static SCM
gdbscm_value_optimized_out_p (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return gdbscm_wrap ([=]
    {
      return scm_from_bool (v_smob->value->optimized_out ());
    });
}

/* (value-address <gdb:value>) -> integer
   Returns #f if the value doesn't have one.  */

static SCM
gdbscm_value_address (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  return gdbscm_wrap ([=]
    {
      if (SCM_UNBNDP (v_smob->address))
	{
	  scoped_value_mark free_values;

	  SCM address = SCM_BOOL_F;

	  try
	    {
	      address = vlscm_scm_from_value (value_addr (value));
	    }
	  catch (const gdb_exception_forced_quit &except)
	    {
	      quit_force (NULL, 0);
	    }
	  catch (const gdb_exception &except)
	    {
	    }

	  if (gdbscm_is_exception (address))
	    return address;

	  v_smob->address = address;
	}

      return v_smob->address;
    });
}

/* (value-dereference <gdb:value>) -> <gdb:value>
   Given a value of a pointer type, apply the C unary * operator to it.  */

static SCM
gdbscm_value_dereference (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      struct value *res_val = value_ind (v_smob->value);
      return vlscm_scm_from_value (res_val);
    });
}

/* (value-referenced-value <gdb:value>) -> <gdb:value>
   Given a value of a reference type, return the value referenced.
   The difference between this function and gdbscm_value_dereference is that
   the latter applies * unary operator to a value, which need not always
   result in the value referenced.
   For example, for a value which is a reference to an 'int' pointer ('int *'),
   gdbscm_value_dereference will result in a value of type 'int' while
   gdbscm_value_referenced_value will result in a value of type 'int *'.  */

static SCM
gdbscm_value_referenced_value (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      struct value *res_val;

      switch (check_typedef (value->type ())->code ())
	{
	case TYPE_CODE_PTR:
	  res_val = value_ind (value);
	  break;
	case TYPE_CODE_REF:
	case TYPE_CODE_RVALUE_REF:
	  res_val = coerce_ref (value);
	  break;
	default:
	  error (_("Trying to get the referenced value from a value which is"
		   " neither a pointer nor a reference"));
	}

      return vlscm_scm_from_value (res_val);
    });
}

static SCM
gdbscm_reference_value (SCM self, enum type_code refcode)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      struct value *res_val = value_ref (value, refcode);
      return vlscm_scm_from_value (res_val);
    });
}

/* (value-reference-value <gdb:value>) -> <gdb:value> */

static SCM
gdbscm_value_reference_value (SCM self)
{
  return gdbscm_reference_value (self, TYPE_CODE_REF);
}

/* (value-rvalue-reference-value <gdb:value>) -> <gdb:value> */

static SCM
gdbscm_value_rvalue_reference_value (SCM self)
{
  return gdbscm_reference_value (self, TYPE_CODE_RVALUE_REF);
}

/* (value-const-value <gdb:value>) -> <gdb:value> */

static SCM
gdbscm_value_const_value (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      struct value *res_val = make_cv_value (1, 0, value);
      return vlscm_scm_from_value (res_val);
    });
}

/* (value-type <gdb:value>) -> <gdb:type> */

static SCM
gdbscm_value_type (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  if (SCM_UNBNDP (v_smob->type))
    v_smob->type = tyscm_scm_from_type (value->type ());

  return v_smob->type;
}

/* (value-dynamic-type <gdb:value>) -> <gdb:type> */

static SCM
gdbscm_value_dynamic_type (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct type *type = NULL;

  if (! SCM_UNBNDP (v_smob->dynamic_type))
    return v_smob->dynamic_type;

  gdbscm_gdb_exception exc {};
  try
    {
      scoped_value_mark free_values;

      type = value->type ();
      type = check_typedef (type);

      if (((type->code () == TYPE_CODE_PTR)
	   || (type->code () == TYPE_CODE_REF))
	  && (type->target_type ()->code () == TYPE_CODE_STRUCT))
	{
	  struct value *target;
	  int was_pointer = type->code () == TYPE_CODE_PTR;

	  if (was_pointer)
	    target = value_ind (value);
	  else
	    target = coerce_ref (value);
	  type = value_rtti_type (target, NULL, NULL, NULL);

	  if (type)
	    {
	      if (was_pointer)
		type = lookup_pointer_type (type);
	      else
		type = lookup_lvalue_reference_type (type);
	    }
	}
      else if (type->code () == TYPE_CODE_STRUCT)
	type = value_rtti_type (value, NULL, NULL, NULL);
      else
	{
	  /* Re-use object's static type.  */
	  type = NULL;
	}
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  if (type == NULL)
    v_smob->dynamic_type = gdbscm_value_type (self);
  else
    v_smob->dynamic_type = tyscm_scm_from_type (type);

  return v_smob->dynamic_type;
}

/* A helper function that implements the various cast operators.  */

static SCM
vlscm_do_cast (SCM self, SCM type_scm, enum exp_opcode op,
	       const char *func_name)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (type_scm, SCM_ARG2, FUNC_NAME);
  struct type *type = tyscm_type_smob_type (t_smob);

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      struct value *res_val;
      if (op == UNOP_DYNAMIC_CAST)
	res_val = value_dynamic_cast (type, value);
      else if (op == UNOP_REINTERPRET_CAST)
	res_val = value_reinterpret_cast (type, value);
      else
	{
	  gdb_assert (op == UNOP_CAST);
	  res_val = value_cast (type, value);
	}

      return vlscm_scm_from_value (res_val);
    });
}

/* (value-cast <gdb:value> <gdb:type>) -> <gdb:value> */

static SCM
gdbscm_value_cast (SCM self, SCM new_type)
{
  return vlscm_do_cast (self, new_type, UNOP_CAST, FUNC_NAME);
}

/* (value-dynamic-cast <gdb:value> <gdb:type>) -> <gdb:value> */

static SCM
gdbscm_value_dynamic_cast (SCM self, SCM new_type)
{
  return vlscm_do_cast (self, new_type, UNOP_DYNAMIC_CAST, FUNC_NAME);
}

/* (value-reinterpret-cast <gdb:value> <gdb:type>) -> <gdb:value> */

static SCM
gdbscm_value_reinterpret_cast (SCM self, SCM new_type)
{
  return vlscm_do_cast (self, new_type, UNOP_REINTERPRET_CAST, FUNC_NAME);
}

/* (value-field <gdb:value> string) -> <gdb:value>
   Given string name of an element inside structure, return its <gdb:value>
   object.  */

static SCM
gdbscm_value_field (SCM self, SCM field_scm)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
		   _("string"));

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      gdb::unique_xmalloc_ptr<char> field = gdbscm_scm_to_c_string (field_scm);

      struct value *tmp = v_smob->value;

      struct value *res_val = value_struct_elt (&tmp, {}, field.get (), NULL,
						"struct/class/union");

      return vlscm_scm_from_value (res_val);
    });
}

/* (value-subscript <gdb:value> integer|<gdb:value>) -> <gdb:value>
   Return the specified value in an array.  */

static SCM
gdbscm_value_subscript (SCM self, SCM index_scm)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct type *type = value->type ();

  SCM_ASSERT (type != NULL, self, SCM_ARG2, FUNC_NAME);

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      SCM except_scm;
      struct value *index
	= vlscm_convert_value_from_scheme (FUNC_NAME, SCM_ARG2, index_scm,
					   &except_scm,
					   type->arch (),
					   current_language);
      if (index == NULL)
	return except_scm;

      /* Assume we are attempting an array access, and let the value code
	 throw an exception if the index has an invalid type.
	 Check the value's type is something that can be accessed via
	 a subscript.  */
      struct value *tmp = coerce_ref (value);
      struct type *tmp_type = check_typedef (tmp->type ());
      if (tmp_type->code () != TYPE_CODE_ARRAY
	  && tmp_type->code () != TYPE_CODE_PTR)
	error (_("Cannot subscript requested type"));

      struct value *res_val = value_subscript (tmp, value_as_long (index));
      return vlscm_scm_from_value (res_val);
    });
}

/* (value-call <gdb:value> arg-list) -> <gdb:value>
   Perform an inferior function call on the value.  */

static SCM
gdbscm_value_call (SCM self, SCM args)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *function = v_smob->value;
  struct type *ftype = NULL;
  long args_count;
  struct value **vargs = NULL;

  gdbscm_gdb_exception exc {};
  try
    {
      ftype = check_typedef (function->type ());
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  SCM_ASSERT_TYPE (ftype->code () == TYPE_CODE_FUNC, self,
		   SCM_ARG1, FUNC_NAME,
		   _("function (value of TYPE_CODE_FUNC)"));

  SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (args)), args,
		   SCM_ARG2, FUNC_NAME, _("list"));

  args_count = scm_ilength (args);
  if (args_count > 0)
    {
      struct gdbarch *gdbarch = get_current_arch ();
      const struct language_defn *language = current_language;
      SCM except_scm;
      long i;

      vargs = XALLOCAVEC (struct value *, args_count);
      for (i = 0; i < args_count; i++)
	{
	  SCM arg = scm_car (args);

	  vargs[i] = vlscm_convert_value_from_scheme (FUNC_NAME,
						      GDBSCM_ARG_NONE, arg,
						      &except_scm,
						      gdbarch, language);
	  if (vargs[i] == NULL)
	    gdbscm_throw (except_scm);

	  args = scm_cdr (args);
	}
      gdb_assert (gdbscm_is_true (scm_null_p (args)));
    }

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;

      auto av = gdb::make_array_view (vargs, args_count);
      value *return_value = call_function_by_hand (function, NULL, av);
      return vlscm_scm_from_value (return_value);
    });
}

/* (value->bytevector <gdb:value>) -> bytevector */

static SCM
gdbscm_value_to_bytevector (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct type *type;
  size_t length = 0;
  const gdb_byte *contents = NULL;
  SCM bv;

  type = value->type ();

  gdbscm_gdb_exception exc {};
  try
    {
      type = check_typedef (type);
      length = type->length ();
      contents = value->contents ().data ();
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  bv = scm_c_make_bytevector (length);
  memcpy (SCM_BYTEVECTOR_CONTENTS (bv), contents, length);

  return bv;
}

/* Helper function to determine if a type is "int-like".  */

static int
is_intlike (struct type *type, int ptr_ok)
{
  return (type->code () == TYPE_CODE_INT
	  || type->code () == TYPE_CODE_ENUM
	  || type->code () == TYPE_CODE_BOOL
	  || type->code () == TYPE_CODE_CHAR
	  || (ptr_ok && type->code () == TYPE_CODE_PTR));
}

/* (value->bool <gdb:value>) -> boolean
   Throws an error if the value is not integer-like.  */

static SCM
gdbscm_value_to_bool (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct type *type;
  LONGEST l = 0;

  type = value->type ();

  gdbscm_gdb_exception exc {};
  try
    {
      type = check_typedef (type);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  SCM_ASSERT_TYPE (is_intlike (type, 1), self, SCM_ARG1, FUNC_NAME,
		   _("integer-like gdb value"));

  try
    {
      if (type->code () == TYPE_CODE_PTR)
	l = value_as_address (value);
      else
	l = value_as_long (value);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return scm_from_bool (l != 0);
}

/* (value->integer <gdb:value>) -> integer
   Throws an error if the value is not integer-like.  */

static SCM
gdbscm_value_to_integer (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct type *type;
  LONGEST l = 0;

  type = value->type ();

  gdbscm_gdb_exception exc {};
  try
    {
      type = check_typedef (type);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  SCM_ASSERT_TYPE (is_intlike (type, 1), self, SCM_ARG1, FUNC_NAME,
		   _("integer-like gdb value"));

  try
    {
      if (type->code () == TYPE_CODE_PTR)
	l = value_as_address (value);
      else
	l = value_as_long (value);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  if (type->is_unsigned ())
    return gdbscm_scm_from_ulongest (l);
  else
    return gdbscm_scm_from_longest (l);
}

/* (value->real <gdb:value>) -> real
   Throws an error if the value is not a number.  */

static SCM
gdbscm_value_to_real (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct type *type;
  double d = 0;
  struct value *check = nullptr;

  type = value->type ();

  gdbscm_gdb_exception exc {};
  try
    {
      type = check_typedef (type);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  SCM_ASSERT_TYPE (is_intlike (type, 0) || type->code () == TYPE_CODE_FLT,
		   self, SCM_ARG1, FUNC_NAME, _("number"));

  try
    {
      if (is_floating_value (value))
	{
	  d = target_float_to_host_double (value->contents ().data (),
					   type);
	  check = value_from_host_double (type, d);
	}
      else if (type->is_unsigned ())
	{
	  d = (ULONGEST) value_as_long (value);
	  check = value_from_ulongest (type, (ULONGEST) d);
	}
      else
	{
	  d = value_as_long (value);
	  check = value_from_longest (type, (LONGEST) d);
	}
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  /* TODO: Is there a better way to check if the value fits?  */
  if (!value_equal (value, check))
    gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
			       _("number can't be converted to a double"));

  return scm_from_double (d);
}

/* (value->string <gdb:value>
       [#:encoding encoding]
       [#:errors #f | 'error | 'substitute]
       [#:length length])
     -> string
   Return Unicode string with value's contents, which must be a string.

   If ENCODING is not given, the string is assumed to be encoded in
   the target's charset.

   ERRORS is one of #f, 'error or 'substitute.
   An error setting of #f means use the default, which is Guile's
   %default-port-conversion-strategy when using Guile >= 2.0.6, or 'error if
   using an earlier version of Guile.  Earlier versions do not properly
   support obtaining the default port conversion strategy.
   If the default is not one of 'error or 'substitute, 'substitute is used.
   An error setting of "error" causes an exception to be thrown if there's
   a decoding error.  An error setting of "substitute" causes invalid
   characters to be replaced with "?".

   If LENGTH is provided, only fetch string to the length provided.
   LENGTH must be a Scheme integer, it can't be a <gdb:value> integer.  */

static SCM
gdbscm_value_to_string (SCM self, SCM rest)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  const SCM keywords[] = {
    encoding_keyword, errors_keyword, length_keyword, SCM_BOOL_F
  };
  int encoding_arg_pos = -1, errors_arg_pos = -1, length_arg_pos = -1;
  char *encoding = NULL;
  SCM errors = SCM_BOOL_F;
  /* Avoid an uninitialized warning from gcc.  */
  gdb_byte *buffer_contents = nullptr;
  int length = -1;
  const char *la_encoding = NULL;
  struct type *char_type = NULL;
  SCM result;

  /* The sequencing here, as everywhere else, is important.
     We can't have existing cleanups when a Scheme exception is thrown.  */

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "#sOi", rest,
			      &encoding_arg_pos, &encoding,
			      &errors_arg_pos, &errors,
			      &length_arg_pos, &length);

  if (errors_arg_pos > 0
      && errors != SCM_BOOL_F
      && !scm_is_eq (errors, error_symbol)
      && !scm_is_eq (errors, substitute_symbol))
    {
      SCM excp
	= gdbscm_make_out_of_range_error (FUNC_NAME, errors_arg_pos, errors,
					  _("invalid error kind"));

      xfree (encoding);
      gdbscm_throw (excp);
    }
  if (errors == SCM_BOOL_F)
    {
      /* N.B. scm_port_conversion_strategy in Guile versions prior to 2.0.6
	 will throw a Scheme error when passed #f.  */
      if (gdbscm_guile_version_is_at_least (2, 0, 6))
	errors = scm_port_conversion_strategy (SCM_BOOL_F);
      else
	errors = error_symbol;
    }
  /* We don't assume anything about the result of scm_port_conversion_strategy.
     From this point on, if errors is not 'errors, use 'substitute.  */

  gdbscm_gdb_exception exc {};
  try
    {
      gdb::unique_xmalloc_ptr<gdb_byte> buffer;
      c_get_string (value, &buffer, &length, &char_type, &la_encoding);
      buffer_contents = buffer.release ();
    }
  catch (const gdb_exception &except)
    {
      xfree (encoding);
      exc = unpack (except);
    }
  GDBSCM_HANDLE_GDB_EXCEPTION (exc);

  /* If errors is "error", scm_from_stringn may throw a Scheme exception.
     Make sure we don't leak.  This is done via scm_dynwind_begin, et.al.  */

  scm_dynwind_begin ((scm_t_dynwind_flags) 0);

  gdbscm_dynwind_xfree (encoding);
  gdbscm_dynwind_xfree (buffer_contents);

  result = scm_from_stringn ((const char *) buffer_contents,
			     length * char_type->length (),
			     (encoding != NULL && *encoding != '\0'
			      ? encoding
			      : la_encoding),
			     scm_is_eq (errors, error_symbol)
			     ? SCM_FAILED_CONVERSION_ERROR
			     : SCM_FAILED_CONVERSION_QUESTION_MARK);

  scm_dynwind_end ();

  return result;
}

/* (value->lazy-string <gdb:value> [#:encoding encoding] [#:length length])
     -> <gdb:lazy-string>
   Return a Scheme object representing a lazy_string_object type.
   A lazy string is a pointer to a string with an optional encoding and length.
   If ENCODING is not given, the target's charset is used.
   If LENGTH is provided then the length parameter is set to LENGTH.
   Otherwise if the value is an array of known length then the array's length
   is used.  Otherwise the length will be set to -1 (meaning first null of
   appropriate with).
   LENGTH must be a Scheme integer, it can't be a <gdb:value> integer.  */

static SCM
gdbscm_value_to_lazy_string (SCM self, SCM rest)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  const SCM keywords[] = { encoding_keyword, length_keyword, SCM_BOOL_F };
  int encoding_arg_pos = -1, length_arg_pos = -1;
  char *encoding = NULL;
  int length = -1;
  SCM result = SCM_BOOL_F; /* -Wall */
  gdbscm_gdb_exception except {};

  /* The sequencing here, as everywhere else, is important.
     We can't have existing cleanups when a Scheme exception is thrown.  */

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "#si", rest,
			      &encoding_arg_pos, &encoding,
			      &length_arg_pos, &length);

  if (length < -1)
    {
      gdbscm_out_of_range_error (FUNC_NAME, length_arg_pos,
				 scm_from_int (length),
				 _("invalid length"));
    }

  try
    {
      scoped_value_mark free_values;

      struct type *type, *realtype;
      CORE_ADDR addr;

      type = value->type ();
      realtype = check_typedef (type);

      switch (realtype->code ())
	{
	case TYPE_CODE_ARRAY:
	  {
	    LONGEST array_length = -1;
	    LONGEST low_bound, high_bound;

	    /* PR 20786: There's no way to specify an array of length zero.
	       Record a length of [0,-1] which is how Ada does it.  Anything
	       we do is broken, but this one possible solution.  */
	    if (get_array_bounds (realtype, &low_bound, &high_bound))
	      array_length = high_bound - low_bound + 1;
	    if (length == -1)
	      length = array_length;
	    else if (array_length == -1)
	      {
		type = lookup_array_range_type (realtype->target_type (),
						0, length - 1);
	      }
	    else if (length != array_length)
	      {
		/* We need to create a new array type with the
		   specified length.  */
		if (length > array_length)
		  error (_("length is larger than array size"));
		type = lookup_array_range_type (type->target_type (),
						low_bound,
						low_bound + length - 1);
	      }
	    addr = value->address ();
	    break;
	  }
	case TYPE_CODE_PTR:
	  /* If a length is specified we defer creating an array of the
	     specified width until we need to.  */
	  addr = value_as_address (value);
	  break;
	default:
	  /* Should flag an error here.  PR 20769.  */
	  addr = value->address ();
	  break;
	}

      result = lsscm_make_lazy_string (addr, length, encoding, type);
    }
  catch (const gdb_exception &ex)
    {
      except = unpack (ex);
    }

  xfree (encoding);
  GDBSCM_HANDLE_GDB_EXCEPTION (except);

  if (gdbscm_is_exception (result))
    gdbscm_throw (result);

  return result;
}

/* (value-lazy? <gdb:value>) -> boolean */

static SCM
gdbscm_value_lazy_p (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  return scm_from_bool (value->lazy ());
}

/* (value-fetch-lazy! <gdb:value>) -> unspecified */

static SCM
gdbscm_value_fetch_lazy_x (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;

  return gdbscm_wrap ([=]
    {
      if (value->lazy ())
	value->fetch_lazy ();
      return SCM_UNSPECIFIED;
    });
}

/* (value-print <gdb:value>) -> string */

static SCM
gdbscm_value_print (SCM self)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct value *value = v_smob->value;
  struct value_print_options opts;

  get_user_print_options (&opts);
  opts.deref_ref = false;

  string_file stb;

  gdbscm_gdb_exception exc {};
  try
    {
      common_val_print (value, &stb, 0, &opts, current_language);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  /* Use SCM_FAILED_CONVERSION_QUESTION_MARK to ensure this doesn't
     throw an error if the encoding fails.
     IWBN to use scm_take_locale_string here, but we'd have to temporarily
     override the default port conversion handler because contrary to
     documentation it doesn't necessarily free the input string.  */
  return scm_from_stringn (stb.c_str (), stb.size (), host_charset (),
			   SCM_FAILED_CONVERSION_QUESTION_MARK);
}

/* (parse-and-eval string) -> <gdb:value>
   Parse a string and evaluate the string as an expression.  */

static SCM
gdbscm_parse_and_eval (SCM expr_scm)
{
  char *expr_str;
  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "s",
			      expr_scm, &expr_str);

  return gdbscm_wrap ([=]
    {
      scoped_value_mark free_values;
      return vlscm_scm_from_value (parse_and_eval (expr_str));
    });
}

/* (history-ref integer) -> <gdb:value>
   Return the specified value from GDB's value history.  */

static SCM
gdbscm_history_ref (SCM index)
{
  int i;
  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "i", index, &i);

  return gdbscm_wrap ([=]
    {
      return vlscm_scm_from_value (access_value_history (i));
    });
}

/* (history-append! <gdb:value>) -> index
   Append VALUE to GDB's value history.  Return its index in the history.  */

static SCM
gdbscm_history_append_x (SCM value)
{
  value_smob *v_smob
    = vlscm_get_value_smob_arg_unsafe (value, SCM_ARG1, FUNC_NAME);
  return gdbscm_wrap ([=]
    {
      return scm_from_int (v_smob->value->record_latest ());
    });
}

/* Initialize the Scheme value code.  */

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

  { "make-value", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_value),
    "\
Create a <gdb:value> representing object.\n\
Typically this is used to convert numbers and strings to\n\
<gdb:value> objects.\n\
\n\
  Arguments: object [#:type <gdb:type>]" },

  { "value-optimized-out?", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_value_optimized_out_p),
    "\
Return #t if the value has been optimizd out." },

  { "value-address", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_address),
    "\
Return the address of the value." },

  { "value-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_type),
    "\
Return the type of the value." },

  { "value-dynamic-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_dynamic_type),
    "\
Return the dynamic type of the value." },

  { "value-cast", 2, 0, 0, as_a_scm_t_subr (gdbscm_value_cast),
    "\
Cast the value to the supplied type.\n\
\n\
  Arguments: <gdb:value> <gdb:type>" },

  { "value-dynamic-cast", 2, 0, 0, as_a_scm_t_subr (gdbscm_value_dynamic_cast),
    "\
Cast the value to the supplied type, as if by the C++\n\
dynamic_cast operator.\n\
\n\
  Arguments: <gdb:value> <gdb:type>" },

  { "value-reinterpret-cast", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_value_reinterpret_cast),
    "\
Cast the value to the supplied type, as if by the C++\n\
reinterpret_cast operator.\n\
\n\
  Arguments: <gdb:value> <gdb:type>" },

  { "value-dereference", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_dereference),
    "\
Return the result of applying the C unary * operator to the value." },

  { "value-referenced-value", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_value_referenced_value),
    "\
Given a value of a reference type, return the value referenced.\n\
The difference between this function and value-dereference is that\n\
the latter applies * unary operator to a value, which need not always\n\
result in the value referenced.\n\
For example, for a value which is a reference to an 'int' pointer ('int *'),\n\
value-dereference will result in a value of type 'int' while\n\
value-referenced-value will result in a value of type 'int *'." },

  { "value-reference-value", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_value_reference_value),
    "\
Return a <gdb:value> object which is a reference to the given value." },

  { "value-rvalue-reference-value", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_value_rvalue_reference_value),
    "\
Return a <gdb:value> object which is an rvalue reference to the given value." },

  { "value-const-value", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_value_const_value),
    "\
Return a <gdb:value> object which is a 'const' version of the given value." },

  { "value-field", 2, 0, 0, as_a_scm_t_subr (gdbscm_value_field),
    "\
Return the specified field of the value.\n\
\n\
  Arguments: <gdb:value> string" },

  { "value-subscript", 2, 0, 0, as_a_scm_t_subr (gdbscm_value_subscript),
    "\
Return the value of the array at the specified index.\n\
\n\
  Arguments: <gdb:value> integer" },

  { "value-call", 2, 0, 0, as_a_scm_t_subr (gdbscm_value_call),
    "\
Perform an inferior function call taking the value as a pointer to the\n\
function to call.\n\
Each element of the argument list must be a <gdb:value> object or an object\n\
that can be converted to one.\n\
The result is the value returned by the function.\n\
\n\
  Arguments: <gdb:value> arg-list" },

  { "value->bool", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_to_bool),
    "\
Return the Scheme boolean representing the GDB value.\n\
The value must be \"integer like\".  Pointers are ok." },

  { "value->integer", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_to_integer),
    "\
Return the Scheme integer representing the GDB value.\n\
The value must be \"integer like\".  Pointers are ok." },

  { "value->real", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_to_real),
    "\
Return the Scheme real number representing the GDB value.\n\
The value must be a number." },

  { "value->bytevector", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_to_bytevector),
    "\
Return a Scheme bytevector with the raw contents of the GDB value.\n\
No transformation, endian or otherwise, is performed." },

  { "value->string", 1, 0, 1, as_a_scm_t_subr (gdbscm_value_to_string),
    "\
Return the Unicode string of the value's contents.\n\
If ENCODING is not given, the string is assumed to be encoded in\n\
the target's charset.\n\
An error setting \"error\" causes an exception to be thrown if there's\n\
a decoding error.  An error setting of \"substitute\" causes invalid\n\
characters to be replaced with \"?\".  The default is \"error\".\n\
If LENGTH is provided, only fetch string to the length provided.\n\
\n\
  Arguments: <gdb:value>\n\
	     [#:encoding encoding] [#:errors \"error\"|\"substitute\"]\n\
	     [#:length length]" },

  { "value->lazy-string", 1, 0, 1,
    as_a_scm_t_subr (gdbscm_value_to_lazy_string),
    "\
Return a Scheme object representing a lazily fetched Unicode string\n\
of the value's contents.\n\
If ENCODING is not given, the string is assumed to be encoded in\n\
the target's charset.\n\
If LENGTH is provided, only fetch string to the length provided.\n\
\n\
  Arguments: <gdb:value> [#:encoding encoding] [#:length length]" },

  { "value-lazy?", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_lazy_p),
    "\
Return #t if the value is lazy (not fetched yet from the inferior).\n\
A lazy value is fetched when needed, or when the value-fetch-lazy! function\n\
is called." },

  { "make-lazy-value", 2, 0, 0, as_a_scm_t_subr (gdbscm_make_lazy_value),
    "\
Create a <gdb:value> that will be lazily fetched from the target.\n\
\n\
  Arguments: <gdb:type> address" },

  { "value-fetch-lazy!", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_fetch_lazy_x),
    "\
Fetch the value from the inferior, if it was lazy.\n\
The result is \"unspecified\"." },

  { "value-print", 1, 0, 0, as_a_scm_t_subr (gdbscm_value_print),
    "\
Return the string representation (print form) of the value." },

  { "parse-and-eval", 1, 0, 0, as_a_scm_t_subr (gdbscm_parse_and_eval),
    "\
Evaluates string in gdb and returns the result as a <gdb:value> object." },

  { "history-ref", 1, 0, 0, as_a_scm_t_subr (gdbscm_history_ref),
    "\
Return the specified value from GDB's value history." },

  { "history-append!", 1, 0, 0, as_a_scm_t_subr (gdbscm_history_append_x),
    "\
Append the specified value onto GDB's value history." },

  END_FUNCTIONS
};

void
gdbscm_initialize_values (void)
{
  value_smob_tag = gdbscm_make_smob_type (value_smob_name,
					  sizeof (value_smob));
  scm_set_smob_free (value_smob_tag, vlscm_free_value_smob);
  scm_set_smob_print (value_smob_tag, vlscm_print_value_smob);
  scm_set_smob_equalp (value_smob_tag, vlscm_equal_p_value_smob);

  gdbscm_define_functions (value_functions, 1);

  type_keyword = scm_from_latin1_keyword ("type");
  encoding_keyword = scm_from_latin1_keyword ("encoding");
  errors_keyword = scm_from_latin1_keyword ("errors");
  length_keyword = scm_from_latin1_keyword ("length");

  error_symbol = scm_from_latin1_symbol ("error");
  escape_symbol = scm_from_latin1_symbol ("escape");
  substitute_symbol = scm_from_latin1_symbol ("substitute");
}
