1344a3780SDimitry Andric //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===// 2344a3780SDimitry Andric // 3344a3780SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4344a3780SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5344a3780SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6344a3780SDimitry Andric // 7344a3780SDimitry Andric //===----------------------------------------------------------------------===// 8344a3780SDimitry Andric 9344a3780SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 10344a3780SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 11344a3780SDimitry Andric 12e3b55780SDimitry Andric #include <optional> 13344a3780SDimitry Andric #include <string> 14344a3780SDimitry Andric 15344a3780SDimitry Andric #include "lldb/Host/Config.h" 16344a3780SDimitry Andric 17344a3780SDimitry Andric #if LLDB_ENABLE_PYTHON 18344a3780SDimitry Andric 19f65dcba8SDimitry Andric // LLDB Python header must be included first 20f65dcba8SDimitry Andric #include "lldb-python.h" 21f65dcba8SDimitry Andric 226f8fc217SDimitry Andric #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h" 23344a3780SDimitry Andric #include "lldb/lldb-forward.h" 24344a3780SDimitry Andric #include "lldb/lldb-types.h" 25f65dcba8SDimitry Andric #include "llvm/Support/Error.h" 26344a3780SDimitry Andric 27e3b55780SDimitry Andric namespace lldb { 28e3b55780SDimitry Andric class SBEvent; 29e3b55780SDimitry Andric class SBCommandReturnObject; 30e3b55780SDimitry Andric class SBValue; 31e3b55780SDimitry Andric class SBStream; 32e3b55780SDimitry Andric class SBStructuredData; 337fa27ce4SDimitry Andric class SBFileSpec; 347fa27ce4SDimitry Andric class SBModuleSpec; 35ac9a064cSDimitry Andric class SBStringList; 36e3b55780SDimitry Andric } // namespace lldb 37e3b55780SDimitry Andric 38344a3780SDimitry Andric namespace lldb_private { 39e3b55780SDimitry Andric namespace python { 40344a3780SDimitry Andric 41e3b55780SDimitry Andric typedef struct swig_type_info swig_type_info; 42344a3780SDimitry Andric 43e3b55780SDimitry Andric python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info); 44e3b55780SDimitry Andric 45e3b55780SDimitry Andric /// A class that automatically clears an SB object when it goes out of scope. 46e3b55780SDimitry Andric /// Use for cases where the SB object points to a temporary/unowned entity. 47e3b55780SDimitry Andric template <typename T> class ScopedPythonObject : PythonObject { 48e3b55780SDimitry Andric public: ScopedPythonObject(T * sb,swig_type_info * info)49e3b55780SDimitry Andric ScopedPythonObject(T *sb, swig_type_info *info) 50e3b55780SDimitry Andric : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {} ~ScopedPythonObject()51e3b55780SDimitry Andric ~ScopedPythonObject() { 52e3b55780SDimitry Andric if (m_sb) 53e3b55780SDimitry Andric *m_sb = T(); 54e3b55780SDimitry Andric } ScopedPythonObject(ScopedPythonObject && rhs)55e3b55780SDimitry Andric ScopedPythonObject(ScopedPythonObject &&rhs) 56e3b55780SDimitry Andric : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {} 57e3b55780SDimitry Andric ScopedPythonObject(const ScopedPythonObject &) = delete; 58e3b55780SDimitry Andric ScopedPythonObject &operator=(const ScopedPythonObject &) = delete; 59e3b55780SDimitry Andric ScopedPythonObject &operator=(ScopedPythonObject &&) = delete; 60e3b55780SDimitry Andric obj()61e3b55780SDimitry Andric const PythonObject &obj() const { return *this; } 62e3b55780SDimitry Andric 63e3b55780SDimitry Andric private: 64e3b55780SDimitry Andric T *m_sb; 65e3b55780SDimitry Andric }; 66e3b55780SDimitry Andric 677fa27ce4SDimitry Andric // TODO: We may want to support other languages in the future w/ SWIG (we 687fa27ce4SDimitry Andric // already support Lua right now, for example). We could create a generic 697fa27ce4SDimitry Andric // SWIGBridge class and have this one specialize it, something like this: 707fa27ce4SDimitry Andric // 717fa27ce4SDimitry Andric // <typename T> 727fa27ce4SDimitry Andric // class SWIGBridge { 737fa27ce4SDimitry Andric // static T ToSWIGWrapper(...); 747fa27ce4SDimitry Andric // }; 757fa27ce4SDimitry Andric // 767fa27ce4SDimitry Andric // class SWIGPythonBridge : public SWIGBridge<PythonObject> { 777fa27ce4SDimitry Andric // template<> static PythonObject ToSWIGWrapper(...); 787fa27ce4SDimitry Andric // }; 797fa27ce4SDimitry Andric // 807fa27ce4SDimitry Andric // And we should be able to more easily support things like Lua 817fa27ce4SDimitry Andric class SWIGBridge { 827fa27ce4SDimitry Andric public: 837fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); 847fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); 857fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); 867fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); 877fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); 887fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); 897fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(const Status &status); 907fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); 917fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); 927fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); 937fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); 947fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); 957fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); 967fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); 977fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); 987fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); 997fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); 100ac9a064cSDimitry Andric static PythonObject ToSWIGWrapper(const Stream *stream); 101ac9a064cSDimitry Andric static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb); 102ac9a064cSDimitry Andric static PythonObject ToSWIGWrapper(Event *event); 103e3b55780SDimitry Andric 1047fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); 1057fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); 1067fa27ce4SDimitry Andric static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); 107e3b55780SDimitry Andric 1087fa27ce4SDimitry Andric static PythonObject 1097fa27ce4SDimitry Andric ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); 1107fa27ce4SDimitry Andric static PythonObject 1117fa27ce4SDimitry Andric ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); 1127fa27ce4SDimitry Andric static PythonObject 1137fa27ce4SDimitry Andric ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); 1147fa27ce4SDimitry Andric 1157fa27ce4SDimitry Andric static python::ScopedPythonObject<lldb::SBCommandReturnObject> 116e3b55780SDimitry Andric ToSWIGWrapper(CommandReturnObject &cmd_retobj); 1177fa27ce4SDimitry Andric // These prototypes are the Pythonic implementations of the required 1187fa27ce4SDimitry Andric // callbacks. Although these are scripting-language specific, their definition 1197fa27ce4SDimitry Andric // depends on the public API. 120e3b55780SDimitry Andric 1217fa27ce4SDimitry Andric static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( 122f65dcba8SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 123f65dcba8SDimitry Andric const lldb::StackFrameSP &sb_frame, 124f65dcba8SDimitry Andric const lldb::BreakpointLocationSP &sb_bp_loc, 12577fc4c14SDimitry Andric const lldb_private::StructuredDataImpl &args_impl); 126f65dcba8SDimitry Andric 1277fa27ce4SDimitry Andric static bool LLDBSwigPythonWatchpointCallbackFunction( 128f65dcba8SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 129f65dcba8SDimitry Andric const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); 130f65dcba8SDimitry Andric 1317fa27ce4SDimitry Andric static bool 1327fa27ce4SDimitry Andric LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, 1337fa27ce4SDimitry Andric const char *session_dictionary_name, 134e3b55780SDimitry Andric lldb::TypeImplSP type_impl_sp); 135e3b55780SDimitry Andric 1367fa27ce4SDimitry Andric static bool LLDBSwigPythonCallTypeScript( 1377fa27ce4SDimitry Andric const char *python_function_name, const void *session_dictionary, 1387fa27ce4SDimitry Andric const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, 1397fa27ce4SDimitry Andric const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); 140f65dcba8SDimitry Andric 1417fa27ce4SDimitry Andric static python::PythonObject 142f65dcba8SDimitry Andric LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, 143f65dcba8SDimitry Andric const char *session_dictionary_name, 144f65dcba8SDimitry Andric const lldb::ValueObjectSP &valobj_sp); 145f65dcba8SDimitry Andric 1467fa27ce4SDimitry Andric static python::PythonObject 1476f8fc217SDimitry Andric LLDBSwigPythonCreateCommandObject(const char *python_class_name, 148f65dcba8SDimitry Andric const char *session_dictionary_name, 14977fc4c14SDimitry Andric lldb::DebuggerSP debugger_sp); 150f65dcba8SDimitry Andric 1517fa27ce4SDimitry Andric static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( 152f65dcba8SDimitry Andric const char *python_class_name, const char *session_dictionary_name, 15377fc4c14SDimitry Andric const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); 154f65dcba8SDimitry Andric 1557fa27ce4SDimitry Andric static unsigned int 1567fa27ce4SDimitry Andric LLDBSwigPythonCallBreakpointResolver(void *implementor, 1577fa27ce4SDimitry Andric const char *method_name, 158f65dcba8SDimitry Andric lldb_private::SymbolContext *sym_ctx); 159f65dcba8SDimitry Andric 1607fa27ce4SDimitry Andric static python::PythonObject LLDBSwigPythonCreateScriptedStopHook( 1616f8fc217SDimitry Andric lldb::TargetSP target_sp, const char *python_class_name, 1626f8fc217SDimitry Andric const char *session_dictionary_name, const StructuredDataImpl &args, 163f65dcba8SDimitry Andric lldb_private::Status &error); 164f65dcba8SDimitry Andric 1657fa27ce4SDimitry Andric static bool 1667fa27ce4SDimitry Andric LLDBSwigPythonStopHookCallHandleStop(void *implementor, 167f65dcba8SDimitry Andric lldb::ExecutionContextRefSP exc_ctx, 168f65dcba8SDimitry Andric lldb::StreamSP stream); 169f65dcba8SDimitry Andric 1707fa27ce4SDimitry Andric static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, 1717fa27ce4SDimitry Andric uint32_t max); 172f65dcba8SDimitry Andric 1737fa27ce4SDimitry Andric static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, 1747fa27ce4SDimitry Andric uint32_t idx); 175f65dcba8SDimitry Andric 1767fa27ce4SDimitry Andric static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, 177f65dcba8SDimitry Andric const char *child_name); 178f65dcba8SDimitry Andric 1797fa27ce4SDimitry Andric static lldb::ValueObjectSP 1807fa27ce4SDimitry Andric LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); 181f65dcba8SDimitry Andric 1827fa27ce4SDimitry Andric static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); 183f65dcba8SDimitry Andric 1847fa27ce4SDimitry Andric static bool 1857fa27ce4SDimitry Andric LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor); 186f65dcba8SDimitry Andric 1877fa27ce4SDimitry Andric static PyObject * 1887fa27ce4SDimitry Andric LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); 189f65dcba8SDimitry Andric 1907fa27ce4SDimitry Andric static bool 1917fa27ce4SDimitry Andric LLDBSwigPythonCallCommand(const char *python_function_name, 192f65dcba8SDimitry Andric const char *session_dictionary_name, 19377fc4c14SDimitry Andric lldb::DebuggerSP debugger, const char *args, 194f65dcba8SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 195f65dcba8SDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp); 196f65dcba8SDimitry Andric 1977fa27ce4SDimitry Andric static bool 1987fa27ce4SDimitry Andric LLDBSwigPythonCallCommandObject(PyObject *implementor, 1997fa27ce4SDimitry Andric lldb::DebuggerSP debugger, const char *args, 200f65dcba8SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 201f65dcba8SDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp); 202ac9a064cSDimitry Andric static bool 203ac9a064cSDimitry Andric LLDBSwigPythonCallParsedCommandObject(PyObject *implementor, 204ac9a064cSDimitry Andric lldb::DebuggerSP debugger, 205ac9a064cSDimitry Andric StructuredDataImpl &args_impl, 206ac9a064cSDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 207ac9a064cSDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp); 208ac9a064cSDimitry Andric 209ac9a064cSDimitry Andric static std::optional<std::string> 210ac9a064cSDimitry Andric LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor, 211ac9a064cSDimitry Andric std::string &command); 212f65dcba8SDimitry Andric 2137fa27ce4SDimitry Andric static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, 214f65dcba8SDimitry Andric const char *session_dictionary_name, 21577fc4c14SDimitry Andric lldb::DebuggerSP debugger); 216f65dcba8SDimitry Andric 2177fa27ce4SDimitry Andric static python::PythonObject 2186f8fc217SDimitry Andric LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, 219f65dcba8SDimitry Andric const char *session_dictionary_name, 220f65dcba8SDimitry Andric const lldb::ProcessSP &process_sp); 221f65dcba8SDimitry Andric 2227fa27ce4SDimitry Andric static python::PythonObject 2236f8fc217SDimitry Andric LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, 224f65dcba8SDimitry Andric const char *session_dictionary_name); 225f65dcba8SDimitry Andric 2267fa27ce4SDimitry Andric static PyObject * 227f65dcba8SDimitry Andric LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, 228f65dcba8SDimitry Andric const lldb::StackFrameSP &frame_sp); 229f65dcba8SDimitry Andric 2307fa27ce4SDimitry Andric static bool LLDBSWIGPythonRunScriptKeywordProcess( 2317fa27ce4SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 2327fa27ce4SDimitry Andric const lldb::ProcessSP &process, std::string &output); 233f65dcba8SDimitry Andric 2347fa27ce4SDimitry Andric static std::optional<std::string> 23577fc4c14SDimitry Andric LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, 236f65dcba8SDimitry Andric const char *session_dictionary_name, 23777fc4c14SDimitry Andric lldb::ThreadSP thread); 238f65dcba8SDimitry Andric 2397fa27ce4SDimitry Andric static bool LLDBSWIGPythonRunScriptKeywordTarget( 2407fa27ce4SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 2417fa27ce4SDimitry Andric const lldb::TargetSP &target, std::string &output); 242f65dcba8SDimitry Andric 2437fa27ce4SDimitry Andric static std::optional<std::string> 24477fc4c14SDimitry Andric LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, 245f65dcba8SDimitry Andric const char *session_dictionary_name, 24677fc4c14SDimitry Andric lldb::StackFrameSP frame); 247f65dcba8SDimitry Andric 2487fa27ce4SDimitry Andric static bool LLDBSWIGPythonRunScriptKeywordValue( 2497fa27ce4SDimitry Andric const char *python_function_name, const char *session_dictionary_name, 2507fa27ce4SDimitry Andric const lldb::ValueObjectSP &value, std::string &output); 251f65dcba8SDimitry Andric 2527fa27ce4SDimitry Andric static void * 2537fa27ce4SDimitry Andric LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, 254f65dcba8SDimitry Andric const lldb::TargetSP &target_sp); 2557fa27ce4SDimitry Andric }; 2567fa27ce4SDimitry Andric 2577fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); 2587fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); 2597fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); 2607fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); 2617fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); 262ac9a064cSDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); 263ac9a064cSDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); 2647fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); 2657fa27ce4SDimitry Andric void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); 2667fa27ce4SDimitry Andric } // namespace python 267344a3780SDimitry Andric 268344a3780SDimitry Andric } // namespace lldb_private 269344a3780SDimitry Andric 270344a3780SDimitry Andric #endif // LLDB_ENABLE_PYTHON 271344a3780SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 272