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 |
85 | ToSWIGWrapper(std::unique_ptr<lldb::SBCommandReturnObject> result_up); |
86 | static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); |
87 | static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); |
88 | static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); |
89 | static PythonObject ToSWIGWrapper(lldb::ModuleSP module_sp); |
90 | static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); |
91 | static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); |
92 | static PythonObject ToSWIGWrapper(Status &&status); |
93 | static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); |
94 | static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); |
95 | static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); |
96 | static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); |
97 | static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); |
98 | static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); |
99 | static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); |
100 | static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); |
101 | static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); |
102 | static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); |
103 | static PythonObject ToSWIGWrapper(const Stream *stream); |
104 | static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb); |
105 | static PythonObject ToSWIGWrapper(Event *event); |
106 | |
107 | static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); |
108 | static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); |
109 | static PythonObject (lldb::DataExtractorSP ); |
110 | |
111 | static PythonObject |
112 | ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); |
113 | static PythonObject |
114 | ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); |
115 | static PythonObject |
116 | ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); |
117 | |
118 | static python::ScopedPythonObject<lldb::SBCommandReturnObject> |
119 | ToSWIGWrapper(CommandReturnObject &cmd_retobj); |
120 | // These prototypes are the Pythonic implementations of the required |
121 | // callbacks. Although these are scripting-language specific, their definition |
122 | // depends on the public API. |
123 | |
124 | static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( |
125 | const char *python_function_name, const char *session_dictionary_name, |
126 | const lldb::StackFrameSP &sb_frame, |
127 | const lldb::BreakpointLocationSP &sb_bp_loc, |
128 | const lldb_private::StructuredDataImpl &args_impl); |
129 | |
130 | static bool LLDBSwigPythonWatchpointCallbackFunction( |
131 | const char *python_function_name, const char *session_dictionary_name, |
132 | const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); |
133 | |
134 | static bool |
135 | LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, |
136 | const char *session_dictionary_name, |
137 | lldb::TypeImplSP type_impl_sp); |
138 | |
139 | static bool LLDBSwigPythonCallTypeScript( |
140 | const char *python_function_name, const void *session_dictionary, |
141 | const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, |
142 | const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); |
143 | |
144 | static python::PythonObject |
145 | LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, |
146 | const char *session_dictionary_name, |
147 | const lldb::ValueObjectSP &valobj_sp); |
148 | |
149 | static python::PythonObject |
150 | LLDBSwigPythonCreateCommandObject(const char *python_class_name, |
151 | const char *session_dictionary_name, |
152 | lldb::DebuggerSP debugger_sp); |
153 | |
154 | static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( |
155 | const char *python_class_name, const char *session_dictionary_name, |
156 | const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); |
157 | |
158 | static unsigned int |
159 | LLDBSwigPythonCallBreakpointResolver(void *implementor, |
160 | const char *method_name, |
161 | lldb_private::SymbolContext *sym_ctx); |
162 | |
163 | static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, |
164 | uint32_t max); |
165 | |
166 | static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, |
167 | uint32_t idx); |
168 | |
169 | static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, |
170 | const char *child_name); |
171 | |
172 | static lldb::ValueObjectSP |
173 | LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); |
174 | |
175 | static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); |
176 | |
177 | static bool |
178 | LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor); |
179 | |
180 | static PyObject * |
181 | LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); |
182 | |
183 | static bool |
184 | LLDBSwigPythonCallCommand(const char *python_function_name, |
185 | const char *session_dictionary_name, |
186 | lldb::DebuggerSP debugger, const char *args, |
187 | lldb_private::CommandReturnObject &cmd_retobj, |
188 | lldb::ExecutionContextRefSP exe_ctx_ref_sp); |
189 | |
190 | static bool |
191 | LLDBSwigPythonCallCommandObject(PyObject *implementor, |
192 | lldb::DebuggerSP debugger, const char *args, |
193 | lldb_private::CommandReturnObject &cmd_retobj, |
194 | lldb::ExecutionContextRefSP exe_ctx_ref_sp); |
195 | static bool LLDBSwigPythonCallParsedCommandObject( |
196 | PyObject *implementor, lldb::DebuggerSP debugger, |
197 | StructuredDataImpl &args_impl, |
198 | lldb_private::CommandReturnObject &cmd_retobj, |
199 | lldb::ExecutionContextRefSP exe_ctx_ref_sp); |
200 | |
201 | static std::optional<std::string> |
202 | LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor, |
203 | std::string &command); |
204 | |
205 | static StructuredData::DictionarySP |
206 | LLDBSwigPythonHandleArgumentCompletionForScriptedCommand( |
207 | PyObject *implementor, std::vector<llvm::StringRef> &args_impl, |
208 | size_t args_pos, size_t pos_in_arg); |
209 | |
210 | static StructuredData::DictionarySP |
211 | LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand( |
212 | PyObject *implementor, llvm::StringRef &long_option, size_t pos_in_arg); |
213 | |
214 | static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, |
215 | const char *session_dictionary_name, |
216 | lldb::DebuggerSP debugger); |
217 | |
218 | static bool |
219 | LLDBSwigPythonCallModuleNewTarget(const char *python_module_name, |
220 | const char *session_dictionary_name, |
221 | lldb::TargetSP target); |
222 | |
223 | static python::PythonObject |
224 | LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, |
225 | const char *session_dictionary_name, |
226 | const lldb::ProcessSP &process_sp); |
227 | |
228 | static python::PythonObject |
229 | LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, |
230 | const char *session_dictionary_name); |
231 | |
232 | static PyObject * |
233 | LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, |
234 | const lldb::StackFrameSP &frame_sp); |
235 | |
236 | static bool LLDBSwigPython_ShouldHide(PyObject *implementor, |
237 | const lldb::StackFrameSP &frame_sp); |
238 | |
239 | static bool LLDBSWIGPythonRunScriptKeywordProcess( |
240 | const char *python_function_name, const char *session_dictionary_name, |
241 | const lldb::ProcessSP &process, std::string &output); |
242 | |
243 | static std::optional<std::string> |
244 | LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, |
245 | const char *session_dictionary_name, |
246 | lldb::ThreadSP thread); |
247 | |
248 | static bool LLDBSWIGPythonRunScriptKeywordTarget( |
249 | const char *python_function_name, const char *session_dictionary_name, |
250 | const lldb::TargetSP &target, std::string &output); |
251 | |
252 | static std::optional<std::string> |
253 | LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, |
254 | const char *session_dictionary_name, |
255 | lldb::StackFrameSP frame); |
256 | |
257 | static bool LLDBSWIGPythonRunScriptKeywordValue( |
258 | const char *python_function_name, const char *session_dictionary_name, |
259 | const lldb::ValueObjectSP &value, std::string &output); |
260 | |
261 | static void * |
262 | LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, |
263 | const lldb::TargetSP &target_sp); |
264 | }; |
265 | |
266 | void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); |
267 | void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); |
268 | void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); |
269 | void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); |
270 | void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); |
271 | void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); |
272 | void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); |
273 | void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); |
274 | void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); |
275 | void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data); |
276 | } // namespace python |
277 | |
278 | } // namespace lldb_private |
279 | |
280 | #endif // LLDB_ENABLE_PYTHON |
281 | #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H |
282 | |