280 lines · c
1//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H10#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H11 12#include <optional>13#include <string>14 15#include "lldb/Host/Config.h"16 17#if LLDB_ENABLE_PYTHON18 19// LLDB Python header must be included first20#include "lldb-python.h"21 22#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"23#include "lldb/lldb-forward.h"24#include "lldb/lldb-types.h"25#include "llvm/Support/Error.h"26 27namespace lldb {28class SBEvent;29class SBCommandReturnObject;30class SBValue;31class SBStream;32class SBStructuredData;33class SBFileSpec;34class SBModuleSpec;35class SBStringList;36} // namespace lldb37 38namespace lldb_private {39namespace python {40 41typedef struct swig_type_info swig_type_info;42 43python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);44 45/// A class that automatically clears an SB object when it goes out of scope.46/// Use for cases where the SB object points to a temporary/unowned entity.47template <typename T> class ScopedPythonObject : PythonObject {48public:49 ScopedPythonObject(T *sb, swig_type_info *info)50 : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}51 ~ScopedPythonObject() {52 if (m_sb)53 *m_sb = T();54 }55 ScopedPythonObject(ScopedPythonObject &&rhs)56 : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}57 ScopedPythonObject(const ScopedPythonObject &) = delete;58 ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;59 ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;60 61 const PythonObject &obj() const { return *this; }62 63private:64 T *m_sb;65};66 67// TODO: We may want to support other languages in the future w/ SWIG (we68// already support Lua right now, for example). We could create a generic69// SWIGBridge class and have this one specialize it, something like this:70//71// <typename T>72// class SWIGBridge {73// static T ToSWIGWrapper(...);74// };75//76// class SWIGPythonBridge : public SWIGBridge<PythonObject> {77// template<> static PythonObject ToSWIGWrapper(...);78// };79//80// And we should be able to more easily support things like Lua81class SWIGBridge {82public:83 static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);84 static PythonObject85 ToSWIGWrapper(std::unique_ptr<lldb::SBCommandReturnObject> result_up);86 static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);87 static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);88 static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);89 static PythonObject ToSWIGWrapper(lldb::ModuleSP module_sp);90 static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);91 static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);92 static PythonObject ToSWIGWrapper(Status &&status);93 static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);94 static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);95 static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);96 static PythonObject ToSWIGWrapper(lldb::StackFrameListSP frames_sp);97 static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);98 static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);99 static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);100 static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp);101 static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);102 static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);103 static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);104 static PythonObject ToSWIGWrapper(const Stream *stream);105 static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb);106 static PythonObject ToSWIGWrapper(Event *event);107 108 static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);109 static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);110 static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);111 static PythonObject ToSWIGWrapper(lldb::DescriptionLevel level);112 113 static PythonObject114 ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);115 static PythonObject116 ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb);117 static PythonObject118 ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb);119 120 static python::ScopedPythonObject<lldb::SBCommandReturnObject>121 ToSWIGWrapper(CommandReturnObject &cmd_retobj);122 // These prototypes are the Pythonic implementations of the required123 // callbacks. Although these are scripting-language specific, their definition124 // depends on the public API.125 126 static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(127 const char *python_function_name, const char *session_dictionary_name,128 const lldb::StackFrameSP &sb_frame,129 const lldb::BreakpointLocationSP &sb_bp_loc,130 const lldb_private::StructuredDataImpl &args_impl);131 132 static bool LLDBSwigPythonWatchpointCallbackFunction(133 const char *python_function_name, const char *session_dictionary_name,134 const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);135 136 static bool137 LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name,138 const char *session_dictionary_name,139 lldb::TypeImplSP type_impl_sp);140 141 static bool LLDBSwigPythonCallTypeScript(142 const char *python_function_name, const void *session_dictionary,143 const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,144 const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);145 146 static python::PythonObject147 LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,148 const char *session_dictionary_name,149 const lldb::ValueObjectSP &valobj_sp);150 151 static python::PythonObject152 LLDBSwigPythonCreateCommandObject(const char *python_class_name,153 const char *session_dictionary_name,154 lldb::DebuggerSP debugger_sp);155 156 static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,157 uint32_t max);158 159 static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor,160 uint32_t idx);161 162 static uint32_t163 LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,164 const char *child_name);165 166 static lldb::ValueObjectSP167 LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);168 169 static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);170 171 static bool172 LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor);173 174 static PyObject *175 LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);176 177 static bool178 LLDBSwigPythonCallCommand(const char *python_function_name,179 const char *session_dictionary_name,180 lldb::DebuggerSP debugger, const char *args,181 lldb_private::CommandReturnObject &cmd_retobj,182 lldb::ExecutionContextRefSP exe_ctx_ref_sp);183 184 static bool185 LLDBSwigPythonCallCommandObject(PyObject *implementor,186 lldb::DebuggerSP debugger, const char *args,187 lldb_private::CommandReturnObject &cmd_retobj,188 lldb::ExecutionContextRefSP exe_ctx_ref_sp);189 static bool LLDBSwigPythonCallParsedCommandObject(190 PyObject *implementor, lldb::DebuggerSP debugger,191 StructuredDataImpl &args_impl,192 lldb_private::CommandReturnObject &cmd_retobj,193 lldb::ExecutionContextRefSP exe_ctx_ref_sp);194 195 static std::optional<std::string>196 LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor,197 std::string &command);198 199 static StructuredData::DictionarySP200 LLDBSwigPythonHandleArgumentCompletionForScriptedCommand(201 PyObject *implementor, std::vector<llvm::StringRef> &args_impl,202 size_t args_pos, size_t pos_in_arg);203 204 static StructuredData::DictionarySP205 LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand(206 PyObject *implementor, llvm::StringRef &long_option, size_t pos_in_arg);207 208 static bool LLDBSwigPythonCallModuleInit(const char *python_module_name,209 const char *session_dictionary_name,210 lldb::DebuggerSP debugger);211 212 static bool213 LLDBSwigPythonCallModuleNewTarget(const char *python_module_name,214 const char *session_dictionary_name,215 lldb::TargetSP target);216 217 static python::PythonObject218 LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,219 const char *session_dictionary_name,220 const lldb::ProcessSP &process_sp);221 222 static python::PythonObject223 LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,224 const char *session_dictionary_name);225 226 static PyObject *227 LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,228 const lldb::StackFrameSP &frame_sp);229 230 static bool LLDBSwigPython_ShouldHide(PyObject *implementor,231 const lldb::StackFrameSP &frame_sp);232 233 static bool LLDBSWIGPythonRunScriptKeywordProcess(234 const char *python_function_name, const char *session_dictionary_name,235 const lldb::ProcessSP &process, std::string &output);236 237 static std::optional<std::string>238 LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,239 const char *session_dictionary_name,240 lldb::ThreadSP thread);241 242 static bool LLDBSWIGPythonRunScriptKeywordTarget(243 const char *python_function_name, const char *session_dictionary_name,244 const lldb::TargetSP &target, std::string &output);245 246 static std::optional<std::string>247 LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,248 const char *session_dictionary_name,249 lldb::StackFrameSP frame);250 251 static bool LLDBSWIGPythonRunScriptKeywordValue(252 const char *python_function_name, const char *session_dictionary_name,253 const lldb::ValueObjectSP &value, std::string &output);254 255 static void *256 LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,257 const lldb::TargetSP &target_sp);258};259 260void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);261void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);262void *LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(PyObject *data);263void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);264void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);265void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);266void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);267void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);268void *LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data);269void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data);270void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);271void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);272void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data);273void *LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *data);274} // namespace python275 276} // namespace lldb_private277 278#endif // LLDB_ENABLE_PYTHON279#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H280