/* GDB/Scheme support for safe calls into the Guile interpreter.

   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.  */

#include "defs.h"
#include "filenames.h"
#include "guile-internal.h"
#include "gdbsupport/pathstuff.h"

/* Struct to marshall args to scscm_safe_call_body.  */

struct c_data
{
  const char *(*func) (void *);
  void *data;
  /* An error message or NULL for success.  */
  const char *result;
};

/* Struct to marshall args through gdbscm_with_catch.  */

struct with_catch_data
{
  scm_t_catch_body func;
  void *data;
  scm_t_catch_handler unwind_handler;
  scm_t_catch_handler pre_unwind_handler;

  /* If EXCP_MATCHER is non-NULL, it is an excp_matcher_func function.
     If the exception is recognized by it, the exception is recorded as is,
     without wrapping it in gdb:with-stack.  */
  excp_matcher_func *excp_matcher;

  SCM stack;
  SCM catch_result;
};

/* The "body" argument to scm_i_with_continuation_barrier.
   Invoke the user-supplied function.  */

static SCM
scscm_safe_call_body (void *d)
{
  struct c_data *data = (struct c_data *) d;

  data->result = data->func (data->data);

  return SCM_UNSPECIFIED;
}

/* A "pre-unwind handler" to scm_c_catch that prints the exception
   according to "set guile print-stack".  */

static SCM
scscm_printing_pre_unwind_handler (void *data, SCM key, SCM args)
{
  SCM stack = scm_make_stack (SCM_BOOL_T, scm_list_1 (scm_from_int (2)));

  gdbscm_print_exception_with_stack (SCM_BOOL_F, stack, key, args);

  return SCM_UNSPECIFIED;
}

/* A no-op unwind handler.  */

static SCM
scscm_nop_unwind_handler (void *data, SCM key, SCM args)
{
  return SCM_UNSPECIFIED;
}

/* The "pre-unwind handler" to scm_c_catch that records the exception
   for possible later printing.  We do this in the pre-unwind handler because
   we want the stack to include point where the exception occurred.

   If DATA is non-NULL, it is an excp_matcher_func function.
   If the exception is recognized by it, the exception is recorded as is,
   without wrapping it in gdb:with-stack.  */

static SCM
scscm_recording_pre_unwind_handler (void *datap, SCM key, SCM args)
{
  struct with_catch_data *data = (struct with_catch_data *) datap;
  excp_matcher_func *matcher = data->excp_matcher;

  if (matcher != NULL && matcher (key))
    return SCM_UNSPECIFIED;

  /* There's no need to record the whole stack if we're not going to print it.
     However, convention is to still print the stack frame in which the
     exception occurred, even if we're not going to print a full backtrace.
     For now, keep it simple.  */

  data->stack = scm_make_stack (SCM_BOOL_T, scm_list_1 (scm_from_int (2)));

  /* IWBN if we could return the <gdb:exception> here and skip the unwind
     handler, but it doesn't work that way.  If we want to return a
     <gdb:exception> object from the catch it needs to come from the unwind
     handler.  So what we do is save the stack for later use by the unwind
     handler.  */

  return SCM_UNSPECIFIED;
}

/* Part two of the recording unwind handler.
   Here we take the stack saved from the pre-unwind handler and create
   the <gdb:exception> object.  */

static SCM
scscm_recording_unwind_handler (void *datap, SCM key, SCM args)
{
  struct with_catch_data *data = (struct with_catch_data *) datap;

  /* We need to record the stack in the exception since we're about to
     throw and lose the location that got the exception.  We do this by
     wrapping the exception + stack in a new exception.  */

  if (gdbscm_is_true (data->stack))
    return gdbscm_make_exception_with_stack (key, args, data->stack);

  return gdbscm_make_exception (key, args);
}

/* Ugh. :-(
   Guile doesn't export scm_i_with_continuation_barrier which is exactly
   what we need.  To cope, have our own wrapper around scm_c_catch and
   pass this as the "body" argument to scm_c_with_continuation_barrier.
   Darn darn darn.  */

static void *
gdbscm_with_catch (void *data)
{
  struct with_catch_data *d = (struct with_catch_data *) data;

  d->catch_result
    = scm_c_catch (SCM_BOOL_T,
		   d->func, d->data,
		   d->unwind_handler, d,
		   d->pre_unwind_handler, d);

#if HAVE_GUILE_MANUAL_FINALIZATION
  scm_run_finalizers ();
#endif

  return NULL;
}

