/* Python interface to finish breakpoints

   Copyright (C) 2011-2012 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/>.  */



#include "defs.h"
#include "exceptions.h"
#include "python-internal.h"
#include "breakpoint.h"
#include "frame.h"
#include "gdbthread.h"
#include "arch-utils.h"
#include "language.h"
#include "observer.h"
#include "inferior.h"
#include "block.h"

static PyTypeObject finish_breakpoint_object_type;

/* Function that is called when a Python finish bp is found out of scope.  */
static char * const outofscope_func = "out_of_scope";

/* struct implementing the gdb.FinishBreakpoint object by extending
   the gdb.Breakpoint class.  */
struct finish_breakpoint_object
{
  /* gdb.Breakpoint base class.  */
  breakpoint_object py_bp;
  /* gdb.Type object of the value return by the breakpointed function.
     May be NULL if no debug information was available or return type
     was VOID.  */
  PyObject *return_type;
  /* gdb.Value object of the function finished by this breakpoint.  Will be
     NULL if return_type is NULL.  */
  PyObject *function_value;
  /* When stopped at this FinishBreakpoint, gdb.Value object returned by
     the function; Py_None if the value is not computable; NULL if GDB is
     not stopped at a FinishBreakpoint.  */
  PyObject *return_value;
};

/* Python function to get the 'return_value' attribute of
   FinishBreakpoint.  */

static PyObject *
bpfinishpy_get_returnvalue (PyObject *self, void *closure)
{
  struct finish_breakpoint_object *self_finishbp =
      (struct finish_breakpoint_object *) self;

  if (!self_finishbp->return_value)
    Py_RETURN_NONE;

  Py_INCREF (self_finishbp->return_value);
  return self_finishbp->return_value;
}

/* Deallocate FinishBreakpoint object.  */

static void
bpfinishpy_dealloc (PyObject *self)
{
  struct finish_breakpoint_object *self_bpfinish =
        (struct finish_breakpoint_object *) self;

  Py_XDECREF (self_bpfinish->function_value);
  Py_XDECREF (self_bpfinish->return_type);
  Py_XDECREF (self_bpfinish->return_value);
}

/* Triggered when gdbpy_should_stop is about to execute the `stop' callback
   of the gdb.FinishBreakpoint object BP_OBJ.  Will compute and cache the
   `return_value', if possible.  */

void
bpfinishpy_pre_stop_hook (struct breakpoint_object *bp_obj)
{
  struct finish_breakpoint_object *self_finishbp =
        (struct finish_breakpoint_object *) bp_obj;
  volatile struct gdb_exception except;

  /* Can compute return_value only once.  */
  gdb_assert (!self_finishbp->return_value);

  if (!self_finishbp->return_type)
    return;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      struct value *function =
        value_object_to_value (self_finishbp->function_value);
      struct type *value_type =
        type_object_to_type (self_finishbp->return_type);
      struct value *ret = get_return_value (function, value_type);

      if (ret)
        {
          self_finishbp->return_value = value_to_value_object (ret);
          if (!self_finishbp->return_value)
              gdbpy_print_stack ();
        }
      else
        {
          Py_INCREF (Py_None);
          self_finishbp->return_value = Py_None;
        }
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      gdbpy_print_stack ();
    }
}

/* Triggered when gdbpy_should_stop has triggered the `stop' callback
   of the gdb.FinishBreakpoint object BP_OBJ.  */

void
bpfinishpy_post_stop_hook (struct breakpoint_object *bp_obj)
{
  volatile struct gdb_exception except;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      /* Can't delete it here, but it will be removed at the next stop.  */
      disable_breakpoint (bp_obj->bp);
      gdb_assert (bp_obj->bp->disposition == disp_del);
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      gdbpy_print_stack ();
    }
}

/* Python function to create a new breakpoint.  */

