public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Allow calling of C++ methods from python
       [not found] <20231215151938.3887-1-ssbssa.ref@yahoo.de>
@ 2023-12-15 15:19 ` Hannes Domani
  2023-12-16  0:30   ` Tom Tromey
  2024-02-08 16:29   ` Tom Tromey
  0 siblings, 2 replies; 8+ messages in thread
From: Hannes Domani @ 2023-12-15 15:19 UTC (permalink / raw)
  To: gdb-patches

Currently it's not possible to call C++ methods from python.
Using this example:
```
class B
{
  static int static_func ();
  int arg0_func ();
  int arg1_func (int arg1);
  int arg2_func (int arg1, int arg2);
};

B *b_obj = new B;
```

Trying to call B::static_func gives this error:
```
(gdb) py b_obj = gdb.parse_and_eval('b_obj')
(gdb) py print(b_obj['static_func']())
Traceback (most recent call last):
  File "<string>", line 1, in <module>
RuntimeError: Value is not callable (not TYPE_CODE_FUNC).
Error while executing Python code.
```

TYPE_CODE_METHOD was simply missing as a possible type in
valpy_call, now the same is possible:
```
(gdb) py b_obj = gdb.parse_and_eval('b_obj')
(gdb) py print(b_obj['static_func']())
1111
```

Note that it's necessary to explicitely add the this pointer
as the first argument in a call of non-static methods:
```
(gdb) py print(b_obj['arg0_func']())
Traceback (most recent call last):
  File "<string>", line 1, in <module>
gdb.error: Too few arguments in function call.
Error while executing Python code.
(gdb) py print(b_obj['arg0_func'](b_obj))
198
```

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13326
---
 gdb/python/py-value.c                    |  5 +++--
 gdb/testsuite/gdb.python/py-value-cc.cc  | 25 ++++++++++++++++++++++++
 gdb/testsuite/gdb.python/py-value-cc.exp | 12 ++++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index f360f849ce6..f5e22593254 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1214,10 +1214,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  if (ftype->code () != TYPE_CODE_FUNC)
+  if (ftype->code () != TYPE_CODE_FUNC && ftype->code () != TYPE_CODE_METHOD)
     {
       PyErr_SetString (PyExc_RuntimeError,
-		       _("Value is not callable (not TYPE_CODE_FUNC)."));
+		       _("Value is not callable (not TYPE_CODE_FUNC"
+			 " or TYPE_CODE_METHOD)."));
       return NULL;
     }
 
diff --git a/gdb/testsuite/gdb.python/py-value-cc.cc b/gdb/testsuite/gdb.python/py-value-cc.cc
index d82e385d6c5..61a8f1a7b0f 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.cc
+++ b/gdb/testsuite/gdb.python/py-value-cc.cc
@@ -37,8 +37,33 @@ union U {
 class B : public A {
  public:
   char a;
+
+  static int static_func ();
+  int arg0_func ();
+  int arg1_func (int arg1);
+  int arg2_func (int arg1, int arg2);
 };
 
+int B::static_func ()
+{
+  return 1111;
+}
+
+int B::arg0_func ()
+{
+  return A::a + a;
+}
+
+int B::arg1_func (int arg1)
+{
+  return a * arg1;
+}
+
+int B::arg2_func (int arg1, int arg2)
+{
+  return a * arg1 + arg2;
+}
+
 struct X
 {
   union { int x; char y; };
diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp
index b6571cd8297..6a424e3b407 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.exp
+++ b/gdb/testsuite/gdb.python/py-value-cc.exp
@@ -99,3 +99,15 @@ gdb_test "python print(uu\[uu_fields\[1\]\]\['a'\])" "1000" "uu.a via field"
 # Test overloaded operators.
 gdb_test_no_output "python a = gdb.parse_and_eval('a')" "init a"
 gdb_test "python print(a + 5)" "10" "a + 5"
+
+# Test inferior function calls of methods.
+gdb_test "py print(b_obj\['static_func'\]())" "1111"
+gdb_test "py print(b_obj\['arg0_func'\]())" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg0_func'\](b_obj))" "198"
+gdb_test "py print(b_obj\['arg1_func'\]())" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg1_func'\](b_obj))" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg1_func'\](b_obj, 3))" "294"
+gdb_test "py print(b_obj\['arg2_func'\]())" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg2_func'\](b_obj))" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg2_func'\](b_obj, 4))" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg2_func'\](b_obj, 5, 6))" "496"
-- 
2.35.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2023-12-15 15:19 ` [PATCH] Allow calling of C++ methods from python Hannes Domani
@ 2023-12-16  0:30   ` Tom Tromey
  2023-12-16 11:40     ` Hannes Domani
  2024-02-08 16:29   ` Tom Tromey
  1 sibling, 1 reply; 8+ messages in thread
From: Tom Tromey @ 2023-12-16  0:30 UTC (permalink / raw)
  To: Hannes Domani; +Cc: gdb-patches

>>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:

Hannes>   static int static_func ();

Hannes> (gdb) py b_obj = gdb.parse_and_eval('b_obj')
Hannes> (gdb) py print(b_obj['static_func']())
Hannes> Traceback (most recent call last):
Hannes>   File "<string>", line 1, in <module>
Hannes> RuntimeError: Value is not callable (not TYPE_CODE_FUNC).

I'm a bit surprised that a static method is not TYPE_CODE_FUNC.
It seems like it should be, because these are really just functions.

Hannes> (gdb) py print(b_obj['arg0_func']())
Hannes> Traceback (most recent call last):
Hannes>   File "<string>", line 1, in <module>
Hannes> gdb.error: Too few arguments in function call.
Hannes> Error while executing Python code.
Hannes> (gdb) py print(b_obj['arg0_func'](b_obj))
Hannes> 198

How does this interact with overloading?

It seems to me that either b_obj['name'] has to return some kind of
overload set, or we need a different API, like b_obj.call_method('name', ...).

In the latter case we could have it automatically supply 'this', at
least when it's needed.

Tom

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2023-12-16  0:30   ` Tom Tromey
@ 2023-12-16 11:40     ` Hannes Domani
  2024-01-03 10:38       ` Hannes Domani
  0 siblings, 1 reply; 8+ messages in thread
