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