1 //===-- PythonDataObjects.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_PYTHONDATAOBJECTS_H 10 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 11 12 #ifndef LLDB_DISABLE_PYTHON 13 14 // LLDB Python header must be included first 15 #include "lldb-python.h" 16 17 #include "lldb/Utility/Flags.h" 18 19 #include "lldb/Host/File.h" 20 #include "lldb/Interpreter/OptionValue.h" 21 #include "lldb/Utility/ConstString.h" 22 #include "lldb/Utility/StructuredData.h" 23 #include "lldb/lldb-defines.h" 24 25 #include "llvm/ADT/ArrayRef.h" 26 27 namespace lldb_private { 28 29 class PythonBytes; 30 class PythonString; 31 class PythonList; 32 class PythonDictionary; 33 class PythonInteger; 34 35 class StructuredPythonObject : public StructuredData::Generic { 36 public: 37 StructuredPythonObject() : StructuredData::Generic() {} 38 39 StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 40 Py_XINCREF(GetValue()); 41 } 42 43 ~StructuredPythonObject() override { 44 if (Py_IsInitialized()) 45 Py_XDECREF(GetValue()); 46 SetValue(nullptr); 47 } 48 49 bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 50 51 void Dump(Stream &s, bool pretty_print = true) const override; 52 53 private: 54 DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 55 }; 56 57 enum class PyObjectType { 58 Unknown, 59 None, 60 Boolean, 61 Integer, 62 Dictionary, 63 List, 64 String, 65 Bytes, 66 ByteArray, 67 Module, 68 Callable, 69 Tuple, 70 File 71 }; 72 73 enum class PyRefType { 74 Borrowed, // We are not given ownership of the incoming PyObject. 75 // We cannot safely hold it without calling Py_INCREF. 76 Owned // We have ownership of the incoming PyObject. We should 77 // not call Py_INCREF. 78 }; 79 80 enum class PyInitialValue { Invalid, Empty }; 81 82 class PythonObject { 83 public: 84 PythonObject() : m_py_obj(nullptr) {} 85 86 PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) { 87 Reset(type, py_obj); 88 } 89 90 PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); } 91 92 virtual ~PythonObject() { Reset(); } 93 94 void Reset() { 95 // Avoid calling the virtual method since it's not necessary 96 // to actually validate the type of the PyObject if we're 97 // just setting to null. 98 if (Py_IsInitialized()) 99 Py_XDECREF(m_py_obj); 100 m_py_obj = nullptr; 101 } 102 103 void Reset(const PythonObject &rhs) { 104 // Avoid calling the virtual method if it's not necessary 105 // to actually validate the type of the PyObject. 106 if (!rhs.IsValid()) 107 Reset(); 108 else 109 Reset(PyRefType::Borrowed, rhs.m_py_obj); 110 } 111 112 // PythonObject is implicitly convertible to PyObject *, which will call the 113 // wrong overload. We want to explicitly disallow this, since a PyObject 114 // *always* owns its reference. Therefore the overload which takes a 115 // PyRefType doesn't make sense, and the copy constructor should be used. 116 void Reset(PyRefType type, const PythonObject &ref) = delete; 117 118 virtual void Reset(PyRefType type, PyObject *py_obj) { 119 if (py_obj == m_py_obj) 120 return; 121 122 if (Py_IsInitialized()) 123 Py_XDECREF(m_py_obj); 124 125 m_py_obj = py_obj; 126 127 // If this is a borrowed reference, we need to convert it to 128 // an owned reference by incrementing it. If it is an owned 129 // reference (for example the caller allocated it with PyDict_New() 130 // then we must *not* increment it. 131 if (Py_IsInitialized() && type == PyRefType::Borrowed) 132 Py_XINCREF(m_py_obj); 133 } 134 135 void Dump() const { 136 if (m_py_obj) 137 _PyObject_Dump(m_py_obj); 138 else 139 puts("NULL"); 140 } 141 142 void Dump(Stream &strm) const; 143 144 PyObject *get() const { return m_py_obj; } 145 146 PyObject *release() { 147 PyObject *result = m_py_obj; 148 m_py_obj = nullptr; 149 return result; 150 } 151 152 PythonObject &operator=(const PythonObject &other) { 153 Reset(PyRefType::Borrowed, other.get()); 154 return *this; 155 } 156 157 PyObjectType GetObjectType() const; 158 159 PythonString Repr() const; 160 161 PythonString Str() const; 162 163 static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 164 const PythonDictionary &dict); 165 166 template <typename T> 167 static T ResolveNameWithDictionary(llvm::StringRef name, 168 const PythonDictionary &dict) { 169 return ResolveNameWithDictionary(name, dict).AsType<T>(); 170 } 171 172 PythonObject ResolveName(llvm::StringRef name) const; 173 174 template <typename T> T ResolveName(llvm::StringRef name) const { 175 return ResolveName(name).AsType<T>(); 176 } 177 178 bool HasAttribute(llvm::StringRef attribute) const; 179 180 PythonObject GetAttributeValue(llvm::StringRef attribute) const; 181 182 bool IsValid() const; 183 184 bool IsAllocated() const; 185 186 bool IsNone() const; 187 188 template <typename T> T AsType() const { 189 if (!T::Check(m_py_obj)) 190 return T(); 191 return T(PyRefType::Borrowed, m_py_obj); 192 } 193 194 StructuredData::ObjectSP CreateStructuredObject() const; 195 196 protected: 197 PyObject *m_py_obj; 198 }; 199 200 class PythonBytes : public PythonObject { 201 public: 202 PythonBytes(); 203 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 204 PythonBytes(const uint8_t *bytes, size_t length); 205 PythonBytes(PyRefType type, PyObject *o); 206 PythonBytes(const PythonBytes &object); 207 208 ~PythonBytes() override; 209 210 static bool Check(PyObject *py_obj); 211 212 // Bring in the no-argument base class version 213 using PythonObject::Reset; 214 215 void Reset(PyRefType type, PyObject *py_obj) override; 216 217 llvm::ArrayRef<uint8_t> GetBytes() const; 218 219 size_t GetSize() const; 220 221 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 222 223 StructuredData::StringSP CreateStructuredString() const; 224 }; 225 226 class PythonByteArray : public PythonObject { 227 public: 228 PythonByteArray(); 229 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 230 PythonByteArray(const uint8_t *bytes, size_t length); 231 PythonByteArray(PyRefType type, PyObject *o); 232 PythonByteArray(const PythonBytes &object); 233 234 ~PythonByteArray() override; 235 236 static bool Check(PyObject *py_obj); 237 238 // Bring in the no-argument base class version 239 using PythonObject::Reset; 240 241 void Reset(PyRefType type, PyObject *py_obj) override; 242 243 llvm::ArrayRef<uint8_t> GetBytes() const; 244 245 size_t GetSize() const; 246 247 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 248 249 StructuredData::StringSP CreateStructuredString() const; 250 }; 251 252 class PythonString : public PythonObject { 253 public: 254 PythonString(); 255 explicit PythonString(llvm::StringRef string); 256 explicit PythonString(const char *string); 257 PythonString(PyRefType type, PyObject *o); 258 PythonString(const PythonString &object); 259 260 ~PythonString() override; 261 262 static bool Check(PyObject *py_obj); 263 264 // Bring in the no-argument base class version 265 using PythonObject::Reset; 266 267 void Reset(PyRefType type, PyObject *py_obj) override; 268 269 llvm::StringRef GetString() const; 270 271 size_t GetSize() const; 272 273 void SetString(llvm::StringRef string); 274 275 StructuredData::StringSP CreateStructuredString() const; 276 }; 277 278 class PythonInteger : public PythonObject { 279 public: 280 PythonInteger(); 281 explicit PythonInteger(int64_t value); 282 PythonInteger(PyRefType type, PyObject *o); 283 PythonInteger(const PythonInteger &object); 284 285 ~PythonInteger() override; 286 287 static bool Check(PyObject *py_obj); 288 289 // Bring in the no-argument base class version 290 using PythonObject::Reset; 291 292 void Reset(PyRefType type, PyObject *py_obj) override; 293 294 int64_t GetInteger() const; 295 296 void SetInteger(int64_t value); 297 298 StructuredData::IntegerSP CreateStructuredInteger() const; 299 }; 300 301 class PythonBoolean : public PythonObject { 302 public: 303 PythonBoolean() = default; 304 explicit PythonBoolean(bool value); 305 PythonBoolean(PyRefType type, PyObject *o); 306 PythonBoolean(const PythonBoolean &object); 307 308 ~PythonBoolean() override = default; 309 310 static bool Check(PyObject *py_obj); 311 312 // Bring in the no-argument base class version 313 using PythonObject::Reset; 314 315 void Reset(PyRefType type, PyObject *py_obj) override; 316 317 bool GetValue() const; 318 319 void SetValue(bool value); 320 321 StructuredData::BooleanSP CreateStructuredBoolean() const; 322 }; 323 324 class PythonList : public PythonObject { 325 public: 326 PythonList() {} 327 explicit PythonList(PyInitialValue value); 328 explicit PythonList(int list_size); 329 PythonList(PyRefType type, PyObject *o); 330 PythonList(const PythonList &list); 331 332 ~PythonList() override; 333 334 static bool Check(PyObject *py_obj); 335 336 // Bring in the no-argument base class version 337 using PythonObject::Reset; 338 339 void Reset(PyRefType type, PyObject *py_obj) override; 340 341 uint32_t GetSize() const; 342 343 PythonObject GetItemAtIndex(uint32_t index) const; 344 345 void SetItemAtIndex(uint32_t index, const PythonObject &object); 346 347 void AppendItem(const PythonObject &object); 348 349 StructuredData::ArraySP CreateStructuredArray() const; 350 }; 351 352 class PythonTuple : public PythonObject { 353 public: 354 PythonTuple() {} 355 explicit PythonTuple(PyInitialValue value); 356 explicit PythonTuple(int tuple_size); 357 PythonTuple(PyRefType type, PyObject *o); 358 PythonTuple(const PythonTuple &tuple); 359 PythonTuple(std::initializer_list<PythonObject> objects); 360 PythonTuple(std::initializer_list<PyObject *> objects); 361 362 ~PythonTuple() override; 363 364 static bool Check(PyObject *py_obj); 365 366 // Bring in the no-argument base class version 367 using PythonObject::Reset; 368 369 void Reset(PyRefType type, PyObject *py_obj) override; 370 371 uint32_t GetSize() const; 372 373 PythonObject GetItemAtIndex(uint32_t index) const; 374 375 void SetItemAtIndex(uint32_t index, const PythonObject &object); 376 377 StructuredData::ArraySP CreateStructuredArray() const; 378 }; 379 380 class PythonDictionary : public PythonObject { 381 public: 382 PythonDictionary() {} 383 explicit PythonDictionary(PyInitialValue value); 384 PythonDictionary(PyRefType type, PyObject *o); 385 PythonDictionary(const PythonDictionary &dict); 386 387 ~PythonDictionary() override; 388 389 static bool Check(PyObject *py_obj); 390 391 // Bring in the no-argument base class version 392 using PythonObject::Reset; 393 394 void Reset(PyRefType type, PyObject *py_obj) override; 395 396 uint32_t GetSize() const; 397 398 PythonList GetKeys() const; 399 400 PythonObject GetItemForKey(const PythonObject &key) const; 401 void SetItemForKey(const PythonObject &key, const PythonObject &value); 402 403 StructuredData::DictionarySP CreateStructuredDictionary() const; 404 }; 405 406 class PythonModule : public PythonObject { 407 public: 408 PythonModule(); 409 PythonModule(PyRefType type, PyObject *o); 410 PythonModule(const PythonModule &dict); 411 412 ~PythonModule() override; 413 414 static bool Check(PyObject *py_obj); 415 416 static PythonModule BuiltinsModule(); 417 418 static PythonModule MainModule(); 419 420 static PythonModule AddModule(llvm::StringRef module); 421 422 static PythonModule ImportModule(llvm::StringRef module); 423 424 // Bring in the no-argument base class version 425 using PythonObject::Reset; 426 427 void Reset(PyRefType type, PyObject *py_obj) override; 428 429 PythonDictionary GetDictionary() const; 430 }; 431 432 class PythonCallable : public PythonObject { 433 public: 434 struct ArgInfo { 435 size_t count; 436 bool is_bound_method : 1; 437 bool has_varargs : 1; 438 bool has_kwargs : 1; 439 }; 440 441 PythonCallable(); 442 PythonCallable(PyRefType type, PyObject *o); 443 PythonCallable(const PythonCallable &dict); 444 445 ~PythonCallable() override; 446 447 static bool Check(PyObject *py_obj); 448 449 // Bring in the no-argument base class version 450 using PythonObject::Reset; 451 452 void Reset(PyRefType type, PyObject *py_obj) override; 453 454 ArgInfo GetNumArguments() const; 455 456 PythonObject operator()(); 457 458 PythonObject operator()(std::initializer_list<PyObject *> args); 459 460 PythonObject operator()(std::initializer_list<PythonObject> args); 461 462 template <typename Arg, typename... Args> 463 PythonObject operator()(const Arg &arg, Args... args) { 464 return operator()({arg, args...}); 465 } 466 }; 467 468 class PythonFile : public PythonObject { 469 public: 470 PythonFile(); 471 PythonFile(File &file, const char *mode); 472 PythonFile(const char *path, const char *mode); 473 PythonFile(PyRefType type, PyObject *o); 474 475 ~PythonFile() override; 476 477 static bool Check(PyObject *py_obj); 478 479 using PythonObject::Reset; 480 481 void Reset(PyRefType type, PyObject *py_obj) override; 482 void Reset(File &file, const char *mode); 483 484 static uint32_t GetOptionsFromMode(llvm::StringRef mode); 485 486 bool GetUnderlyingFile(File &file) const; 487 }; 488 489 } // namespace lldb_private 490 491 #endif 492 493 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 494