1 //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 11 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 12 13 // C Includes 14 // C++ Includes 15 // Other libraries and framework includes 16 // Project includes 17 #include "lldb/lldb-defines.h" 18 #include "lldb/Core/ConstString.h" 19 #include "lldb/Core/StructuredData.h" 20 #include "lldb/Core/Flags.h" 21 #include "lldb/Host/File.h" 22 #include "lldb/Interpreter/OptionValue.h" 23 24 namespace lldb_private { 25 26 class PythonString; 27 class PythonList; 28 class PythonDictionary; 29 class PythonInteger; 30 31 class StructuredPythonObject : public StructuredData::Generic 32 { 33 public: 34 StructuredPythonObject() 35 : StructuredData::Generic() 36 { 37 } 38 39 StructuredPythonObject(void *obj) 40 : StructuredData::Generic(obj) 41 { 42 Py_XINCREF(GetValue()); 43 } 44 45 ~StructuredPythonObject() override 46 { 47 if (Py_IsInitialized()) 48 Py_XDECREF(GetValue()); 49 SetValue(nullptr); 50 } 51 52 bool 53 IsValid() const override 54 { 55 return GetValue() && GetValue() != Py_None; 56 } 57 58 void Dump(Stream &s) const override; 59 60 private: 61 DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 62 }; 63 64 enum class PyObjectType 65 { 66 Unknown, 67 None, 68 Integer, 69 Dictionary, 70 List, 71 String, 72 Module, 73 File 74 }; 75 76 enum class PyRefType 77 { 78 Borrowed, // We are not given ownership of the incoming PyObject. 79 // We cannot safely hold it without calling Py_INCREF. 80 Owned // We have ownership of the incoming PyObject. We should 81 // not call Py_INCREF. 82 }; 83 84 enum class PyInitialValue 85 { 86 Invalid, 87 Empty 88 }; 89 90 class PythonObject 91 { 92 public: 93 PythonObject() 94 : m_py_obj(nullptr) 95 { 96 } 97 98 PythonObject(PyRefType type, PyObject *py_obj) 99 : m_py_obj(nullptr) 100 { 101 Reset(type, py_obj); 102 } 103 104 PythonObject(const PythonObject &rhs) 105 : m_py_obj(nullptr) 106 { 107 Reset(rhs); 108 } 109 110 virtual ~PythonObject() 111 { 112 Reset(); 113 } 114 115 void 116 Reset() 117 { 118 // Avoid calling the virtual method since it's not necessary 119 // to actually validate the type of the PyObject if we're 120 // just setting to null. 121 if (Py_IsInitialized()) 122 Py_XDECREF(m_py_obj); 123 m_py_obj = nullptr; 124 } 125 126 void 127 Reset(const PythonObject &rhs) 128 { 129 // Avoid calling the virtual method if it's not necessary 130 // to actually validate the type of the PyObject. 131 if (!rhs.IsValid()) 132 Reset(); 133 else 134 Reset(PyRefType::Borrowed, rhs.m_py_obj); 135 } 136 137 // PythonObject is implicitly convertible to PyObject *, which will call the 138 // wrong overload. We want to explicitly disallow this, since a PyObject 139 // *always* owns its reference. Therefore the overload which takes a 140 // PyRefType doesn't make sense, and the copy constructor should be used. 141 void 142 Reset(PyRefType type, const PythonObject &ref) = delete; 143 144 virtual void 145 Reset(PyRefType type, PyObject *py_obj) 146 { 147 if (py_obj == m_py_obj) 148 return; 149 150 if (Py_IsInitialized()) 151 Py_XDECREF(m_py_obj); 152 153 m_py_obj = py_obj; 154 155 // If this is a borrowed reference, we need to convert it to 156 // an owned reference by incrementing it. If it is an owned 157 // reference (for example the caller allocated it with PyDict_New() 158 // then we must *not* increment it. 159 if (Py_IsInitialized() && type == PyRefType::Borrowed) 160 Py_XINCREF(m_py_obj); 161 } 162 163 void 164 Dump () const 165 { 166 if (m_py_obj) 167 _PyObject_Dump (m_py_obj); 168 else 169 puts ("NULL"); 170 } 171 172 void 173 Dump (Stream &strm) const; 174 175 PyObject* 176 get() const 177 { 178 return m_py_obj; 179 } 180 181 PyObject* 182 release() 183 { 184 PyObject *result = m_py_obj; 185 m_py_obj = nullptr; 186 return result; 187 } 188 189 PythonObject & 190 operator=(const PythonObject &other) 191 { 192 Reset(PyRefType::Borrowed, other.get()); 193 return *this; 194 } 195 196 PyObjectType 197 GetObjectType() const; 198 199 PythonString 200 Repr() const; 201 202 PythonString 203 Str() const; 204 205 static PythonObject 206 ResolveNameGlobal(llvm::StringRef name); 207 208 PythonObject 209 ResolveName(llvm::StringRef name) const; 210 211 bool 212 HasAttribute(llvm::StringRef attribute) const; 213 214 PythonObject 215 GetAttributeValue(llvm::StringRef attribute) const; 216 217 bool 218 IsValid() const; 219 220 bool 221 IsAllocated() const; 222 223 bool 224 IsNone() const; 225 226 template<typename T> 227 T AsType() const 228 { 229 if (!T::Check(m_py_obj)) 230 return T(); 231 return T(PyRefType::Borrowed, m_py_obj); 232 } 233 234 StructuredData::ObjectSP 235 CreateStructuredObject() const; 236 237 protected: 238 PyObject* m_py_obj; 239 }; 240 241 class PythonString : public PythonObject 242 { 243 public: 244 PythonString(); 245 explicit PythonString(llvm::StringRef string); 246 explicit PythonString(const char *string); 247 PythonString(PyRefType type, PyObject *o); 248 PythonString(const PythonString &object); 249 250 ~PythonString() override; 251 252 static bool Check(PyObject *py_obj); 253 254 // Bring in the no-argument base class version 255 using PythonObject::Reset; 256 257 void Reset(PyRefType type, PyObject *py_obj) override; 258 259 llvm::StringRef 260 GetString() const; 261 262 size_t 263 GetSize() const; 264 265 void SetString(llvm::StringRef string); 266 267 StructuredData::StringSP CreateStructuredString() const; 268 }; 269 270 class PythonInteger : public PythonObject 271 { 272 public: 273 PythonInteger(); 274 explicit PythonInteger(int64_t value); 275 PythonInteger(PyRefType type, PyObject *o); 276 PythonInteger(const PythonInteger &object); 277 278 ~PythonInteger() override; 279 280 static bool Check(PyObject *py_obj); 281 282 // Bring in the no-argument base class version 283 using PythonObject::Reset; 284 285 void Reset(PyRefType type, PyObject *py_obj) override; 286 287 int64_t GetInteger() const; 288 289 void 290 SetInteger (int64_t value); 291 292 StructuredData::IntegerSP CreateStructuredInteger() const; 293 }; 294 295 class PythonList : public PythonObject 296 { 297 public: 298 explicit PythonList(PyInitialValue value); 299 explicit PythonList(int list_size); 300 PythonList(PyRefType type, PyObject *o); 301 PythonList(const PythonList &list); 302 303 ~PythonList() override; 304 305 static bool Check(PyObject *py_obj); 306 307 // Bring in the no-argument base class version 308 using PythonObject::Reset; 309 310 void Reset(PyRefType type, PyObject *py_obj) override; 311 312 uint32_t GetSize() const; 313 314 PythonObject GetItemAtIndex(uint32_t index) const; 315 316 void SetItemAtIndex(uint32_t index, const PythonObject &object); 317 318 void AppendItem(const PythonObject &object); 319 320 StructuredData::ArraySP CreateStructuredArray() const; 321 }; 322 323 class PythonDictionary : public PythonObject 324 { 325 public: 326 explicit PythonDictionary(PyInitialValue value); 327 PythonDictionary(PyRefType type, PyObject *o); 328 PythonDictionary(const PythonDictionary &dict); 329 330 ~PythonDictionary() override; 331 332 static bool Check(PyObject *py_obj); 333 334 // Bring in the no-argument base class version 335 using PythonObject::Reset; 336 337 void Reset(PyRefType type, PyObject *py_obj) override; 338 339 uint32_t GetSize() const; 340 341 PythonList GetKeys() const; 342 343 PythonObject GetItemForKey(const PythonObject &key) const; 344 void SetItemForKey(const PythonObject &key, const PythonObject &value); 345 346 StructuredData::DictionarySP CreateStructuredDictionary() const; 347 }; 348 349 class PythonModule : public PythonObject 350 { 351 public: 352 PythonModule(); 353 PythonModule(PyRefType type, PyObject *o); 354 PythonModule(const PythonModule &dict); 355 356 ~PythonModule() override; 357 358 static bool Check(PyObject *py_obj); 359 360 static PythonModule MainModule(); 361 362 // Bring in the no-argument base class version 363 using PythonObject::Reset; 364 365 void Reset(PyRefType type, PyObject *py_obj) override; 366 367 PythonDictionary GetDictionary() const; 368 }; 369 370 class PythonFile : public PythonObject 371 { 372 public: 373 PythonFile(); 374 PythonFile(File &file, const char *mode); 375 PythonFile(const char *path, const char *mode); 376 PythonFile(PyRefType type, PyObject *o); 377 378 ~PythonFile() override; 379 380 static bool Check(PyObject *py_obj); 381 382 using PythonObject::Reset; 383 384 void Reset(PyRefType type, PyObject *py_obj) override; 385 void Reset(File &file, const char *mode); 386 387 bool GetUnderlyingFile(File &file) const; 388 }; 389 390 } // namespace lldb_private 391 392 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 393