1edb35d95SEugene Zelenko //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// 22c1f46dcSZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62c1f46dcSZachary Turner // 72c1f46dcSZachary Turner //===----------------------------------------------------------------------===// 82c1f46dcSZachary Turner 9*085328eeSLawrence D'Anna // 10*085328eeSLawrence D'Anna // !! FIXME FIXME FIXME !! 11*085328eeSLawrence D'Anna // 12*085328eeSLawrence D'Anna // Python APIs nearly all can return an exception. They do this 13*085328eeSLawrence D'Anna // by returning NULL, or -1, or some such value and setting 14*085328eeSLawrence D'Anna // the exception state with PyErr_Set*(). Exceptions must be 15*085328eeSLawrence D'Anna // handled before further python API functions are called. Failure 16*085328eeSLawrence D'Anna // to do so will result in asserts on debug builds of python. 17*085328eeSLawrence D'Anna // It will also sometimes, but not usually result in crashes of 18*085328eeSLawrence D'Anna // release builds. 19*085328eeSLawrence D'Anna // 20*085328eeSLawrence D'Anna // Nearly all the code in this header does not handle python exceptions 21*085328eeSLawrence D'Anna // correctly. It should all be converted to return Expected<> or 22*085328eeSLawrence D'Anna // Error types to capture the exception. 23*085328eeSLawrence D'Anna // 24*085328eeSLawrence D'Anna // Everything in this file except functions that return Error or 25*085328eeSLawrence D'Anna // Expected<> is considered deprecated and should not be 26*085328eeSLawrence D'Anna // used in new code. If you need to use it, fix it first. 27*085328eeSLawrence D'Anna // 28*085328eeSLawrence D'Anna 292c1f46dcSZachary Turner #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 302c1f46dcSZachary Turner #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 312c1f46dcSZachary Turner 32d68983e3SPavel Labath #ifndef LLDB_DISABLE_PYTHON 33d68983e3SPavel Labath 3441de9a97SKate Stone // LLDB Python header must be included first 3541de9a97SKate Stone #include "lldb-python.h" 3641de9a97SKate Stone 379c40264fSZachary Turner #include "lldb/Host/File.h" 38f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h" 392c1f46dcSZachary Turner 405a72c02bSZachary Turner #include "llvm/ADT/ArrayRef.h" 415a72c02bSZachary Turner 422c1f46dcSZachary Turner namespace lldb_private { 43edb35d95SEugene Zelenko 44*085328eeSLawrence D'Anna class PythonObject; 455a72c02bSZachary Turner class PythonBytes; 462c1f46dcSZachary Turner class PythonString; 472c1f46dcSZachary Turner class PythonList; 482c1f46dcSZachary Turner class PythonDictionary; 492c1f46dcSZachary Turner class PythonInteger; 50*085328eeSLawrence D'Anna class PythonException; 512c1f46dcSZachary Turner 52b9c1b51eSKate Stone class StructuredPythonObject : public StructuredData::Generic { 532c1f46dcSZachary Turner public: 54b9c1b51eSKate Stone StructuredPythonObject() : StructuredData::Generic() {} 552c1f46dcSZachary Turner 56b9c1b51eSKate Stone StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 572c1f46dcSZachary Turner Py_XINCREF(GetValue()); 582c1f46dcSZachary Turner } 592c1f46dcSZachary Turner 60b9c1b51eSKate Stone ~StructuredPythonObject() override { 612c1f46dcSZachary Turner if (Py_IsInitialized()) 622c1f46dcSZachary Turner Py_XDECREF(GetValue()); 632c1f46dcSZachary Turner SetValue(nullptr); 642c1f46dcSZachary Turner } 652c1f46dcSZachary Turner 66b9c1b51eSKate Stone bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 672c1f46dcSZachary Turner 682783d817SJonas Devlieghere void Serialize(llvm::json::OStream &s) const override; 692c1f46dcSZachary Turner 702c1f46dcSZachary Turner private: 712c1f46dcSZachary Turner DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 722c1f46dcSZachary Turner }; 732c1f46dcSZachary Turner 74b9c1b51eSKate Stone enum class PyObjectType { 752c1f46dcSZachary Turner Unknown, 762c1f46dcSZachary Turner None, 77b81d715cSTatyana Krasnukha Boolean, 782c1f46dcSZachary Turner Integer, 792c1f46dcSZachary Turner Dictionary, 802c1f46dcSZachary Turner List, 819c40264fSZachary Turner String, 825a72c02bSZachary Turner Bytes, 83f9d6d204SZachary Turner ByteArray, 847841efbbSZachary Turner Module, 85a1405147SZachary Turner Callable, 86a1405147SZachary Turner Tuple, 879c40264fSZachary Turner File 882c1f46dcSZachary Turner }; 892c1f46dcSZachary Turner 90b9c1b51eSKate Stone enum class PyRefType { 91f8b22f8fSZachary Turner Borrowed, // We are not given ownership of the incoming PyObject. 92f8b22f8fSZachary Turner // We cannot safely hold it without calling Py_INCREF. 93f8b22f8fSZachary Turner Owned // We have ownership of the incoming PyObject. We should 94f8b22f8fSZachary Turner // not call Py_INCREF. 95f8b22f8fSZachary Turner }; 96f8b22f8fSZachary Turner 97*085328eeSLawrence D'Anna namespace python { 98*085328eeSLawrence D'Anna 99*085328eeSLawrence D'Anna // Take a reference that you already own, and turn it into 100*085328eeSLawrence D'Anna // a PythonObject. 101*085328eeSLawrence D'Anna // 102*085328eeSLawrence D'Anna // Most python API methods will return a +1 reference 103*085328eeSLawrence D'Anna // if they succeed or NULL if and only if 104*085328eeSLawrence D'Anna // they set an exception. Use this to collect such return 105*085328eeSLawrence D'Anna // values, after checking for NULL. 106*085328eeSLawrence D'Anna // 107*085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be 108*085328eeSLawrence D'Anna // checked to be of the correct type. 109*085328eeSLawrence D'Anna template <typename T> T Take(PyObject *obj) { 110*085328eeSLawrence D'Anna assert(obj); 111*085328eeSLawrence D'Anna assert(!PyErr_Occurred()); 112*085328eeSLawrence D'Anna T thing(PyRefType::Owned, obj); 113*085328eeSLawrence D'Anna assert(thing.IsValid()); 114*085328eeSLawrence D'Anna return std::move(thing); 115*085328eeSLawrence D'Anna } 116*085328eeSLawrence D'Anna 117*085328eeSLawrence D'Anna // Retain a reference you have borrowed, and turn it into 118*085328eeSLawrence D'Anna // a PythonObject. 119*085328eeSLawrence D'Anna // 120*085328eeSLawrence D'Anna // A minority of python APIs return a borrowed reference 121*085328eeSLawrence D'Anna // instead of a +1. They will also return NULL if and only 122*085328eeSLawrence D'Anna // if they set an exception. Use this to collect such return 123*085328eeSLawrence D'Anna // values, after checking for NULL. 124*085328eeSLawrence D'Anna // 125*085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be 126*085328eeSLawrence D'Anna // checked to be of the correct type. 127*085328eeSLawrence D'Anna template <typename T> T Retain(PyObject *obj) { 128*085328eeSLawrence D'Anna assert(obj); 129*085328eeSLawrence D'Anna assert(!PyErr_Occurred()); 130*085328eeSLawrence D'Anna T thing(PyRefType::Borrowed, obj); 131*085328eeSLawrence D'Anna assert(thing.IsValid()); 132*085328eeSLawrence D'Anna return std::move(thing); 133*085328eeSLawrence D'Anna } 134*085328eeSLawrence D'Anna 135*085328eeSLawrence D'Anna } // namespace python 136*085328eeSLawrence D'Anna 137b9c1b51eSKate Stone enum class PyInitialValue { Invalid, Empty }; 138f8b22f8fSZachary Turner 139*085328eeSLawrence D'Anna template <typename T, typename Enable = void> struct PythonFormat; 140*085328eeSLawrence D'Anna 141*085328eeSLawrence D'Anna template <> struct PythonFormat<unsigned long long> { 142*085328eeSLawrence D'Anna static constexpr char format = 'K'; 143*085328eeSLawrence D'Anna static auto get(unsigned long long value) { return value; } 144*085328eeSLawrence D'Anna }; 145*085328eeSLawrence D'Anna 146*085328eeSLawrence D'Anna template <> struct PythonFormat<long long> { 147*085328eeSLawrence D'Anna static constexpr char format = 'L'; 148*085328eeSLawrence D'Anna static auto get(long long value) { return value; } 149*085328eeSLawrence D'Anna }; 150*085328eeSLawrence D'Anna 151*085328eeSLawrence D'Anna template <typename T> 152*085328eeSLawrence D'Anna struct PythonFormat< 153*085328eeSLawrence D'Anna T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 154*085328eeSLawrence D'Anna static constexpr char format = 'O'; 155*085328eeSLawrence D'Anna static auto get(const T &value) { return value.get(); } 156*085328eeSLawrence D'Anna }; 157*085328eeSLawrence D'Anna 158b9c1b51eSKate Stone class PythonObject { 1592c1f46dcSZachary Turner public: 160b9c1b51eSKate Stone PythonObject() : m_py_obj(nullptr) {} 1612c1f46dcSZachary Turner 162b9c1b51eSKate Stone PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) { 163f8b22f8fSZachary Turner Reset(type, py_obj); 1642c1f46dcSZachary Turner } 1652c1f46dcSZachary Turner 166b9c1b51eSKate Stone PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); } 1672c1f46dcSZachary Turner 168*085328eeSLawrence D'Anna PythonObject(PythonObject &&rhs) { 169*085328eeSLawrence D'Anna m_py_obj = rhs.m_py_obj; 170*085328eeSLawrence D'Anna rhs.m_py_obj = nullptr; 171*085328eeSLawrence D'Anna } 172*085328eeSLawrence D'Anna 173b9c1b51eSKate Stone virtual ~PythonObject() { Reset(); } 1742c1f46dcSZachary Turner 175b9c1b51eSKate Stone void Reset() { 176f8b22f8fSZachary Turner // Avoid calling the virtual method since it's not necessary 177f8b22f8fSZachary Turner // to actually validate the type of the PyObject if we're 178f8b22f8fSZachary Turner // just setting to null. 179*085328eeSLawrence D'Anna if (m_py_obj && Py_IsInitialized()) 180*085328eeSLawrence D'Anna Py_DECREF(m_py_obj); 181f8b22f8fSZachary Turner m_py_obj = nullptr; 1822c1f46dcSZachary Turner } 183f8b22f8fSZachary Turner 184b9c1b51eSKate Stone void Reset(const PythonObject &rhs) { 185f8b22f8fSZachary Turner // Avoid calling the virtual method if it's not necessary 186f8b22f8fSZachary Turner // to actually validate the type of the PyObject. 18760c24f70SZachary Turner if (!rhs.IsValid()) 188f8b22f8fSZachary Turner Reset(); 189f8b22f8fSZachary Turner else 190f8b22f8fSZachary Turner Reset(PyRefType::Borrowed, rhs.m_py_obj); 191f8b22f8fSZachary Turner } 192f8b22f8fSZachary Turner 193f8b22f8fSZachary Turner // PythonObject is implicitly convertible to PyObject *, which will call the 194f8b22f8fSZachary Turner // wrong overload. We want to explicitly disallow this, since a PyObject 195f8b22f8fSZachary Turner // *always* owns its reference. Therefore the overload which takes a 196f8b22f8fSZachary Turner // PyRefType doesn't make sense, and the copy constructor should be used. 197b9c1b51eSKate Stone void Reset(PyRefType type, const PythonObject &ref) = delete; 198f8b22f8fSZachary Turner 199*085328eeSLawrence D'Anna // FIXME We shouldn't have virtual anything. PythonObject should be a 200*085328eeSLawrence D'Anna // strictly pass-by-value type. 201b9c1b51eSKate Stone virtual void Reset(PyRefType type, PyObject *py_obj) { 202f8b22f8fSZachary Turner if (py_obj == m_py_obj) 203f8b22f8fSZachary Turner return; 204f8b22f8fSZachary Turner 205f8b22f8fSZachary Turner if (Py_IsInitialized()) 206f8b22f8fSZachary Turner Py_XDECREF(m_py_obj); 207f8b22f8fSZachary Turner 208f8b22f8fSZachary Turner m_py_obj = py_obj; 209f8b22f8fSZachary Turner 210f8b22f8fSZachary Turner // If this is a borrowed reference, we need to convert it to 211f8b22f8fSZachary Turner // an owned reference by incrementing it. If it is an owned 212f8b22f8fSZachary Turner // reference (for example the caller allocated it with PyDict_New() 213f8b22f8fSZachary Turner // then we must *not* increment it. 214*085328eeSLawrence D'Anna if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 215f8b22f8fSZachary Turner Py_XINCREF(m_py_obj); 2162c1f46dcSZachary Turner } 2172c1f46dcSZachary Turner 218b9c1b51eSKate Stone void Dump() const { 2192c1f46dcSZachary Turner if (m_py_obj) 2202c1f46dcSZachary Turner _PyObject_Dump(m_py_obj); 2212c1f46dcSZachary Turner else 2222c1f46dcSZachary Turner puts("NULL"); 2232c1f46dcSZachary Turner } 2242c1f46dcSZachary Turner 225b9c1b51eSKate Stone void Dump(Stream &strm) const; 2262c1f46dcSZachary Turner 227b9c1b51eSKate Stone PyObject *get() const { return m_py_obj; } 2282c1f46dcSZachary Turner 229b9c1b51eSKate Stone PyObject *release() { 23060c24f70SZachary Turner PyObject *result = m_py_obj; 23160c24f70SZachary Turner m_py_obj = nullptr; 23260c24f70SZachary Turner return result; 23360c24f70SZachary Turner } 23460c24f70SZachary Turner 235b9c1b51eSKate Stone PythonObject &operator=(const PythonObject &other) { 236f8b22f8fSZachary Turner Reset(PyRefType::Borrowed, other.get()); 237f8b22f8fSZachary Turner return *this; 2382c1f46dcSZachary Turner } 2392c1f46dcSZachary Turner 240*085328eeSLawrence D'Anna void Reset(PythonObject &&other) { 241*085328eeSLawrence D'Anna Reset(); 242*085328eeSLawrence D'Anna m_py_obj = other.m_py_obj; 243*085328eeSLawrence D'Anna other.m_py_obj = nullptr; 244*085328eeSLawrence D'Anna } 245*085328eeSLawrence D'Anna 246*085328eeSLawrence D'Anna PythonObject &operator=(PythonObject &&other) { 247*085328eeSLawrence D'Anna Reset(std::move(other)); 248*085328eeSLawrence D'Anna return *this; 249*085328eeSLawrence D'Anna } 250*085328eeSLawrence D'Anna 251b9c1b51eSKate Stone PyObjectType GetObjectType() const; 2527841efbbSZachary Turner 253b9c1b51eSKate Stone PythonString Repr() const; 2547841efbbSZachary Turner 255b9c1b51eSKate Stone PythonString Str() const; 2567841efbbSZachary Turner 257b9c1b51eSKate Stone static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 258b9c1b51eSKate Stone const PythonDictionary &dict); 2597841efbbSZachary Turner 260b58fb2f4SZachary Turner template <typename T> 261b9c1b51eSKate Stone static T ResolveNameWithDictionary(llvm::StringRef name, 262b9c1b51eSKate Stone const PythonDictionary &dict) { 263b58fb2f4SZachary Turner return ResolveNameWithDictionary(name, dict).AsType<T>(); 264b58fb2f4SZachary Turner } 265b58fb2f4SZachary Turner 266b9c1b51eSKate Stone PythonObject ResolveName(llvm::StringRef name) const; 2677841efbbSZachary Turner 268b9c1b51eSKate Stone template <typename T> T ResolveName(llvm::StringRef name) const { 269b58fb2f4SZachary Turner return ResolveName(name).AsType<T>(); 270b58fb2f4SZachary Turner } 271b58fb2f4SZachary Turner 272b9c1b51eSKate Stone bool HasAttribute(llvm::StringRef attribute) const; 2739c40264fSZachary Turner 274b9c1b51eSKate Stone PythonObject GetAttributeValue(llvm::StringRef attribute) const; 2757d6d218eSZachary Turner 276*085328eeSLawrence D'Anna bool IsNone() const { return m_py_obj == Py_None; } 277f8b22f8fSZachary Turner 278*085328eeSLawrence D'Anna bool IsValid() const { return m_py_obj != nullptr; } 279f8b22f8fSZachary Turner 280*085328eeSLawrence D'Anna bool IsAllocated() const { return IsValid() && !IsNone(); } 281*085328eeSLawrence D'Anna 282*085328eeSLawrence D'Anna explicit operator bool() const { return IsValid() && !IsNone(); } 2832c1f46dcSZachary Turner 284b9c1b51eSKate Stone template <typename T> T AsType() const { 2857d6d218eSZachary Turner if (!T::Check(m_py_obj)) 2867d6d218eSZachary Turner return T(); 2877d6d218eSZachary Turner return T(PyRefType::Borrowed, m_py_obj); 2887d6d218eSZachary Turner } 2897d6d218eSZachary Turner 290b9c1b51eSKate Stone StructuredData::ObjectSP CreateStructuredObject() const; 2912c1f46dcSZachary Turner 2922c1f46dcSZachary Turner protected: 293*085328eeSLawrence D'Anna static llvm::Error nullDeref() { 294*085328eeSLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(), 295*085328eeSLawrence D'Anna "A NULL PyObject* was dereferenced"); 296*085328eeSLawrence D'Anna } 297*085328eeSLawrence D'Anna static llvm::Error exception(const char *s = nullptr) { 298*085328eeSLawrence D'Anna return llvm::make_error<PythonException>(s); 299*085328eeSLawrence D'Anna } 300*085328eeSLawrence D'Anna 301*085328eeSLawrence D'Anna public: 302*085328eeSLawrence D'Anna template <typename... T> 303*085328eeSLawrence D'Anna llvm::Expected<PythonObject> CallMethod(const char *name, 304*085328eeSLawrence D'Anna const T &... t) const { 305*085328eeSLawrence D'Anna const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 306*085328eeSLawrence D'Anna #if PY_MAJOR_VERSION < 3 307*085328eeSLawrence D'Anna PyObject *obj = PyObject_CallMethod(m_py_obj, const_cast<char *>(name), 308*085328eeSLawrence D'Anna const_cast<char *>(format), 309*085328eeSLawrence D'Anna PythonFormat<T>::get(t)...); 310*085328eeSLawrence D'Anna #else 311*085328eeSLawrence D'Anna PyObject *obj = 312*085328eeSLawrence D'Anna PyObject_CallMethod(m_py_obj, name, format, PythonFormat<T>::get(t)...); 313*085328eeSLawrence D'Anna #endif 314*085328eeSLawrence D'Anna if (!obj) 315*085328eeSLawrence D'Anna return exception(); 316*085328eeSLawrence D'Anna return python::Take<PythonObject>(obj); 317*085328eeSLawrence D'Anna } 318*085328eeSLawrence D'Anna 319*085328eeSLawrence D'Anna llvm::Expected<PythonObject> GetAttribute(const char *name) const { 320*085328eeSLawrence D'Anna if (!m_py_obj) 321*085328eeSLawrence D'Anna return nullDeref(); 322*085328eeSLawrence D'Anna PyObject *obj = PyObject_GetAttrString(m_py_obj, name); 323*085328eeSLawrence D'Anna if (!obj) 324*085328eeSLawrence D'Anna return exception(); 325*085328eeSLawrence D'Anna return python::Take<PythonObject>(obj); 326*085328eeSLawrence D'Anna } 327*085328eeSLawrence D'Anna 328*085328eeSLawrence D'Anna llvm::Expected<bool> IsTrue() { 329*085328eeSLawrence D'Anna if (!m_py_obj) 330*085328eeSLawrence D'Anna return nullDeref(); 331*085328eeSLawrence D'Anna int r = PyObject_IsTrue(m_py_obj); 332*085328eeSLawrence D'Anna if (r < 0) 333*085328eeSLawrence D'Anna return exception(); 334*085328eeSLawrence D'Anna return !!r; 335*085328eeSLawrence D'Anna } 336*085328eeSLawrence D'Anna 337*085328eeSLawrence D'Anna llvm::Expected<long long> AsLongLong() { 338*085328eeSLawrence D'Anna if (!m_py_obj) 339*085328eeSLawrence D'Anna return nullDeref(); 340*085328eeSLawrence D'Anna assert(!PyErr_Occurred()); 341*085328eeSLawrence D'Anna long long r = PyLong_AsLongLong(m_py_obj); 342*085328eeSLawrence D'Anna if (PyErr_Occurred()) 343*085328eeSLawrence D'Anna return exception(); 344*085328eeSLawrence D'Anna return r; 345*085328eeSLawrence D'Anna } 346*085328eeSLawrence D'Anna 347*085328eeSLawrence D'Anna llvm::Expected<bool> IsInstance(const PythonObject &cls) { 348*085328eeSLawrence D'Anna if (!m_py_obj || !cls.IsValid()) 349*085328eeSLawrence D'Anna return nullDeref(); 350*085328eeSLawrence D'Anna int r = PyObject_IsInstance(m_py_obj, cls.get()); 351*085328eeSLawrence D'Anna if (r < 0) 352*085328eeSLawrence D'Anna return exception(); 353*085328eeSLawrence D'Anna return !!r; 354*085328eeSLawrence D'Anna } 355*085328eeSLawrence D'Anna 356*085328eeSLawrence D'Anna protected: 3572c1f46dcSZachary Turner PyObject *m_py_obj; 3582c1f46dcSZachary Turner }; 3592c1f46dcSZachary Turner 360*085328eeSLawrence D'Anna namespace python { 361*085328eeSLawrence D'Anna 362*085328eeSLawrence D'Anna // This is why C++ needs monads. 363*085328eeSLawrence D'Anna template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 364*085328eeSLawrence D'Anna if (!obj) 365*085328eeSLawrence D'Anna return obj.takeError(); 366*085328eeSLawrence D'Anna if (!T::Check(obj.get().get())) 367*085328eeSLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(), 368*085328eeSLawrence D'Anna "type error"); 369*085328eeSLawrence D'Anna return T(PyRefType::Borrowed, std::move(obj.get().get())); 370*085328eeSLawrence D'Anna } 371*085328eeSLawrence D'Anna 372*085328eeSLawrence D'Anna template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 373*085328eeSLawrence D'Anna 374*085328eeSLawrence D'Anna template <> 375*085328eeSLawrence D'Anna llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 376*085328eeSLawrence D'Anna 377*085328eeSLawrence D'Anna } // namespace python 378*085328eeSLawrence D'Anna 379b9c1b51eSKate Stone class PythonBytes : public PythonObject { 3805a72c02bSZachary Turner public: 3815a72c02bSZachary Turner PythonBytes(); 3825a72c02bSZachary Turner explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 3835a72c02bSZachary Turner PythonBytes(const uint8_t *bytes, size_t length); 3845a72c02bSZachary Turner PythonBytes(PyRefType type, PyObject *o); 3855a72c02bSZachary Turner 3865a72c02bSZachary Turner ~PythonBytes() override; 3875a72c02bSZachary Turner 388b9c1b51eSKate Stone static bool Check(PyObject *py_obj); 3895a72c02bSZachary Turner 3905a72c02bSZachary Turner // Bring in the no-argument base class version 3915a72c02bSZachary Turner using PythonObject::Reset; 3925a72c02bSZachary Turner 393b9c1b51eSKate Stone void Reset(PyRefType type, PyObject *py_obj) override; 3945a72c02bSZachary Turner 395b9c1b51eSKate Stone llvm::ArrayRef<uint8_t> GetBytes() const; 3965a72c02bSZachary Turner 397b9c1b51eSKate Stone size_t GetSize() const; 3985a72c02bSZachary Turner 399b9c1b51eSKate Stone void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 4005a72c02bSZachary Turner 401b9c1b51eSKate Stone StructuredData::StringSP CreateStructuredString() const; 4025a72c02bSZachary Turner }; 4035a72c02bSZachary Turner 404b9c1b51eSKate Stone class PythonByteArray : public PythonObject { 405f9d6d204SZachary Turner public: 406f9d6d204SZachary Turner PythonByteArray(); 407f9d6d204SZachary Turner explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 408f9d6d204SZachary Turner PythonByteArray(const uint8_t *bytes, size_t length); 409f9d6d204SZachary Turner PythonByteArray(PyRefType type, PyObject *o); 410f9d6d204SZachary Turner PythonByteArray(const PythonBytes &object); 411f9d6d204SZachary Turner 412f9d6d204SZachary Turner ~PythonByteArray() override; 413f9d6d204SZachary Turner 414b9c1b51eSKate Stone static bool Check(PyObject *py_obj); 415f9d6d204SZachary Turner 416f9d6d204SZachary Turner // Bring in the no-argument base class version 417f9d6d204SZachary Turner using PythonObject::Reset; 418f9d6d204SZachary Turner 419b9c1b51eSKate Stone void Reset(PyRefType type, PyObject *py_obj) override; 420f9d6d204SZachary Turner 421b9c1b51eSKate Stone llvm::ArrayRef<uint8_t> GetBytes() const; 422f9d6d204SZachary Turner 423b9c1b51eSKate Stone size_t GetSize() const; 424f9d6d204SZachary Turner 425b9c1b51eSKate Stone void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 426f9d6d204SZachary Turner 427b9c1b51eSKate Stone StructuredData::StringSP CreateStructuredString() const; 428f9d6d204SZachary Turner }; 429f9d6d204SZachary Turner 430b9c1b51eSKate Stone class PythonString : public PythonObject { 4312c1f46dcSZachary Turner public: 432*085328eeSLawrence D'Anna static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 433*085328eeSLawrence D'Anna 4342c1f46dcSZachary Turner PythonString(); 435*085328eeSLawrence D'Anna explicit PythonString(llvm::StringRef string); // safe, null on error 43687f47729SZachary Turner PythonString(PyRefType type, PyObject *o); 437edb35d95SEugene Zelenko 438f8b22f8fSZachary Turner ~PythonString() override; 4392c1f46dcSZachary Turner 44022c8efcdSZachary Turner static bool Check(PyObject *py_obj); 44122c8efcdSZachary Turner 442f8b22f8fSZachary Turner // Bring in the no-argument base class version 443f8b22f8fSZachary Turner using PythonObject::Reset; 444f8b22f8fSZachary Turner 445f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 4462c1f46dcSZachary Turner 447*085328eeSLawrence D'Anna llvm::StringRef GetString() const; // safe, empty string on error 448*085328eeSLawrence D'Anna 449*085328eeSLawrence D'Anna llvm::Expected<llvm::StringRef> AsUTF8() const; 4502c1f46dcSZachary Turner 451b9c1b51eSKate Stone size_t GetSize() const; 4522c1f46dcSZachary Turner 453*085328eeSLawrence D'Anna void SetString(llvm::StringRef string); // safe, null on error 4542c1f46dcSZachary Turner 4552c1f46dcSZachary Turner StructuredData::StringSP CreateStructuredString() const; 4562c1f46dcSZachary Turner }; 4572c1f46dcSZachary Turner 458b9c1b51eSKate Stone class PythonInteger : public PythonObject { 4592c1f46dcSZachary Turner public: 4602c1f46dcSZachary Turner PythonInteger(); 46187f47729SZachary Turner explicit PythonInteger(int64_t value); 462f8b22f8fSZachary Turner PythonInteger(PyRefType type, PyObject *o); 463edb35d95SEugene Zelenko 464f8b22f8fSZachary Turner ~PythonInteger() override; 4652c1f46dcSZachary Turner 46622c8efcdSZachary Turner static bool Check(PyObject *py_obj); 46722c8efcdSZachary Turner 468f8b22f8fSZachary Turner // Bring in the no-argument base class version 469f8b22f8fSZachary Turner using PythonObject::Reset; 470f8b22f8fSZachary Turner 471f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 4722c1f46dcSZachary Turner 4732c1f46dcSZachary Turner int64_t GetInteger() const; 4742c1f46dcSZachary Turner 475b9c1b51eSKate Stone void SetInteger(int64_t value); 4762c1f46dcSZachary Turner 4772c1f46dcSZachary Turner StructuredData::IntegerSP CreateStructuredInteger() const; 4782c1f46dcSZachary Turner }; 4792c1f46dcSZachary Turner 480b81d715cSTatyana Krasnukha class PythonBoolean : public PythonObject { 481b81d715cSTatyana Krasnukha public: 482b81d715cSTatyana Krasnukha PythonBoolean() = default; 483b81d715cSTatyana Krasnukha explicit PythonBoolean(bool value); 484b81d715cSTatyana Krasnukha PythonBoolean(PyRefType type, PyObject *o); 485b81d715cSTatyana Krasnukha 486b81d715cSTatyana Krasnukha ~PythonBoolean() override = default; 487b81d715cSTatyana Krasnukha 488b81d715cSTatyana Krasnukha static bool Check(PyObject *py_obj); 489b81d715cSTatyana Krasnukha 490b81d715cSTatyana Krasnukha // Bring in the no-argument base class version 491b81d715cSTatyana Krasnukha using PythonObject::Reset; 492b81d715cSTatyana Krasnukha 493b81d715cSTatyana Krasnukha void Reset(PyRefType type, PyObject *py_obj) override; 494b81d715cSTatyana Krasnukha 495b81d715cSTatyana Krasnukha bool GetValue() const; 496b81d715cSTatyana Krasnukha 497b81d715cSTatyana Krasnukha void SetValue(bool value); 498b81d715cSTatyana Krasnukha 499b81d715cSTatyana Krasnukha StructuredData::BooleanSP CreateStructuredBoolean() const; 500b81d715cSTatyana Krasnukha }; 501b81d715cSTatyana Krasnukha 502b9c1b51eSKate Stone class PythonList : public PythonObject { 5032c1f46dcSZachary Turner public: 504a1405147SZachary Turner PythonList() {} 50587f47729SZachary Turner explicit PythonList(PyInitialValue value); 50687f47729SZachary Turner explicit PythonList(int list_size); 507f8b22f8fSZachary Turner PythonList(PyRefType type, PyObject *o); 508edb35d95SEugene Zelenko 509f8b22f8fSZachary Turner ~PythonList() override; 5102c1f46dcSZachary Turner 51122c8efcdSZachary Turner static bool Check(PyObject *py_obj); 51222c8efcdSZachary Turner 513f8b22f8fSZachary Turner // Bring in the no-argument base class version 514f8b22f8fSZachary Turner using PythonObject::Reset; 515f8b22f8fSZachary Turner 516f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 5172c1f46dcSZachary Turner 5182c1f46dcSZachary Turner uint32_t GetSize() const; 5192c1f46dcSZachary Turner 5202c1f46dcSZachary Turner PythonObject GetItemAtIndex(uint32_t index) const; 5212c1f46dcSZachary Turner 522f8b22f8fSZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object); 5232c1f46dcSZachary Turner 524f8b22f8fSZachary Turner void AppendItem(const PythonObject &object); 5252c1f46dcSZachary Turner 5262c1f46dcSZachary Turner StructuredData::ArraySP CreateStructuredArray() const; 5272c1f46dcSZachary Turner }; 5282c1f46dcSZachary Turner 529b9c1b51eSKate Stone class PythonTuple : public PythonObject { 530a1405147SZachary Turner public: 531a1405147SZachary Turner PythonTuple() {} 532a1405147SZachary Turner explicit PythonTuple(PyInitialValue value); 533a1405147SZachary Turner explicit PythonTuple(int tuple_size); 534a1405147SZachary Turner PythonTuple(PyRefType type, PyObject *o); 535a1405147SZachary Turner PythonTuple(std::initializer_list<PythonObject> objects); 536a1405147SZachary Turner PythonTuple(std::initializer_list<PyObject *> objects); 537a1405147SZachary Turner 538a1405147SZachary Turner ~PythonTuple() override; 539a1405147SZachary Turner 540a1405147SZachary Turner static bool Check(PyObject *py_obj); 541a1405147SZachary Turner 542a1405147SZachary Turner // Bring in the no-argument base class version 543a1405147SZachary Turner using PythonObject::Reset; 544a1405147SZachary Turner 545a1405147SZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 546a1405147SZachary Turner 547a1405147SZachary Turner uint32_t GetSize() const; 548a1405147SZachary Turner 549a1405147SZachary Turner PythonObject GetItemAtIndex(uint32_t index) const; 550a1405147SZachary Turner 551a1405147SZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object); 552a1405147SZachary Turner 553a1405147SZachary Turner StructuredData::ArraySP CreateStructuredArray() const; 554a1405147SZachary Turner }; 555a1405147SZachary Turner 556b9c1b51eSKate Stone class PythonDictionary : public PythonObject { 5572c1f46dcSZachary Turner public: 558a1405147SZachary Turner PythonDictionary() {} 55987f47729SZachary Turner explicit PythonDictionary(PyInitialValue value); 560f8b22f8fSZachary Turner PythonDictionary(PyRefType type, PyObject *o); 561edb35d95SEugene Zelenko 562f8b22f8fSZachary Turner ~PythonDictionary() override; 5632c1f46dcSZachary Turner 56422c8efcdSZachary Turner static bool Check(PyObject *py_obj); 56522c8efcdSZachary Turner 566f8b22f8fSZachary Turner // Bring in the no-argument base class version 567f8b22f8fSZachary Turner using PythonObject::Reset; 568f8b22f8fSZachary Turner 569f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 5702c1f46dcSZachary Turner 5712c1f46dcSZachary Turner uint32_t GetSize() const; 5722c1f46dcSZachary Turner 573f8b22f8fSZachary Turner PythonList GetKeys() const; 5742c1f46dcSZachary Turner 575f8b22f8fSZachary Turner PythonObject GetItemForKey(const PythonObject &key) const; 576f8b22f8fSZachary Turner void SetItemForKey(const PythonObject &key, const PythonObject &value); 5772c1f46dcSZachary Turner 5782c1f46dcSZachary Turner StructuredData::DictionarySP CreateStructuredDictionary() const; 5792c1f46dcSZachary Turner }; 58087f47729SZachary Turner 581b9c1b51eSKate Stone class PythonModule : public PythonObject { 5827841efbbSZachary Turner public: 5837841efbbSZachary Turner PythonModule(); 5847841efbbSZachary Turner PythonModule(PyRefType type, PyObject *o); 5857841efbbSZachary Turner 5867841efbbSZachary Turner ~PythonModule() override; 5877841efbbSZachary Turner 5887841efbbSZachary Turner static bool Check(PyObject *py_obj); 5897841efbbSZachary Turner 590b9c1b51eSKate Stone static PythonModule BuiltinsModule(); 591a1405147SZachary Turner 592b9c1b51eSKate Stone static PythonModule MainModule(); 593a1405147SZachary Turner 594b9c1b51eSKate Stone static PythonModule AddModule(llvm::StringRef module); 5957841efbbSZachary Turner 596*085328eeSLawrence D'Anna // safe, returns invalid on error; 597*085328eeSLawrence D'Anna static PythonModule ImportModule(llvm::StringRef name) { 598*085328eeSLawrence D'Anna std::string s = name; 599*085328eeSLawrence D'Anna auto mod = Import(s.c_str()); 600*085328eeSLawrence D'Anna if (!mod) { 601*085328eeSLawrence D'Anna llvm::consumeError(mod.takeError()); 602*085328eeSLawrence D'Anna return PythonModule(); 603*085328eeSLawrence D'Anna } 604*085328eeSLawrence D'Anna return std::move(mod.get()); 605*085328eeSLawrence D'Anna } 606*085328eeSLawrence D'Anna 607*085328eeSLawrence D'Anna static llvm::Expected<PythonModule> Import(const char *name); 608*085328eeSLawrence D'Anna 609*085328eeSLawrence D'Anna llvm::Expected<PythonObject> Get(const char *name); 6102419f1d5SZachary Turner 6117841efbbSZachary Turner // Bring in the no-argument base class version 6127841efbbSZachary Turner using PythonObject::Reset; 6137841efbbSZachary Turner 6147841efbbSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 6157841efbbSZachary Turner 6167841efbbSZachary Turner PythonDictionary GetDictionary() const; 6177841efbbSZachary Turner }; 6187841efbbSZachary Turner 619b9c1b51eSKate Stone class PythonCallable : public PythonObject { 620a1405147SZachary Turner public: 621b58fb2f4SZachary Turner struct ArgInfo { 622b58fb2f4SZachary Turner size_t count; 623a5d6765cSEnrico Granata bool is_bound_method : 1; 624b58fb2f4SZachary Turner bool has_varargs : 1; 625b58fb2f4SZachary Turner bool has_kwargs : 1; 626b58fb2f4SZachary Turner }; 627b58fb2f4SZachary Turner 628a1405147SZachary Turner PythonCallable(); 629a1405147SZachary Turner PythonCallable(PyRefType type, PyObject *o); 630a1405147SZachary Turner 631a1405147SZachary Turner ~PythonCallable() override; 632a1405147SZachary Turner 633b9c1b51eSKate Stone static bool Check(PyObject *py_obj); 634a1405147SZachary Turner 635a1405147SZachary Turner // Bring in the no-argument base class version 636a1405147SZachary Turner using PythonObject::Reset; 637a1405147SZachary Turner 638b9c1b51eSKate Stone void Reset(PyRefType type, PyObject *py_obj) override; 639a1405147SZachary Turner 640b9c1b51eSKate Stone ArgInfo GetNumArguments() const; 64127a14f19SJim Ingham 64227a14f19SJim Ingham // If the callable is a Py_Class, then find the number of arguments 64327a14f19SJim Ingham // of the __init__ method. 64427a14f19SJim Ingham ArgInfo GetNumInitArguments() const; 645b58fb2f4SZachary Turner 646b9c1b51eSKate Stone PythonObject operator()(); 647a1405147SZachary Turner 648b9c1b51eSKate Stone PythonObject operator()(std::initializer_list<PyObject *> args); 649a1405147SZachary Turner 650b9c1b51eSKate Stone PythonObject operator()(std::initializer_list<PythonObject> args); 651b58fb2f4SZachary Turner 652b58fb2f4SZachary Turner template <typename Arg, typename... Args> 653b9c1b51eSKate Stone PythonObject operator()(const Arg &arg, Args... args) { 654b58fb2f4SZachary Turner return operator()({arg, args...}); 655b58fb2f4SZachary Turner } 656a1405147SZachary Turner }; 657a1405147SZachary Turner 658b9c1b51eSKate Stone class PythonFile : public PythonObject { 6599c40264fSZachary Turner public: 66032064024SZachary Turner PythonFile(); 661eda01c31SZachary Turner PythonFile(File &file, const char *mode); 6629c40264fSZachary Turner PythonFile(PyRefType type, PyObject *o); 663edb35d95SEugene Zelenko 6649c40264fSZachary Turner ~PythonFile() override; 6659c40264fSZachary Turner 6669c40264fSZachary Turner static bool Check(PyObject *py_obj); 6679c40264fSZachary Turner 6689c40264fSZachary Turner using PythonObject::Reset; 6699c40264fSZachary Turner 6709c40264fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 6719c40264fSZachary Turner void Reset(File &file, const char *mode); 672eda01c31SZachary Turner 6732fce1137SLawrence D'Anna lldb::FileUP GetUnderlyingFile() const; 674*085328eeSLawrence D'Anna 675*085328eeSLawrence D'Anna llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 676*085328eeSLawrence D'Anna llvm::Expected<lldb::FileSP> 677*085328eeSLawrence D'Anna ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 6789c40264fSZachary Turner }; 6799c40264fSZachary Turner 680*085328eeSLawrence D'Anna class PythonException : public llvm::ErrorInfo<PythonException> { 681*085328eeSLawrence D'Anna private: 682*085328eeSLawrence D'Anna PyObject *m_exception_type, *m_exception, *m_traceback; 683*085328eeSLawrence D'Anna PyObject *m_repr_bytes; 684*085328eeSLawrence D'Anna 685*085328eeSLawrence D'Anna public: 686*085328eeSLawrence D'Anna static char ID; 687*085328eeSLawrence D'Anna const char *toCString() const; 688*085328eeSLawrence D'Anna PythonException(const char *caller = nullptr); 689*085328eeSLawrence D'Anna void Restore(); 690*085328eeSLawrence D'Anna ~PythonException(); 691*085328eeSLawrence D'Anna void log(llvm::raw_ostream &OS) const override; 692*085328eeSLawrence D'Anna std::error_code convertToErrorCode() const override; 693*085328eeSLawrence D'Anna }; 694*085328eeSLawrence D'Anna 695*085328eeSLawrence D'Anna // This extracts the underlying T out of an Expected<T> and returns it. 696*085328eeSLawrence D'Anna // If the Expected is an Error instead of a T, that error will be converted 697*085328eeSLawrence D'Anna // into a python exception, and this will return a default-constructed T. 698*085328eeSLawrence D'Anna // 699*085328eeSLawrence D'Anna // This is appropriate for use right at the boundary of python calling into 700*085328eeSLawrence D'Anna // C++, such as in a SWIG typemap. In such a context you should simply 701*085328eeSLawrence D'Anna // check if the returned T is valid, and if it is, return a NULL back 702*085328eeSLawrence D'Anna // to python. This will result in the Error being raised as an exception 703*085328eeSLawrence D'Anna // from python code's point of view. 704*085328eeSLawrence D'Anna // 705*085328eeSLawrence D'Anna // For example: 706*085328eeSLawrence D'Anna // ``` 707*085328eeSLawrence D'Anna // Expected<Foo *> efoop = some_cpp_function(); 708*085328eeSLawrence D'Anna // Foo *foop = unwrapOrSetPythonException(efoop); 709*085328eeSLawrence D'Anna // if (!foop) 710*085328eeSLawrence D'Anna // return NULL; 711*085328eeSLawrence D'Anna // do_something(*foop); 712*085328eeSLawrence D'Anna // 713*085328eeSLawrence D'Anna // If the Error returned was itself created because a python exception was 714*085328eeSLawrence D'Anna // raised when C++ code called into python, then the original exception 715*085328eeSLawrence D'Anna // will be restored. Otherwise a simple string exception will be raised. 716*085328eeSLawrence D'Anna template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 717*085328eeSLawrence D'Anna if (expected) 718*085328eeSLawrence D'Anna return expected.get(); 719*085328eeSLawrence D'Anna llvm::handleAllErrors( 720*085328eeSLawrence D'Anna expected.takeError(), [](PythonException &E) { E.Restore(); }, 721*085328eeSLawrence D'Anna [](const llvm::ErrorInfoBase &E) { 722*085328eeSLawrence D'Anna PyErr_SetString(PyExc_Exception, E.message().c_str()); 723*085328eeSLawrence D'Anna }); 724*085328eeSLawrence D'Anna return T(); 725*085328eeSLawrence D'Anna } 726*085328eeSLawrence D'Anna 7272c1f46dcSZachary Turner } // namespace lldb_private 7282c1f46dcSZachary Turner 729a281b42bSZachary Turner #endif 730d68983e3SPavel Labath 731d68983e3SPavel Labath #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 732