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