https://github.com/chelcassanova created 
https://github.com/llvm/llvm-project/pull/95318

This commit refactors the typemaps and static functions used in the SWIG 
typemaps and wrappers to be in their own SWIG files that are included in the 
main `python.swig` file.

>From 51ea2794e3ea5369d5197103775476819154b019 Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova <chelsea_cassan...@apple.com>
Date: Wed, 12 Jun 2024 14:42:39 -0700
Subject: [PATCH] [lldb][swig] Refactor callback typemaps and functions

This commit refactors the typemaps and static functions used in the SWIG
typemaps and wrappers to be in their own SWIG files that are included in
the main `python.swig` file.
---
 .../python/python-callbacks-typemaps.swig     | 119 ++++++++++++++++++
 .../python/python-callbacks-wrapper.swig      | 101 +++++++++++++++
 lldb/bindings/python/python-typemaps.swig     | 116 -----------------
 lldb/bindings/python/python-wrapper.swig      |  96 --------------
 lldb/bindings/python/python.swig              |   2 +
 5 files changed, 222 insertions(+), 212 deletions(-)
 create mode 100644 lldb/bindings/python/python-callbacks-typemaps.swig
 create mode 100644 lldb/bindings/python/python-callbacks-wrapper.swig

diff --git a/lldb/bindings/python/python-callbacks-typemaps.swig 
b/lldb/bindings/python/python-callbacks-typemaps.swig
new file mode 100644
index 0000000000000..71f01c1144557
--- /dev/null
+++ b/lldb/bindings/python/python-callbacks-typemaps.swig
@@ -0,0 +1,119 @@
+/*
+ Typemaps specific to callback functions in LLDB. If editing this file
+ use the Python C API to access Python objects instead of using 
PythonDataObjects.
+*/
+
+// For Log::LogOutputCallback
+%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
+  if (!($input == Py_None ||
+        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
+    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+    SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonLogOutputCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
+}
+
+// For lldb::SBDebuggerDestroyCallback
+%typemap(in) (lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) {
+  if (!($input == Py_None ||
+        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
+    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+    SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBDebuggerTerminateCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::SBDebuggerDestroyCallback destroy_callback, void 
*baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
+}
+
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
+    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+    SWIG_fail;
+  }
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
+}
+// For lldb::SBPlatformLocateModuleCallback
+%typemap(in) (lldb::SBPlatformLocateModuleCallback callback,
+              void *callback_baton) {
+  if (!($input == Py_None ||
+        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
+    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+    SWIG_fail;
+  }
+
+  if ($input == Py_None) {
+    $1 = nullptr;
+    $2 = nullptr;
+  } else {
+    PythonCallable callable = Retain<PythonCallable>($input);
+    if (!callable.IsValid()) {
+      PyErr_SetString(PyExc_TypeError, "Need a valid callable object");
+      SWIG_fail;
+    }
+
+    llvm::Expected<PythonCallable::ArgInfo> arg_info = callable.GetArgInfo();
+    if (!arg_info) {
+      PyErr_SetString(PyExc_TypeError,
+                      ("Could not get arguments: " +
+                          llvm::toString(arg_info.takeError())).c_str());
+      SWIG_fail;
+    }
+
+    if (arg_info.get().max_positional_args != 3) {
+      PyErr_SetString(PyExc_TypeError, "Expected 3 argument callable object");
+      SWIG_fail;
+    }
+
+    // NOTE: When this is called multiple times, this will leak the Python
+    // callable object as other callbacks, because this does not call Py_DECREF
+    // the object. But it should be almost zero impact since this method is
+    // expected to be called only once.
+
+    // Don't lose the callback reference
+    Py_INCREF($input);
+
+    $1 = LLDBSwigPythonCallLocateModuleCallback;
+    $2 = $input;
+  }
+}
+
+%typemap(typecheck) (lldb::SBPlatformLocateModuleCallback callback,
+                     void *callback_baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
+}
diff --git a/lldb/bindings/python/python-callbacks-wrapper.swig 
b/lldb/bindings/python/python-callbacks-wrapper.swig
new file mode 100644
index 0000000000000..0b48436ef3102
--- /dev/null
+++ b/lldb/bindings/python/python-callbacks-wrapper.swig
@@ -0,0 +1,101 @@
+/*
+  Wrapper that holds static functions used for callback typemaps in LLDB.
+*/
+
+%header %{
+// For the LogOutputCallback functions
+static void LLDBSwigPythonCallPythonLogOutputCallback(const char *str,
+                                                      void *baton) {
+  if (baton != Py_None) {
+    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+    PyObject *result = PyObject_CallFunction(
+        reinterpret_cast<PyObject *>(baton), const_cast<char *>("s"), str);
+    Py_XDECREF(result);
+    SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+}
+
+// For DebuggerTerminateCallback functions
+static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t debugger_id,
+                                                      void *baton) {
+  if (baton != Py_None) {
+    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+    PyObject *result = PyObject_CallFunction(
+        reinterpret_cast<PyObject *>(baton), const_cast<char *>("l"), 
debugger_id);
+    Py_XDECREF(result);
+    SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+}
+
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool ret_val = false;
+  if (baton != Py_None) {
+    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+    // Create a PyList of items since we're going to pass it to the callback 
as a tuple
+    // of arguments.
+    PyObject *py_argv = PyList_New(0);
+    for (const char **arg = argv; arg && *arg; arg++) {
+      std::string arg_string = *arg;
+      PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), 
arg_string.size());
+      PyList_Append(py_argv, py_string);
+    }
+
+    PyObject *result = PyObject_CallObject(
+        reinterpret_cast<PyObject *>(baton), PyList_AsTuple(py_argv));
+    ret_val = result ? PyObject_IsTrue(result) : false;
+    Py_XDECREF(result);
+    SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return ret_val;
+}
+
+static SBError LLDBSwigPythonCallLocateModuleCallback(
+    void *callback_baton, const SBModuleSpec &module_spec_sb,
+    SBFileSpec &module_file_spec_sb, SBFileSpec &symbol_file_spec_sb) {
+  SWIG_Python_Thread_Block swig_thread_block;
+
+  PyErr_Cleaner py_err_cleaner(true);
+  PythonObject module_spec_arg = SWIGBridge::ToSWIGWrapper(
+      std::make_unique<SBModuleSpec>(module_spec_sb));
+  PythonObject module_file_spec_arg = SWIGBridge::ToSWIGWrapper(
+      std::make_unique<SBFileSpec>(module_file_spec_sb));
+  PythonObject symbol_file_spec_arg = SWIGBridge::ToSWIGWrapper(
+      std::make_unique<SBFileSpec>(symbol_file_spec_sb));
+
+  PythonCallable callable =
+      Retain<PythonCallable>(reinterpret_cast<PyObject *>(callback_baton));
+  if (!callable.IsValid()) {
+    return SBError("The callback callable is not valid.");
+  }
+
+  PythonObject result = callable(module_spec_arg, module_file_spec_arg,
+                                 symbol_file_spec_arg);
+
+  if (!result.IsAllocated())
+    return SBError("No result.");
+  lldb::SBError *sb_error_ptr = nullptr;
+  if (SWIG_ConvertPtr(result.get(), (void **)&sb_error_ptr,
+                      SWIGTYPE_p_lldb__SBError, 0) == -1) {
+    return SBError("Result is not SBError.");
+  }
+
+  if (sb_error_ptr->Success()) {
+    lldb::SBFileSpec *sb_module_file_spec_ptr = nullptr;
+    if (SWIG_ConvertPtr(module_file_spec_arg.get(),
+                        (void **)&sb_module_file_spec_ptr,
+                        SWIGTYPE_p_lldb__SBFileSpec, 0) == -1)
+      return SBError("module_file_spec is not SBFileSpec.");
+
+    lldb::SBFileSpec *sb_symbol_file_spec_ptr = nullptr;
+    if (SWIG_ConvertPtr(symbol_file_spec_arg.get(),
+                        (void **)&sb_symbol_file_spec_ptr,
+                        SWIGTYPE_p_lldb__SBFileSpec, 0) == -1)
+      return SBError("symbol_file_spec is not SBFileSpec.");
+
+    module_file_spec_sb = *sb_module_file_spec_ptr;
+    symbol_file_spec_sb = *sb_symbol_file_spec_ptr;
+  }
+
+  return *sb_error_ptr;
+}
+%}
diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index c39594c7df041..3af54826e8248 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,71 +427,6 @@ template <> bool SetNumberFromPyObject<double>(double 
&number, PyObject *obj) {
   free($1);
 }
 
-// For Log::LogOutputCallback
-%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
-  if (!($input == Py_None ||
-        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
-    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
-    SWIG_fail;
-  }
-
-  // FIXME (filcab): We can't currently check if our callback is already
-  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
-  // baton) nor can we just remove all traces of a callback, if we want to
-  // revert to a file logging mechanism.
-
-  // Don't lose the callback reference
-  Py_INCREF($input);
-  $1 = LLDBSwigPythonCallPythonLogOutputCallback;
-  $2 = $input;
-}
-
-%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
-  $1 = $input == Py_None;
-  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
-}
-
-// For lldb::SBDebuggerDestroyCallback
-%typemap(in) (lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) {
-  if (!($input == Py_None ||
-        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
-    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
-    SWIG_fail;
-  }
-
-  // FIXME (filcab): We can't currently check if our callback is already
-  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
-  // baton) nor can we just remove all traces of a callback, if we want to
-  // revert to a file logging mechanism.
-
-  // Don't lose the callback reference
-  Py_INCREF($input);
-  $1 = LLDBSwigPythonCallPythonSBDebuggerTerminateCallback;
-  $2 = $input;
-}
-
-%typemap(typecheck) (lldb::SBDebuggerDestroyCallback destroy_callback, void 
*baton) {
-  $1 = $input == Py_None;
-  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
-}
-
-%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
-  if (!($input == Py_None ||
-        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
-    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
-    SWIG_fail;
-  }
-
-  // Don't lose the callback reference.
-  Py_INCREF($input);
-  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
-  $2 = $input;
-}
-%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {
-  $1 = $input == Py_None;
-  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
-}
-
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
@@ -661,54 +596,3 @@ template <> bool SetNumberFromPyObject<double>(double 
&number, PyObject *obj) {
     return NULL;
   }
 }