/* A wrapper around scm_with_guile that prints backtraces and exceptions
   according to "set guile print-stack".
   The result if NULL if no exception occurred, otherwise it is a statically
   allocated error message (caller must *not* free).  */

const char *
gdbscm_with_guile (const char *(*func) (void *), void *data)
{
  struct c_data c_data;
  struct with_catch_data catch_data;

  c_data.func = func;
  c_data.data = data;
  /* Set this now in case an exception is thrown.  */
  c_data.result = _("Error while executing Scheme code.");

  catch_data.func = scscm_safe_call_body;
  catch_data.data = &c_data;
  catch_data.unwind_handler = scscm_nop_unwind_handler;
  catch_data.pre_unwind_handler = scscm_printing_pre_unwind_handler;
  catch_data.excp_matcher = NULL;
  catch_data.stack = SCM_BOOL_F;
  catch_data.catch_result = SCM_UNSPECIFIED;

  scm_with_guile (gdbscm_with_catch, &catch_data);

  return c_data.result;
}

/* Another wrapper of scm_with_guile for use by the safe call/apply routines
   in this file, as well as for general purpose calling other functions safely.
   For these we want to record the exception, but leave the possible printing
   of it to later.  */

SCM
gdbscm_call_guile (SCM (*func) (void *), void *data,
		   excp_matcher_func *ok_excps)
{
  struct with_catch_data catch_data;

  catch_data.func = func;
  catch_data.data = data;
  catch_data.unwind_handler = scscm_recording_unwind_handler;
  catch_data.pre_unwind_handler = scscm_recording_pre_unwind_handler;
  catch_data.excp_matcher = ok_excps;
  catch_data.stack = SCM_BOOL_F;
  catch_data.catch_result = SCM_UNSPECIFIED;

#if 0
  scm_c_with_continuation_barrier (gdbscm_with_catch, &catch_data);
#else
  scm_with_guile (gdbscm_with_catch, &catch_data);
#endif

  return catch_data.catch_result;
}

/* Utilities to safely call Scheme code, catching all exceptions, and
   preventing continuation capture.
   The result is the result of calling the function, or if an exception occurs
   then the result is a <gdb:exception> smob, which can be tested for with
   gdbscm_is_exception.  */

/* Helper for gdbscm_safe_call_0.  */

static SCM
scscm_call_0_body (void *argsp)
{
  SCM *args = (SCM *) argsp;

  return scm_call_0 (args[0]);
}

SCM
gdbscm_safe_call_0 (SCM proc, excp_matcher_func *ok_excps)
{
  SCM args[] = { proc };

  return gdbscm_call_guile (scscm_call_0_body, args, ok_excps);
}

/* Helper for gdbscm_safe_call_1.  */

static SCM
scscm_call_1_body (void *argsp)
{
  SCM *args = (SCM *) argsp;

  return scm_call_1 (args[0], args[1]);
}

SCM
gdbscm_safe_call_1 (SCM proc, SCM arg0, excp_matcher_func *ok_excps)
{
  SCM args[] = { proc, arg0 };

  return gdbscm_call_guile (scscm_call_1_body, args, ok_excps);
}

/* Helper for gdbscm_safe_call_2.  */

static SCM
scscm_call_2_body (void *argsp)
{
  SCM *args = (SCM *) argsp;

  return scm_call_2 (args[0], args[1], args[2]);
}

SCM
gdbscm_safe_call_2 (SCM proc, SCM arg0, SCM arg1, excp_matcher_func *ok_excps)
{
  SCM args[] = { proc, arg0, arg1 };

  return gdbscm_call_guile (scscm_call_2_body, args, ok_excps);
}

/* Helper for gdbscm_safe_call_3.  */

static SCM
scscm_call_3_body (void *argsp)
{
  SCM *args = (SCM *) argsp;

  return scm_call_3 (args[0], args[1], args[2], args[3]);
}

SCM
gdbscm_safe_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3,
		    excp_matcher_func *ok_excps)
{
  SCM args[] = { proc, arg1, arg2, arg3 };

  return gdbscm_call_guile (scscm_call_3_body, args, ok_excps);
}

/* Helper for gdbscm_safe_call_4.  */

static SCM
scscm_call_4_body (void *argsp)
{
  SCM *args = (SCM *) argsp;

  return scm_call_4 (args[0], args[1], args[2], args[3], args[4]);
}

SCM
gdbscm_safe_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4,
		    excp_matcher_func *ok_excps)
{
  SCM args[] = { proc, arg1, arg2, arg3, arg4 };

  return gdbscm_call_guile (scscm_call_4_body, args, ok_excps);
}

/* Helper for gdbscm_safe_apply_1.  */

