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