static int
bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static char *keywords[] = { "frame", "internal", NULL };
  struct finish_breakpoint_object *self_bpfinish =
      (struct finish_breakpoint_object *) self;
  int type = bp_breakpoint;
  PyObject *frame_obj = NULL;
  int thread;
  struct frame_info *frame, *prev_frame = NULL;
  struct frame_id frame_id;
  PyObject *internal = NULL;
  int internal_bp = 0;
  CORE_ADDR finish_pc, pc;
  volatile struct gdb_exception except;
  char *addr_str, small_buf[100];
  struct symbol *function;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
                                    &frame_obj, &internal))
    return -1;

  /* Default frame to gdb.newest_frame if necessary.  */
  if (!frame_obj)
    frame_obj = gdbpy_newest_frame (NULL, NULL);
  else
    Py_INCREF (frame_obj);

  frame = frame_object_to_frame_info (frame_obj);
  Py_DECREF (frame_obj);

  if (frame == NULL)
    goto invalid_frame;
  
  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      prev_frame = get_prev_frame (frame);
      if (prev_frame == 0)
        {
          PyErr_SetString (PyExc_ValueError, _("\"FinishBreakpoint\" not "   \
                                               "meaningful in the outermost "\
                                               "frame."));
        }
      else if (get_frame_type (prev_frame) == DUMMY_FRAME)
        {
          PyErr_SetString (PyExc_ValueError, _("\"FinishBreakpoint\" cannot "\
                                               "be set on a dummy frame."));
        }
      else
        {
          frame_id = get_frame_id (prev_frame);
          if (frame_id_eq (frame_id, null_frame_id))
            PyErr_SetString (PyExc_ValueError,
                             _("Invalid ID for the `frame' object."));
        }
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      return -1;
    }
  else if (PyErr_Occurred ())
    return -1;

  thread = pid_to_thread_id (inferior_ptid);
  if (thread == 0)
    {
      PyErr_SetString (PyExc_ValueError,
                       _("No thread currently selected."));
      return -1;
    }

  if (internal)
    {
      internal_bp = PyObject_IsTrue (internal);
      if (internal_bp == -1) 
        {
          PyErr_SetString (PyExc_ValueError, 
                           _("The value of `internal' must be a boolean."));
          return -1;
        }
    }

  /* Find the function we will return from.  */
  self_bpfinish->return_type = NULL;
  self_bpfinish->function_value = NULL;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      if (get_frame_pc_if_available (frame, &pc))
        {
          function = find_pc_function (pc);
          if (function != NULL)
            {
              struct type *ret_type =
                  TYPE_TARGET_TYPE (SYMBOL_TYPE (function));

              /* Remember only non-void return types.  */
              if (TYPE_CODE (ret_type) != TYPE_CODE_VOID)
                {
                  struct value *func_value;

                  /* Ignore Python errors at this stage.  */
                  self_bpfinish->return_type = type_to_type_object (ret_type);
                  PyErr_Clear ();
                  func_value = read_var_value (function, frame);
                  self_bpfinish->function_value =
                      value_to_value_object (func_value);
                  PyErr_Clear ();
                }
            }
        }
    }
  if (except.reason < 0
      || !self_bpfinish->return_type || !self_bpfinish->function_value)
    {
      /* Won't be able to compute return value.  */
      Py_XDECREF (self_bpfinish->return_type);
      Py_XDECREF (self_bpfinish->function_value);

      self_bpfinish->return_type = NULL;
      self_bpfinish->function_value = NULL;
    }

  bppy_pending_object = &self_bpfinish->py_bp;
  bppy_pending_object->number = -1;
  bppy_pending_object->bp = NULL;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      /* Set a breakpoint on the return address.  */
      finish_pc = get_frame_pc (prev_frame);
      xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (finish_pc));
      addr_str = small_buf;

      create_breakpoint (python_gdbarch,
                         addr_str, NULL, thread, NULL,
                         0,
                         1 /*temp_flag*/,
                         bp_breakpoint,
                         0,
                         AUTO_BOOLEAN_TRUE,
                         &bkpt_breakpoint_ops,
                         0, 1, internal_bp, 0);
    }
  GDB_PY_SET_HANDLE_EXCEPTION (except);
  
  self_bpfinish->py_bp.bp->frame_id = frame_id;
  self_bpfinish->py_bp.is_finish_bp = 1;
  
  /* Bind the breakpoint with the current program space.  */
  self_bpfinish->py_bp.bp->pspace = current_program_space;

  return 0;
  
 invalid_frame:
  PyErr_SetString (PyExc_ValueError, 
                   _("Invalid ID for the `frame' object."));
  return -1;
}

/* Called when GDB notices that the finish breakpoint BP_OBJ is out of
   the current callstack.  Triggers the method OUT_OF_SCOPE if implemented,
   then delete the breakpoint.  */

static void
bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj)
{
  breakpoint_object *bp_obj = (breakpoint_object *) bpfinish_obj;
  PyObject *py_obj = (PyObject *) bp_obj;

  if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled
      && PyObject_HasAttrString (py_obj, outofscope_func))
    {
      if (!PyObject_CallMethod (py_obj, outofscope_func, NULL))
          gdbpy_print_stack ();
    }

  delete_breakpoint (bpfinish_obj->py_bp.bp);
}