From: Hannes Domani @ 2023-12-16 11:40 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

 Am Samstag, 16. Dezember 2023, 01:30:31 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben:

> >>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
>
> Hannes>  static int static_func ();
>
> Hannes> (gdb) py b_obj = gdb.parse_and_eval('b_obj')
> Hannes> (gdb) py print(b_obj['static_func']())
> Hannes> Traceback (most recent call last):
> Hannes>  File "<string>", line 1, in <module>
> Hannes> RuntimeError: Value is not callable (not TYPE_CODE_FUNC).
>
> I'm a bit surprised that a static method is not TYPE_CODE_FUNC.
> It seems like it should be, because these are really just functions.

I never really questioned it being TYPE_CODE_METHOD, I was just wondering
instead if there is a flag that tells us that it is a static method.


> Hannes> (gdb) py print(b_obj['arg0_func']())
> Hannes> Traceback (most recent call last):
> Hannes>  File "<string>", line 1, in <module>
> Hannes> gdb.error: Too few arguments in function call.
> Hannes> Error while executing Python code.
> Hannes> (gdb) py print(b_obj['arg0_func'](b_obj))
> Hannes> 198
>
> How does this interact with overloading?

Probably as you expected, it doesn't work, since the [] operator
of gdb.Value doesn't know what to do:

(gdb) py print(b_obj['overloaded_func'])
Traceback (most recent call last):
  File "<string>", line 1, in <module>
gdb.error: cannot resolve overloaded method `overloaded_func': no arguments supplied
Error while executing Python code.


> It seems to me that either b_obj['name'] has to return some kind of
> overload set, or we need a different API, like b_obj.call_method('name', ...).
>
> In the latter case we could have it automatically supply 'this', at
> least when it's needed.

The overload set would probably be relatively easy to implement, while
the call_method would be easier to use, if it automatically chooses the
right one based on the arguments.


Regards
Hannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2023-12-16 11:40     ` Hannes Domani
@ 2024-01-03 10:38       ` Hannes Domani
  2024-01-17 15:52         ` Hannes Domani
  0 siblings, 1 reply; 8+ messages in thread
From: Hannes Domani @ 2024-01-03 10:38 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

 Ping.


Am Samstag, 16. Dezember 2023, 12:40:25 MEZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:

