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