| //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H | |
| #define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H | |
| #include <optional> | |
| #include <string> | |
| #include "lldb-python.h" | |
| #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h" | |
| #include "lldb/lldb-forward.h" | |
| #include "lldb/lldb-types.h" | |
| #include "llvm/Support/Error.h" | |
| namespace lldb { | |
| class SBEvent; | |
| class SBCommandReturnObject; | |
| class SBValue; | |
| class SBStream; | |
| class SBStructuredData; | |
| class SBFileSpec; | |
| class SBModuleSpec; | |
| class SBStringList; | |
| } // namespace lldb | |
| namespace lldb_private { | |
| namespace python { | |
| typedef struct swig_type_info swig_type_info; | |
| python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info); | |
| /// A class that automatically clears an SB object when it goes out of scope. | |
| /// Use for cases where the SB object points to a temporary/unowned entity. | |
| template <typename T> class ScopedPythonObject : public PythonObject { | |
| public: | |
| ScopedPythonObject(T *sb, swig_type_info *info) | |
| : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {} | |
| ~ScopedPythonObject() { | |
| if (m_sb) | |
| *m_sb = T(); | |
| } | |
| ScopedPythonObject(ScopedPythonObject &&rhs) | |
| : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {} | |
| ScopedPythonObject(const ScopedPythonObject &) = delete; | |
| ScopedPythonObject &operator=(const ScopedPythonObject &) = delete; | |
| ScopedPythonObject &operator=(ScopedPythonObject &&) = delete; | |
| const PythonObject &obj() const { return *this; } | |
| private: | |
| T *m_sb; | |
| }; | |
| // TODO: We may want to support other languages in the future w/ SWIG (we | |
| // already support Lua right now, for example). We could create a generic | |
| // SWIGBridge class and have this one specialize it, something like this: | |
| // | |
| // <typename T> | |
| // class SWIGBridge { | |
| // static T ToSWIGWrapper(...); | |
| // }; | |
| // | |
| // class SWIGPythonBridge : public SWIGBridge<PythonObject> { | |
| // template<> static PythonObject ToSWIGWrapper(...); | |
| // }; | |
| // | |
| // And we should be able to more easily support things like Lua | |
| class SWIGBridge { | |
| public: | |
| static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); | |
| static PythonObject | |
| ToSWIGWrapper(std::unique_ptr<lldb::SBCommandReturnObject> result_up); | |
| static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); | |
| static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp, | |
| bool use_synthetic); | |
| static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); | |
| static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); | |
| static PythonObject ToSWIGWrapper(lldb::ModuleSP module_sp); | |
| static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); | |
| static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); | |
| static PythonObject ToSWIGWrapper(Status &&status); | |
| static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); | |
| static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); | |
| static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); | |
| static PythonObject ToSWIGWrapper(lldb::StackFrameListSP frames_sp); | |
| static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); | |
| static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); | |
| static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); | |
| static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); | |
| static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); | |
| static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); | |
| static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); | |
| static PythonObject ToSWIGWrapper(const Stream *stream); | |
| static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb); | |
| static PythonObject ToSWIGWrapper(Event *event); | |
| static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); | |
| static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); | |
| static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); | |
| static PythonObject ToSWIGWrapper(lldb::DescriptionLevel level); | |
| static PythonObject ToSWIGWrapper(lldb::StepType step_type); | |
| static PythonObject | |
| ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); | |
| static PythonObject | |
| ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); | |
| static PythonObject | |
| ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); | |
| static python::ScopedPythonObject<lldb::SBCommandReturnObject> | |
| ToSWIGWrapper(CommandReturnObject &cmd_retobj); | |
| // These prototypes are the Pythonic implementations of the required | |
| // callbacks. Although these are scripting-language specific, their definition | |
| // depends on the public API. | |
| static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( | |
| const char *python_function_name, const char *session_dictionary_name, | |
| const lldb::StackFrameSP &sb_frame, | |
| const lldb::BreakpointLocationSP &sb_bp_loc, | |
| const lldb_private::StructuredDataImpl &args_impl); | |
| static bool LLDBSwigPythonWatchpointCallbackFunction( | |
| const char *python_function_name, const char *session_dictionary_name, | |
| const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); | |
| static bool | |
| LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, | |
| const char *session_dictionary_name, | |
| lldb::TypeImplSP type_impl_sp); | |
| static bool LLDBSwigPythonCallTypeScript( | |
| const char *python_function_name, const void *session_dictionary, | |
| const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, | |
| const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); | |
| static python::PythonObject | |
| LLDBSwigPythonCreateCommandObject(const char *python_class_name, | |
| const char *session_dictionary_name, | |
| lldb::DebuggerSP debugger_sp); | |
| static lldb::ValueObjectSP | |
| LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); | |
| static bool | |
| LLDBSwigPythonCallCommand(const char *python_function_name, | |
| const char *session_dictionary_name, | |
| lldb::DebuggerSP debugger, const char *args, | |
| lldb_private::CommandReturnObject &cmd_retobj, | |
| lldb::ExecutionContextRefSP exe_ctx_ref_sp); | |
| static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, | |
| const char *session_dictionary_name, | |
| lldb::DebuggerSP debugger); | |
| static bool | |
| LLDBSwigPythonCallModuleNewTarget(const char *python_module_name, | |
| const char *session_dictionary_name, | |
| lldb::TargetSP target); | |
| static python::PythonObject | |
| LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, | |
| const char *session_dictionary_name, | |
| const lldb::ProcessSP &process_sp); | |
| static bool LLDBSWIGPythonRunScriptKeywordProcess( | |
| const char *python_function_name, const char *session_dictionary_name, | |
| const lldb::ProcessSP &process, std::string &output); | |
| static std::optional<std::string> | |
| LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, | |
| const char *session_dictionary_name, | |
| lldb::ThreadSP thread); | |
| static bool LLDBSWIGPythonRunScriptKeywordTarget( | |
| const char *python_function_name, const char *session_dictionary_name, | |
| const lldb::TargetSP &target, std::string &output); | |
| static std::optional<std::string> | |
| LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, | |
| const char *session_dictionary_name, | |
| lldb::StackFrameSP frame); | |
| static bool LLDBSWIGPythonRunScriptKeywordValue( | |
| const char *python_function_name, const char *session_dictionary_name, | |
| const lldb::ValueObjectSP &value, std::string &output); | |
| static void * | |
| LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, | |
| const lldb::TargetSP &target_sp); | |
| }; | |
| void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBCommandReturnObject(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBDebugger(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBThread(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBThreadPlan(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBValueList(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *data); | |
| void *LLDBSWIGPython_CastPyObjectToSBTarget(PyObject *data); | |
| } // namespace python | |
| } // namespace lldb_private | |
| #endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H |