static SCM
scscm_apply_1_body (void *argsp)
{
  SCM *args = (SCM *) argsp;

  return scm_apply_1 (args[0], args[1], args[2]);
}

SCM
gdbscm_safe_apply_1 (SCM proc, SCM arg0, SCM rest, excp_matcher_func *ok_excps)
{
  SCM args[] = { proc, arg0, rest };

  return gdbscm_call_guile (scscm_apply_1_body, args, ok_excps);
}

/* Utilities to call Scheme code, not catching exceptions, and
   not preventing continuation capture.
   The result is the result of calling the function.
   If an exception occurs then Guile is left to handle the exception,
   unwinding the stack as appropriate.

   USE THESE WITH CARE.
   Typically these are called from functions that implement Scheme procedures,
   and we don't want to catch the exception; otherwise it will get printed
   twice: once when first caught and once if it ends up being rethrown and the
   rethrow reaches the top repl, which will confuse the user.

   While these calls just pass the call off to the corresponding Guile
   procedure, all such calls are routed through these ones to:
   a) provide a place to put hooks or whatnot in if we need to,
   b) add "unsafe" to the name to alert the reader.  */

SCM
gdbscm_unsafe_call_1 (SCM proc, SCM arg0)
{
  return scm_call_1 (proc, arg0);
}

/* Utilities for safely evaluating a Scheme expression string.  */

struct eval_scheme_string_data
{
  const char *string;
  int display_result;
};

/* Wrapper to eval a C string in the Guile interpreter.
   This is passed to gdbscm_with_guile.  */

static const char *
scscm_eval_scheme_string (void *datap)
{
  struct eval_scheme_string_data *data
    = (struct eval_scheme_string_data *) datap;
  SCM result = scm_c_eval_string (data->string);

  if (data->display_result && !scm_is_eq (result, SCM_UNSPECIFIED))
    {
      SCM port = scm_current_output_port ();

      scm_write (result, port);
      scm_newline (port);
    }

  /* If we get here the eval succeeded.  */
  return NULL;
}

/* Evaluate EXPR in the Guile interpreter, catching all exceptions
   and preventing continuation capture.
   The result is NULL if no exception occurred.  Otherwise, the exception is
   printed according to "set guile print-stack" and the result is an error
   message.  */

gdb::unique_xmalloc_ptr<char>
gdbscm_safe_eval_string (const char *string, int display_result)
{
  struct eval_scheme_string_data data = { string, display_result };
  const char *result;

  result = gdbscm_with_guile (scscm_eval_scheme_string, (void *) &data);

  if (result != NULL)
    return make_unique_xstrdup (result);
  return NULL;
}

/* Utilities for safely loading Scheme scripts.  */

/* Helper function for gdbscm_safe_source_scheme_script.  */

static const char *
scscm_source_scheme_script (void *data)
{
  const char *filename = (const char *) data;

  /* The Guile docs don't specify what the result is.
     Maybe it's SCM_UNSPECIFIED, but the docs should specify that. :-) */
  scm_c_primitive_load_path (filename);

  /* If we get here the load succeeded.  */
  return NULL;
}

/* Try to load a script, catching all exceptions,
   and preventing continuation capture.
   The result is NULL if the load succeeded.  Otherwise, the exception is
   printed according to "set guile print-stack" and the result is an error
   message allocated with malloc, caller must free.  */

gdb::unique_xmalloc_ptr<char>
gdbscm_safe_source_script (const char *filename)
{
  /* scm_c_primitive_load_path only looks in %load-path for files with
     relative paths.  An alternative could be to temporarily add "." to
     %load-path, but we don't want %load-path to be searched.  At least not
     by default.  This function is invoked by the "source" GDB command which
     already has its own path search support.  */
  gdb::unique_xmalloc_ptr<char> abs_filename;
  const char *result;

  if (!IS_ABSOLUTE_PATH (filename))
    {
      abs_filename = gdb_realpath (filename);
      filename = abs_filename.get ();
    }

  result = gdbscm_with_guile (scscm_source_scheme_script,
			      (void *) filename);

  if (result != NULL)
    return make_unique_xstrdup (result);
  return NULL;
}

/* Utility for entering an interactive Guile repl.  */

void
gdbscm_enter_repl (void)
{
  /* It's unfortunate to have to resort to something like this, but
     scm_shell doesn't return.  :-(  I found this code on guile-user@.  */
  gdbscm_safe_call_1 (scm_c_public_ref ("system repl repl", "start-repl"),
		      scm_from_latin1_symbol ("scheme"), NULL);
}
