1 //===-- ScriptedPythonInterface.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_SCRIPTEDPYTHONINTERFACE_H 10 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H 11 12 #include "lldb/Host/Config.h" 13 14 #if LLDB_ENABLE_PYTHON 15 16 #include "lldb/Interpreter/ScriptedInterface.h" 17 #include "lldb/Utility/DataBufferHeap.h" 18 19 #include "PythonDataObjects.h" 20 #include "SWIGPythonBridge.h" 21 #include "ScriptInterpreterPythonImpl.h" 22 23 namespace lldb_private { 24 class ScriptInterpreterPythonImpl; 25 class ScriptedPythonInterface : virtual public ScriptedInterface { 26 public: 27 ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter); 28 virtual ~ScriptedPythonInterface() = default; 29 30 protected: 31 template <typename T = StructuredData::ObjectSP> 32 T ExtractValueFromPythonObject(python::PythonObject &p, Status &error) { 33 return p.CreateStructuredObject(); 34 } 35 36 template <typename T = StructuredData::ObjectSP, typename... Args> 37 T Dispatch(llvm::StringRef method_name, Status &error, Args... args) { 38 using namespace python; 39 using Locker = ScriptInterpreterPythonImpl::Locker; 40 41 std::string caller_signature = 42 llvm::Twine(__PRETTY_FUNCTION__ + llvm::Twine(" (") + 43 llvm::Twine(method_name) + llvm::Twine(")")) 44 .str(); 45 if (!m_object_instance_sp) 46 return ErrorWithMessage<T>(caller_signature, "Python object ill-formed", 47 error); 48 49 Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 50 Locker::FreeLock); 51 52 PythonObject implementor(PyRefType::Borrowed, 53 (PyObject *)m_object_instance_sp->GetValue()); 54 55 if (!implementor.IsAllocated()) 56 return ErrorWithMessage<T>(caller_signature, 57 "Python implementor not allocated.", error); 58 59 PythonObject pmeth( 60 PyRefType::Owned, 61 PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); 62 63 if (PyErr_Occurred()) 64 PyErr_Clear(); 65 66 if (!pmeth.IsAllocated()) 67 return ErrorWithMessage<T>(caller_signature, 68 "Python method not allocated.", error); 69 70 if (PyCallable_Check(pmeth.get()) == 0) { 71 if (PyErr_Occurred()) 72 PyErr_Clear(); 73 return ErrorWithMessage<T>(caller_signature, 74 "Python method not callable.", error); 75 } 76 77 if (PyErr_Occurred()) 78 PyErr_Clear(); 79 80 // TODO: make `const char *` when removing support for Python 2. 81 char *format = nullptr; 82 std::string format_buffer; 83 84 if (sizeof...(Args) > 0) { 85 FormatArgs(format_buffer, args...); 86 // TODO: make `const char *` when removing support for Python 2. 87 format = const_cast<char *>(format_buffer.c_str()); 88 } 89 90 // TODO: make `const char *` when removing support for Python 2. 91 PythonObject py_return( 92 PyRefType::Owned, 93 PyObject_CallMethod(implementor.get(), 94 const_cast<char *>(method_name.data()), format, 95 args...)); 96 97 if (PyErr_Occurred()) { 98 PyErr_Print(); 99 PyErr_Clear(); 100 return ErrorWithMessage<T>(caller_signature, 101 "Python method could not be called.", error); 102 } 103 104 if (!py_return.IsAllocated()) 105 return ErrorWithMessage<T>(caller_signature, "Returned object is null.", 106 error); 107 108 return ExtractValueFromPythonObject<T>(py_return, error); 109 } 110 111 Status GetStatusFromMethod(llvm::StringRef method_name); 112 113 template <typename T, typename... Args> 114 void FormatArgs(std::string &fmt, T arg, Args... args) const { 115 FormatArgs(fmt, arg); 116 FormatArgs(fmt, args...); 117 } 118 119 template <typename T> void FormatArgs(std::string &fmt, T arg) const { 120 fmt += GetPythonValueFormatString(arg); 121 } 122 123 void FormatArgs(std::string &fmt) const {} 124 125 // The lifetime is managed by the ScriptInterpreter 126 ScriptInterpreterPythonImpl &m_interpreter; 127 }; 128 129 template <> 130 StructuredData::DictionarySP 131 ScriptedPythonInterface::ExtractValueFromPythonObject< 132 StructuredData::DictionarySP>(python::PythonObject &p, Status &error); 133 134 template <> 135 Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>( 136 python::PythonObject &p, Status &error); 137 138 template <> 139 lldb::DataExtractorSP 140 ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>( 141 python::PythonObject &p, Status &error); 142 143 template <> 144 llvm::Optional<MemoryRegionInfo> 145 ScriptedPythonInterface::ExtractValueFromPythonObject< 146 llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error); 147 148 } // namespace lldb_private 149 150 #endif // LLDB_ENABLE_PYTHON 151 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H 152