1fe6060f1SDimitry Andric //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric 
9fe6060f1SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
10fe6060f1SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
11fe6060f1SDimitry Andric 
12bdd1243dSDimitry Andric #include <optional>
13fe6060f1SDimitry Andric #include <string>
14fe6060f1SDimitry Andric 
15fe6060f1SDimitry Andric #include "lldb/Host/Config.h"
16fe6060f1SDimitry Andric 
17fe6060f1SDimitry Andric #if LLDB_ENABLE_PYTHON
18fe6060f1SDimitry Andric 
194824e7fdSDimitry Andric // LLDB Python header must be included first
204824e7fdSDimitry Andric #include "lldb-python.h"
214824e7fdSDimitry Andric 
2204eeddc0SDimitry Andric #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
23fe6060f1SDimitry Andric #include "lldb/lldb-forward.h"
24fe6060f1SDimitry Andric #include "lldb/lldb-types.h"
254824e7fdSDimitry Andric #include "llvm/Support/Error.h"
26fe6060f1SDimitry Andric 
27bdd1243dSDimitry Andric namespace lldb {
28bdd1243dSDimitry Andric class SBEvent;
29bdd1243dSDimitry Andric class SBCommandReturnObject;
30bdd1243dSDimitry Andric class SBValue;
31bdd1243dSDimitry Andric class SBStream;
32bdd1243dSDimitry Andric class SBStructuredData;
33*fe013be4SDimitry Andric class SBFileSpec;
34*fe013be4SDimitry Andric class SBModuleSpec;
35bdd1243dSDimitry Andric } // namespace lldb
36bdd1243dSDimitry Andric 
37fe6060f1SDimitry Andric namespace lldb_private {
38bdd1243dSDimitry Andric namespace python {
39fe6060f1SDimitry Andric 
40bdd1243dSDimitry Andric typedef struct swig_type_info swig_type_info;
41fe6060f1SDimitry Andric 
42bdd1243dSDimitry Andric python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);
43bdd1243dSDimitry Andric 
44bdd1243dSDimitry Andric /// A class that automatically clears an SB object when it goes out of scope.
45bdd1243dSDimitry Andric /// Use for cases where the SB object points to a temporary/unowned entity.
46bdd1243dSDimitry Andric template <typename T> class ScopedPythonObject : PythonObject {
47bdd1243dSDimitry Andric public:
48bdd1243dSDimitry Andric   ScopedPythonObject(T *sb, swig_type_info *info)
49bdd1243dSDimitry Andric       : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
50bdd1243dSDimitry Andric   ~ScopedPythonObject() {
51bdd1243dSDimitry Andric     if (m_sb)
52bdd1243dSDimitry Andric       *m_sb = T();
53bdd1243dSDimitry Andric   }
54bdd1243dSDimitry Andric   ScopedPythonObject(ScopedPythonObject &&rhs)
55bdd1243dSDimitry Andric       : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
56bdd1243dSDimitry Andric   ScopedPythonObject(const ScopedPythonObject &) = delete;
57bdd1243dSDimitry Andric   ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
58bdd1243dSDimitry Andric   ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
59bdd1243dSDimitry Andric 
60bdd1243dSDimitry Andric   const PythonObject &obj() const { return *this; }
61bdd1243dSDimitry Andric 
62bdd1243dSDimitry Andric private:
63bdd1243dSDimitry Andric   T *m_sb;
64bdd1243dSDimitry Andric };
65bdd1243dSDimitry Andric 
66*fe013be4SDimitry Andric // TODO: We may want to support other languages in the future w/ SWIG (we
67*fe013be4SDimitry Andric // already support Lua right now, for example). We could create a generic
68*fe013be4SDimitry Andric // SWIGBridge class and have this one specialize it, something like this:
69*fe013be4SDimitry Andric //
70*fe013be4SDimitry Andric // <typename T>
71*fe013be4SDimitry Andric // class SWIGBridge {
72*fe013be4SDimitry Andric //   static T ToSWIGWrapper(...);
73*fe013be4SDimitry Andric // };
74*fe013be4SDimitry Andric //
75*fe013be4SDimitry Andric // class SWIGPythonBridge : public SWIGBridge<PythonObject> {
76*fe013be4SDimitry Andric //   template<> static PythonObject ToSWIGWrapper(...);
77*fe013be4SDimitry Andric // };
78*fe013be4SDimitry Andric //
79*fe013be4SDimitry Andric // And we should be able to more easily support things like Lua
80*fe013be4SDimitry Andric class SWIGBridge {
81*fe013be4SDimitry Andric public:
82*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
83*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);
84*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);
85*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);
86*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);
87*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);
88*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(const Status &status);
89*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);
90*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);
91*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);
92*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);
93*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);
94*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);
95*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp);
96*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
97*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
98*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
99bdd1243dSDimitry Andric 
100*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
101*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
102*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
103bdd1243dSDimitry Andric 
104*fe013be4SDimitry Andric   static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
105*fe013be4SDimitry Andric   static PythonObject
106*fe013be4SDimitry Andric   ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
107*fe013be4SDimitry Andric   static PythonObject
108*fe013be4SDimitry Andric   ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb);
109*fe013be4SDimitry Andric   static PythonObject
110*fe013be4SDimitry Andric   ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb);
111*fe013be4SDimitry Andric 
112*fe013be4SDimitry Andric   static python::ScopedPythonObject<lldb::SBCommandReturnObject>
113bdd1243dSDimitry Andric   ToSWIGWrapper(CommandReturnObject &cmd_retobj);
114*fe013be4SDimitry Andric   static python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event);
115*fe013be4SDimitry Andric   // These prototypes are the Pythonic implementations of the required
116*fe013be4SDimitry Andric   // callbacks. Although these are scripting-language specific, their definition
117*fe013be4SDimitry Andric   // depends on the public API.
118bdd1243dSDimitry Andric 
119*fe013be4SDimitry Andric   static python::PythonObject LLDBSwigPythonCreateScriptedObject(
12004eeddc0SDimitry Andric       const char *python_class_name, const char *session_dictionary_name,
121bdd1243dSDimitry Andric       lldb::ExecutionContextRefSP exe_ctx_sp,
122bdd1243dSDimitry Andric       const lldb_private::StructuredDataImpl &args_impl,
123349cc55cSDimitry Andric       std::string &error_string);
124349cc55cSDimitry Andric 
125*fe013be4SDimitry Andric   static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
1264824e7fdSDimitry Andric       const char *python_function_name, const char *session_dictionary_name,
1274824e7fdSDimitry Andric       const lldb::StackFrameSP &sb_frame,
1284824e7fdSDimitry Andric       const lldb::BreakpointLocationSP &sb_bp_loc,
1290eae32dcSDimitry Andric       const lldb_private::StructuredDataImpl &args_impl);
1304824e7fdSDimitry Andric 
131*fe013be4SDimitry Andric   static bool LLDBSwigPythonWatchpointCallbackFunction(
1324824e7fdSDimitry Andric       const char *python_function_name, const char *session_dictionary_name,
1334824e7fdSDimitry Andric       const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
1344824e7fdSDimitry Andric 
135*fe013be4SDimitry Andric   static bool
136*fe013be4SDimitry Andric   LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name,
137*fe013be4SDimitry Andric                                           const char *session_dictionary_name,
138bdd1243dSDimitry Andric                                           lldb::TypeImplSP type_impl_sp);
139bdd1243dSDimitry Andric 
140*fe013be4SDimitry Andric   static bool LLDBSwigPythonCallTypeScript(
141*fe013be4SDimitry Andric       const char *python_function_name, const void *session_dictionary,
142*fe013be4SDimitry Andric       const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
143*fe013be4SDimitry Andric       const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);
1444824e7fdSDimitry Andric 
145*fe013be4SDimitry Andric   static python::PythonObject
1464824e7fdSDimitry Andric   LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
1474824e7fdSDimitry Andric                                         const char *session_dictionary_name,
1484824e7fdSDimitry Andric                                         const lldb::ValueObjectSP &valobj_sp);
1494824e7fdSDimitry Andric 
150*fe013be4SDimitry Andric   static python::PythonObject
15104eeddc0SDimitry Andric   LLDBSwigPythonCreateCommandObject(const char *python_class_name,
1524824e7fdSDimitry Andric                                     const char *session_dictionary_name,
1530eae32dcSDimitry Andric                                     lldb::DebuggerSP debugger_sp);
1544824e7fdSDimitry Andric 
155*fe013be4SDimitry Andric   static python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan(
1564824e7fdSDimitry Andric       const char *python_class_name, const char *session_dictionary_name,
1570eae32dcSDimitry Andric       const StructuredDataImpl &args_data, std::string &error_string,
1584824e7fdSDimitry Andric       const lldb::ThreadPlanSP &thread_plan_sp);
1594824e7fdSDimitry Andric 
160*fe013be4SDimitry Andric   static bool LLDBSWIGPythonCallThreadPlan(void *implementor,
161*fe013be4SDimitry Andric                                            const char *method_name,
1624824e7fdSDimitry Andric                                            lldb_private::Event *event_sp,
1634824e7fdSDimitry Andric                                            bool &got_error);
1644824e7fdSDimitry Andric 
165*fe013be4SDimitry Andric   static bool LLDBSWIGPythonCallThreadPlan(void *implementor,
166*fe013be4SDimitry Andric                                            const char *method_name,
167*fe013be4SDimitry Andric                                            lldb_private::Stream *stream,
168*fe013be4SDimitry Andric                                            bool &got_error);
169*fe013be4SDimitry Andric 
170*fe013be4SDimitry Andric   static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
1714824e7fdSDimitry Andric       const char *python_class_name, const char *session_dictionary_name,
1720eae32dcSDimitry Andric       const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
1734824e7fdSDimitry Andric 
174*fe013be4SDimitry Andric   static unsigned int
175*fe013be4SDimitry Andric   LLDBSwigPythonCallBreakpointResolver(void *implementor,
176*fe013be4SDimitry Andric                                        const char *method_name,
1774824e7fdSDimitry Andric                                        lldb_private::SymbolContext *sym_ctx);
1784824e7fdSDimitry Andric 
179*fe013be4SDimitry Andric   static python::PythonObject LLDBSwigPythonCreateScriptedStopHook(
18004eeddc0SDimitry Andric       lldb::TargetSP target_sp, const char *python_class_name,
18104eeddc0SDimitry Andric       const char *session_dictionary_name, const StructuredDataImpl &args,
1824824e7fdSDimitry Andric       lldb_private::Status &error);
1834824e7fdSDimitry Andric 
184*fe013be4SDimitry Andric   static bool
185*fe013be4SDimitry Andric   LLDBSwigPythonStopHookCallHandleStop(void *implementor,
1864824e7fdSDimitry Andric                                        lldb::ExecutionContextRefSP exc_ctx,
1874824e7fdSDimitry Andric                                        lldb::StreamSP stream);
1884824e7fdSDimitry Andric 
189*fe013be4SDimitry Andric   static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,
190*fe013be4SDimitry Andric                                                     uint32_t max);
1914824e7fdSDimitry Andric 
192*fe013be4SDimitry Andric   static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor,
193*fe013be4SDimitry Andric                                                   uint32_t idx);
1944824e7fdSDimitry Andric 
195*fe013be4SDimitry Andric   static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,
1964824e7fdSDimitry Andric                                                     const char *child_name);
1974824e7fdSDimitry Andric 
198*fe013be4SDimitry Andric   static lldb::ValueObjectSP
199*fe013be4SDimitry Andric   LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
2004824e7fdSDimitry Andric 
201*fe013be4SDimitry Andric   static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);
2024824e7fdSDimitry Andric 
203*fe013be4SDimitry Andric   static bool
204*fe013be4SDimitry Andric   LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor);
2054824e7fdSDimitry Andric 
206*fe013be4SDimitry Andric   static PyObject *
207*fe013be4SDimitry Andric   LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
2084824e7fdSDimitry Andric 
209*fe013be4SDimitry Andric   static bool
210*fe013be4SDimitry Andric   LLDBSwigPythonCallCommand(const char *python_function_name,
2114824e7fdSDimitry Andric                             const char *session_dictionary_name,
2120eae32dcSDimitry Andric                             lldb::DebuggerSP debugger, const char *args,
2134824e7fdSDimitry Andric                             lldb_private::CommandReturnObject &cmd_retobj,
2144824e7fdSDimitry Andric                             lldb::ExecutionContextRefSP exe_ctx_ref_sp);
2154824e7fdSDimitry Andric 
216*fe013be4SDimitry Andric   static bool
217*fe013be4SDimitry Andric   LLDBSwigPythonCallCommandObject(PyObject *implementor,
218*fe013be4SDimitry Andric                                   lldb::DebuggerSP debugger, const char *args,
2194824e7fdSDimitry Andric                                   lldb_private::CommandReturnObject &cmd_retobj,
2204824e7fdSDimitry Andric                                   lldb::ExecutionContextRefSP exe_ctx_ref_sp);
2214824e7fdSDimitry Andric 
222*fe013be4SDimitry Andric   static bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
2234824e7fdSDimitry Andric                                            const char *session_dictionary_name,
2240eae32dcSDimitry Andric                                            lldb::DebuggerSP debugger);
2254824e7fdSDimitry Andric 
226*fe013be4SDimitry Andric   static python::PythonObject
22704eeddc0SDimitry Andric   LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
2284824e7fdSDimitry Andric                                const char *session_dictionary_name,
2294824e7fdSDimitry Andric                                const lldb::ProcessSP &process_sp);
2304824e7fdSDimitry Andric 
231*fe013be4SDimitry Andric   static python::PythonObject
23204eeddc0SDimitry Andric   LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
2334824e7fdSDimitry Andric                                        const char *session_dictionary_name);
2344824e7fdSDimitry Andric 
235*fe013be4SDimitry Andric   static PyObject *
2364824e7fdSDimitry Andric   LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
2374824e7fdSDimitry Andric                                         const lldb::StackFrameSP &frame_sp);
2384824e7fdSDimitry Andric 
239*fe013be4SDimitry Andric   static bool LLDBSWIGPythonRunScriptKeywordProcess(
240*fe013be4SDimitry Andric       const char *python_function_name, const char *session_dictionary_name,
241*fe013be4SDimitry Andric       const lldb::ProcessSP &process, std::string &output);
2424824e7fdSDimitry Andric 
243*fe013be4SDimitry Andric   static std::optional<std::string>
2440eae32dcSDimitry Andric   LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
2454824e7fdSDimitry Andric                                        const char *session_dictionary_name,
2460eae32dcSDimitry Andric                                        lldb::ThreadSP thread);
2474824e7fdSDimitry Andric 
248*fe013be4SDimitry Andric   static bool LLDBSWIGPythonRunScriptKeywordTarget(
249*fe013be4SDimitry Andric       const char *python_function_name, const char *session_dictionary_name,
250*fe013be4SDimitry Andric       const lldb::TargetSP &target, std::string &output);
2514824e7fdSDimitry Andric 
252*fe013be4SDimitry Andric   static std::optional<std::string>
2530eae32dcSDimitry Andric   LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
2544824e7fdSDimitry Andric                                       const char *session_dictionary_name,
2550eae32dcSDimitry Andric                                       lldb::StackFrameSP frame);
2564824e7fdSDimitry Andric 
257*fe013be4SDimitry Andric   static bool LLDBSWIGPythonRunScriptKeywordValue(
258*fe013be4SDimitry Andric       const char *python_function_name, const char *session_dictionary_name,
259*fe013be4SDimitry Andric       const lldb::ValueObjectSP &value, std::string &output);
2604824e7fdSDimitry Andric 
261*fe013be4SDimitry Andric   static void *
262*fe013be4SDimitry Andric   LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
2634824e7fdSDimitry Andric                                    const lldb::TargetSP &target_sp);
264*fe013be4SDimitry Andric };
265*fe013be4SDimitry Andric 
266*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
267*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
268*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
269*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
270*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
271*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
272*fe013be4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
273*fe013be4SDimitry Andric } // namespace python
274fe6060f1SDimitry Andric 
275fe6060f1SDimitry Andric } // namespace lldb_private
276fe6060f1SDimitry Andric 
277fe6060f1SDimitry Andric #endif // LLDB_ENABLE_PYTHON
278fe6060f1SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
279