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 return PyObjectType::Unknown; 79 } 80 81 PythonString 82 PythonObject::Repr() 83 { 84 if (!m_py_obj) 85 return PythonString(); 86 PyObject *repr = PyObject_Repr(m_py_obj); 87 if (!repr) 88 return PythonString(); 89 return PythonString(PyRefType::Owned, repr); 90 } 91 92 PythonString 93 PythonObject::Str() 94 { 95 if (!m_py_obj) 96 return PythonString(); 97 PyObject *str = PyObject_Str(m_py_obj); 98 if (!str) 99 return PythonString(); 100 return PythonString(PyRefType::Owned, str); 101 } 102 103 bool 104 PythonObject::IsNone() const 105 { 106 return m_py_obj == Py_None; 107 } 108 109 bool 110 PythonObject::IsValid() const 111 { 112 return m_py_obj != nullptr; 113 } 114 115 bool 116 PythonObject::IsAllocated() const 117 { 118 return IsValid() && !IsNone(); 119 } 120 121 StructuredData::ObjectSP 122 PythonObject::CreateStructuredObject() const 123 { 124 switch (GetObjectType()) 125 { 126 case PyObjectType::Dictionary: 127 return PythonDictionary(PyRefType::Borrowed, m_py_obj).CreateStructuredDictionary(); 128 case PyObjectType::Integer: 129 return PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger(); 130 case PyObjectType::List: 131 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); 132 case PyObjectType::String: 133 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 134 case PyObjectType::None: 135 return StructuredData::ObjectSP(); 136 default: 137 return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); 138 } 139 } 140 141 //---------------------------------------------------------------------- 142 // PythonString 143 //---------------------------------------------------------------------- 144 145 PythonString::PythonString(PyRefType type, PyObject *py_obj) 146 : PythonObject() 147 { 148 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string 149 } 150 151 PythonString::PythonString(const PythonString &object) 152 : PythonObject(object) 153 { 154 } 155 156 PythonString::PythonString(llvm::StringRef string) 157 : PythonObject() 158 { 159 SetString(string); 160 } 161 162 PythonString::PythonString(const char *string) 163 : PythonObject() 164 { 165 SetString(llvm::StringRef(string)); 166 } 167 168 PythonString::PythonString() 169 : PythonObject() 170 { 171 } 172 173 PythonString::~PythonString () 174 { 175 } 176 177 bool 178 PythonString::Check(PyObject *py_obj) 179 { 180 if (!py_obj) 181 return false; 182 183 #if PY_MAJOR_VERSION >= 3 184 return PyUnicode_Check(py_obj); 185 #else 186 return PyString_Check(py_obj); 187 #endif 188 } 189 190 void 191 PythonString::Reset(PyRefType type, PyObject *py_obj) 192 { 193 // Grab the desired reference type so that if we end up rejecting 194 // `py_obj` it still gets decremented if necessary. 195 PythonObject result(type, py_obj); 196 197 if (!PythonString::Check(py_obj)) 198 { 199 PythonObject::Reset(); 200 return; 201 } 202 203 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 204 // back into the virtual implementation. 205 PythonObject::Reset(PyRefType::Borrowed, result.get()); 206 } 207 208 llvm::StringRef 209 PythonString::GetString() const 210 { 211 if (!IsValid()) 212 return llvm::StringRef(); 213 214 Py_ssize_t size; 215 char *c; 216 217 #if PY_MAJOR_VERSION >= 3 218 c = PyUnicode_AsUTF8AndSize(m_py_obj, &size); 219 #else 220 PyString_AsStringAndSize(m_py_obj, &c, &size); 221 #endif 222 return llvm::StringRef(c, size); 223 } 224 225 size_t 226 PythonString::GetSize() const 227 { 228 if (IsValid()) 229 { 230 #if PY_MAJOR_VERSION >= 3 231 return PyUnicode_GetSize(m_py_obj); 232 #else 233 return PyString_Size(m_py_obj); 234 #endif 235 } 236 return 0; 237 } 238 239 void 240 PythonString::SetString (llvm::StringRef string) 241 { 242 #if PY_MAJOR_VERSION >= 3 243 PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size()); 244 PythonObject::Reset(PyRefType::Owned, unicode); 245 #else 246 PyObject *str = PyString_FromStringAndSize(string.data(), string.size()); 247 PythonObject::Reset(PyRefType::Owned, str); 248 #endif 249 } 250 251 StructuredData::StringSP 252 PythonString::CreateStructuredString() const 253 { 254 StructuredData::StringSP result(new StructuredData::String); 255 result->SetValue(GetString()); 256 return result; 257 } 258 259 //---------------------------------------------------------------------- 260 // PythonInteger 261 //---------------------------------------------------------------------- 262 263 PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj) 264 : PythonObject() 265 { 266 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type 267 } 268 269 PythonInteger::PythonInteger(const PythonInteger &object) 270 : PythonObject(object) 271 { 272 } 273 274 PythonInteger::PythonInteger(int64_t value) 275 : PythonObject() 276 { 277 SetInteger(value); 278 } 279 280 281 PythonInteger::~PythonInteger () 282 { 283 } 284 285 bool 286 PythonInteger::Check(PyObject *py_obj) 287 { 288 if (!py_obj) 289 return false; 290 291 #if PY_MAJOR_VERSION >= 3 292 // Python 3 does not have PyInt_Check. There is only one type of 293 // integral value, long. 294 return PyLong_Check(py_obj); 295 #else 296 return PyLong_Check(py_obj) || PyInt_Check(py_obj); 297 #endif 298 } 299 300 void 301 PythonInteger::Reset(PyRefType type, PyObject *py_obj) 302 { 303 // Grab the desired reference type so that if we end up rejecting 304 // `py_obj` it still gets decremented if necessary. 305 PythonObject result(type, py_obj); 306 307 if (!PythonInteger::Check(py_obj)) 308 { 309 PythonObject::Reset(); 310 return; 311 } 312 313 #if PY_MAJOR_VERSION < 3 314 // Always store this as a PyLong, which makes interoperability between 315 // Python 2.x and Python 3.x easier. This is only necessary in 2.x, 316 // since 3.x doesn't even have a PyInt. 317 if (PyInt_Check(py_obj)) 318 { 319 // Since we converted the original object to a different type, the new 320 // object is an owned object regardless of the ownership semantics requested 321 // by the user. 322 result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj))); 323 } 324 #endif 325 326 assert(PyLong_Check(result.get()) && "Couldn't get a PyLong from this PyObject"); 327 328 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 329 // back into the virtual implementation. 330 PythonObject::Reset(PyRefType::Borrowed, result.get()); 331 } 332 333 int64_t 334 PythonInteger::GetInteger() const 335 { 336 if (m_py_obj) 337 { 338 assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong"); 339 340 return PyLong_AsLongLong(m_py_obj); 341 } 342 return UINT64_MAX; 343 } 344 345 void 346 PythonInteger::SetInteger(int64_t value) 347 { 348 PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value)); 349 } 350 351 StructuredData::IntegerSP 352 PythonInteger::CreateStructuredInteger() const 353 { 354 StructuredData::IntegerSP result(new StructuredData::Integer); 355 result->SetValue(GetInteger()); 356 return result; 357 } 358 359 //---------------------------------------------------------------------- 360 // PythonList 361 //---------------------------------------------------------------------- 362 363 PythonList::PythonList(PyInitialValue value) 364 : PythonObject() 365 { 366 if (value == PyInitialValue::Empty) 367 Reset(PyRefType::Owned, PyList_New(0)); 368 } 369 370 PythonList::PythonList(int list_size) 371 : PythonObject() 372 { 373 Reset(PyRefType::Owned, PyList_New(list_size)); 374 } 375 376 PythonList::PythonList(PyRefType type, PyObject *py_obj) 377 : PythonObject() 378 { 379 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list 380 } 381 382 PythonList::PythonList(const PythonList &list) 383 : PythonObject(list) 384 { 385 } 386 387 PythonList::~PythonList () 388 { 389 } 390 391 bool 392 PythonList::Check(PyObject *py_obj) 393 { 394 if (!py_obj) 395 return false; 396 return PyList_Check(py_obj); 397 } 398 399 void 400 PythonList::Reset(PyRefType type, PyObject *py_obj) 401 { 402 // Grab the desired reference type so that if we end up rejecting 403 // `py_obj` it still gets decremented if necessary. 404 PythonObject result(type, py_obj); 405 406 if (!PythonList::Check(py_obj)) 407 { 408 PythonObject::Reset(); 409 return; 410 } 411 412 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 413 // back into the virtual implementation. 414 PythonObject::Reset(PyRefType::Borrowed, result.get()); 415 } 416 417 uint32_t 418 PythonList::GetSize() const 419 { 420 if (IsValid()) 421 return PyList_GET_SIZE(m_py_obj); 422 return 0; 423 } 424 425 PythonObject 426 PythonList::GetItemAtIndex(uint32_t index) const 427 { 428 if (IsValid()) 429 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index)); 430 return PythonObject(); 431 } 432 433 void 434 PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) 435 { 436 if (IsAllocated() && object.IsValid()) 437 { 438 // PyList_SetItem is documented to "steal" a reference, so we need to 439 // convert it to an owned reference by incrementing it. 440 Py_INCREF(object.get()); 441 PyList_SetItem(m_py_obj, index, object.get()); 442 } 443 } 444 445 void 446 PythonList::AppendItem(const PythonObject &object) 447 { 448 if (IsAllocated() && object.IsValid()) 449 { 450 // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF` 451 // here like we do with `PyList_SetItem`. 452 PyList_Append(m_py_obj, object.get()); 453 } 454 } 455 456 StructuredData::ArraySP 457 PythonList::CreateStructuredArray() const 458 { 459 StructuredData::ArraySP result(new StructuredData::Array); 460 uint32_t count = GetSize(); 461 for (uint32_t i = 0; i < count; ++i) 462 { 463 PythonObject obj = GetItemAtIndex(i); 464 result->AddItem(obj.CreateStructuredObject()); 465 } 466 return result; 467 } 468 469 //---------------------------------------------------------------------- 470 // PythonDictionary 471 //---------------------------------------------------------------------- 472 473 PythonDictionary::PythonDictionary(PyInitialValue value) 474 : PythonObject() 475 { 476 if (value == PyInitialValue::Empty) 477 Reset(PyRefType::Owned, PyDict_New()); 478 } 479 480 PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj) 481 : PythonObject() 482 { 483 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary 484 } 485 486 PythonDictionary::PythonDictionary(const PythonDictionary &object) 487 : PythonObject(object) 488 { 489 } 490 491 PythonDictionary::~PythonDictionary () 492 { 493 } 494 495 bool 496 PythonDictionary::Check(PyObject *py_obj) 497 { 498 if (!py_obj) 499 return false; 500 501 return PyDict_Check(py_obj); 502 } 503 504 void 505 PythonDictionary::Reset(PyRefType type, PyObject *py_obj) 506 { 507 // Grab the desired reference type so that if we end up rejecting 508 // `py_obj` it still gets decremented if necessary. 509 PythonObject result(type, py_obj); 510 511 if (!PythonDictionary::Check(py_obj)) 512 { 513 PythonObject::Reset(); 514 return; 515 } 516 517 // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls 518 // back into the virtual implementation. 519 PythonObject::Reset(PyRefType::Borrowed, result.get()); 520 } 521 522 uint32_t 523 PythonDictionary::GetSize() const 524 { 525 if (IsValid()) 526 return PyDict_Size(m_py_obj); 527 return 0; 528 } 529 530 PythonList 531 PythonDictionary::GetKeys() const 532 { 533 if (IsValid()) 534 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj)); 535 return PythonList(PyInitialValue::Invalid); 536 } 537 538 PythonObject 539 PythonDictionary::GetItemForKey(const PythonObject &key) const 540 { 541 if (IsAllocated() && key.IsValid()) 542 return PythonObject(PyRefType::Borrowed, PyDict_GetItem(m_py_obj, key.get())); 543 return PythonObject(); 544 } 545 546 void 547 PythonDictionary::SetItemForKey(const PythonObject &key, const PythonObject &value) 548 { 549 if (IsAllocated() && key.IsValid() && value.IsValid()) 550 PyDict_SetItem(m_py_obj, key.get(), value.get()); 551 } 552 553 StructuredData::DictionarySP 554 PythonDictionary::CreateStructuredDictionary() const 555 { 556 StructuredData::DictionarySP result(new StructuredData::Dictionary); 557 PythonList keys(GetKeys()); 558 uint32_t num_keys = keys.GetSize(); 559 for (uint32_t i = 0; i < num_keys; ++i) 560 { 561 PythonObject key = keys.GetItemAtIndex(i); 562 PythonObject value = GetItemForKey(key); 563 StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 564 result->AddItem(key.Str().GetString(), structured_value); 565 } 566 return result; 567 } 568 569 #endif 570