xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h (revision c1d1a752cea105dba1aa999bc90feb5faa974bec)
1 //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
10 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
11 
12 #if LLDB_ENABLE_PYTHON
13 
14 // clang-format off
15 // LLDB Python header must be included first
16 #include "lldb-python.h"
17 //clang-format on
18 #endif
19 
20 #include "lldb/Host/Config.h"
21 
22 #include <optional>
23 #include <string>
24 
25 #if LLDB_ENABLE_PYTHON
26 
27 #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
28 #include "lldb/lldb-forward.h"
29 #include "lldb/lldb-types.h"
30 #include "llvm/Support/Error.h"
31 
32 namespace lldb {
33 class SBEvent;
34 class SBCommandReturnObject;
35 class SBValue;
36 class SBStream;
37 class SBStructuredData;
38 class SBFileSpec;
39 class SBModuleSpec;
40 class SBStringList;
41 } // namespace lldb
42 
43 namespace lldb_private {
44 namespace python {
45 
46 typedef struct swig_type_info swig_type_info;
47 
48 python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);
49 
50 /// A class that automatically clears an SB object when it goes out of scope.
51 /// Use for cases where the SB object points to a temporary/unowned entity.
52 template <typename T> class ScopedPythonObject : PythonObject {
53 public:
54   ScopedPythonObject(T *sb, swig_type_info *info)
55       : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
56   ~ScopedPythonObject() {
57     if (m_sb)
58       *m_sb = T();
59   }
60   ScopedPythonObject(ScopedPythonObject &&rhs)
61       : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
62   ScopedPythonObject(const ScopedPythonObject &) = delete;
63   ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
64   ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
65 
66   const PythonObject &obj() const { return *this; }
67 
68 private:
69   T *m_sb;
70 };
71 
72 // TODO: We may want to support other languages in the future w/ SWIG (we
73 // already support Lua right now, for example). We could create a generic
74 // SWIGBridge class and have this one specialize it, something like this:
75 //
76 // <typename T>
77 // class SWIGBridge {
78 //   static T ToSWIGWrapper(...);
79 // };
80 //
81 // class SWIGPythonBridge : public SWIGBridge<PythonObject> {
82 //   template<> static PythonObject ToSWIGWrapper(...);
83 // };
84 //
85 // And we should be able to more easily support things like Lua
86 class SWIGBridge {
87 public:
88   static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
89   static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);
90   static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);
91   static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);
92   static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);
93   static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);
94   static PythonObject ToSWIGWrapper(const Status &status);
95   static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);
96   static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);
97   static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);
98   static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);
99   static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);
100   static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);
101   static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp);
102   static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
103   static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
104   static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
105   static PythonObject ToSWIGWrapper(const Stream *stream);
106   static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb);
107   static PythonObject ToSWIGWrapper(Event *event);
108 
109   static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
110   static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
111   static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
112 
113   static PythonObject
114   ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
115   static PythonObject
116   ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb);
117   static PythonObject
118   ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb);
119 
120   static python::ScopedPythonObject<lldb::SBCommandReturnObject>
121   ToSWIGWrapper(CommandReturnObject &cmd_retobj);
122   // These prototypes are the Pythonic implementations of the required
123   // callbacks. Although these are scripting-language specific, their definition
124   // depends on the public API.
125 
126   static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
127       const char *python_function_name, const char *session_dictionary_name,
128       const lldb::StackFrameSP &sb_frame,
129       const lldb::BreakpointLocationSP &sb_bp_loc,
130       const lldb_private::StructuredDataImpl &args_impl);
131 
132   static bool LLDBSwigPythonWatchpointCallbackFunction(
133       const char *python_function_name, const char *session_dictionary_name,
134       const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
135 
136   static bool
137   LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name,
138                                           const char *session_dictionary_name,
139                                           lldb::TypeImplSP type_impl_sp);
140 
141   static bool LLDBSwigPythonCallTypeScript(
142       const char *python_function_name, const void *session_dictionary,
143       const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
144       const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);
145 
146   static python::PythonObject
147   LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
148                                         const char *session_dictionary_name,
149                                         const lldb::ValueObjectSP &valobj_sp);
150 
151   static python::PythonObject
152   LLDBSwigPythonCreateCommandObject(const char *python_class_name,
153                                     const char *session_dictionary_name,
154                                     lldb::DebuggerSP debugger_sp);
155 
156   static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
157       const char *python_class_name, const char *session_dictionary_name,
158       const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
159 
160   static unsigned int
161   LLDBSwigPythonCallBreakpointResolver(void *implementor,
162                                        const char *method_name,
163                                        lldb_private::SymbolContext *sym_ctx);
164 
165   static python::PythonObject LLDBSwigPythonCreateScriptedStopHook(
166       lldb::TargetSP target_sp, const char *python_class_name,
167       const char *session_dictionary_name, const StructuredDataImpl &args,
168       lldb_private::Status &error);
169 
170   static bool
171   LLDBSwigPythonStopHookCallHandleStop(void *implementor,
172                                        lldb::ExecutionContextRefSP exc_ctx,
173                                        lldb::StreamSP stream);
174 
175   static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,
176                                                     uint32_t max);
177 
178   static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor,
179                                                   uint32_t idx);
180 
181   static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,
182                                                     const char *child_name);
183 
184   static lldb::ValueObjectSP
185   LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
186 
187   static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);
188 
189   static bool
190   LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor);
191 
192   static PyObject *
193   LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
194 
195   static bool
196   LLDBSwigPythonCallCommand(const char *python_function_name,
197                             const char *session_dictionary_name,
198                             lldb::DebuggerSP debugger, const char *args,
199                             lldb_private::CommandReturnObject &cmd_retobj,
200                             lldb::ExecutionContextRefSP exe_ctx_ref_sp);
201 
202   static bool
203   LLDBSwigPythonCallCommandObject(PyObject *implementor,
204                                   lldb::DebuggerSP debugger, const char *args,
205                                   lldb_private::CommandReturnObject &cmd_retobj,
206                                   lldb::ExecutionContextRefSP exe_ctx_ref_sp);
207   static bool
208   LLDBSwigPythonCallParsedCommandObject(PyObject *implementor,
209                                   lldb::DebuggerSP debugger,
210                                   StructuredDataImpl &args_impl,
211                                   lldb_private::CommandReturnObject &cmd_retobj,
212                                   lldb::ExecutionContextRefSP exe_ctx_ref_sp);
213 
214   static std::optional<std::string>
215   LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor,
216                                                    std::string &command);
217 
218   static bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
219                                            const char *session_dictionary_name,
220                                            lldb::DebuggerSP debugger);
221 
222   static python::PythonObject
223   LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
224                                const char *session_dictionary_name,
225                                const lldb::ProcessSP &process_sp);
226 
227   static python::PythonObject
228   LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
229                                        const char *session_dictionary_name);
230 
231   static PyObject *
232   LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
233                                         const lldb::StackFrameSP &frame_sp);
234 
235   static bool LLDBSWIGPythonRunScriptKeywordProcess(
236       const char *python_function_name, const char *session_dictionary_name,
237       const lldb::ProcessSP &process, std::string &output);
238 
239   static std::optional<std::string>
240   LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
241                                        const char *session_dictionary_name,
242                                        lldb::ThreadSP thread);
243 
244   static bool LLDBSWIGPythonRunScriptKeywordTarget(
245       const char *python_function_name, const char *session_dictionary_name,
246       const lldb::TargetSP &target, std::string &output);
247 
248   static std::optional<std::string>
249   LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
250                                       const char *session_dictionary_name,
251                                       lldb::StackFrameSP frame);
252 
253   static bool LLDBSWIGPythonRunScriptKeywordValue(
254       const char *python_function_name, const char *session_dictionary_name,
255       const lldb::ValueObjectSP &value, std::string &output);
256 
257   static void *
258   LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
259                                    const lldb::TargetSP &target_sp);
260 };
261 
262 void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
263 void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
264 void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
265 void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
266 void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
267 void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
268 void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
269 void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
270 void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
271 } // namespace python
272 
273 } // namespace lldb_private
274 
275 #endif // LLDB_ENABLE_PYTHON
276 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
277