1edb35d95SEugene Zelenko //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// 22c1f46dcSZachary Turner // 32c1f46dcSZachary Turner // The LLVM Compiler Infrastructure 42c1f46dcSZachary Turner // 52c1f46dcSZachary Turner // This file is distributed under the University of Illinois Open Source 62c1f46dcSZachary Turner // License. See LICENSE.TXT for details. 72c1f46dcSZachary Turner // 82c1f46dcSZachary Turner //===----------------------------------------------------------------------===// 92c1f46dcSZachary Turner 102c1f46dcSZachary Turner #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 112c1f46dcSZachary Turner #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 122c1f46dcSZachary Turner 132c1f46dcSZachary Turner // C Includes 142c1f46dcSZachary Turner // C++ Includes 152c1f46dcSZachary Turner // Other libraries and framework includes 162c1f46dcSZachary Turner // Project includes 172c1f46dcSZachary Turner #include "lldb/lldb-defines.h" 182c1f46dcSZachary Turner #include "lldb/Core/ConstString.h" 192c1f46dcSZachary Turner #include "lldb/Core/StructuredData.h" 202c1f46dcSZachary Turner #include "lldb/Core/Flags.h" 219c40264fSZachary Turner #include "lldb/Host/File.h" 222c1f46dcSZachary Turner #include "lldb/Interpreter/OptionValue.h" 232c1f46dcSZachary Turner 242c1f46dcSZachary Turner namespace lldb_private { 25edb35d95SEugene Zelenko 262c1f46dcSZachary Turner class PythonString; 272c1f46dcSZachary Turner class PythonList; 282c1f46dcSZachary Turner class PythonDictionary; 292c1f46dcSZachary Turner class PythonInteger; 302c1f46dcSZachary Turner 312c1f46dcSZachary Turner class StructuredPythonObject : public StructuredData::Generic 322c1f46dcSZachary Turner { 332c1f46dcSZachary Turner public: 342c1f46dcSZachary Turner StructuredPythonObject() 352c1f46dcSZachary Turner : StructuredData::Generic() 362c1f46dcSZachary Turner { 372c1f46dcSZachary Turner } 382c1f46dcSZachary Turner 392c1f46dcSZachary Turner StructuredPythonObject(void *obj) 402c1f46dcSZachary Turner : StructuredData::Generic(obj) 412c1f46dcSZachary Turner { 422c1f46dcSZachary Turner Py_XINCREF(GetValue()); 432c1f46dcSZachary Turner } 442c1f46dcSZachary Turner 45edb35d95SEugene Zelenko ~StructuredPythonObject() override 462c1f46dcSZachary Turner { 472c1f46dcSZachary Turner if (Py_IsInitialized()) 482c1f46dcSZachary Turner Py_XDECREF(GetValue()); 492c1f46dcSZachary Turner SetValue(nullptr); 502c1f46dcSZachary Turner } 512c1f46dcSZachary Turner 522c1f46dcSZachary Turner bool 532c1f46dcSZachary Turner IsValid() const override 542c1f46dcSZachary Turner { 552c1f46dcSZachary Turner return GetValue() && GetValue() != Py_None; 562c1f46dcSZachary Turner } 572c1f46dcSZachary Turner 582c1f46dcSZachary Turner void Dump(Stream &s) const override; 592c1f46dcSZachary Turner 602c1f46dcSZachary Turner private: 612c1f46dcSZachary Turner DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 622c1f46dcSZachary Turner }; 632c1f46dcSZachary Turner 642c1f46dcSZachary Turner enum class PyObjectType 652c1f46dcSZachary Turner { 662c1f46dcSZachary Turner Unknown, 672c1f46dcSZachary Turner None, 682c1f46dcSZachary Turner Integer, 692c1f46dcSZachary Turner Dictionary, 702c1f46dcSZachary Turner List, 719c40264fSZachary Turner String, 72*7841efbbSZachary Turner Module, 739c40264fSZachary Turner File 742c1f46dcSZachary Turner }; 752c1f46dcSZachary Turner 76f8b22f8fSZachary Turner enum class PyRefType 77f8b22f8fSZachary Turner { 78f8b22f8fSZachary Turner Borrowed, // We are not given ownership of the incoming PyObject. 79f8b22f8fSZachary Turner // We cannot safely hold it without calling Py_INCREF. 80f8b22f8fSZachary Turner Owned // We have ownership of the incoming PyObject. We should 81f8b22f8fSZachary Turner // not call Py_INCREF. 82f8b22f8fSZachary Turner }; 83f8b22f8fSZachary Turner 84f8b22f8fSZachary Turner enum class PyInitialValue 85f8b22f8fSZachary Turner { 86f8b22f8fSZachary Turner Invalid, 87f8b22f8fSZachary Turner Empty 88f8b22f8fSZachary Turner }; 89f8b22f8fSZachary Turner 902c1f46dcSZachary Turner class PythonObject 912c1f46dcSZachary Turner { 922c1f46dcSZachary Turner public: 93f8b22f8fSZachary Turner PythonObject() 94f8b22f8fSZachary Turner : m_py_obj(nullptr) 952c1f46dcSZachary Turner { 962c1f46dcSZachary Turner } 972c1f46dcSZachary Turner 98f8b22f8fSZachary Turner PythonObject(PyRefType type, PyObject *py_obj) 99f8b22f8fSZachary Turner : m_py_obj(nullptr) 1002c1f46dcSZachary Turner { 101f8b22f8fSZachary Turner Reset(type, py_obj); 1022c1f46dcSZachary Turner } 1032c1f46dcSZachary Turner 104f8b22f8fSZachary Turner PythonObject(const PythonObject &rhs) 105f8b22f8fSZachary Turner : m_py_obj(nullptr) 1062c1f46dcSZachary Turner { 107f8b22f8fSZachary Turner Reset(rhs); 1082c1f46dcSZachary Turner } 1092c1f46dcSZachary Turner 110edb35d95SEugene Zelenko virtual ~PythonObject() 111edb35d95SEugene Zelenko { 112edb35d95SEugene Zelenko Reset(); 113edb35d95SEugene Zelenko } 1142c1f46dcSZachary Turner 115f8b22f8fSZachary Turner void 116f8b22f8fSZachary Turner Reset() 1172c1f46dcSZachary Turner { 118f8b22f8fSZachary Turner // Avoid calling the virtual method since it's not necessary 119f8b22f8fSZachary Turner // to actually validate the type of the PyObject if we're 120f8b22f8fSZachary Turner // just setting to null. 1212c1f46dcSZachary Turner if (Py_IsInitialized()) 1222c1f46dcSZachary Turner Py_XDECREF(m_py_obj); 123f8b22f8fSZachary Turner m_py_obj = nullptr; 1242c1f46dcSZachary Turner } 125f8b22f8fSZachary Turner 126f8b22f8fSZachary Turner void 127f8b22f8fSZachary Turner Reset(const PythonObject &rhs) 128f8b22f8fSZachary Turner { 129f8b22f8fSZachary Turner // Avoid calling the virtual method if it's not necessary 130f8b22f8fSZachary Turner // to actually validate the type of the PyObject. 13160c24f70SZachary Turner if (!rhs.IsValid()) 132f8b22f8fSZachary Turner Reset(); 133f8b22f8fSZachary Turner else 134f8b22f8fSZachary Turner Reset(PyRefType::Borrowed, rhs.m_py_obj); 135f8b22f8fSZachary Turner } 136f8b22f8fSZachary Turner 137f8b22f8fSZachary Turner // PythonObject is implicitly convertible to PyObject *, which will call the 138f8b22f8fSZachary Turner // wrong overload. We want to explicitly disallow this, since a PyObject 139f8b22f8fSZachary Turner // *always* owns its reference. Therefore the overload which takes a 140f8b22f8fSZachary Turner // PyRefType doesn't make sense, and the copy constructor should be used. 141f8b22f8fSZachary Turner void 142f8b22f8fSZachary Turner Reset(PyRefType type, const PythonObject &ref) = delete; 143f8b22f8fSZachary Turner 144f8b22f8fSZachary Turner virtual void 145f8b22f8fSZachary Turner Reset(PyRefType type, PyObject *py_obj) 146f8b22f8fSZachary Turner { 147f8b22f8fSZachary Turner if (py_obj == m_py_obj) 148f8b22f8fSZachary Turner return; 149f8b22f8fSZachary Turner 150f8b22f8fSZachary Turner if (Py_IsInitialized()) 151f8b22f8fSZachary Turner Py_XDECREF(m_py_obj); 152f8b22f8fSZachary Turner 153f8b22f8fSZachary Turner m_py_obj = py_obj; 154f8b22f8fSZachary Turner 155f8b22f8fSZachary Turner // If this is a borrowed reference, we need to convert it to 156f8b22f8fSZachary Turner // an owned reference by incrementing it. If it is an owned 157f8b22f8fSZachary Turner // reference (for example the caller allocated it with PyDict_New() 158f8b22f8fSZachary Turner // then we must *not* increment it. 159f8b22f8fSZachary Turner if (Py_IsInitialized() && type == PyRefType::Borrowed) 160f8b22f8fSZachary Turner Py_XINCREF(m_py_obj); 1612c1f46dcSZachary Turner } 1622c1f46dcSZachary Turner 1632c1f46dcSZachary Turner void 1642c1f46dcSZachary Turner Dump () const 1652c1f46dcSZachary Turner { 1662c1f46dcSZachary Turner if (m_py_obj) 1672c1f46dcSZachary Turner _PyObject_Dump (m_py_obj); 1682c1f46dcSZachary Turner else 1692c1f46dcSZachary Turner puts ("NULL"); 1702c1f46dcSZachary Turner } 1712c1f46dcSZachary Turner 1722c1f46dcSZachary Turner void 1732c1f46dcSZachary Turner Dump (Stream &strm) const; 1742c1f46dcSZachary Turner 1752c1f46dcSZachary Turner PyObject* 1762c1f46dcSZachary Turner get() const 1772c1f46dcSZachary Turner { 1782c1f46dcSZachary Turner return m_py_obj; 1792c1f46dcSZachary Turner } 1802c1f46dcSZachary Turner 18160c24f70SZachary Turner PyObject* 18260c24f70SZachary Turner release() 18360c24f70SZachary Turner { 18460c24f70SZachary Turner PyObject *result = m_py_obj; 18560c24f70SZachary Turner m_py_obj = nullptr; 18660c24f70SZachary Turner return result; 18760c24f70SZachary Turner } 18860c24f70SZachary Turner 189f8b22f8fSZachary Turner PythonObject & 190f8b22f8fSZachary Turner operator=(const PythonObject &other) 1912c1f46dcSZachary Turner { 192f8b22f8fSZachary Turner Reset(PyRefType::Borrowed, other.get()); 193f8b22f8fSZachary Turner return *this; 1942c1f46dcSZachary Turner } 1952c1f46dcSZachary Turner 196*7841efbbSZachary Turner PyObjectType 197*7841efbbSZachary Turner GetObjectType() const; 198*7841efbbSZachary Turner 199*7841efbbSZachary Turner PythonString 200*7841efbbSZachary Turner Repr() const; 201*7841efbbSZachary Turner 202*7841efbbSZachary Turner PythonString 203*7841efbbSZachary Turner Str() const; 204*7841efbbSZachary Turner 205*7841efbbSZachary Turner static PythonObject 206*7841efbbSZachary Turner ResolveNameGlobal(llvm::StringRef name); 207*7841efbbSZachary Turner 208*7841efbbSZachary Turner PythonObject 209*7841efbbSZachary Turner ResolveName(llvm::StringRef name) const; 210*7841efbbSZachary Turner 2112c1f46dcSZachary Turner bool 2129c40264fSZachary Turner HasAttribute(llvm::StringRef attribute) const; 2139c40264fSZachary Turner 2147d6d218eSZachary Turner PythonObject 2157d6d218eSZachary Turner GetAttributeValue(llvm::StringRef attribute) const; 2167d6d218eSZachary Turner 2179c40264fSZachary Turner bool 218f8b22f8fSZachary Turner IsValid() const; 219f8b22f8fSZachary Turner 220f8b22f8fSZachary Turner bool 221f8b22f8fSZachary Turner IsAllocated() const; 222f8b22f8fSZachary Turner 223f8b22f8fSZachary Turner bool 224f8b22f8fSZachary Turner IsNone() const; 2252c1f46dcSZachary Turner 2267d6d218eSZachary Turner template<typename T> 2277d6d218eSZachary Turner T AsType() const 2287d6d218eSZachary Turner { 2297d6d218eSZachary Turner if (!T::Check(m_py_obj)) 2307d6d218eSZachary Turner return T(); 2317d6d218eSZachary Turner return T(PyRefType::Borrowed, m_py_obj); 2327d6d218eSZachary Turner } 2337d6d218eSZachary Turner 234*7841efbbSZachary Turner StructuredData::ObjectSP 235*7841efbbSZachary Turner CreateStructuredObject() const; 2362c1f46dcSZachary Turner 2372c1f46dcSZachary Turner protected: 2382c1f46dcSZachary Turner PyObject* m_py_obj; 2392c1f46dcSZachary Turner }; 2402c1f46dcSZachary Turner 2412c1f46dcSZachary Turner class PythonString : public PythonObject 2422c1f46dcSZachary Turner { 2432c1f46dcSZachary Turner public: 2442c1f46dcSZachary Turner PythonString(); 245f8b22f8fSZachary Turner explicit PythonString(llvm::StringRef string); 246f8b22f8fSZachary Turner explicit PythonString(const char *string); 24787f47729SZachary Turner PythonString(PyRefType type, PyObject *o); 24887f47729SZachary Turner PythonString(const PythonString &object); 249edb35d95SEugene Zelenko 250f8b22f8fSZachary Turner ~PythonString() override; 2512c1f46dcSZachary Turner 25222c8efcdSZachary Turner static bool Check(PyObject *py_obj); 25322c8efcdSZachary Turner 254f8b22f8fSZachary Turner // Bring in the no-argument base class version 255f8b22f8fSZachary Turner using PythonObject::Reset; 256f8b22f8fSZachary Turner 257f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 2582c1f46dcSZachary Turner 2592c1f46dcSZachary Turner llvm::StringRef 2602c1f46dcSZachary Turner GetString() const; 2612c1f46dcSZachary Turner 2622c1f46dcSZachary Turner size_t 2632c1f46dcSZachary Turner GetSize() const; 2642c1f46dcSZachary Turner 2652c1f46dcSZachary Turner void SetString(llvm::StringRef string); 2662c1f46dcSZachary Turner 2672c1f46dcSZachary Turner StructuredData::StringSP CreateStructuredString() const; 2682c1f46dcSZachary Turner }; 2692c1f46dcSZachary Turner 2702c1f46dcSZachary Turner class PythonInteger : public PythonObject 2712c1f46dcSZachary Turner { 2722c1f46dcSZachary Turner public: 2732c1f46dcSZachary Turner PythonInteger(); 27487f47729SZachary Turner explicit PythonInteger(int64_t value); 275f8b22f8fSZachary Turner PythonInteger(PyRefType type, PyObject *o); 276f8b22f8fSZachary Turner PythonInteger(const PythonInteger &object); 277edb35d95SEugene Zelenko 278f8b22f8fSZachary Turner ~PythonInteger() override; 2792c1f46dcSZachary Turner 28022c8efcdSZachary Turner static bool Check(PyObject *py_obj); 28122c8efcdSZachary Turner 282f8b22f8fSZachary Turner // Bring in the no-argument base class version 283f8b22f8fSZachary Turner using PythonObject::Reset; 284f8b22f8fSZachary Turner 285f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 2862c1f46dcSZachary Turner 2872c1f46dcSZachary Turner int64_t GetInteger() const; 2882c1f46dcSZachary Turner 2892c1f46dcSZachary Turner void 2902c1f46dcSZachary Turner SetInteger (int64_t value); 2912c1f46dcSZachary Turner 2922c1f46dcSZachary Turner StructuredData::IntegerSP CreateStructuredInteger() const; 2932c1f46dcSZachary Turner }; 2942c1f46dcSZachary Turner 2952c1f46dcSZachary Turner class PythonList : public PythonObject 2962c1f46dcSZachary Turner { 2972c1f46dcSZachary Turner public: 29887f47729SZachary Turner explicit PythonList(PyInitialValue value); 29987f47729SZachary Turner explicit PythonList(int list_size); 300f8b22f8fSZachary Turner PythonList(PyRefType type, PyObject *o); 301f8b22f8fSZachary Turner PythonList(const PythonList &list); 302edb35d95SEugene Zelenko 303f8b22f8fSZachary Turner ~PythonList() override; 3042c1f46dcSZachary Turner 30522c8efcdSZachary Turner static bool Check(PyObject *py_obj); 30622c8efcdSZachary Turner 307f8b22f8fSZachary Turner // Bring in the no-argument base class version 308f8b22f8fSZachary Turner using PythonObject::Reset; 309f8b22f8fSZachary Turner 310f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 3112c1f46dcSZachary Turner 3122c1f46dcSZachary Turner uint32_t GetSize() const; 3132c1f46dcSZachary Turner 3142c1f46dcSZachary Turner PythonObject GetItemAtIndex(uint32_t index) const; 3152c1f46dcSZachary Turner 316f8b22f8fSZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object); 3172c1f46dcSZachary Turner 318f8b22f8fSZachary Turner void AppendItem(const PythonObject &object); 3192c1f46dcSZachary Turner 3202c1f46dcSZachary Turner StructuredData::ArraySP CreateStructuredArray() const; 3212c1f46dcSZachary Turner }; 3222c1f46dcSZachary Turner 3232c1f46dcSZachary Turner class PythonDictionary : public PythonObject 3242c1f46dcSZachary Turner { 3252c1f46dcSZachary Turner public: 32687f47729SZachary Turner explicit PythonDictionary(PyInitialValue value); 327f8b22f8fSZachary Turner PythonDictionary(PyRefType type, PyObject *o); 328f8b22f8fSZachary Turner PythonDictionary(const PythonDictionary &dict); 329edb35d95SEugene Zelenko 330f8b22f8fSZachary Turner ~PythonDictionary() override; 3312c1f46dcSZachary Turner 33222c8efcdSZachary Turner static bool Check(PyObject *py_obj); 33322c8efcdSZachary Turner 334f8b22f8fSZachary Turner // Bring in the no-argument base class version 335f8b22f8fSZachary Turner using PythonObject::Reset; 336f8b22f8fSZachary Turner 337f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 3382c1f46dcSZachary Turner 3392c1f46dcSZachary Turner uint32_t GetSize() const; 3402c1f46dcSZachary Turner 341f8b22f8fSZachary Turner PythonList GetKeys() const; 3422c1f46dcSZachary Turner 343f8b22f8fSZachary Turner PythonObject GetItemForKey(const PythonObject &key) const; 344f8b22f8fSZachary Turner void SetItemForKey(const PythonObject &key, const PythonObject &value); 3452c1f46dcSZachary Turner 3462c1f46dcSZachary Turner StructuredData::DictionarySP CreateStructuredDictionary() const; 3472c1f46dcSZachary Turner }; 34887f47729SZachary Turner 349*7841efbbSZachary Turner class PythonModule : public PythonObject 350*7841efbbSZachary Turner { 351*7841efbbSZachary Turner public: 352*7841efbbSZachary Turner PythonModule(); 353*7841efbbSZachary Turner PythonModule(PyRefType type, PyObject *o); 354*7841efbbSZachary Turner PythonModule(const PythonModule &dict); 355*7841efbbSZachary Turner 356*7841efbbSZachary Turner ~PythonModule() override; 357*7841efbbSZachary Turner 358*7841efbbSZachary Turner static bool Check(PyObject *py_obj); 359*7841efbbSZachary Turner 360*7841efbbSZachary Turner static PythonModule MainModule(); 361*7841efbbSZachary Turner 362*7841efbbSZachary Turner // Bring in the no-argument base class version 363*7841efbbSZachary Turner using PythonObject::Reset; 364*7841efbbSZachary Turner 365*7841efbbSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 366*7841efbbSZachary Turner 367*7841efbbSZachary Turner PythonDictionary GetDictionary() const; 368*7841efbbSZachary Turner }; 369*7841efbbSZachary Turner 3709c40264fSZachary Turner class PythonFile : public PythonObject 3719c40264fSZachary Turner { 3729c40264fSZachary Turner public: 37332064024SZachary Turner PythonFile(); 374eda01c31SZachary Turner PythonFile(File &file, const char *mode); 375eda01c31SZachary Turner PythonFile(const char *path, const char *mode); 3769c40264fSZachary Turner PythonFile(PyRefType type, PyObject *o); 377edb35d95SEugene Zelenko 3789c40264fSZachary Turner ~PythonFile() override; 3799c40264fSZachary Turner 3809c40264fSZachary Turner static bool Check(PyObject *py_obj); 3819c40264fSZachary Turner 3829c40264fSZachary Turner using PythonObject::Reset; 3839c40264fSZachary Turner 3849c40264fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 3859c40264fSZachary Turner void Reset(File &file, const char *mode); 386eda01c31SZachary Turner 387eda01c31SZachary Turner bool GetUnderlyingFile(File &file) const; 3889c40264fSZachary Turner }; 3899c40264fSZachary Turner 3902c1f46dcSZachary Turner } // namespace lldb_private 3912c1f46dcSZachary Turner 3922c1f46dcSZachary Turner #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 393