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

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.Type object of the function finished by this breakpoint.  Will be
     NULL if return_type is NULL.  */
  PyObject *function_type;
  /* 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_type);
  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 *ret =
          get_return_value (type_object_to_type (self_finishbp->function_type),
                            type_object_to_type (self_finishbp->return_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_type = 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)
                {
                  /* Ignore Python errors at this stage.  */
                  self_bpfinish->return_type = type_to_type_object (ret_type);
                  PyErr_Clear ();
                  self_bpfinish->function_type =
                      type_to_type_object (SYMBOL_TYPE (function));
                  PyErr_Clear ();
                }
            }
        }
    }
  if (except.reason < 0
      || !self_bpfinish->return_type || !self_bpfinish->function_type)
    {
      /* Won't be able to compute return value.  */
      Py_XDECREF (self_bpfinish->return_type);
      Py_XDECREF (self_bpfinish->function_type);

      self_bpfinish->return_type = NULL;
      self_bpfinish->function_type = 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,
                         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)
{
  volatile struct gdb_exception except;
  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 */
};
