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; 3306c3fb27SDimitry Andric class SBFileSpec; 3406c3fb27SDimitry Andric class SBModuleSpec; 35*0fca6ea1SDimitry Andric class SBStringList; 36bdd1243dSDimitry Andric } // namespace lldb 37bdd1243dSDimitry Andric 38fe6060f1SDimitry Andric namespace lldb_private { 39bdd1243dSDimitry Andric namespace python { 40fe6060f1SDimitry Andric 41bdd1243dSDimitry Andric typedef struct swig_type_info swig_type_info; 42fe6060f1SDimitry Andric 43bdd1243dSDimitry Andric python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info); 44bdd1243dSDimitry Andric 45bdd1243dSDimitry Andric /// A class that automatically clears an SB object when it goes out of scope. 46bdd1243dSDimitry Andric /// Use for cases where the SB object points to a temporary/unowned entity. 47bdd1243dSDimitry Andric template <typename T> class ScopedPythonObject : PythonObject { 48bdd1243dSDimitry Andric public: 49bdd1243dSDimitry Andric ScopedPythonObject(T *sb, swig_type_info *info) 50bdd1243dSDimitry Andric : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {} 51bdd1243dSDimitry Andric ~ScopedPythonObject() { 52bdd1243dSDimitry Andric if (m_sb) 53bdd1243dSDimitry Andric *m_sb = T(); 54bdd1243dSDimitry Andric } 55bdd1243dSDimitry Andric ScopedPythonObject(ScopedPythonObject &&rhs) 56bdd1243dSDimitry Andric : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {} 57bdd1243dSDimitry Andric ScopedPythonObject(const ScopedPythonObject &) = delete; 58bdd1243dSDimitry Andric ScopedPythonObject &operator=(const ScopedPythonObject &) = delete; 59bdd1243dSDimitry Andric ScopedPythonObject &operator=(ScopedPythonObject &&) = delete; 60bdd1243dSDimitry Andric 61bdd1243dSDimitry Andric const PythonObject &obj() const { return *this; } 62bdd1243dSDimitry Andric 63bdd1243dSDimitry Andric private: 64bdd1243dSDimitry Andric T *m_sb; 65bdd1243dSDimitry Andric }; 66bdd1243dSDimitry Andric 6706c3fb27SDimitry Andric // TODO: We may want to support other languages in the future w/ SWIG (we 6806c3fb27SDimitry Andric // already support Lua right now, for example). We could create a generic 6906c3fb27SDimitry Andric // SWIGBridge class and have this one specialize it, something like this: 7006c3fb27SDimitry Andric // 7106c3fb27SDimitry Andric // <typename T> 7206c3fb27SDimitry Andric // class SWIGBridge { 7306c3fb27SDimitry Andric // static T ToSWIGWrapper(...); 7406c3fb27SDimitry Andric // }; 7506c3fb27SDimitry Andric // 7606c3fb27SDimitry Andric // class SWIGPythonBridge : public SWIGBridge<PythonObject> { 7706c3fb27SDimitry Andric // template<> static PythonObject ToSWIGWrapper(...); 7806c3fb27SDimitry Andric // }; 7906c3fb27SDimitry Andric // 8006c3fb27SDimitry Andric // And we should be able to more easily support things like Lua 8106c3fb27SDimitry Andric class SWIGBridge { 8206c3fb27SDimitry Andric public: 8306c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); 8406c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); 8506c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); 8606c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); 8706c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); 8806c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); 8906c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(const Status &status); 9006c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); 9106c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); 9206c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); 9306c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); 9406c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); 9506c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); 9606c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); 9706c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); 9806c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); 9906c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); 100*0fca6ea1SDimitry Andric static PythonObject ToSWIGWrapper(const Stream *stream); 101*0fca6ea1SDimitry Andric static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb); 102*0fca6ea1SDimitry Andric static PythonObject ToSWIGWrapper(Event *event); 103bdd1243dSDimitry Andric 10406c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); 10506c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); 10606c3fb27SDimitry Andric static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); 107bdd1243dSDimitry Andric 10806c3fb27SDimitry Andric static PythonObject 10906c3fb27SDimitry Andric ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); 11006c3fb27SDimitry Andric static PythonObject 11106c3fb27SDimitry Andric ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); 11206c3fb27SDimitry Andric static PythonObject 11306c3fb27SDimitry Andric ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); 11406c3fb27SDimitry Andric 11506c3fb27SDimitry Andric static python::ScopedPythonObject<lldb::SBCommandReturnObject> 116bdd1243dSDimitry Andric ToSWIGWrapper(CommandReturnObject &cmd_retobj); 11706c3fb27SDimitry Andric // These prototypes are the Pythonic implementations of the required 11806c3fb27SDimitry Andric // callbacks. Although these are scripting-language specific, their definition 11906c3fb27SDimitry Andric // depends on the public API. 120bdd1243dSDimitry Andric 12106c3fb27SDimitry Andric static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( 1224824e7fdSDimitry Andric const char *python_function_name, const char *session_dictionary_name, 1234824e7fdSDimitry Andric const lldb::StackFrameSP &sb_frame, 1244824e7fdSDimitry Andric const lldb::BreakpointLocationSP &sb_bp_loc, 1250eae32dcSDimitry Andric const lldb_private::StructuredDataImpl &args_impl); 1264824e7fdSDimitry Andric 12706c3fb27SDimitry Andric static bool LLDBSwigPythonWatchpointCallbackFunction( 1284824e7fdSDimitry Andric const char *python_function_name, const char *session_dictionary_name, 1294824e7fdSDimitry Andric const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); 1304824e7fdSDimitry Andric 13106c3fb27SDimitry Andric static bool 13206c3fb27SDimitry Andric LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, 13306c3fb27SDimitry Andric const char *session_dictionary_name, 134bdd1243dSDimitry Andric lldb::TypeImplSP type_impl_sp); 135bdd1243dSDimitry Andric 13606c3fb27SDimitry Andric static bool LLDBSwigPythonCallTypeScript( 13706c3fb27SDimitry Andric const char *python_function_name, const void *session_dictionary, 13806c3fb27SDimitry Andric const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, 13906c3fb27SDimitry Andric const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); 1404824e7fdSDimitry Andric 14106c3fb27SDimitry Andric static python::PythonObject 1424824e7fdSDimitry Andric LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, 1434824e7fdSDimitry Andric const char *session_dictionary_name, 1444824e7fdSDimitry Andric const lldb::ValueObjectSP &valobj_sp); 1454824e7fdSDimitry Andric 14606c3fb27SDimitry Andric static python::PythonObject 14704eeddc0SDimitry Andric LLDBSwigPythonCreateCommandObject(const char *python_class_name, 1484824e7fdSDimitry Andric const char *session_dictionary_name, 1490eae32dcSDimitry Andric lldb::DebuggerSP debugger_sp); 1504824e7fdSDimitry Andric 15106c3fb27SDimitry Andric static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( 1524824e7fdSDimitry Andric const char *python_class_name, const char *session_dictionary_name, 1530eae32dcSDimitry Andric const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); 1544824e7fdSDimitry Andric 15506c3fb27SDimitry Andric static unsigned int 15606c3fb27SDimitry Andric LLDBSwigPythonCallBreakpointResolver(void *implementor, 15706c3fb27SDimitry Andric const char *method_name, 1584824e7fdSDimitry Andric lldb_private::SymbolContext *sym_ctx); 1594824e7fdSDimitry Andric 16006c3fb27SDimitry Andric static python::PythonObject LLDBSwigPythonCreateScriptedStopHook( 16104eeddc0SDimitry Andric lldb::TargetSP target_sp, const char *python_class_name, 16204eeddc0SDimitry Andric const char *session_dictionary_name, const StructuredDataImpl &args, 1634824e7fdSDimitry Andric lldb_private::Status &error); 1644824e7fdSDimitry Andric 16506c3fb27SDimitry Andric static bool 16606c3fb27SDimitry Andric LLDBSwigPythonStopHookCallHandleStop(void *implementor, 1674824e7fdSDimitry Andric lldb::ExecutionContextRefSP exc_ctx, 1684824e7fdSDimitry Andric lldb::StreamSP stream); 1694824e7fdSDimitry Andric 17006c3fb27SDimitry Andric static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, 17106c3fb27SDimitry Andric uint32_t max); 1724824e7fdSDimitry Andric 17306c3fb27SDimitry Andric static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, 17406c3fb27SDimitry Andric uint32_t idx); 1754824e7fdSDimitry Andric 17606c3fb27SDimitry Andric static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, 1774824e7fdSDimitry Andric const char *child_name); 1784824e7fdSDimitry Andric 17906c3fb27SDimitry Andric static lldb::ValueObjectSP 18006c3fb27SDimitry Andric LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); 1814824e7fdSDimitry Andric 18206c3fb27SDimitry Andric static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); 1834824e7fdSDimitry Andric 18406c3fb27SDimitry Andric static bool 18506c3fb27SDimitry Andric LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor); 1864824e7fdSDimitry Andric 18706c3fb27SDimitry Andric static PyObject * 18806c3fb27SDimitry Andric LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); 1894824e7fdSDimitry Andric 19006c3fb27SDimitry Andric static bool 19106c3fb27SDimitry Andric LLDBSwigPythonCallCommand(const char *python_function_name, 1924824e7fdSDimitry Andric const char *session_dictionary_name, 1930eae32dcSDimitry Andric lldb::DebuggerSP debugger, const char *args, 1944824e7fdSDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 1954824e7fdSDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp); 1964824e7fdSDimitry Andric 19706c3fb27SDimitry Andric static bool 19806c3fb27SDimitry Andric LLDBSwigPythonCallCommandObject(PyObject *implementor, 19906c3fb27SDimitry Andric lldb::DebuggerSP debugger, const char *args, 2004824e7fdSDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 2014824e7fdSDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp); 202*0fca6ea1SDimitry Andric static bool 203*0fca6ea1SDimitry Andric LLDBSwigPythonCallParsedCommandObject(PyObject *implementor, 204*0fca6ea1SDimitry Andric lldb::DebuggerSP debugger, 205*0fca6ea1SDimitry Andric StructuredDataImpl &args_impl, 206*0fca6ea1SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 207*0fca6ea1SDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp); 208*0fca6ea1SDimitry Andric 209*0fca6ea1SDimitry Andric static std::optional<std::string> 210*0fca6ea1SDimitry Andric LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor, 211*0fca6ea1SDimitry Andric std::string &command); 2124824e7fdSDimitry Andric 21306c3fb27SDimitry Andric static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, 2144824e7fdSDimitry Andric const char *session_dictionary_name, 2150eae32dcSDimitry Andric lldb::DebuggerSP debugger); 2164824e7fdSDimitry Andric 21706c3fb27SDimitry Andric static python::PythonObject 21804eeddc0SDimitry Andric LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, 2194824e7fdSDimitry Andric const char *session_dictionary_name, 2204824e7fdSDimitry Andric const lldb::ProcessSP &process_sp); 2214824e7fdSDimitry Andric 22206c3fb27SDimitry Andric static python::PythonObject 22304eeddc0SDimitry Andric LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, 2244824e7fdSDimitry Andric const char *session_dictionary_name); 2254824e7fdSDimitry Andric 22606c3fb27SDimitry Andric static PyObject * 2274824e7fdSDimitry Andric LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, 2284824e7fdSDimitry Andric const lldb::StackFrameSP &frame_sp); 2294824e7fdSDimitry Andric 23006c3fb27SDimitry Andric static bool LLDBSWIGPythonRunScriptKeywordProcess( 23106c3fb27SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 23206c3fb27SDimitry Andric const lldb::ProcessSP &process, std::string &output); 2334824e7fdSDimitry Andric 23406c3fb27SDimitry Andric static std::optional<std::string> 2350eae32dcSDimitry Andric LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, 2364824e7fdSDimitry Andric const char *session_dictionary_name, 2370eae32dcSDimitry Andric lldb::ThreadSP thread); 2384824e7fdSDimitry Andric 23906c3fb27SDimitry Andric static bool LLDBSWIGPythonRunScriptKeywordTarget( 24006c3fb27SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 24106c3fb27SDimitry Andric const lldb::TargetSP &target, std::string &output); 2424824e7fdSDimitry Andric 24306c3fb27SDimitry Andric static std::optional<std::string> 2440eae32dcSDimitry Andric LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, 2454824e7fdSDimitry Andric const char *session_dictionary_name, 2460eae32dcSDimitry Andric lldb::StackFrameSP frame); 2474824e7fdSDimitry Andric 24806c3fb27SDimitry Andric static bool LLDBSWIGPythonRunScriptKeywordValue( 24906c3fb27SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 25006c3fb27SDimitry Andric const lldb::ValueObjectSP &value, std::string &output); 2514824e7fdSDimitry Andric 25206c3fb27SDimitry Andric static void * 25306c3fb27SDimitry Andric LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, 2544824e7fdSDimitry Andric const lldb::TargetSP &target_sp); 25506c3fb27SDimitry Andric }; 25606c3fb27SDimitry Andric 25706c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); 25806c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); 25906c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); 26006c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); 26106c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); 262*0fca6ea1SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); 263*0fca6ea1SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); 26406c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); 26506c3fb27SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); 26606c3fb27SDimitry Andric } // namespace python 267fe6060f1SDimitry Andric 268fe6060f1SDimitry Andric } // namespace lldb_private 269fe6060f1SDimitry Andric 270fe6060f1SDimitry Andric #endif // LLDB_ENABLE_PYTHON 271fe6060f1SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 272