12c1f46dcSZachary Turner //===-- 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 162c1f46dcSZachary Turner // Other libraries and framework includes 172c1f46dcSZachary Turner // Project includes 182c1f46dcSZachary Turner #include "lldb/lldb-defines.h" 192c1f46dcSZachary Turner #include "lldb/Core/ConstString.h" 202c1f46dcSZachary Turner #include "lldb/Core/StructuredData.h" 212c1f46dcSZachary Turner #include "lldb/Core/Flags.h" 222c1f46dcSZachary Turner #include "lldb/Interpreter/OptionValue.h" 232c1f46dcSZachary Turner 242c1f46dcSZachary Turner namespace lldb_private { 252c1f46dcSZachary Turner class PythonString; 262c1f46dcSZachary Turner class PythonList; 272c1f46dcSZachary Turner class PythonDictionary; 282c1f46dcSZachary Turner class PythonInteger; 292c1f46dcSZachary Turner 302c1f46dcSZachary Turner class StructuredPythonObject : public StructuredData::Generic 312c1f46dcSZachary Turner { 322c1f46dcSZachary Turner public: 332c1f46dcSZachary Turner StructuredPythonObject() 342c1f46dcSZachary Turner : StructuredData::Generic() 352c1f46dcSZachary Turner { 362c1f46dcSZachary Turner } 372c1f46dcSZachary Turner 382c1f46dcSZachary Turner StructuredPythonObject(void *obj) 392c1f46dcSZachary Turner : StructuredData::Generic(obj) 402c1f46dcSZachary Turner { 412c1f46dcSZachary Turner Py_XINCREF(GetValue()); 422c1f46dcSZachary Turner } 432c1f46dcSZachary Turner 442c1f46dcSZachary Turner virtual ~StructuredPythonObject() 452c1f46dcSZachary Turner { 462c1f46dcSZachary Turner if (Py_IsInitialized()) 472c1f46dcSZachary Turner Py_XDECREF(GetValue()); 482c1f46dcSZachary Turner SetValue(nullptr); 492c1f46dcSZachary Turner } 502c1f46dcSZachary Turner 512c1f46dcSZachary Turner bool 522c1f46dcSZachary Turner IsValid() const override 532c1f46dcSZachary Turner { 542c1f46dcSZachary Turner return GetValue() && GetValue() != Py_None; 552c1f46dcSZachary Turner } 562c1f46dcSZachary Turner 572c1f46dcSZachary Turner void Dump(Stream &s) const override; 582c1f46dcSZachary Turner 592c1f46dcSZachary Turner private: 602c1f46dcSZachary Turner DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 612c1f46dcSZachary Turner }; 622c1f46dcSZachary Turner 632c1f46dcSZachary Turner enum class PyObjectType 642c1f46dcSZachary Turner { 652c1f46dcSZachary Turner Unknown, 662c1f46dcSZachary Turner None, 672c1f46dcSZachary Turner Integer, 682c1f46dcSZachary Turner Dictionary, 692c1f46dcSZachary Turner List, 702c1f46dcSZachary Turner String 712c1f46dcSZachary Turner }; 722c1f46dcSZachary Turner 73*f8b22f8fSZachary Turner enum class PyRefType 74*f8b22f8fSZachary Turner { 75*f8b22f8fSZachary Turner Borrowed, // We are not given ownership of the incoming PyObject. 76*f8b22f8fSZachary Turner // We cannot safely hold it without calling Py_INCREF. 77*f8b22f8fSZachary Turner Owned // We have ownership of the incoming PyObject. We should 78*f8b22f8fSZachary Turner // not call Py_INCREF. 79*f8b22f8fSZachary Turner }; 80*f8b22f8fSZachary Turner 81*f8b22f8fSZachary Turner enum class PyInitialValue 82*f8b22f8fSZachary Turner { 83*f8b22f8fSZachary Turner Invalid, 84*f8b22f8fSZachary Turner Empty 85*f8b22f8fSZachary Turner }; 86*f8b22f8fSZachary Turner 872c1f46dcSZachary Turner class PythonObject 882c1f46dcSZachary Turner { 892c1f46dcSZachary Turner public: 90*f8b22f8fSZachary Turner PythonObject() 91*f8b22f8fSZachary Turner : m_py_obj(nullptr) 922c1f46dcSZachary Turner { 932c1f46dcSZachary Turner } 942c1f46dcSZachary Turner 95*f8b22f8fSZachary Turner PythonObject(PyRefType type, PyObject *py_obj) 96*f8b22f8fSZachary Turner : m_py_obj(nullptr) 972c1f46dcSZachary Turner { 98*f8b22f8fSZachary Turner Reset(type, py_obj); 992c1f46dcSZachary Turner } 1002c1f46dcSZachary Turner 101*f8b22f8fSZachary Turner PythonObject(const PythonObject &rhs) 102*f8b22f8fSZachary Turner : m_py_obj(nullptr) 1032c1f46dcSZachary Turner { 104*f8b22f8fSZachary Turner Reset(rhs); 1052c1f46dcSZachary Turner } 1062c1f46dcSZachary Turner 107*f8b22f8fSZachary Turner virtual ~PythonObject() { Reset(); } 1082c1f46dcSZachary Turner 109*f8b22f8fSZachary Turner void 110*f8b22f8fSZachary Turner Reset() 1112c1f46dcSZachary Turner { 112*f8b22f8fSZachary Turner // Avoid calling the virtual method since it's not necessary 113*f8b22f8fSZachary Turner // to actually validate the type of the PyObject if we're 114*f8b22f8fSZachary Turner // just setting to null. 1152c1f46dcSZachary Turner if (Py_IsInitialized()) 1162c1f46dcSZachary Turner Py_XDECREF(m_py_obj); 117*f8b22f8fSZachary Turner m_py_obj = nullptr; 1182c1f46dcSZachary Turner } 119*f8b22f8fSZachary Turner 120*f8b22f8fSZachary Turner void 121*f8b22f8fSZachary Turner Reset(const PythonObject &rhs) 122*f8b22f8fSZachary Turner { 123*f8b22f8fSZachary Turner // Avoid calling the virtual method if it's not necessary 124*f8b22f8fSZachary Turner // to actually validate the type of the PyObject. 125*f8b22f8fSZachary Turner if (!rhs.get()) 126*f8b22f8fSZachary Turner Reset(); 127*f8b22f8fSZachary Turner else 128*f8b22f8fSZachary Turner Reset(PyRefType::Borrowed, rhs.m_py_obj); 129*f8b22f8fSZachary Turner } 130*f8b22f8fSZachary Turner 131*f8b22f8fSZachary Turner // PythonObject is implicitly convertible to PyObject *, which will call the 132*f8b22f8fSZachary Turner // wrong overload. We want to explicitly disallow this, since a PyObject 133*f8b22f8fSZachary Turner // *always* owns its reference. Therefore the overload which takes a 134*f8b22f8fSZachary Turner // PyRefType doesn't make sense, and the copy constructor should be used. 135*f8b22f8fSZachary Turner void 136*f8b22f8fSZachary Turner Reset(PyRefType type, const PythonObject &ref) = delete; 137*f8b22f8fSZachary Turner 138*f8b22f8fSZachary Turner virtual void 139*f8b22f8fSZachary Turner Reset(PyRefType type, PyObject *py_obj) 140*f8b22f8fSZachary Turner { 141*f8b22f8fSZachary Turner if (py_obj == m_py_obj) 142*f8b22f8fSZachary Turner return; 143*f8b22f8fSZachary Turner 144*f8b22f8fSZachary Turner if (Py_IsInitialized()) 145*f8b22f8fSZachary Turner Py_XDECREF(m_py_obj); 146*f8b22f8fSZachary Turner 147*f8b22f8fSZachary Turner m_py_obj = py_obj; 148*f8b22f8fSZachary Turner 149*f8b22f8fSZachary Turner // If this is a borrowed reference, we need to convert it to 150*f8b22f8fSZachary Turner // an owned reference by incrementing it. If it is an owned 151*f8b22f8fSZachary Turner // reference (for example the caller allocated it with PyDict_New() 152*f8b22f8fSZachary Turner // then we must *not* increment it. 153*f8b22f8fSZachary Turner if (Py_IsInitialized() && type == PyRefType::Borrowed) 154*f8b22f8fSZachary Turner Py_XINCREF(m_py_obj); 1552c1f46dcSZachary Turner } 1562c1f46dcSZachary Turner 1572c1f46dcSZachary Turner void 1582c1f46dcSZachary Turner Dump () const 1592c1f46dcSZachary Turner { 1602c1f46dcSZachary Turner if (m_py_obj) 1612c1f46dcSZachary Turner _PyObject_Dump (m_py_obj); 1622c1f46dcSZachary Turner else 1632c1f46dcSZachary Turner puts ("NULL"); 1642c1f46dcSZachary Turner } 1652c1f46dcSZachary Turner 1662c1f46dcSZachary Turner void 1672c1f46dcSZachary Turner Dump (Stream &strm) const; 1682c1f46dcSZachary Turner 1692c1f46dcSZachary Turner PyObject* 1702c1f46dcSZachary Turner get () const 1712c1f46dcSZachary Turner { 1722c1f46dcSZachary Turner return m_py_obj; 1732c1f46dcSZachary Turner } 1742c1f46dcSZachary Turner 1752c1f46dcSZachary Turner PyObjectType GetObjectType() const; 1762c1f46dcSZachary Turner 1772c1f46dcSZachary Turner PythonString 1782c1f46dcSZachary Turner Repr (); 1792c1f46dcSZachary Turner 1802c1f46dcSZachary Turner PythonString 1812c1f46dcSZachary Turner Str (); 1822c1f46dcSZachary Turner 183*f8b22f8fSZachary Turner PythonObject & 184*f8b22f8fSZachary Turner operator=(const PythonObject &other) 1852c1f46dcSZachary Turner { 186*f8b22f8fSZachary Turner Reset(PyRefType::Borrowed, other.get()); 187*f8b22f8fSZachary Turner return *this; 1882c1f46dcSZachary Turner } 1892c1f46dcSZachary Turner 1902c1f46dcSZachary Turner bool 191*f8b22f8fSZachary Turner IsValid() const; 192*f8b22f8fSZachary Turner 193*f8b22f8fSZachary Turner bool 194*f8b22f8fSZachary Turner IsAllocated() const; 195*f8b22f8fSZachary Turner 196*f8b22f8fSZachary Turner bool 197*f8b22f8fSZachary Turner IsNone() const; 1982c1f46dcSZachary Turner 1992c1f46dcSZachary Turner StructuredData::ObjectSP CreateStructuredObject() const; 2002c1f46dcSZachary Turner 2012c1f46dcSZachary Turner protected: 2022c1f46dcSZachary Turner PyObject* m_py_obj; 2032c1f46dcSZachary Turner }; 2042c1f46dcSZachary Turner 2052c1f46dcSZachary Turner class PythonString : public PythonObject 2062c1f46dcSZachary Turner { 2072c1f46dcSZachary Turner public: 2082c1f46dcSZachary Turner PythonString(); 209*f8b22f8fSZachary Turner PythonString(PyRefType type, PyObject *o); 210*f8b22f8fSZachary Turner PythonString(const PythonString &object); 211*f8b22f8fSZachary Turner explicit PythonString(llvm::StringRef string); 212*f8b22f8fSZachary Turner explicit PythonString(const char *string); 213*f8b22f8fSZachary Turner ~PythonString() override; 2142c1f46dcSZachary Turner 21522c8efcdSZachary Turner static bool Check(PyObject *py_obj); 21622c8efcdSZachary Turner 217*f8b22f8fSZachary Turner // Bring in the no-argument base class version 218*f8b22f8fSZachary Turner using PythonObject::Reset; 219*f8b22f8fSZachary Turner 220*f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 2212c1f46dcSZachary Turner 2222c1f46dcSZachary Turner llvm::StringRef 2232c1f46dcSZachary Turner GetString() const; 2242c1f46dcSZachary Turner 2252c1f46dcSZachary Turner size_t 2262c1f46dcSZachary Turner GetSize() const; 2272c1f46dcSZachary Turner 2282c1f46dcSZachary Turner void SetString(llvm::StringRef string); 2292c1f46dcSZachary Turner 2302c1f46dcSZachary Turner StructuredData::StringSP CreateStructuredString() const; 2312c1f46dcSZachary Turner }; 2322c1f46dcSZachary Turner 2332c1f46dcSZachary Turner class PythonInteger : public PythonObject 2342c1f46dcSZachary Turner { 2352c1f46dcSZachary Turner public: 2362c1f46dcSZachary Turner PythonInteger(); 237*f8b22f8fSZachary Turner PythonInteger(PyRefType type, PyObject *o); 238*f8b22f8fSZachary Turner PythonInteger(const PythonInteger &object); 239*f8b22f8fSZachary Turner explicit PythonInteger(int64_t value); 240*f8b22f8fSZachary Turner ~PythonInteger() override; 2412c1f46dcSZachary Turner 24222c8efcdSZachary Turner static bool Check(PyObject *py_obj); 24322c8efcdSZachary Turner 244*f8b22f8fSZachary Turner // Bring in the no-argument base class version 245*f8b22f8fSZachary Turner using PythonObject::Reset; 246*f8b22f8fSZachary Turner 247*f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 2482c1f46dcSZachary Turner 2492c1f46dcSZachary Turner int64_t GetInteger() const; 2502c1f46dcSZachary Turner 2512c1f46dcSZachary Turner void 2522c1f46dcSZachary Turner SetInteger (int64_t value); 2532c1f46dcSZachary Turner 2542c1f46dcSZachary Turner StructuredData::IntegerSP CreateStructuredInteger() const; 2552c1f46dcSZachary Turner }; 2562c1f46dcSZachary Turner 2572c1f46dcSZachary Turner class PythonList : public PythonObject 2582c1f46dcSZachary Turner { 2592c1f46dcSZachary Turner public: 260*f8b22f8fSZachary Turner PythonList(PyInitialValue value); 261*f8b22f8fSZachary Turner PythonList(PyRefType type, PyObject *o); 262*f8b22f8fSZachary Turner PythonList(const PythonList &list); 263*f8b22f8fSZachary Turner ~PythonList() override; 2642c1f46dcSZachary Turner 26522c8efcdSZachary Turner static bool Check(PyObject *py_obj); 26622c8efcdSZachary Turner 267*f8b22f8fSZachary Turner // Bring in the no-argument base class version 268*f8b22f8fSZachary Turner using PythonObject::Reset; 269*f8b22f8fSZachary Turner 270*f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 2712c1f46dcSZachary Turner 2722c1f46dcSZachary Turner uint32_t GetSize() const; 2732c1f46dcSZachary Turner 2742c1f46dcSZachary Turner PythonObject GetItemAtIndex(uint32_t index) const; 2752c1f46dcSZachary Turner 276*f8b22f8fSZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object); 2772c1f46dcSZachary Turner 278*f8b22f8fSZachary Turner void AppendItem(const PythonObject &object); 2792c1f46dcSZachary Turner 2802c1f46dcSZachary Turner StructuredData::ArraySP CreateStructuredArray() const; 2812c1f46dcSZachary Turner }; 2822c1f46dcSZachary Turner 2832c1f46dcSZachary Turner class PythonDictionary : public PythonObject 2842c1f46dcSZachary Turner { 2852c1f46dcSZachary Turner public: 286*f8b22f8fSZachary Turner PythonDictionary(PyInitialValue value); 287*f8b22f8fSZachary Turner PythonDictionary(PyRefType type, PyObject *o); 288*f8b22f8fSZachary Turner PythonDictionary(const PythonDictionary &dict); 289*f8b22f8fSZachary Turner ~PythonDictionary() override; 2902c1f46dcSZachary Turner 29122c8efcdSZachary Turner static bool Check(PyObject *py_obj); 29222c8efcdSZachary Turner 293*f8b22f8fSZachary Turner // Bring in the no-argument base class version 294*f8b22f8fSZachary Turner using PythonObject::Reset; 295*f8b22f8fSZachary Turner 296*f8b22f8fSZachary Turner void Reset(PyRefType type, PyObject *py_obj) override; 2972c1f46dcSZachary Turner 2982c1f46dcSZachary Turner uint32_t GetSize() const; 2992c1f46dcSZachary Turner 300*f8b22f8fSZachary Turner PythonList GetKeys() const; 3012c1f46dcSZachary Turner 302*f8b22f8fSZachary Turner PythonObject GetItemForKey(const PythonObject &key) const; 303*f8b22f8fSZachary Turner void SetItemForKey(const PythonObject &key, const PythonObject &value); 3042c1f46dcSZachary Turner 3052c1f46dcSZachary Turner StructuredData::DictionarySP CreateStructuredDictionary() const; 3062c1f46dcSZachary Turner }; 3072c1f46dcSZachary Turner } // namespace lldb_private 3082c1f46dcSZachary Turner 3092c1f46dcSZachary Turner #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 310