-
-// For lldb::SBPlatformLocateModuleCallback
-%typemap(in) (lldb::SBPlatformLocateModuleCallback callback,
-              void *callback_baton) {
-  if (!($input == Py_None ||
-        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
-    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
-    SWIG_fail;
-  }
-
-  if ($input == Py_None) {
-    $1 = nullptr;
-    $2 = nullptr;
-  } else {
-    PythonCallable callable = Retain<PythonCallable>($input);
-    if (!callable.IsValid()) {
-      PyErr_SetString(PyExc_TypeError, "Need a valid callable object");
-      SWIG_fail;
-    }
-
-    llvm::Expected<PythonCallable::ArgInfo> arg_info = callable.GetArgInfo();
-    if (!arg_info) {
-      PyErr_SetString(PyExc_TypeError,
-                      ("Could not get arguments: " +
-                          llvm::toString(arg_info.takeError())).c_str());
-      SWIG_fail;
-    }
-
-    if (arg_info.get().max_positional_args != 3) {
-      PyErr_SetString(PyExc_TypeError, "Expected 3 argument callable object");
-      SWIG_fail;
-    }
-
-    // NOTE: When this is called multiple times, this will leak the Python
-    // callable object as other callbacks, because this does not call Py_DECREF
-    // the object. But it should be almost zero impact since this method is
-    // expected to be called only once.
-
-    // Don't lose the callback reference
-    Py_INCREF($input);
-
-    $1 = LLDBSwigPythonCallLocateModuleCallback;
-    $2 = $input;
-  }
-}
-
-%typemap(typecheck) (lldb::SBPlatformLocateModuleCallback callback,
-                     void *callback_baton) {
-  $1 = $input == Py_None;
-  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
-}
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index bd3de8ce5d46c..f2cdc39626dc0 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1074,100 +1074,4 @@ lldb::ValueObjectSP 
lldb_private::python::SWIGBridge::LLDBSWIGPython_GetValueObj
   }
   return valobj_sp;
 }
