1 //===-- PythonDataObjects.cpp ------------------------------------*- 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 #ifdef LLDB_DISABLE_PYTHON 11 12 // Python is disabled in this build 13 14 #else 15 16 #include "lldb-python.h" 17 #include "PythonDataObjects.h" 18 #include "ScriptInterpreterPython.h" 19 20 #include "lldb/Core/Stream.h" 21 #include "lldb/Host/File.h" 22 #include "lldb/Interpreter/ScriptInterpreter.h" 23 24 #include <stdio.h> 25 26 using namespace lldb_private; 27 using namespace lldb; 28 29 void 30 StructuredPythonObject::Dump(Stream &s) const 31 { 32 s << "Python Obj: 0x" << GetValue(); 33 } 34 35 //---------------------------------------------------------------------- 36 // PythonObject 37 //---------------------------------------------------------------------- 38 39 void 40 PythonObject::Dump(Stream &strm) const 41 { 42 if (m_py_obj) 43 { 44 FILE *file = ::tmpfile(); 45 if (file) 46 { 47 ::PyObject_Print (m_py_obj, file, 0); 48 const long length = ftell (file); 49 if (length) 50 { 51 ::rewind(file); 52 std::vector<char> file_contents (length,'\0'); 53 const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file); 54 if (length_read > 0) 55 strm.Write (file_contents.data(), length_read); 56 } 57 ::fclose (file); 58 } 59 } 60 else 61 strm.PutCString ("NULL"); 62 } 63 64 PyObjectType 65 PythonObject::GetObjectType() const 66 { 67 if (!IsAllocated()) 68 return PyObjectType::None; 69 70 if (PythonList::Check(m_py_obj)) 71 return PyObjectType::List; 72 if (PythonDictionary::Check(m_py_obj)) 73 return PyObjectType::Dictionary; 74 if (PythonString::Check(m_py_obj)) 75 return PyObjectType::String; 76 if (PythonInteger::Check(m_py_obj)) 77 return PyObjectType::Integer; 78 if (PythonFile::Check(m_py_obj)) 79 return PyObjectType::File; 80 return PyObjectType::Unknown; 81 } 82 83 PythonString 84 PythonObject::Repr() 85 { 86 if (!m_py_obj) 87 return PythonString(); 88 PyObject *repr = PyObject_Repr(m_py_obj); 89 if (!repr) 90 return PythonString(); 91 return PythonString(PyRefType::Owned, repr); 92 } 93 94 PythonString 95 PythonObject::Str() 96 { 97 if (!m_py_obj) 98 return PythonString(); 99 PyObject *str = PyObject_Str(m_py_obj); 100 if (!str) 101 return PythonString(); 102 return PythonString(PyRefType::Owned, str); 103 } 104 105 bool 106 PythonObject::HasAttribute(llvm::StringRef attr) const 107 { 108 if (!IsValid()) 109 return false; 110 PythonString py_attr(attr); 111 return !!PyObject_HasAttr(m_py_obj, py_attr.get()); 112 } 113 114 PythonObject 115 PythonObject::GetAttributeValue(llvm::StringRef attr) const 116 { 117 if (!IsValid()) 118 return PythonObject(); 119 120 PythonString py_attr(attr); 121 if (!PyObject_HasAttr(m_py_obj, py_attr.get())) 122 return PythonObject(); 123 124 return PythonObject(PyRefType::Owned, 125 PyObject_GetAttr(m_py_obj, py_attr.get())); 126 } 127 128 bool 129 PythonObject::IsNone() const 130 { 131 return m_py_obj == Py_None; 132 } 133 134 bool 135 PythonObject::IsValid() const 136 { 137 return m_py_obj != nullptr; 138 } 139 140 bool 141 PythonObject::IsAllocated() const 142 { 143 return IsValid() && !IsNone(); 144 } 145 146 StructuredData::ObjectSP 147 PythonObject::CreateStructuredObject() const 148 { 149 switch (GetObjectType()) 150 { 151 case PyObjectType::Dictionary: 152 return PythonDictionary(PyRefType::Borrowed, m_py_obj).CreateStructuredDictionary(); 153 case PyObjectType::Integer: 154 return PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger(); 155 case PyObjectType::List: 156 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); 157 case PyObjectType::String: 158 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 159 case PyObjectType::None: 160 return StructuredData::ObjectSP(); 161 default: 162 return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); 163 } 164 } 165 166 //---------------------------------------------------------------------- 167 // PythonString 168 //---------------------------------------------------------------------- 169 170 PythonString::PythonString(PyRefType type, PyObject *py_obj) 171 : PythonObject() 172 { 173 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string 174 } 175 176 PythonString::PythonString(const PythonString &object) 177 : PythonObject(object) 178 { 179 } 180 181 PythonString::PythonString(llvm::StringRef string) 182 : PythonObject() 183 { 184 SetString(string); 185 } 186 187 PythonString::PythonString(const char *string) 188 : PythonObject() 189 { 190 SetString(llvm::StringRef(string)); 191 } 192 193 PythonString::PythonString() 194 : PythonObject() 195 { 196 } 197 198 PythonString::~PythonString () 199 { 200 } 201 202 bool 203 PythonString::Check(PyObject *py_obj) 204 { 205 if (!py_obj) 206 return false; 207 208 if (PyUnicode_Check(py_obj)) 209 return true; 210 #if PY_MAJOR_VERSION < 3 211 if (PyString_Check(py_obj)) 212 return true; 213 #endif 214 return false; 215 } 216 217 void 218 PythonString::Reset(PyRefType type, PyObject *py_obj) 219 { 220 // Grab the desired reference type so that if we end up rejecting 221 // `py_obj` it still gets decremented if necessary. 222 PythonObject result(type, py_obj); 223 224 if (!PythonString::Check(py_obj)) 225 { 226 PythonObject::Reset(); 227 return; 228 } 229 #if PY_MAJOR_VERSION < 3 230 // In Python 2, Don't store PyUnicode objects directly, because we need 231 // access to their underlying character buffers which Python 2 doesn't 232 // provide. 233 if (PyUnicode_Check(py_obj)) 234 result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get())); 235 #endif 236 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 237 // back into the virtual implementation. 238 PythonObject::Reset(PyRefType::Borrowed, result.get()); 239 } 240 241 llvm::StringRef 242 PythonString::GetString() const 243 { 244 if (!IsValid()) 245 return llvm::StringRef(); 246 247 Py_ssize_t size; 248 char *c; 249 250 #if PY_MAJOR_VERSION >= 3 251 c = PyUnicode_AsUTF8AndSize(m_py_obj, &size); 252 #else 253 PyString_AsStringAndSize(m_py_obj, &c, &size); 254 #endif 255 return llvm::StringRef(c, size); 256 } 257 258 size_t 259 PythonString::GetSize() const 260 { 261 if (IsValid()) 262 { 263 #if PY_MAJOR_VERSION >= 3 264 return PyUnicode_GetSize(m_py_obj); 265 #else 266 return PyString_Size(m_py_obj); 267 #endif 268 } 269 return 0; 270 } 271 272 void 273 PythonString::SetString (llvm::StringRef string) 274 { 275 #if PY_MAJOR_VERSION >= 3 276 PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size()); 277 PythonObject::Reset(PyRefType::Owned, unicode); 278 #else 279 PyObject *str = PyString_FromStringAndSize(string.data(), string.size()); 280 PythonObject::Reset(PyRefType::Owned, str); 281 #endif 282 } 283 284 StructuredData::StringSP 285 PythonString::CreateStructuredString() const 286 { 287 StructuredData::StringSP result(new StructuredData::String); 288 result->SetValue(GetString()); 289 return result; 290 } 291 292 //---------------------------------------------------------------------- 293 // PythonInteger 294 //---------------------------------------------------------------------- 295 296 PythonInteger::PythonInteger() 297 : PythonObject() 298 { 299 300 } 301 302 PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj) 303 : PythonObject() 304 { 305 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type 306 } 307 308 PythonInteger::PythonInteger(const PythonInteger &object) 309 : PythonObject(object) 310 { 311 } 312 313 PythonInteger::PythonInteger(int64_t value) 314 : PythonObject() 315 { 316 SetInteger(value); 317 } 318 319 320 PythonInteger::~PythonInteger () 321 { 322 } 323 324 bool 325 PythonInteger::Check(PyObject *py_obj) 326 { 327 if (!py_obj) 328 return false; 329 330 #if PY_MAJOR_VERSION >= 3 331 // Python 3 does not have PyInt_Check. There is only one type of 332 // integral value, long. 333 return PyLong_Check(py_obj); 334 #else 335 return PyLong_Check(py_obj) || PyInt_Check(py_obj); 336 #endif 337 } 338 339 void 340 PythonInteger::Reset(PyRefType type, PyObject *py_obj) 341 { 342 // Grab the desired reference type so that if we end up rejecting 343 // `py_obj` it still gets decremented if necessary. 344 PythonObject result(type, py_obj); 345 346 if (!PythonInteger::Check(py_obj)) 347 { 348 PythonObject::Reset(); 349 return; 350 } 351 352 #if PY_MAJOR_VERSION < 3 353 // Always store this as a PyLong, which makes interoperability between 354 // Python 2.x and Python 3.x easier. This is only necessary in 2.x, 355 // since 3.x doesn't even have a PyInt. 356 if (PyInt_Check(py_obj)) 357 { 358 // Since we converted the original object to a different type, the new 359 // object is an owned object regardless of the ownership semantics requested 360 // by the user. 361 result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj))); 362 } 363 #endif 364 365 assert(PyLong_Check(result.get()) && "Couldn't get a PyLong from this PyObject"); 366 367 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 368 // back into the virtual implementation. 369 PythonObject::Reset(PyRefType::Borrowed, result.get()); 370 } 371 372 int64_t 373 PythonInteger::GetInteger() const 374 { 375 if (m_py_obj) 376 { 377 assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong"); 378 379 return PyLong_AsLongLong(m_py_obj); 380 } 381 return UINT64_MAX; 382 } 383 384 void 385 PythonInteger::SetInteger(int64_t value) 386 { 387 PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value)); 388 } 389 390 StructuredData::IntegerSP 391 PythonInteger::CreateStructuredInteger() const 392 { 393 StructuredData::IntegerSP result(new StructuredData::Integer); 394 result->SetValue(GetInteger()); 395 return result; 396 } 397 398 //---------------------------------------------------------------------- 399 // PythonList 400 //---------------------------------------------------------------------- 401 402 PythonList::PythonList(PyInitialValue value) 403 : PythonObject() 404 { 405 if (value == PyInitialValue::Empty) 406 Reset(PyRefType::Owned, PyList_New(0)); 407 } 408 409 PythonList::PythonList(int list_size) 410 : PythonObject() 411 { 412 Reset(PyRefType::Owned, PyList_New(list_size)); 413 } 414 415 PythonList::PythonList(PyRefType type, PyObject *py_obj) 416 : PythonObject() 417 { 418 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list 419 } 420 421 PythonList::PythonList(const PythonList &list) 422 : PythonObject(list) 423 { 424 } 425 426 PythonList::~PythonList () 427 { 428 } 429 430 bool 431 PythonList::Check(PyObject *py_obj) 432 { 433 if (!py_obj) 434 return false; 435 return PyList_Check(py_obj); 436 } 437 438 void 439 PythonList::Reset(PyRefType type, PyObject *py_obj) 440 { 441 // Grab the desired reference type so that if we end up rejecting 442 // `py_obj` it still gets decremented if necessary. 443 PythonObject result(type, py_obj); 444 445 if (!PythonList::Check(py_obj)) 446 { 447 PythonObject::Reset(); 448 return; 449 } 450 451 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 452 // back into the virtual implementation. 453 PythonObject::Reset(PyRefType::Borrowed, result.get()); 454 } 455 456 uint32_t 457 PythonList::GetSize() const 458 { 459 if (IsValid()) 460 return PyList_GET_SIZE(m_py_obj); 461 return 0; 462 } 463 464 PythonObject 465 PythonList::GetItemAtIndex(uint32_t index) const 466 { 467 if (IsValid()) 468 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index)); 469 return PythonObject(); 470 } 471 472 void 473 PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) 474 { 475 if (IsAllocated() && object.IsValid()) 476 { 477 // PyList_SetItem is documented to "steal" a reference, so we need to 478 // convert it to an owned reference by incrementing it. 479 Py_INCREF(object.get()); 480 PyList_SetItem(m_py_obj, index, object.get()); 481 } 482 } 483 484 void 485 PythonList::AppendItem(const PythonObject &object) 486 { 487 if (IsAllocated() && object.IsValid()) 488 { 489 // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF` 490 // here like we do with `PyList_SetItem`. 491 PyList_Append(m_py_obj, object.get()); 492 } 493 } 494 495 StructuredData::ArraySP 496 PythonList::CreateStructuredArray() const 497 { 498 StructuredData::ArraySP result(new StructuredData::Array); 499 uint32_t count = GetSize(); 500 for (uint32_t i = 0; i < count; ++i) 501 { 502 PythonObject obj = GetItemAtIndex(i); 503 result->AddItem(obj.CreateStructuredObject()); 504 } 505 return result; 506 } 507 508 //---------------------------------------------------------------------- 509 // PythonDictionary 510 //---------------------------------------------------------------------- 511 512 PythonDictionary::PythonDictionary(PyInitialValue value) 513 : PythonObject() 514 { 515 if (value == PyInitialValue::Empty) 516 Reset(PyRefType::Owned, PyDict_New()); 517 } 518 519 PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj) 520 : PythonObject() 521 { 522 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary 523 } 524 525 PythonDictionary::PythonDictionary(const PythonDictionary &object) 526 : PythonObject(object) 527 { 528 } 529 530 PythonDictionary::~PythonDictionary () 531 { 532 } 533 534 bool 535 PythonDictionary::Check(PyObject *py_obj) 536 { 537 if (!py_obj) 538 return false; 539 540 return PyDict_Check(py_obj); 541 } 542 543 void 544 PythonDictionary::Reset(PyRefType type, PyObject *py_obj) 545 { 546 // Grab the desired reference type so that if we end up rejecting 547 // `py_obj` it still gets decremented if necessary. 548 PythonObject result(type, py_obj); 549 550 if (!PythonDictionary::Check(py_obj)) 551 { 552 PythonObject::Reset(); 553 return; 554 } 555 556 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 557 // back into the virtual implementation. 558 PythonObject::Reset(PyRefType::Borrowed, result.get()); 559 } 560 561 uint32_t 562 PythonDictionary::GetSize() const 563 { 564 if (IsValid()) 565 return PyDict_Size(m_py_obj); 566 return 0; 567 } 568 569 PythonList 570 PythonDictionary::GetKeys() const 571 { 572 if (IsValid()) 573 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj)); 574 return PythonList(PyInitialValue::Invalid); 575 } 576 577 PythonObject 578 PythonDictionary::GetItemForKey(const PythonObject &key) const 579 { 580 if (IsAllocated() && key.IsValid()) 581 return PythonObject(PyRefType::Borrowed, PyDict_GetItem(m_py_obj, key.get())); 582 return PythonObject(); 583 } 584 585 void 586 PythonDictionary::SetItemForKey(const PythonObject &key, const PythonObject &value) 587 { 588 if (IsAllocated() && key.IsValid() && value.IsValid()) 589 PyDict_SetItem(m_py_obj, key.get(), value.get()); 590 } 591 592 StructuredData::DictionarySP 593 PythonDictionary::CreateStructuredDictionary() const 594 { 595 StructuredData::DictionarySP result(new StructuredData::Dictionary); 596 PythonList keys(GetKeys()); 597 uint32_t num_keys = keys.GetSize(); 598 for (uint32_t i = 0; i < num_keys; ++i) 599 { 600 PythonObject key = keys.GetItemAtIndex(i); 601 PythonObject value = GetItemForKey(key); 602 StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 603 result->AddItem(key.Str().GetString(), structured_value); 604 } 605 return result; 606 } 607 608 PythonFile::PythonFile(File &file, const char *mode) 609 { 610 Reset(file, mode); 611 } 612 613 PythonFile::PythonFile(const char *path, const char *mode) 614 { 615 FILE *fp = nullptr; 616 fp = fopen(path, mode); 617 lldb_private::File file(fp, true); 618 Reset(file, mode); 619 } 620 621 PythonFile::PythonFile(PyRefType type, PyObject *o) 622 { 623 Reset(type, o); 624 } 625 626 PythonFile::~PythonFile() 627 { 628 } 629 630 bool 631 PythonFile::Check(PyObject *py_obj) 632 { 633 #if PY_MAJOR_VERSION < 3 634 return PyFile_Check(py_obj); 635 #else 636 // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a 637 // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper 638 // over `io.open()`, which returns some object derived from `io.IOBase`. 639 // As a result, the only way to detect a file in Python 3 is to check whether 640 // it inherits from `io.IOBase`. Since it is possible for non-files to also 641 // inherit from `io.IOBase`, we additionally verify that it has the `fileno` 642 // attribute, which should guarantee that it is backed by the file system. 643 PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io")); 644 PythonDictionary io_dict(PyRefType::Borrowed, PyModule_GetDict(io_module.get())); 645 PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase")); 646 647 PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj)); 648 649 if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get())) 650 return false; 651 if (!object_type.HasAttribute("fileno")) 652 return false; 653 654 return true; 655 #endif 656 } 657 658 void 659 PythonFile::Reset(PyRefType type, PyObject *py_obj) 660 { 661 // Grab the desired reference type so that if we end up rejecting 662 // `py_obj` it still gets decremented if necessary. 663 PythonObject result(type, py_obj); 664 665 if (!PythonFile::Check(py_obj)) 666 { 667 PythonObject::Reset(); 668 return; 669 } 670 671 // Calling PythonObject::Reset(const PythonObject&) will lead to stack 672 // overflow since it calls back into the virtual implementation. 673 PythonObject::Reset(PyRefType::Borrowed, result.get()); 674 } 675 676 void 677 PythonFile::Reset(File &file, const char *mode) 678 { 679 char *cmode = const_cast<char *>(mode); 680 #if PY_MAJOR_VERSION >= 3 681 Reset(PyRefType::Owned, 682 PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, -1, nullptr, "ignore", nullptr, 0)); 683 #else 684 // Read through the Python source, doesn't seem to modify these strings 685 Reset(PyRefType::Owned, 686 PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, nullptr)); 687 #endif 688 } 689 690 bool 691 PythonFile::GetUnderlyingFile(File &file) const 692 { 693 if (!IsValid()) 694 return false; 695 696 file.Close(); 697 // We don't own the file descriptor returned by this function, make sure the 698 // File object knows about that. 699 file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false); 700 return file.IsValid(); 701 } 702 703 704 #endif 705