/* Callback for `bpfinishpy_detect_out_scope'.  Triggers Python's
   `B->out_of_scope' function if B is a FinishBreakpoint out of its scope.  */

static int
bpfinishpy_detect_out_scope_cb (struct breakpoint *b, void *args)
{
  volatile struct gdb_exception except;
  struct breakpoint *bp_stopped = (struct breakpoint *) args;
  PyObject *py_bp = (PyObject *) b->py_bp_object;
  struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();
  
  /* Trigger out_of_scope if this is a FinishBreakpoint and its frame is
     not anymore in the current callstack.  */
  if (py_bp != NULL && b->py_bp_object->is_finish_bp)
    {
      struct finish_breakpoint_object *finish_bp =
          (struct finish_breakpoint_object *) py_bp;

      /* Check scope if not currently stopped at the FinishBreakpoint.  */
      if (b != bp_stopped)
        {
          TRY_CATCH (except, RETURN_MASK_ALL)
            {
              if (b->pspace == current_inferior ()->pspace
                  && (!target_has_registers
                      || frame_find_by_id (b->frame_id) == NULL))
                bpfinishpy_out_of_scope (finish_bp);
            }
          if (except.reason < 0)
            {
              gdbpy_convert_exception (except);
              gdbpy_print_stack ();
            }
        }
    }

  return 0;
}

/* Attached to `stop' notifications, check if the execution has run
   out of the scope of any FinishBreakpoint before it has been hit.  */

static void
bpfinishpy_handle_stop (struct bpstats *bs, int print_frame)
{
  struct cleanup *cleanup = ensure_python_env (get_current_arch (),
                                               current_language);

  iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb,
                            bs == NULL ? NULL : bs->breakpoint_at);

  do_cleanups (cleanup);
}

/* Attached to `exit' notifications, triggers all the necessary out of
   scope notifications.  */

static void
bpfinishpy_handle_exit (struct inferior *inf)
{
  struct cleanup *cleanup = ensure_python_env (target_gdbarch,
                                               current_language);

  iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb, NULL);

  do_cleanups (cleanup);
}

/* Initialize the Python finish breakpoint code.  */

void
gdbpy_initialize_finishbreakpoints (void)
{
  if (PyType_Ready (&finish_breakpoint_object_type) < 0)
      return;
  
  Py_INCREF (&finish_breakpoint_object_type);
  PyModule_AddObject (gdb_module, "FinishBreakpoint",
                      (PyObject *) &finish_breakpoint_object_type);
    
  observer_attach_normal_stop (bpfinishpy_handle_stop);
  observer_attach_inferior_exit (bpfinishpy_handle_exit);
}

static PyGetSetDef finish_breakpoint_object_getset[] = {
  { "return_value", bpfinishpy_get_returnvalue, NULL,
  "gdb.Value object representing the return value, if any. \
None otherwise.", NULL },
    { NULL }  /* Sentinel.  */
};

static PyTypeObject finish_breakpoint_object_type =
{
  PyObject_HEAD_INIT (NULL)
  0,                              /*ob_size*/
  "gdb.FinishBreakpoint",         /*tp_name*/
  sizeof (struct finish_breakpoint_object),  /*tp_basicsize*/
  0,                              /*tp_itemsize*/
  bpfinishpy_dealloc,             /*tp_dealloc*/
  0,                              /*tp_print*/
  0,                              /*tp_getattr*/
  0,                              /*tp_setattr*/
  0,                              /*tp_compare*/
  0,                              /*tp_repr*/
  0,                              /*tp_as_number*/
  0,                              /*tp_as_sequence*/
  0,                              /*tp_as_mapping*/
  0,                              /*tp_hash */
  0,                              /*tp_call*/
  0,                              /*tp_str*/
  0,                              /*tp_getattro*/
  0,                              /*tp_setattro */
  0,                              /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
  "GDB finish breakpoint object", /* tp_doc */
  0,                              /* tp_traverse */
  0,                              /* tp_clear */
  0,                              /* tp_richcompare */
  0,                              /* tp_weaklistoffset */
  0,                              /* tp_iter */
  0,                              /* tp_iternext */
  0,                              /* tp_methods */
  0,                              /* tp_members */
  finish_breakpoint_object_getset,/* tp_getset */
  &breakpoint_object_type,        /* tp_base */
  0,                              /* tp_dict */
  0,                              /* tp_descr_get */
  0,                              /* tp_descr_set */
  0,                              /* tp_dictoffset */
  bpfinishpy_init,                /* tp_init */
  0,                              /* tp_alloc */
  0                               /* tp_new */
};
