11f6a57c1SMed Ismail Bennani //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===// 21f6a57c1SMed Ismail Bennani // 31f6a57c1SMed Ismail Bennani // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41f6a57c1SMed Ismail Bennani // See https://llvm.org/LICENSE.txt for license information. 51f6a57c1SMed Ismail Bennani // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61f6a57c1SMed Ismail Bennani // 71f6a57c1SMed Ismail Bennani //===----------------------------------------------------------------------===// 81f6a57c1SMed Ismail Bennani 91f6a57c1SMed Ismail Bennani #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 101f6a57c1SMed Ismail Bennani #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 111f6a57c1SMed Ismail Bennani 12c1d1a752SMed Ismail Bennani #include <optional> 13c1d1a752SMed Ismail Bennani #include <string> 141f6a57c1SMed Ismail Bennani 15e8504cb0SMed Ismail Bennani #include "lldb/Host/Config.h" 16e8504cb0SMed Ismail Bennani 17c1d1a752SMed Ismail Bennani #if LLDB_ENABLE_PYTHON 189a14adeaSPavel Labath 19e8504cb0SMed Ismail Bennani // LLDB Python header must be included first 20e8504cb0SMed Ismail Bennani #include "lldb-python.h" 21e8504cb0SMed Ismail Bennani 22c154f397SPavel Labath #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h" 231f6a57c1SMed Ismail Bennani #include "lldb/lldb-forward.h" 241f6a57c1SMed Ismail Bennani #include "lldb/lldb-types.h" 259a14adeaSPavel Labath #include "llvm/Support/Error.h" 261f6a57c1SMed Ismail Bennani 277e01924eSMed Ismail Bennani namespace lldb { 287e01924eSMed Ismail Bennani class SBEvent; 297e01924eSMed Ismail Bennani class SBCommandReturnObject; 307e01924eSMed Ismail Bennani class SBValue; 317e01924eSMed Ismail Bennani class SBStream; 327e01924eSMed Ismail Bennani class SBStructuredData; 33c4fa6fafSKazuki Sakamoto class SBFileSpec; 34c4fa6fafSKazuki Sakamoto class SBModuleSpec; 35a69ecb24Sjimingham class SBStringList; 367e01924eSMed Ismail Bennani } // namespace lldb 377e01924eSMed Ismail Bennani 381f6a57c1SMed Ismail Bennani namespace lldb_private { 397e01924eSMed Ismail Bennani namespace python { 407e01924eSMed Ismail Bennani 417e01924eSMed Ismail Bennani typedef struct swig_type_info swig_type_info; 427e01924eSMed Ismail Bennani 437e01924eSMed Ismail Bennani python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info); 447e01924eSMed Ismail Bennani 457e01924eSMed Ismail Bennani /// A class that automatically clears an SB object when it goes out of scope. 467e01924eSMed Ismail Bennani /// Use for cases where the SB object points to a temporary/unowned entity. 477e01924eSMed Ismail Bennani template <typename T> class ScopedPythonObject : PythonObject { 487e01924eSMed Ismail Bennani public: 497e01924eSMed Ismail Bennani ScopedPythonObject(T *sb, swig_type_info *info) 507e01924eSMed Ismail Bennani : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {} 517e01924eSMed Ismail Bennani ~ScopedPythonObject() { 527e01924eSMed Ismail Bennani if (m_sb) 537e01924eSMed Ismail Bennani *m_sb = T(); 547e01924eSMed Ismail Bennani } 557e01924eSMed Ismail Bennani ScopedPythonObject(ScopedPythonObject &&rhs) 567e01924eSMed Ismail Bennani : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {} 577e01924eSMed Ismail Bennani ScopedPythonObject(const ScopedPythonObject &) = delete; 587e01924eSMed Ismail Bennani ScopedPythonObject &operator=(const ScopedPythonObject &) = delete; 597e01924eSMed Ismail Bennani ScopedPythonObject &operator=(ScopedPythonObject &&) = delete; 607e01924eSMed Ismail Bennani 617e01924eSMed Ismail Bennani const PythonObject &obj() const { return *this; } 627e01924eSMed Ismail Bennani 637e01924eSMed Ismail Bennani private: 647e01924eSMed Ismail Bennani T *m_sb; 657e01924eSMed Ismail Bennani }; 667e01924eSMed Ismail Bennani 6727b6a4e6SAlex Langford // TODO: We may want to support other languages in the future w/ SWIG (we 6827b6a4e6SAlex Langford // already support Lua right now, for example). We could create a generic 6927b6a4e6SAlex Langford // SWIGBridge class and have this one specialize it, something like this: 7027b6a4e6SAlex Langford // 7127b6a4e6SAlex Langford // <typename T> 7227b6a4e6SAlex Langford // class SWIGBridge { 7327b6a4e6SAlex Langford // static T ToSWIGWrapper(...); 7427b6a4e6SAlex Langford // }; 7527b6a4e6SAlex Langford // 7627b6a4e6SAlex Langford // class SWIGPythonBridge : public SWIGBridge<PythonObject> { 7727b6a4e6SAlex Langford // template<> static PythonObject ToSWIGWrapper(...); 7827b6a4e6SAlex Langford // }; 7927b6a4e6SAlex Langford // 8027b6a4e6SAlex Langford // And we should be able to more easily support things like Lua 8127b6a4e6SAlex Langford class SWIGBridge { 8227b6a4e6SAlex Langford public: 8327b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); 8427b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); 8527b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); 8627b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); 87*b6960e2aSrchamala static PythonObject ToSWIGWrapper(lldb::ModuleSP module_sp); 8827b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); 8927b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); 90f732157aSMed Ismail Bennani static PythonObject ToSWIGWrapper(Status &&status); 9127b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); 9227b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); 9327b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); 9427b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); 9527b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); 9627b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); 9727b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); 9827b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); 9927b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); 10027b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); 1019a9ec228SMed Ismail Bennani static PythonObject ToSWIGWrapper(const Stream *stream); 1029a9ec228SMed Ismail Bennani static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb); 1039a9ec228SMed Ismail Bennani static PythonObject ToSWIGWrapper(Event *event); 1047e01924eSMed Ismail Bennani 10527b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); 10627b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); 10727b6a4e6SAlex Langford static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); 108b9d4c94aSMed Ismail Bennani 10927b6a4e6SAlex Langford static PythonObject 11027b6a4e6SAlex Langford ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); 111c4fa6fafSKazuki Sakamoto static PythonObject 112c4fa6fafSKazuki Sakamoto ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); 113c4fa6fafSKazuki Sakamoto static PythonObject 114c4fa6fafSKazuki Sakamoto ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); 1157e01924eSMed Ismail Bennani 11627b6a4e6SAlex Langford static python::ScopedPythonObject<lldb::SBCommandReturnObject> 1177e01924eSMed Ismail Bennani ToSWIGWrapper(CommandReturnObject &cmd_retobj); 11827b6a4e6SAlex Langford // These prototypes are the Pythonic implementations of the required 11927b6a4e6SAlex Langford // callbacks. Although these are scripting-language specific, their definition 12027b6a4e6SAlex Langford // depends on the public API. 1217e01924eSMed Ismail Bennani 12227b6a4e6SAlex Langford static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( 12327b6a4e6SAlex Langford const char *python_function_name, const char *session_dictionary_name, 12427b6a4e6SAlex Langford const lldb::StackFrameSP &sb_frame, 12527b6a4e6SAlex Langford const lldb::BreakpointLocationSP &sb_bp_loc, 12627b6a4e6SAlex Langford const lldb_private::StructuredDataImpl &args_impl); 12727b6a4e6SAlex Langford 12827b6a4e6SAlex Langford static bool LLDBSwigPythonWatchpointCallbackFunction( 12927b6a4e6SAlex Langford const char *python_function_name, const char *session_dictionary_name, 13027b6a4e6SAlex Langford const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); 13127b6a4e6SAlex Langford 13227b6a4e6SAlex Langford static bool 13327b6a4e6SAlex Langford LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, 13427b6a4e6SAlex Langford const char *session_dictionary_name, 13527b6a4e6SAlex Langford lldb::TypeImplSP type_impl_sp); 13627b6a4e6SAlex Langford 13727b6a4e6SAlex Langford static bool LLDBSwigPythonCallTypeScript( 13827b6a4e6SAlex Langford const char *python_function_name, const void *session_dictionary, 13927b6a4e6SAlex Langford const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, 14027b6a4e6SAlex Langford const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); 14127b6a4e6SAlex Langford 14227b6a4e6SAlex Langford static python::PythonObject 14327b6a4e6SAlex Langford LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, 14427b6a4e6SAlex Langford const char *session_dictionary_name, 14527b6a4e6SAlex Langford const lldb::ValueObjectSP &valobj_sp); 14627b6a4e6SAlex Langford 14727b6a4e6SAlex Langford static python::PythonObject 14827b6a4e6SAlex Langford LLDBSwigPythonCreateCommandObject(const char *python_class_name, 14927b6a4e6SAlex Langford const char *session_dictionary_name, 15027b6a4e6SAlex Langford lldb::DebuggerSP debugger_sp); 15127b6a4e6SAlex Langford 15227b6a4e6SAlex Langford static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( 15327b6a4e6SAlex Langford const char *python_class_name, const char *session_dictionary_name, 15427b6a4e6SAlex Langford const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); 15527b6a4e6SAlex Langford 15627b6a4e6SAlex Langford static unsigned int 15727b6a4e6SAlex Langford LLDBSwigPythonCallBreakpointResolver(void *implementor, 15827b6a4e6SAlex Langford const char *method_name, 15927b6a4e6SAlex Langford lldb_private::SymbolContext *sym_ctx); 16027b6a4e6SAlex Langford 16127b6a4e6SAlex Langford static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, 16227b6a4e6SAlex Langford uint32_t max); 16327b6a4e6SAlex Langford 16427b6a4e6SAlex Langford static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, 16527b6a4e6SAlex Langford uint32_t idx); 16627b6a4e6SAlex Langford 16727b6a4e6SAlex Langford static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, 16827b6a4e6SAlex Langford const char *child_name); 16927b6a4e6SAlex Langford 17027b6a4e6SAlex Langford static lldb::ValueObjectSP 17127b6a4e6SAlex Langford LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); 17227b6a4e6SAlex Langford 17327b6a4e6SAlex Langford static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); 17427b6a4e6SAlex Langford 17527b6a4e6SAlex Langford static bool 17627b6a4e6SAlex Langford LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor); 17727b6a4e6SAlex Langford 17827b6a4e6SAlex Langford static PyObject * 17927b6a4e6SAlex Langford LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); 18027b6a4e6SAlex Langford 18127b6a4e6SAlex Langford static bool 18227b6a4e6SAlex Langford LLDBSwigPythonCallCommand(const char *python_function_name, 18327b6a4e6SAlex Langford const char *session_dictionary_name, 18427b6a4e6SAlex Langford lldb::DebuggerSP debugger, const char *args, 18527b6a4e6SAlex Langford lldb_private::CommandReturnObject &cmd_retobj, 18627b6a4e6SAlex Langford lldb::ExecutionContextRefSP exe_ctx_ref_sp); 18727b6a4e6SAlex Langford 18827b6a4e6SAlex Langford static bool 18927b6a4e6SAlex Langford LLDBSwigPythonCallCommandObject(PyObject *implementor, 19027b6a4e6SAlex Langford lldb::DebuggerSP debugger, const char *args, 19127b6a4e6SAlex Langford lldb_private::CommandReturnObject &cmd_retobj, 19227b6a4e6SAlex Langford lldb::ExecutionContextRefSP exe_ctx_ref_sp); 193a69ecb24Sjimingham static bool 194a69ecb24Sjimingham LLDBSwigPythonCallParsedCommandObject(PyObject *implementor, 195a69ecb24Sjimingham lldb::DebuggerSP debugger, 196a69ecb24Sjimingham StructuredDataImpl &args_impl, 197a69ecb24Sjimingham lldb_private::CommandReturnObject &cmd_retobj, 198a69ecb24Sjimingham lldb::ExecutionContextRefSP exe_ctx_ref_sp); 19927b6a4e6SAlex Langford 20077d131edSjimingham static std::optional<std::string> 20177d131edSjimingham LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor, 20277d131edSjimingham std::string &command); 20377d131edSjimingham 20404b443e7Sjimingham static StructuredData::DictionarySP 20504b443e7Sjimingham LLDBSwigPythonHandleArgumentCompletionForScriptedCommand( 20604b443e7Sjimingham PyObject *implementor, std::vector<llvm::StringRef> &args_impl, 20704b443e7Sjimingham size_t args_pos, size_t pos_in_arg); 20804b443e7Sjimingham 20904b443e7Sjimingham static StructuredData::DictionarySP 21004b443e7Sjimingham LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand( 21104b443e7Sjimingham PyObject *implementor, llvm::StringRef &long_option, size_t pos_in_arg); 21204b443e7Sjimingham 21327b6a4e6SAlex Langford static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, 21427b6a4e6SAlex Langford const char *session_dictionary_name, 21527b6a4e6SAlex Langford lldb::DebuggerSP debugger); 21627b6a4e6SAlex Langford 21727b6a4e6SAlex Langford static python::PythonObject 21827b6a4e6SAlex Langford LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, 21927b6a4e6SAlex Langford const char *session_dictionary_name, 22027b6a4e6SAlex Langford const lldb::ProcessSP &process_sp); 22127b6a4e6SAlex Langford 22227b6a4e6SAlex Langford static python::PythonObject 22327b6a4e6SAlex Langford LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, 22427b6a4e6SAlex Langford const char *session_dictionary_name); 22527b6a4e6SAlex Langford 22627b6a4e6SAlex Langford static PyObject * 22727b6a4e6SAlex Langford LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, 22827b6a4e6SAlex Langford const lldb::StackFrameSP &frame_sp); 22927b6a4e6SAlex Langford 2303c0fba4fSAdrian Prantl static bool LLDBSwigPython_ShouldHide(PyObject *implementor, 2313c0fba4fSAdrian Prantl const lldb::StackFrameSP &frame_sp); 2323c0fba4fSAdrian Prantl 23327b6a4e6SAlex Langford static bool LLDBSWIGPythonRunScriptKeywordProcess( 23427b6a4e6SAlex Langford const char *python_function_name, const char *session_dictionary_name, 23527b6a4e6SAlex Langford const lldb::ProcessSP &process, std::string &output); 23627b6a4e6SAlex Langford 23727b6a4e6SAlex Langford static std::optional<std::string> 23827b6a4e6SAlex Langford LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, 23927b6a4e6SAlex Langford const char *session_dictionary_name, 24027b6a4e6SAlex Langford lldb::ThreadSP thread); 24127b6a4e6SAlex Langford 24227b6a4e6SAlex Langford static bool LLDBSWIGPythonRunScriptKeywordTarget( 24327b6a4e6SAlex Langford const char *python_function_name, const char *session_dictionary_name, 24427b6a4e6SAlex Langford const lldb::TargetSP &target, std::string &output); 24527b6a4e6SAlex Langford 24627b6a4e6SAlex Langford static std::optional<std::string> 24727b6a4e6SAlex Langford LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, 24827b6a4e6SAlex Langford const char *session_dictionary_name, 24927b6a4e6SAlex Langford lldb::StackFrameSP frame); 25027b6a4e6SAlex Langford 25127b6a4e6SAlex Langford static bool LLDBSWIGPythonRunScriptKeywordValue( 25227b6a4e6SAlex Langford const char *python_function_name, const char *session_dictionary_name, 25327b6a4e6SAlex Langford const lldb::ValueObjectSP &value, std::string &output); 25427b6a4e6SAlex Langford 25527b6a4e6SAlex Langford static void * 25627b6a4e6SAlex Langford LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, 25727b6a4e6SAlex Langford const lldb::TargetSP &target_sp); 25827b6a4e6SAlex Langford }; 2591f6a57c1SMed Ismail Bennani 2609a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); 261e31d0c20SMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); 262b9d4c94aSMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); 263b9d4c94aSMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); 2649a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); 2659a9ec228SMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); 2669a9ec228SMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); 2679a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); 2689a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); 269f732157aSMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data); 27027b6a4e6SAlex Langford } // namespace python 2711f6a57c1SMed Ismail Bennani 272ec00502bSShafik Yaghmour } // namespace lldb_private 2731f6a57c1SMed Ismail Bennani 2741f6a57c1SMed Ismail Bennani #endif // LLDB_ENABLE_PYTHON 2751f6a57c1SMed Ismail Bennani #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 276