> Am Samstag, 16. Dezember 2023, 01:30:31 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben:
>
> > >>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
> >
> > Hannes>  static int static_func ();
> >
> > Hannes> (gdb) py b_obj = gdb.parse_and_eval('b_obj')
> > Hannes> (gdb) py print(b_obj['static_func']())
> > Hannes> Traceback (most recent call last):
> > Hannes>  File "<string>", line 1, in <module>
> > Hannes> RuntimeError: Value is not callable (not TYPE_CODE_FUNC).
> >
> > I'm a bit surprised that a static method is not TYPE_CODE_FUNC.
> > It seems like it should be, because these are really just functions.
>
> I never really questioned it being TYPE_CODE_METHOD, I was just wondering
> instead if there is a flag that tells us that it is a static method.
>
>
> > Hannes> (gdb) py print(b_obj['arg0_func']())
> > Hannes> Traceback (most recent call last):
> > Hannes>  File "<string>", line 1, in <module>
> > Hannes> gdb.error: Too few arguments in function call.
> > Hannes> Error while executing Python code.
> > Hannes> (gdb) py print(b_obj['arg0_func'](b_obj))
> > Hannes> 198
> >
> > How does this interact with overloading?
>
> Probably as you expected, it doesn't work, since the [] operator
> of gdb.Value doesn't know what to do:
>
> (gdb) py print(b_obj['overloaded_func'])
> Traceback (most recent call last):
>   File "<string>", line 1, in <module>
> gdb.error: cannot resolve overloaded method `overloaded_func': no arguments supplied
> Error while executing Python code.
>
>
> > It seems to me that either b_obj['name'] has to return some kind of
> > overload set, or we need a different API, like b_obj.call_method('name', ...).
> >
> > In the latter case we could have it automatically supply 'this', at
> > least when it's needed.
>
> The overload set would probably be relatively easy to implement, while
> the call_method would be easier to use, if it automatically chooses the
> right one based on the arguments.
>
>
> Regards
>
> Hannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2024-01-03 10:38       ` Hannes Domani
@ 2024-01-17 15:52         ` Hannes Domani
  2024-01-26 17:02           ` Hannes Domani
  0 siblings, 1 reply; 8+ messages in thread
From: Hannes Domani @ 2024-01-17 15:52 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

 Ping.


Am Mittwoch, 3. Januar 2024, 11:38:57 MEZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:

> Ping.
>
>
> Am Samstag, 16. Dezember 2023, 12:40:25 MEZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:
>
> > Am Samstag, 16. Dezember 2023, 01:30:31 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben:
> >
> > > >>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
> > >
> > > Hannes>  static int static_func ();
> > >
> > > Hannes> (gdb) py b_obj = gdb.parse_and_eval('b_obj')
> > > Hannes> (gdb) py print(b_obj['static_func']())
> > > Hannes> Traceback (most recent call last):
> > > Hannes>  File "<string>", line 1, in <module>
> > > Hannes> RuntimeError: Value is not callable (not TYPE_CODE_FUNC).
> > >
> > > I'm a bit surprised that a static method is not TYPE_CODE_FUNC.
> > > It seems like it should be, because these are really just functions.
> >
> > I never really questioned it being TYPE_CODE_METHOD, I was just wondering
> > instead if there is a flag that tells us that it is a static method.
> >
> >
> > > Hannes> (gdb) py print(b_obj['arg0_func']())
> > > Hannes> Traceback (most recent call last):
> > > Hannes>  File "<string>", line 1, in <module>
> > > Hannes> gdb.error: Too few arguments in function call.
> > > Hannes> Error while executing Python code.
> > > Hannes> (gdb) py print(b_obj['arg0_func'](b_obj))
> > > Hannes> 198
> > >
> > > How does this interact with overloading?
> >
> > Probably as you expected, it doesn't work, since the [] operator
> > of gdb.Value doesn't know what to do:
> >
> > (gdb) py print(b_obj['overloaded_func'])
> > Traceback (most recent call last):
> >   File "<string>", line 1, in <module>
> > gdb.error: cannot resolve overloaded method `overloaded_func': no arguments supplied
> > Error while executing Python code.
> >
> >
> > > It seems to me that either b_obj['name'] has to return some kind of
> > > overload set, or we need a different API, like b_obj.call_method('name', ...).
> > >
> > > In the latter case we could have it automatically supply 'this', at
> > > least when it's needed.
> >
> > The overload set would probably be relatively easy to implement, while
> > the call_method would be easier to use, if it automatically chooses the
> > right one based on the arguments.
> >
> >
> > Regards
> >
> > Hannes


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2024-01-17 15:52         ` Hannes Domani
@ 2024-01-26 17:02           ` Hannes Domani
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Domani @ 2024-01-26 17:02 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

 Ping.


Am Mittwoch, 17. Januar 2024, 16:52:56 MEZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:

> Ping.
>
>
> Am Mittwoch, 3. Januar 2024, 11:38:57 MEZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:
>
> > Ping.
> >
> >
> > Am Samstag, 16. Dezember 2023, 12:40:25 MEZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:
> >
> > > Am Samstag, 16. Dezember 2023, 01:30:31 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben:
> > >
> > > > >>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
> > > >
> > > > Hannes>  static int static_func ();
> > > >
> > > > Hannes> (gdb) py b_obj = gdb.parse_and_eval('b_obj')
> > > > Hannes> (gdb) py print(b_obj['static_func']())
> > > > Hannes> Traceback (most recent call last):
> > > > Hannes>  File "<string>", line 1, in <module>
> > > > Hannes> RuntimeError: Value is not callable (not TYPE_CODE_FUNC).
> > > >
> > > > I'm a bit surprised that a static method is not TYPE_CODE_FUNC.
> > > > It seems like it should be, because these are really just functions.
> > >
> > > I never really questioned it being TYPE_CODE_METHOD, I was just wondering
> > > instead if there is a flag that tells us that it is a static method.
> > >
> > >
> > > > Hannes> (gdb) py print(b_obj['arg0_func']())
> > > > Hannes> Traceback (most recent call last):
> > > > Hannes>  File "<string>", line 1, in <module>
> > > > Hannes> gdb.error: Too few arguments in function call.
> > > > Hannes> Error while executing Python code.
> > > > Hannes> (gdb) py print(b_obj['arg0_func'](b_obj))
> > > > Hannes> 198
> > > >
> > > > How does this interact with overloading?
> > >
> > > Probably as you expected, it doesn't work, since the [] operator
> > > of gdb.Value doesn't know what to do:
> > >
> > > (gdb) py print(b_obj['overloaded_func'])
> > > Traceback (most recent call last):
> > >   File "<string>", line 1, in <module>
> > > gdb.error: cannot resolve overloaded method `overloaded_func': no arguments supplied
> > > Error while executing Python code.
> > >
> > >
> > > > It seems to me that either b_obj['name'] has to return some kind of
> > > > overload set, or we need a different API, like b_obj.call_method('name', ...).
> > > >
> > > > In the latter case we could have it automatically supply 'this', at
> > > > least when it's needed.
> > >
> > > The overload set would probably be relatively easy to implement, while
> > > the call_method would be easier to use, if it automatically chooses the
> > > right one based on the arguments.
> > >
> > >
> > > Regards
> > >
> > > Hannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2023-12-15 15:19 ` [PATCH] Allow calling of C++ methods from python Hannes Domani
  2023-12-16  0:30   ` Tom Tromey
