Add a new 'info proc files' subcommand of 'info proc'.
[deliverable/binutils-gdb.git] / gdb / python / py-xmethods.c
index 6505d066e745a87e2e704eb1aaa862b6a7f5c772..8e616cd4e2d6410694e9bf924ca003fbccc3f234 100644 (file)
@@ -1,6 +1,6 @@
 /* Support for debug methods in Python.
 
-   Copyright (C) 2013-2017 Free Software Foundation, Inc.
+   Copyright (C) 2013-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -37,54 +37,43 @@ static const char matchers_attr_str[] = "xmethods";
 static PyObject *py_match_method_name = NULL;
 static PyObject *py_get_arg_types_method_name = NULL;
 
-struct gdbpy_worker_data
+struct python_xmethod_worker : xmethod_worker
 {
-  PyObject *worker;
-  PyObject *this_type;
-};
+  python_xmethod_worker (PyObject *worker, PyObject *this_type);
+  ~python_xmethod_worker ();
 
-static struct xmethod_worker *new_python_xmethod_worker (PyObject *item,
-                                                        PyObject *py_obj_type);
+  DISABLE_COPY_AND_ASSIGN (python_xmethod_worker);
 
-/* Implementation of free_xmethod_worker_data for Python.  */
+  /* Implementation of xmethod_worker::invoke for Python.  */
 
-void
-gdbpy_free_xmethod_worker_data (const struct extension_language_defn *extlang,
-                               void *data)
-{
-  struct gdbpy_worker_data *worker_data = (struct gdbpy_worker_data *) data;
+  value *invoke (value *obj, value **args, int nargs) override;
 
-  gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
+  /* Implementation of xmethod_worker::do_get_arg_types for Python.  */
 
-  /* We don't do much here, but we still need the GIL.  */
-  gdbpy_enter enter_py (get_current_arch (), current_language);
+  ext_lang_rc do_get_arg_types (int *nargs, type ***arg_types) override;
 
-  Py_DECREF (worker_data->worker);
-  Py_DECREF (worker_data->this_type);
-  xfree (worker_data);
-}
+  /* Implementation of xmethod_worker::do_get_result_type for Python.
 
-/* Implementation of clone_xmethod_worker_data for Python.  */
+     For backward compatibility with 7.9, which did not support getting the
+     result type, if the get_result_type operation is not provided by WORKER
+     then EXT_LANG_RC_OK is returned and NULL is returned in *RESULT_TYPE.  */
 
-void *
-gdbpy_clone_xmethod_worker_data (const struct extension_language_defn *extlang,
-                                void *data)
-{
-  struct gdbpy_worker_data *worker_data
-    = (struct gdbpy_worker_data *) data, *new_data;
+  ext_lang_rc do_get_result_type (value *obj, value **args, int nargs,
+                                 type **result_type_ptr) override;
 
-  gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
+private:
 
+  PyObject *m_py_worker;
+  PyObject *m_this_type;
+};
+
+python_xmethod_worker::~python_xmethod_worker ()
+{
   /* We don't do much here, but we still need the GIL.  */
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
-  new_data = XCNEW (struct gdbpy_worker_data);
-  new_data->worker = worker_data->worker;
-  new_data->this_type = worker_data->this_type;
-  Py_INCREF (new_data->worker);
-  Py_INCREF (new_data->this_type);
-
-  return new_data;
+  Py_DECREF (m_py_worker);
+  Py_DECREF (m_this_type);
 }
 
 /* Invoke the "match" method of the MATCHER and return a new reference
@@ -96,8 +85,8 @@ invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
 {
   int enabled;
 
-  gdbpy_ref enabled_field (PyObject_GetAttrString (matcher,
-                                                  enabled_field_name));
+  gdbpy_ref<> enabled_field (PyObject_GetAttrString (matcher,
+                                                    enabled_field_name));
   if (enabled_field == NULL)
     return NULL;
 
@@ -110,11 +99,12 @@ invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
       Py_RETURN_NONE;
     }
 
-  gdbpy_ref match_method (PyObject_GetAttrString (matcher, match_method_name));
+  gdbpy_ref<> match_method (PyObject_GetAttrString (matcher,
+                                                   match_method_name));
   if (match_method == NULL)
     return NULL;
 
-  gdbpy_ref py_xmethod_name (PyString_FromString (xmethod_name));
+  gdbpy_ref<> py_xmethod_name (PyString_FromString (xmethod_name));
   if (py_xmethod_name == NULL)
     return NULL;
 
@@ -129,17 +119,15 @@ enum ext_lang_rc
 gdbpy_get_matching_xmethod_workers
   (const struct extension_language_defn *extlang,
    struct type *obj_type, const char *method_name,
-   xmethod_worker_vec **dm_vec)
+   std::vector<xmethod_worker_up> *dm_vec)
 {
   struct objfile *objfile;
-  VEC (xmethod_worker_ptr) *worker_vec = NULL;
-  PyObject *py_progspace;
 
   gdb_assert (obj_type != NULL && method_name != NULL);
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
-  gdbpy_ref py_type (type_to_type_object (obj_type));
+  gdbpy_ref<> py_type (type_to_type_object (obj_type));
   if (py_type == NULL)
     {
       gdbpy_print_stack ();
@@ -147,7 +135,7 @@ gdbpy_get_matching_xmethod_workers
     }
 
   /* Create an empty list of debug methods.  */
