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 (IsNULLOrNone()) 68 return PyObjectType::None; 69 70 if (PyList_Check(m_py_obj)) 71 return PyObjectType::List; 72 if (PyDict_Check(m_py_obj)) 73 return PyObjectType::Dictionary; 74 if (PyString_Check(m_py_obj)) 75 return PyObjectType::String; 76 if (PyInt_Check(m_py_obj) || PyLong_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(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(str); 101 } 102 103 bool 104 PythonObject::IsNULLOrNone () const 105 { 106 return ((m_py_obj == nullptr) || (m_py_obj == Py_None)); 107 } 108 109 StructuredData::ObjectSP 110 PythonObject::CreateStructuredObject() const 111 { 112 switch (GetObjectType()) 113 { 114 case PyObjectType::Dictionary: 115 return PythonDictionary(m_py_obj).CreateStructuredDictionary(); 116 case PyObjectType::Integer: 117 return PythonInteger(m_py_obj).CreateStructuredInteger(); 118 case PyObjectType::List: 119 return PythonList(m_py_obj).CreateStructuredArray(); 120 case PyObjectType::String: 121 return PythonString(m_py_obj).CreateStructuredString(); 122 case PyObjectType::None: 123 return StructuredData::ObjectSP(); 124 default: 125 return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); 126 } 127 } 128 129 //---------------------------------------------------------------------- 130 // PythonString 131 //---------------------------------------------------------------------- 132 133 PythonString::PythonString (PyObject *py_obj) : 134 PythonObject() 135 { 136 Reset(py_obj); // Use "Reset()" to ensure that py_obj is a string 137 } 138 139 PythonString::PythonString (const PythonObject &object) : 140 PythonObject() 141 { 142 Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string 143 } 144 145 PythonString::PythonString (llvm::StringRef string) : 146 PythonObject(PyString_FromStringAndSize(string.data(), string.size())) 147 { 148 } 149 150 PythonString::PythonString(const char *string) : 151 PythonObject(PyString_FromString(string)) 152 { 153 } 154 155 PythonString::PythonString () : 156 PythonObject() 157 { 158 } 159 160 PythonString::~PythonString () 161 { 162 } 163 164 bool 165 PythonString::Reset (PyObject *py_obj) 166 { 167 if (py_obj && PyString_Check(py_obj)) 168 return PythonObject::Reset(py_obj); 169 170 PythonObject::Reset(nullptr); 171 return py_obj == nullptr; 172 } 173 174 llvm::StringRef 175 PythonString::GetString() const 176 { 177 if (m_py_obj) 178 return llvm::StringRef(PyString_AsString(m_py_obj), GetSize()); 179 return llvm::StringRef(); 180 } 181 182 size_t 183 PythonString::GetSize() const 184 { 185 if (m_py_obj) 186 return PyString_Size(m_py_obj); 187 return 0; 188 } 189 190 void 191 PythonString::SetString (llvm::StringRef string) 192 { 193 PythonObject::Reset(PyString_FromStringAndSize(string.data(), string.size())); 194 } 195 196 StructuredData::StringSP 197 PythonString::CreateStructuredString() const 198 { 199 StructuredData::StringSP result(new StructuredData::String); 200 result->SetValue(GetString()); 201 return result; 202 } 203 204 //---------------------------------------------------------------------- 205 // PythonInteger 206 //---------------------------------------------------------------------- 207 208 PythonInteger::PythonInteger (PyObject *py_obj) : 209 PythonObject() 210 { 211 Reset(py_obj); // Use "Reset()" to ensure that py_obj is a integer type 212 } 213 214 PythonInteger::PythonInteger (const PythonObject &object) : 215 PythonObject() 216 { 217 Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type 218 } 219 220 PythonInteger::PythonInteger (int64_t value) : 221 PythonObject() 222 { 223 SetInteger (value); 224 } 225 226 227 PythonInteger::~PythonInteger () 228 { 229 } 230 231 bool 232 PythonInteger::Reset (PyObject *py_obj) 233 { 234 if (py_obj) 235 { 236 if (PyInt_Check (py_obj) || PyLong_Check(py_obj)) 237 return PythonObject::Reset(py_obj); 238 } 239 240 PythonObject::Reset(nullptr); 241 return py_obj == nullptr; 242 } 243 244 int64_t 245 PythonInteger::GetInteger() const 246 { 247 if (m_py_obj) 248 { 249 if (PyInt_Check(m_py_obj)) 250 return PyInt_AsLong(m_py_obj); 251 else if (PyLong_Check(m_py_obj)) 252 return PyLong_AsLongLong(m_py_obj); 253 } 254 return UINT64_MAX; 255 } 256 257 void 258 PythonInteger::SetInteger (int64_t value) 259 { 260 PythonObject::Reset(PyLong_FromLongLong(value)); 261 } 262 263 StructuredData::IntegerSP 264 PythonInteger::CreateStructuredInteger() const 265 { 266 StructuredData::IntegerSP result(new StructuredData::Integer); 267 result->SetValue(GetInteger()); 268 return result; 269 } 270 271 //---------------------------------------------------------------------- 272 // PythonList 273 //---------------------------------------------------------------------- 274 275 PythonList::PythonList (bool create_empty) : 276 PythonObject(create_empty ? PyList_New(0) : nullptr) 277 { 278 } 279 280 PythonList::PythonList (uint32_t count) : 281 PythonObject(PyList_New(count)) 282 { 283 } 284 285 PythonList::PythonList (PyObject *py_obj) : 286 PythonObject() 287 { 288 Reset(py_obj); // Use "Reset()" to ensure that py_obj is a list 289 } 290 291 292 PythonList::PythonList (const PythonObject &object) : 293 PythonObject() 294 { 295 Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list 296 } 297 298 PythonList::~PythonList () 299 { 300 } 301 302 bool 303 PythonList::Reset (PyObject *py_obj) 304 { 305 if (py_obj && PyList_Check(py_obj)) 306 return PythonObject::Reset(py_obj); 307 308 PythonObject::Reset(nullptr); 309 return py_obj == nullptr; 310 } 311 312 uint32_t 313 PythonList::GetSize() const 314 { 315 if (m_py_obj) 316 return PyList_GET_SIZE(m_py_obj); 317 return 0; 318 } 319 320 PythonObject 321 PythonList::GetItemAtIndex(uint32_t index) const 322 { 323 if (m_py_obj) 324 return PythonObject(PyList_GetItem(m_py_obj, index)); 325 return PythonObject(); 326 } 327 328 void 329 PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object) 330 { 331 if (m_py_obj && object) 332 PyList_SetItem(m_py_obj, index, object.get()); 333 } 334 335 void 336 PythonList::AppendItem (const PythonObject &object) 337 { 338 if (m_py_obj && object) 339 PyList_Append(m_py_obj, object.get()); 340 } 341 342 StructuredData::ArraySP 343 PythonList::CreateStructuredArray() const 344 { 345 StructuredData::ArraySP result(new StructuredData::Array); 346 uint32_t count = GetSize(); 347 for (uint32_t i = 0; i < count; ++i) 348 { 349 PythonObject obj = GetItemAtIndex(i); 350 result->AddItem(obj.CreateStructuredObject()); 351 } 352 return result; 353 } 354 355 //---------------------------------------------------------------------- 356 // PythonDictionary 357 //---------------------------------------------------------------------- 358 359 PythonDictionary::PythonDictionary (bool create_empty) : 360 PythonObject(create_empty ? PyDict_New() : nullptr) 361 { 362 } 363 364 PythonDictionary::PythonDictionary (PyObject *py_obj) : 365 PythonObject(py_obj) 366 { 367 Reset(py_obj); // Use "Reset()" to ensure that py_obj is a dictionary 368 } 369 370 371 PythonDictionary::PythonDictionary (const PythonObject &object) : 372 PythonObject() 373 { 374 Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary 375 } 376 377 PythonDictionary::~PythonDictionary () 378 { 379 } 380 381 bool 382 PythonDictionary::Reset (PyObject *py_obj) 383 { 384 if (py_obj && PyDict_Check(py_obj)) 385 return PythonObject::Reset(py_obj); 386 387 PythonObject::Reset(nullptr); 388 return py_obj == nullptr; 389 } 390 391 uint32_t 392 PythonDictionary::GetSize() const 393 { 394 if (m_py_obj) 395 return PyDict_Size(m_py_obj); 396 return 0; 397 } 398 399 PythonObject 400 PythonDictionary::GetItemForKey (const char *key) const 401 { 402 if (key && key[0]) 403 { 404 PythonString python_key(key); 405 return GetItemForKey(python_key); 406 } 407 return PythonObject(); 408 } 409 410 411 PythonObject 412 PythonDictionary::GetItemForKey (const PythonString &key) const 413 { 414 if (m_py_obj && key) 415 return PythonObject(PyDict_GetItem(m_py_obj, key.get())); 416 return PythonObject(); 417 } 418 419 420 const char * 421 PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const 422 { 423 if (m_py_obj && key) 424 { 425 PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get()); 426 if (py_obj && PyString_Check(py_obj)) 427 return PyString_AsString(py_obj); 428 } 429 return fail_value; 430 } 431 432 int64_t 433 PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const 434 { 435 if (m_py_obj && key) 436 { 437 PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get()); 438 if (py_obj) 439 { 440 if (PyInt_Check(py_obj)) 441 return PyInt_AsLong(py_obj); 442 443 if (PyLong_Check(py_obj)) 444 return PyLong_AsLong(py_obj); 445 } 446 } 447 return fail_value; 448 } 449 450 PythonList 451 PythonDictionary::GetKeys () const 452 { 453 if (m_py_obj) 454 return PythonList(PyDict_Keys(m_py_obj)); 455 return PythonList(true); 456 } 457 458 PythonString 459 PythonDictionary::GetKeyAtPosition (uint32_t pos) const 460 { 461 PyObject *key, *value; 462 Py_ssize_t pos_iter = 0; 463 464 if (m_py_obj) 465 { 466 while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) 467 { 468 if (pos-- == 0) 469 return PythonString(key); 470 } 471 } 472 return PythonString(); 473 } 474 475 PythonObject 476 PythonDictionary::GetValueAtPosition (uint32_t pos) const 477 { 478 PyObject *key, *value; 479 Py_ssize_t pos_iter = 0; 480 481 if (!m_py_obj) 482 return PythonObject(); 483 484 while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) { 485 if (pos-- == 0) 486 return PythonObject(value); 487 } 488 return PythonObject(); 489 } 490 491 void 492 PythonDictionary::SetItemForKey (const PythonString &key, PyObject *value) 493 { 494 if (m_py_obj && key && value) 495 PyDict_SetItem(m_py_obj, key.get(), value); 496 } 497 498 void 499 PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value) 500 { 501 if (m_py_obj && key && value) 502 PyDict_SetItem(m_py_obj, key.get(), value.get()); 503 } 504 505 StructuredData::DictionarySP 506 PythonDictionary::CreateStructuredDictionary() const 507 { 508 StructuredData::DictionarySP result(new StructuredData::Dictionary); 509 PythonList keys(GetKeys()); 510 uint32_t num_keys = keys.GetSize(); 511 for (uint32_t i = 0; i < num_keys; ++i) 512 { 513 PythonObject key = keys.GetItemAtIndex(i); 514 PythonString key_str = key.Str(); 515 PythonObject value = GetItemForKey(key); 516 StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 517 result->AddItem(key_str.GetString(), structured_value); 518 } 519 return result; 520 } 521 522 #endif 523