-
-// For the LogOutputCallback functions
-static void LLDBSwigPythonCallPythonLogOutputCallback(const char *str,
-                                                      void *baton) {
-  if (baton != Py_None) {
-    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-    PyObject *result = PyObject_CallFunction(
-        reinterpret_cast<PyObject *>(baton), const_cast<char *>("s"), str);
-    Py_XDECREF(result);
-    SWIG_PYTHON_THREAD_END_BLOCK;
-  }
-}
-
-// For DebuggerTerminateCallback functions
-static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t debugger_id,
-                                                      void *baton) {
-  if (baton != Py_None) {
-    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-    PyObject *result = PyObject_CallFunction(
-        reinterpret_cast<PyObject *>(baton), const_cast<char *>("l"), 
debugger_id);
-    Py_XDECREF(result);
-    SWIG_PYTHON_THREAD_END_BLOCK;
-  }
-}
-
-static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
-  bool ret_val = false;
-  if (baton != Py_None) {
-    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-    // Create a PyList of items since we're going to pass it to the callback 
as a tuple
-    // of arguments.
-    PyObject *py_argv = PyList_New(0);
-    for (const char **arg = argv; arg && *arg; arg++) {
-      std::string arg_string = *arg;
-      PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), 
arg_string.size());
-      PyList_Append(py_argv, py_string);
-    }
-
-    PyObject *result = PyObject_CallObject(
-        reinterpret_cast<PyObject *>(baton), PyList_AsTuple(py_argv));
-    ret_val = result ? PyObject_IsTrue(result) : false;
-    Py_XDECREF(result);
-    SWIG_PYTHON_THREAD_END_BLOCK;
-  }
-  return ret_val;
-}
-
-static SBError LLDBSwigPythonCallLocateModuleCallback(
-    void *callback_baton, const SBModuleSpec &module_spec_sb,
-    SBFileSpec &module_file_spec_sb, SBFileSpec &symbol_file_spec_sb) {
-  SWIG_Python_Thread_Block swig_thread_block;
-
-  PyErr_Cleaner py_err_cleaner(true);
-  PythonObject module_spec_arg = SWIGBridge::ToSWIGWrapper(
-      std::make_unique<SBModuleSpec>(module_spec_sb));
-  PythonObject module_file_spec_arg = SWIGBridge::ToSWIGWrapper(
-      std::make_unique<SBFileSpec>(module_file_spec_sb));
-  PythonObject symbol_file_spec_arg = SWIGBridge::ToSWIGWrapper(
-      std::make_unique<SBFileSpec>(symbol_file_spec_sb));
-
-  PythonCallable callable =
-      Retain<PythonCallable>(reinterpret_cast<PyObject *>(callback_baton));
-  if (!callable.IsValid()) {
-    return SBError("The callback callable is not valid.");
-  }
-
-  PythonObject result = callable(module_spec_arg, module_file_spec_arg,
-                                 symbol_file_spec_arg);
-
-  if (!result.IsAllocated())
-    return SBError("No result.");
-  lldb::SBError *sb_error_ptr = nullptr;
-  if (SWIG_ConvertPtr(result.get(), (void **)&sb_error_ptr,
-                      SWIGTYPE_p_lldb__SBError, 0) == -1) {
-    return SBError("Result is not SBError.");
-  }
-
-  if (sb_error_ptr->Success()) {
-    lldb::SBFileSpec *sb_module_file_spec_ptr = nullptr;
-    if (SWIG_ConvertPtr(module_file_spec_arg.get(),
-                        (void **)&sb_module_file_spec_ptr,
-                        SWIGTYPE_p_lldb__SBFileSpec, 0) == -1)
-      return SBError("module_file_spec is not SBFileSpec.");
-
-    lldb::SBFileSpec *sb_symbol_file_spec_ptr = nullptr;
-    if (SWIG_ConvertPtr(symbol_file_spec_arg.get(),
-                        (void **)&sb_symbol_file_spec_ptr,
-                        SWIGTYPE_p_lldb__SBFileSpec, 0) == -1)
-      return SBError("symbol_file_spec is not SBFileSpec.");
-
-    module_file_spec_sb = *sb_module_file_spec_ptr;
-    symbol_file_spec_sb = *sb_symbol_file_spec_ptr;
-  }
-
-  return *sb_error_ptr;
-}
 %}
diff --git a/lldb/bindings/python/python.swig b/lldb/bindings/python/python.swig
index 278c0eed2bab2..e4944b3ebe413 100644
--- a/lldb/bindings/python/python.swig
+++ b/lldb/bindings/python/python.swig
@@ -110,6 +110,7 @@ def lldb_iter(obj, getsize, getelem):
 
 %include <std_string.i>
 %include "python-typemaps.swig"
+%include "python-callbacks-typemaps.swig"
 %include "macros.swig"
 %include "headers.swig"
 
@@ -125,6 +126,7 @@ using namespace lldb;
 %include "interfaces.swig"
 %include "python-extensions.swig"
 %include "python-wrapper.swig"
+%include "python-callbacks-wrapper.swig"
 
 %pythoncode%{
 debugger_unique_id = 0

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to