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 bool 115 PythonObject::IsNone() const 116 { 117 return m_py_obj == Py_None; 118 } 119 120 bool 121 PythonObject::IsValid() const 122 { 123 return m_py_obj != nullptr; 124 } 125 126 bool 127 PythonObject::IsAllocated() const 128 { 129 return IsValid() && !IsNone(); 130 } 131 132 StructuredData::ObjectSP 133 PythonObject::CreateStructuredObject() const 134 { 135 switch (GetObjectType()) 136 { 137 case PyObjectType::Dictionary: 138 return PythonDictionary(PyRefType::Borrowed, m_py_obj).CreateStructuredDictionary(); 139 case PyObjectType::Integer: 140 return PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger(); 141 case PyObjectType::List: 142 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); 143 case PyObjectType::String: 144 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 145 case PyObjectType::None: 146 return StructuredData::ObjectSP(); 147 default: 148 return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); 149 } 150 } 151 152 //---------------------------------------------------------------------- 153 // PythonString 154 //---------------------------------------------------------------------- 155 156 PythonString::PythonString(PyRefType type, PyObject *py_obj) 157 : PythonObject() 158 { 159 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string 160 } 161 162 PythonString::PythonString(const PythonString &object) 163 : PythonObject(object) 164 { 165 } 166 167 PythonString::PythonString(llvm::StringRef string) 168 : PythonObject() 169 { 170 SetString(string); 171 } 172 173 PythonString::PythonString(const char *string) 174 : PythonObject() 175 { 176 SetString(llvm::StringRef(string)); 177 } 178 179 PythonString::PythonString() 180 : PythonObject() 181 { 182 } 183 184 PythonString::~PythonString () 185 { 186 } 187 188 bool 189 PythonString::Check(PyObject *py_obj) 190 { 191 if (!py_obj) 192 return false; 193 194 #if PY_MAJOR_VERSION >= 3 195 return PyUnicode_Check(py_obj); 196 #else 197 return PyString_Check(py_obj); 198 #endif 199 } 200 201 void 202 PythonString::Reset(PyRefType type, PyObject *py_obj) 203 { 204 // Grab the desired reference type so that if we end up rejecting 205 // `py_obj` it still gets decremented if necessary. 206 PythonObject result(type, py_obj); 207 208 if (!PythonString::Check(py_obj)) 209 { 210 PythonObject::Reset(); 211 return; 212 } 213 214 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 215 // back into the virtual implementation. 216 PythonObject::Reset(PyRefType::Borrowed, result.get()); 217 } 218 219 llvm::StringRef 220 PythonString::GetString() const 221 { 222 if (!IsValid()) 223 return llvm::StringRef(); 224 225 Py_ssize_t size; 226 char *c; 227 228 #if PY_MAJOR_VERSION >= 3 229 c = PyUnicode_AsUTF8AndSize(m_py_obj, &size); 230 #else 231 PyString_AsStringAndSize(m_py_obj, &c, &size); 232 #endif 233 return llvm::StringRef(c, size); 234 } 235 236 size_t 237 PythonString::GetSize() const 238 { 239 if (IsValid()) 240 { 241 #if PY_MAJOR_VERSION >= 3 242 return PyUnicode_GetSize(m_py_obj); 243 #else 244 return PyString_Size(m_py_obj); 245 #endif 246 } 247 return 0; 248 } 249 250 void 251 PythonString::SetString (llvm::StringRef string) 252 { 253 #if PY_MAJOR_VERSION >= 3 254 PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size()); 255 PythonObject::Reset(PyRefType::Owned, unicode); 256 #else 257 PyObject *str = PyString_FromStringAndSize(string.data(), string.size()); 258 PythonObject::Reset(PyRefType::Owned, str); 259 #endif 260 } 261 262 StructuredData::StringSP 263 PythonString::CreateStructuredString() const 264 { 265 StructuredData::StringSP result(new StructuredData::String); 266 result->SetValue(GetString()); 267 return result; 268 } 269 270 //---------------------------------------------------------------------- 271 // PythonInteger 272 //---------------------------------------------------------------------- 273 274 PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj) 275 : PythonObject() 276 { 277 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type 278 } 279 280 PythonInteger::PythonInteger(const PythonInteger &object) 281 : PythonObject(object) 282 { 283 } 284 285 PythonInteger::PythonInteger(int64_t value) 286 : PythonObject() 287 { 288 SetInteger(value); 289 } 290 291 292 PythonInteger::~PythonInteger () 293 { 294 } 295 296 bool 297 PythonInteger::Check(PyObject *py_obj) 298 { 299 if (!py_obj) 300 return false; 301 302 #if PY_MAJOR_VERSION >= 3 303 // Python 3 does not have PyInt_Check. There is only one type of 304 // integral value, long. 305 return PyLong_Check(py_obj); 306 #else 307 return PyLong_Check(py_obj) || PyInt_Check(py_obj); 308 #endif 309 } 310 311 void 312 PythonInteger::Reset(PyRefType type, PyObject *py_obj) 313 { 314 // Grab the desired reference type so that if we end up rejecting 315 // `py_obj` it still gets decremented if necessary. 316 PythonObject result(type, py_obj); 317 318 if (!PythonInteger::Check(py_obj)) 319 { 320 PythonObject::Reset(); 321 return; 322 } 323 324 #if PY_MAJOR_VERSION < 3 325 // Always store this as a PyLong, which makes interoperability between 326 // Python 2.x and Python 3.x easier. This is only necessary in 2.x, 327 // since 3.x doesn't even have a PyInt. 328 if (PyInt_Check(py_obj)) 329 { 330 // Since we converted the original object to a different type, the new 331 // object is an owned object regardless of the ownership semantics requested 332 // by the user. 333 result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj))); 334 } 335 #endif 336 337 assert(PyLong_Check(result.get()) && "Couldn't get a PyLong from this PyObject"); 338 339 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 340 // back into the virtual implementation. 341 PythonObject::Reset(PyRefType::Borrowed, result.get()); 342 } 343 344 int64_t 345 PythonInteger::GetInteger() const 346 { 347 if (m_py_obj) 348 { 349 assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong"); 350 351 return PyLong_AsLongLong(m_py_obj); 352 } 353 return UINT64_MAX; 354 } 355 356 void 357 PythonInteger::SetInteger(int64_t value) 358 { 359 PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value)); 360 } 361 362 StructuredData::IntegerSP 363 PythonInteger::CreateStructuredInteger() const 364 { 365 StructuredData::IntegerSP result(new StructuredData::Integer); 366 result->SetValue(GetInteger()); 367 return result; 368 } 369 370 //---------------------------------------------------------------------- 371 // PythonList 372 //---------------------------------------------------------------------- 373 374 PythonList::PythonList(PyInitialValue value) 375 : PythonObject() 376 { 377 if (value == PyInitialValue::Empty) 378 Reset(PyRefType::Owned, PyList_New(0)); 379 } 380 381 PythonList::PythonList(int list_size) 382 : PythonObject() 383 { 384 Reset(PyRefType::Owned, PyList_New(list_size)); 385 } 386 387 PythonList::PythonList(PyRefType type, PyObject *py_obj) 388 : PythonObject() 389 { 390 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list 391 } 392 393 PythonList::PythonList(const PythonList &list) 394 : PythonObject(list) 395 { 396 } 397 398 PythonList::~PythonList () 399 { 400 } 401 402 bool 403 PythonList::Check(PyObject *py_obj) 404 { 405 if (!py_obj) 406 return false; 407 return PyList_Check(py_obj); 408 } 409 410 void 411 PythonList::Reset(PyRefType type, PyObject *py_obj) 412 { 413 // Grab the desired reference type so that if we end up rejecting 414 // `py_obj` it still gets decremented if necessary. 415 PythonObject result(type, py_obj); 416 417 if (!PythonList::Check(py_obj)) 418 { 419 PythonObject::Reset(); 420 return; 421 } 422 423 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 424 // back into the virtual implementation. 425 PythonObject::Reset(PyRefType::Borrowed, result.get()); 426 } 427 428 uint32_t 429 PythonList::GetSize() const 430 { 431 if (IsValid()) 432 return PyList_GET_SIZE(m_py_obj); 433 return 0; 434 } 435 436 PythonObject 437 PythonList::GetItemAtIndex(uint32_t index) const 438 { 439 if (IsValid()) 440 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index)); 441 return PythonObject(); 442 } 443 444 void 445 PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) 446 { 447 if (IsAllocated() && object.IsValid()) 448 { 449 // PyList_SetItem is documented to "steal" a reference, so we need to 450 // convert it to an owned reference by incrementing it. 451 Py_INCREF(object.get()); 452 PyList_SetItem(m_py_obj, index, object.get()); 453 } 454 } 455 456 void 457 PythonList::AppendItem(const PythonObject &object) 458 { 459 if (IsAllocated() && object.IsValid()) 460 { 461 // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF` 462 // here like we do with `PyList_SetItem`. 463 PyList_Append(m_py_obj, object.get()); 464 } 465 } 466 467 StructuredData::ArraySP 468 PythonList::CreateStructuredArray() const 469 { 470 StructuredData::ArraySP result(new StructuredData::Array); 471 uint32_t count = GetSize(); 472 for (uint32_t i = 0; i < count; ++i) 473 { 474 PythonObject obj = GetItemAtIndex(i); 475 result->AddItem(obj.CreateStructuredObject()); 476 } 477 return result; 478 } 479 480 //---------------------------------------------------------------------- 481 // PythonDictionary 482 //---------------------------------------------------------------------- 483 484 PythonDictionary::PythonDictionary(PyInitialValue value) 485 : PythonObject() 486 { 487 if (value == PyInitialValue::Empty) 488 Reset(PyRefType::Owned, PyDict_New()); 489 } 490 491 PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj) 492 : PythonObject() 493 { 494 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary 495 } 496 497 PythonDictionary::PythonDictionary(const PythonDictionary &object) 498 : PythonObject(object) 499 { 500 } 501 502 PythonDictionary::~PythonDictionary () 503 { 504 } 505 506 bool 507 PythonDictionary::Check(PyObject *py_obj) 508 { 509 if (!py_obj) 510 return false; 511 512 return PyDict_Check(py_obj); 513 } 514 515 void 516 PythonDictionary::Reset(PyRefType type, PyObject *py_obj) 517 { 518 // Grab the desired reference type so that if we end up rejecting 519 // `py_obj` it still gets decremented if necessary. 520 PythonObject result(type, py_obj); 521 522 if (!PythonDictionary::Check(py_obj)) 523 { 524 PythonObject::Reset(); 525 return; 526 } 527 528 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 529 // back into the virtual implementation. 530 PythonObject::Reset(PyRefType::Borrowed, result.get()); 531 } 532 533 uint32_t 534 PythonDictionary::GetSize() const 535 { 536 if (IsValid()) 537 return PyDict_Size(m_py_obj); 538 return 0; 539 } 540 541 PythonList 542 PythonDictionary::GetKeys() const 543 { 544 if (IsValid()) 545 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj)); 546 return PythonList(PyInitialValue::Invalid); 547 } 548 549 PythonObject 550 PythonDictionary::GetItemForKey(const PythonObject &key) const 551 { 552 if (IsAllocated() && key.IsValid()) 553 return PythonObject(PyRefType::Borrowed, PyDict_GetItem(m_py_obj, key.get())); 554 return PythonObject(); 555 } 556 557 void 558 PythonDictionary::SetItemForKey(const PythonObject &key, const PythonObject &value) 559 { 560 if (IsAllocated() && key.IsValid() && value.IsValid()) 561 PyDict_SetItem(m_py_obj, key.get(), value.get()); 562 } 563 564 StructuredData::DictionarySP 565 PythonDictionary::CreateStructuredDictionary() const 566 { 567 StructuredData::DictionarySP result(new StructuredData::Dictionary); 568 PythonList keys(GetKeys()); 569 uint32_t num_keys = keys.GetSize(); 570 for (uint32_t i = 0; i < num_keys; ++i) 571 { 572 PythonObject key = keys.GetItemAtIndex(i); 573 PythonObject value = GetItemForKey(key); 574 StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 575 result->AddItem(key.Str().GetString(), structured_value); 576 } 577 return result; 578 } 579 580 PythonFile::PythonFile(File &file, const char *mode) 581 { 582 Reset(file, mode); 583 } 584 585 PythonFile::PythonFile(PyRefType type, PyObject *o) 586 { 587 Reset(type, o); 588 } 589 590 PythonFile::~PythonFile() 591 { 592 } 593 594 bool 595 PythonFile::Check(PyObject *py_obj) 596 { 597 #if PY_MAJOR_VERSION < 3 598 return PyFile_Check(py_obj); 599 #else 600 // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a 601 // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper 602 // over `io.open()`, which returns some object derived from `io.IOBase`. 603 // As a result, the only way to detect a file in Python 3 is to check whether 604 // it inherits from `io.IOBase`. Since it is possible for non-files to also 605 // inherit from `io.IOBase`, we additionally verify that it has the `fileno` 606 // attribute, which should guarantee that it is backed by the file system. 607 PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io")); 608 PythonDictionary io_dict(PyRefType::Borrowed, PyModule_GetDict(io_module.get())); 609 PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase")); 610 611 PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj)); 612 613 if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get())) 614 return false; 615 if (!object_type.HasAttribute("fileno")) 616 return false; 617 618 return true; 619 #endif 620 } 621 622 void 623 PythonFile::Reset(PyRefType type, PyObject *py_obj) 624 { 625 // Grab the desired reference type so that if we end up rejecting 626 // `py_obj` it still gets decremented if necessary. 627 PythonObject result(type, py_obj); 628 629 if (!PythonFile::Check(py_obj)) 630 { 631 PythonObject::Reset(); 632 return; 633 } 634 635 // Calling PythonObject::Reset(const PythonObject&) will lead to stack 636 // overflow since it calls back into the virtual implementation. 637 PythonObject::Reset(PyRefType::Borrowed, result.get()); 638 } 639 640 void 641 PythonFile::Reset(File &file, const char *mode) 642 { 643 char *cmode = const_cast<char *>(mode); 644 #if PY_MAJOR_VERSION >= 3 645 Reset(PyRefType::Owned, 646 PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, -1, nullptr, "ignore", nullptr, 0)); 647 #else 648 // Read through the Python source, doesn't seem to modify these strings 649 Reset(PyRefType::Owned, 650 PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, nullptr)); 651 #endif 652 } 653 654 #endif 655