-  gdbpy_ref py_xmethod_matcher_list (PyList_New (0));
+  gdbpy_ref<> py_xmethod_matcher_list (PyList_New (0));
   if (py_xmethod_matcher_list == NULL)
     {
       gdbpy_print_stack ();
@@ -159,7 +147,7 @@ gdbpy_get_matching_xmethod_workers
      list individually, but there's no data yet to show it's needed.  */
   ALL_OBJFILES (objfile)
     {
-      PyObject *py_objfile = objfile_to_objfile_object (objfile);
+      gdbpy_ref<> py_objfile = objfile_to_objfile_object (objfile);
 
       if (py_objfile == NULL)
        {
@@ -167,9 +155,10 @@ gdbpy_get_matching_xmethod_workers
          return EXT_LANG_RC_ERROR;
        }
 
-      gdbpy_ref objfile_matchers (objfpy_get_xmethods (py_objfile, NULL));
-      gdbpy_ref temp (PySequence_Concat (py_xmethod_matcher_list.get (),
-                                        objfile_matchers.get ()));
+      gdbpy_ref<> objfile_matchers (objfpy_get_xmethods (py_objfile.get (),
+                                                        NULL));
+      gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
+                                          objfile_matchers.get ()));
       if (temp == NULL)
        {
          gdbpy_print_stack ();
@@ -181,13 +170,14 @@ gdbpy_get_matching_xmethod_workers
 
   /* Gather debug methods matchers registered with the current program
      space.  */
-  py_progspace = pspace_to_pspace_object (current_program_space);
+  gdbpy_ref<> py_progspace = pspace_to_pspace_object (current_program_space);
   if (py_progspace != NULL)
     {
-      gdbpy_ref pspace_matchers (pspy_get_xmethods (py_progspace, NULL));
+      gdbpy_ref<> pspace_matchers (pspy_get_xmethods (py_progspace.get (),
+                                                     NULL));
 
-      gdbpy_ref temp (PySequence_Concat (py_xmethod_matcher_list.get (),
-                                        pspace_matchers.get ()));
+      gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
+                                          pspace_matchers.get ()));
       if (temp == NULL)
        {
          gdbpy_print_stack ();
@@ -206,12 +196,12 @@ gdbpy_get_matching_xmethod_workers
   if (gdb_python_module != NULL
       && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
     {
-      gdbpy_ref gdb_matchers (PyObject_GetAttrString (gdb_python_module,
-                                                     matchers_attr_str));
+      gdbpy_ref<> gdb_matchers (PyObject_GetAttrString (gdb_python_module,
+                                                       matchers_attr_str));
       if (gdb_matchers != NULL)
        {
-         gdbpy_ref temp (PySequence_Concat (py_xmethod_matcher_list.get (),
-                                            gdb_matchers.get ()));
+         gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
+                                              gdb_matchers.get ()));
          if (temp == NULL)
            {
              gdbpy_print_stack ();
@@ -227,7 +217,7 @@ gdbpy_get_matching_xmethod_workers
        }
     }
 
-  gdbpy_ref list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
+  gdbpy_ref<> list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
   if (list_iter == NULL)
     {
       gdbpy_print_stack ();
@@ -235,7 +225,7 @@ gdbpy_get_matching_xmethod_workers
     }
   while (true)
     {
-      gdbpy_ref matcher (PyIter_Next (list_iter.get ()));
+      gdbpy_ref<> matcher (PyIter_Next (list_iter.get ()));
       if (matcher == NULL)
        {
          if (PyErr_Occurred ())
@@ -246,9 +236,9 @@ gdbpy_get_matching_xmethod_workers
          break;
        }
 
-      gdbpy_ref match_result (invoke_match_method (matcher.get (),
-                                                  py_type.get (),
-                                                  method_name));
+      gdbpy_ref<> match_result (invoke_match_method (matcher.get (),
+                                                    py_type.get (),
+                                                    method_name));
 
       if (match_result == NULL)
        {
@@ -259,7 +249,7 @@ gdbpy_get_matching_xmethod_workers
        ; /* This means there was no match.  */
       else if (PySequence_Check (match_result.get ()))
        {
-         gdbpy_ref iter (PyObject_GetIter (match_result.get ()));
+         gdbpy_ref<> iter (PyObject_GetIter (match_result.get ()));
 
          if (iter == NULL)
            {
@@ -270,7 +260,7 @@ gdbpy_get_matching_xmethod_workers
            {
              struct xmethod_worker *worker;
 
-             gdbpy_ref py_worker (PyIter_Next (iter.get ()));
+             gdbpy_ref<> py_worker (PyIter_Next (iter.get ()));
              if (py_worker == NULL)
                {
                  if (PyErr_Occurred ())
@@ -281,57 +271,51 @@ gdbpy_get_matching_xmethod_workers
                  break;
                }
 
-             worker = new_python_xmethod_worker (py_worker.get (),
+             worker = new python_xmethod_worker (py_worker.get (),
                                                  py_type.get ());
-             VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
+
+             dm_vec->emplace_back (worker);
            }
        }
       else
        {
          struct xmethod_worker *worker;
 
-         worker = new_python_xmethod_worker (match_result.get (),
+         worker = new python_xmethod_worker (match_result.get (),
                                              py_type.get ());
-         VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
+         dm_vec->emplace_back (worker);
        }
     }
 
-  *dm_vec = worker_vec;
-
   return EXT_LANG_RC_OK;
 }
 
-/* Implementation of get_xmethod_arg_types for Python.  */
+/* See declaration.  */
 
-enum ext_lang_rc
-gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
-                            struct xmethod_worker *worker,
-                            int *nargs, struct type ***arg_types)
+ext_lang_rc
+python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
 {
   /* The gdbpy_enter object needs to be placed first, so that it's the last to
      be destroyed.  */
   gdbpy_enter enter_py (get_current_arch (), current_language);
-  struct gdbpy_worker_data *worker_data
-    = (struct gdbpy_worker_data *) worker->data;
-  PyObject *py_worker = worker_data->worker;
   struct type *obj_type;
   int i = 1, arg_count;
-  gdbpy_ref list_iter;
+  gdbpy_ref<> list_iter;
 
   /* Set nargs to -1 so that any premature return from this function returns
      an invalid/unusable number of arg types.  */
   *nargs = -1;
 
-  gdbpy_ref get_arg_types_method
-    (PyObject_GetAttrString (py_worker, get_arg_types_method_name));
+  gdbpy_ref<> get_arg_types_method
+    (PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
   if (get_arg_types_method == NULL)
     {
       gdbpy_print_stack ();
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref py_argtype_list
-    (PyObject_CallMethodObjArgs (py_worker, py_get_arg_types_method_name,
+  gdbpy_ref<> py_argtype_list
+    (PyObject_CallMethodObjArgs (m_py_worker, py_get_arg_types_method_name,
                                 NULL));
   if (py_argtype_list == NULL)
     {
@@ -368,7 +352,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
     {
       while (true)
        {
-         gdbpy_ref item (PyIter_Next (list_iter.get ()));
+         gdbpy_ref<> item (PyIter_Next (list_iter.get ()));
          if (item == NULL)
            {
              if (PyErr_Occurred ())
@@ -417,7 +401,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
   /* Add the type of 'this' as the first argument.  The 'this' pointer should
      be a 'const' value.  Hence, create a 'const' variant of the 'this' pointer
      type.  */
-  obj_type = type_object_to_type (worker_data->this_type);
+  obj_type = type_object_to_type (m_this_type);
   (type_array.get ())[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
                                         NULL);
   *nargs = i;
@@ -426,18 +410,12 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
   return EXT_LANG_RC_OK;
 }
 
-/* Implementation of get_xmethod_result_type for Python.  */
+/* See declaration.  */
 
-enum ext_lang_rc
-gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
-                              struct xmethod_worker *worker,
-                              struct value *obj,
-                              struct value **args, int nargs,
-                              struct type **result_type_ptr)
+ext_lang_rc
+python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
+                                          type **result_type_ptr)
 {
-  struct gdbpy_worker_data *worker_data
-    = (struct gdbpy_worker_data *) worker->data;
-  PyObject *py_worker = worker_data->worker;
   struct type *obj_type, *this_type;
   int i;
 
@@ -445,8 +423,8 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
 
   /* First see if there is a get_result_type method.
      If not this could be an old xmethod (pre 7.9.1).  */
-  gdbpy_ref get_result_type_method
-    (PyObject_GetAttrString (py_worker, get_result_type_method_name));
+  gdbpy_ref<> get_result_type_method
+    (PyObject_GetAttrString (m_py_worker, get_result_type_method_name));
   if (get_result_type_method == NULL)
     {
       PyErr_Clear ();
@@ -455,7 +433,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
     }
 
   obj_type = check_typedef (value_type (obj));
-  this_type = check_typedef (type_object_to_type (worker_data->this_type));
+  this_type = check_typedef (type_object_to_type (m_this_type));
   if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
     {
       struct type *this_ptr = lookup_pointer_type (this_type);
@@ -463,9 +441,10 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
        obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
        obj = value_cast (this_ref, obj);
@@ -475,14 +454,14 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_type))
        obj = value_cast (this_type, obj);
     }
-  gdbpy_ref py_value_obj (value_to_value_object (obj));
+  gdbpy_ref<> py_value_obj (value_to_value_object (obj));
   if (py_value_obj == NULL)
     {
       gdbpy_print_stack ();
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref py_arg_tuple (PyTuple_New (nargs + 1));
+  gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
   if (py_arg_tuple == NULL)
     {
       gdbpy_print_stack ();
@@ -505,7 +484,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
     }
 
-  gdbpy_ref py_result_type
+  gdbpy_ref<> py_result_type
     (PyObject_CallObject (get_result_type_method.get (), py_arg_tuple.get ()));
   if (py_result_type == NULL)
     {
@@ -526,24 +505,20 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
   return EXT_LANG_RC_OK;
 }
 
-/* Implementation of invoke_xmethod for Python.  */
+/* See declaration.  */
 
 struct value *
-gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
-                     struct xmethod_worker *worker,
-                     struct value *obj, struct value **args, int nargs)
+python_xmethod_worker::invoke (struct value *obj, struct value **args,
+                              int nargs)
 {
+  gdbpy_enter enter_py (get_current_arch (), current_language);
+
   int i;
   struct type *obj_type, *this_type;
   struct value *res = NULL;
-  struct gdbpy_worker_data *worker_data
-    = (struct gdbpy_worker_data *) worker->data;
-  PyObject *xmethod_worker = worker_data->worker;
-
-  gdbpy_enter enter_py (get_current_arch (), current_language);
 
   obj_type = check_typedef (value_type (obj));
-  this_type = check_typedef (type_object_to_type (worker_data->this_type));
+  this_type = check_typedef (type_object_to_type (m_this_type));
   if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
     {
       struct type *this_ptr = lookup_pointer_type (this_type);
@@ -551,9 +526,10 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
        obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref
+       = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
        obj = value_cast (this_ref, obj);
@@ -563,14 +539,14 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_type))
        obj = value_cast (this_type, obj);
     }
-  gdbpy_ref py_value_obj (value_to_value_object (obj));
+  gdbpy_ref<> py_value_obj (value_to_value_object (obj));
   if (py_value_obj == NULL)
     {
       gdbpy_print_stack ();
       error (_("Error while executing Python code."));
     }
 
-  gdbpy_ref py_arg_tuple (PyTuple_New (nargs + 1));
+  gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
   if (py_arg_tuple == NULL)
     {
       gdbpy_print_stack ();
@@ -594,8 +570,8 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
     }
 
-  gdbpy_ref py_result (PyObject_CallObject (xmethod_worker,
-                                           py_arg_tuple.get ()));
+  gdbpy_ref<> py_result (PyObject_CallObject (m_py_worker,
+                                             py_arg_tuple.get ()));
   if (py_result == NULL)
     {
       gdbpy_print_stack ();
@@ -620,24 +596,15 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
   return res;
 }
 
-/* Creates a new Python xmethod_worker object.
-   The new object has data of type 'struct gdbpy_worker_data' composed
-   with the components PY_WORKER and THIS_TYPE.  */
-
-static struct xmethod_worker *
-new_python_xmethod_worker (PyObject *py_worker, PyObject *this_type)
+python_xmethod_worker::python_xmethod_worker (PyObject *py_worker,
+                                              PyObject *this_type)
+: xmethod_worker (&extension_language_python),
+  m_py_worker (py_worker), m_this_type (this_type)
 {
-  struct gdbpy_worker_data *data;
+  gdb_assert (m_py_worker != NULL && m_this_type != NULL);
 
-  gdb_assert (py_worker != NULL && this_type != NULL);
-
-  data = XCNEW (struct gdbpy_worker_data);
-  data->worker = py_worker;
-  data->this_type = this_type;
   Py_INCREF (py_worker);
   Py_INCREF (this_type);
-
-  return new_xmethod_worker (&extension_language_python, data);
 }
 
 int
This page took 0.033127 seconds and 4 git commands to generate.