@ 2024-02-08 16:29   ` Tom Tromey
  2024-02-08 19:11     ` Hannes Domani
  1 sibling, 1 reply; 8+ messages in thread
From: Tom Tromey @ 2024-02-08 16:29 UTC (permalink / raw)
  To: Hannes Domani; +Cc: gdb-patches

>>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:

Hannes> Currently it's not possible to call C++ methods from python.

Hannes> Note that it's necessary to explicitely add the this pointer
Hannes> as the first argument in a call of non-static methods:

While I think it would be good to handle overloading, it occurs to me
that we don't really try to do this for global calls either.  And, the
approach you've taken here does not prevent future improvements.

So, I think this is ok.  Thank you.

Approved-By: Tom Tromey <tom@tromey.com>

Tom

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow calling of C++ methods from python
  2024-02-08 16:29   ` Tom Tromey
@ 2024-02-08 19:11     ` Hannes Domani
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Domani @ 2024-02-08 19:11 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

 Am Donnerstag, 8. Februar 2024 um 17:29:11 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben:

> >>>>> "Hannes" == Hannes Domani <ssbssa@yahoo.de> writes:
>
> Hannes> Currently it's not possible to call C++ methods from python.
>
> Hannes> Note that it's necessary to explicitely add the this pointer
> Hannes> as the first argument in a call of non-static methods:
>
> While I think it would be good to handle overloading, it occurs to me
> that we don't really try to do this for global calls either.  And, the
> approach you've taken here does not prevent future improvements.
>
> So, I think this is ok.  Thank you.
>
> Approved-By: Tom Tromey <tom@tromey.com>

Pushed, thanks.


Hannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-02-08 19:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20231215151938.3887-1-ssbssa.ref@yahoo.de>
2023-12-15 15:19 ` [PATCH] Allow calling of C++ methods from python Hannes Domani
2023-12-16  0:30   ` Tom Tromey
2023-12-16 11:40     ` Hannes Domani
2024-01-03 10:38       ` Hannes Domani
2024-01-17 15:52         ` Hannes Domani
2024-01-26 17:02           ` Hannes Domani
2024-02-08 16:29   ` Tom Tromey
2024-02-08 19:11     ` Hannes Domani

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).