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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 10 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 11 12 #include <optional> 13 #include <string> 14 15 #include "lldb/Host/Config.h" 16 17 #if LLDB_ENABLE_PYTHON 18 19 // LLDB Python header must be included first 20 #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 27 namespace lldb { 28 class SBEvent; 29 class SBCommandReturnObject; 30 class SBValue; 31 class SBStream; 32 class SBStructuredData; 33 class SBFileSpec; 34 class SBModuleSpec; 35 class SBStringList; 36 } // namespace lldb 37 38 namespace lldb_private { 39 namespace python { 40 41 typedef struct swig_type_info swig_type_info; 42 43 python::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. 47 template <typename T> class ScopedPythonObject : PythonObject { 48 public: ScopedPythonObject(T * sb,swig_type_info * info)49 ScopedPythonObject(T *sb, swig_type_info *info) 50 : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {} ~ScopedPythonObject()51 ~ScopedPythonObject() { 52 if (m_sb) 53 *m_sb = T(); 54 } ScopedPythonObject(ScopedPythonObject && rhs)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 obj()61 const PythonObject &obj() const { return *this; } 62 63 private: 64 T *m_sb; 65 }; 66 67 // TODO: We may want to support other languages in the future w/ SWIG (we 68 // already support Lua right now, for example). We could create a generic 69 // 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 Lua 81 class SWIGBridge { 82 public: 83 static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); 84 static PythonObject 85 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::DebuggerSP debugger_sp); 97 static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); 98 static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); 99 static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); 100 static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); 101 static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); 102 static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); 103 static PythonObject ToSWIGWrapper(const Stream *stream); 104 static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb); 105 static PythonObject ToSWIGWrapper(Event *event); 106 107 static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); 108 static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); 109 static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); 110 111 static PythonObject 112 ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); 113 static PythonObject 114 ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); 115 static PythonObject 116 ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); 117 118 static python::ScopedPythonObject<lldb::SBCommandReturnObject> 119 ToSWIGWrapper(CommandReturnObject &cmd_retobj); 120 // These prototypes are the Pythonic implementations of the required 121 // callbacks. Although these are scripting-language specific, their definition 122 // depends on the public API. 123 124 static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( 125 const char *python_function_name, const char *session_dictionary_name, 126 const lldb::StackFrameSP &sb_frame, 127 const lldb::BreakpointLocationSP &sb_bp_loc, 128 const lldb_private::StructuredDataImpl &args_impl); 129 130 static bool LLDBSwigPythonWatchpointCallbackFunction( 131 const char *python_function_name, const char *session_dictionary_name, 132 const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); 133 134 static bool 135 LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, 136 const char *session_dictionary_name, 137 lldb::TypeImplSP type_impl_sp); 138 139 static bool LLDBSwigPythonCallTypeScript( 140 const char *python_function_name, const void *session_dictionary, 141 const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, 142 const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); 143 144 static python::PythonObject 145 LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, 146 const char *session_dictionary_name, 147 const lldb::ValueObjectSP &valobj_sp); 148 149 static python::PythonObject 150 LLDBSwigPythonCreateCommandObject(const char *python_class_name, 151 const char *session_dictionary_name, 152 lldb::DebuggerSP debugger_sp); 153 154 static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( 155 const char *python_class_name, const char *session_dictionary_name, 156 const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); 157 158 static unsigned int 159 LLDBSwigPythonCallBreakpointResolver(void *implementor, 160 const char *method_name, 161 lldb_private::SymbolContext *sym_ctx); 162 163 static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, 164 uint32_t max); 165 166 static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, 167 uint32_t idx); 168 169 static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, 170 const char *child_name); 171 172 static lldb::ValueObjectSP 173 LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); 174 175 static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); 176 177 static bool 178 LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor); 179 180 static PyObject * 181 LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); 182 183 static bool 184 LLDBSwigPythonCallCommand(const char *python_function_name, 185 const char *session_dictionary_name, 186 lldb::DebuggerSP debugger, const char *args, 187 lldb_private::CommandReturnObject &cmd_retobj, 188 lldb::ExecutionContextRefSP exe_ctx_ref_sp); 189 190 static bool 191 LLDBSwigPythonCallCommandObject(PyObject *implementor, 192 lldb::DebuggerSP debugger, const char *args, 193 lldb_private::CommandReturnObject &cmd_retobj, 194 lldb::ExecutionContextRefSP exe_ctx_ref_sp); 195 static bool LLDBSwigPythonCallParsedCommandObject( 196 PyObject *implementor, lldb::DebuggerSP debugger, 197 StructuredDataImpl &args_impl, 198 lldb_private::CommandReturnObject &cmd_retobj, 199 lldb::ExecutionContextRefSP exe_ctx_ref_sp); 200 201 static std::optional<std::string> 202 LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor, 203 std::string &command); 204 205 static StructuredData::DictionarySP 206 LLDBSwigPythonHandleArgumentCompletionForScriptedCommand( 207 PyObject *implementor, std::vector<llvm::StringRef> &args_impl, 208 size_t args_pos, size_t pos_in_arg); 209 210 static StructuredData::DictionarySP 211 LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand( 212 PyObject *implementor, llvm::StringRef &long_option, size_t pos_in_arg); 213 214 static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, 215 const char *session_dictionary_name, 216 lldb::DebuggerSP debugger); 217 218 static bool 219 LLDBSwigPythonCallModuleNewTarget(const char *python_module_name, 220 const char *session_dictionary_name, 221 lldb::TargetSP target); 222 223 static python::PythonObject 224 LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, 225 const char *session_dictionary_name, 226 const lldb::ProcessSP &process_sp); 227 228 static python::PythonObject 229 LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, 230 const char *session_dictionary_name); 231 232 static PyObject * 233 LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, 234 const lldb::StackFrameSP &frame_sp); 235 236 static bool LLDBSwigPython_ShouldHide(PyObject *implementor, 237 const lldb::StackFrameSP &frame_sp); 238 239 static bool LLDBSWIGPythonRunScriptKeywordProcess( 240 const char *python_function_name, const char *session_dictionary_name, 241 const lldb::ProcessSP &process, std::string &output); 242 243 static std::optional<std::string> 244 LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, 245 const char *session_dictionary_name, 246 lldb::ThreadSP thread); 247 248 static bool LLDBSWIGPythonRunScriptKeywordTarget( 249 const char *python_function_name, const char *session_dictionary_name, 250 const lldb::TargetSP &target, std::string &output); 251 252 static std::optional<std::string> 253 LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, 254 const char *session_dictionary_name, 255 lldb::StackFrameSP frame); 256 257 static bool LLDBSWIGPythonRunScriptKeywordValue( 258 const char *python_function_name, const char *session_dictionary_name, 259 const lldb::ValueObjectSP &value, std::string &output); 260 261 static void * 262 LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, 263 const lldb::TargetSP &target_sp); 264 }; 265 266 void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); 267 void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); 268 void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); 269 void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); 270 void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); 271 void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); 272 void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); 273 void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); 274 void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); 275 void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data); 276 } // namespace python 277 278 } // namespace lldb_private 279 280 #endif // LLDB_ENABLE_PYTHON 281 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H 282