xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (revision b9c1b51e45b845debb76d8658edabca70ca56079)
1 //===-- PythonDataObjects.cpp ------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #ifdef LLDB_DISABLE_PYTHON
12 
13 // Python is disabled in this build
14 
15 #else
16 
17 #include "PythonDataObjects.h"
18 #include "ScriptInterpreterPython.h"
19 
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Host/File.h"
22 #include "lldb/Host/FileSystem.h"
23 #include "lldb/Interpreter/ScriptInterpreter.h"
24 
25 #include "llvm/Support/ConvertUTF.h"
26 
27 #include <stdio.h>
28 
29 #include "llvm/ADT/StringSwitch.h"
30 
31 using namespace lldb_private;
32 using namespace lldb;
33 
34 void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const {
35   s << "Python Obj: 0x" << GetValue();
36 }
37 
38 //----------------------------------------------------------------------
39 // PythonObject
40 //----------------------------------------------------------------------
41 
42 void PythonObject::Dump(Stream &strm) const {
43   if (m_py_obj) {
44     FILE *file = ::tmpfile();
45     if (file) {
46       ::PyObject_Print(m_py_obj, file, 0);
47       const long length = ftell(file);
48       if (length) {
49         ::rewind(file);
50         std::vector<char> file_contents(length, '\0');
51         const size_t length_read =
52             ::fread(file_contents.data(), 1, file_contents.size(), file);
53         if (length_read > 0)
54           strm.Write(file_contents.data(), length_read);
55       }
56       ::fclose(file);
57     }
58   } else
59     strm.PutCString("NULL");
60 }
61 
62 PyObjectType PythonObject::GetObjectType() const {
63   if (!IsAllocated())
64     return PyObjectType::None;
65 
66   if (PythonModule::Check(m_py_obj))
67     return PyObjectType::Module;
68   if (PythonList::Check(m_py_obj))
69     return PyObjectType::List;
70   if (PythonTuple::Check(m_py_obj))
71     return PyObjectType::Tuple;
72   if (PythonDictionary::Check(m_py_obj))
73     return PyObjectType::Dictionary;
74   if (PythonString::Check(m_py_obj))
75     return PyObjectType::String;
76 #if PY_MAJOR_VERSION >= 3
77   if (PythonBytes::Check(m_py_obj))
78     return PyObjectType::Bytes;
79 #endif
80   if (PythonByteArray::Check(m_py_obj))
81     return PyObjectType::ByteArray;
82   if (PythonInteger::Check(m_py_obj))
83     return PyObjectType::Integer;
84   if (PythonFile::Check(m_py_obj))
85     return PyObjectType::File;
86   if (PythonCallable::Check(m_py_obj))
87     return PyObjectType::Callable;
88   return PyObjectType::Unknown;
89 }
90 
91 PythonString PythonObject::Repr() const {
92   if (!m_py_obj)
93     return PythonString();
94   PyObject *repr = PyObject_Repr(m_py_obj);
95   if (!repr)
96     return PythonString();
97   return PythonString(PyRefType::Owned, repr);
98 }
99 
100 PythonString PythonObject::Str() const {
101   if (!m_py_obj)
102     return PythonString();
103   PyObject *str = PyObject_Str(m_py_obj);
104   if (!str)
105     return PythonString();
106   return PythonString(PyRefType::Owned, str);
107 }
108 
109 PythonObject
110 PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
111                                         const PythonDictionary &dict) {
112   size_t dot_pos = name.find_first_of('.');
113   llvm::StringRef piece = name.substr(0, dot_pos);
114   PythonObject result = dict.GetItemForKey(PythonString(piece));
115   if (dot_pos == llvm::StringRef::npos) {
116     // There was no dot, we're done.
117     return result;
118   }
119 
120   // There was a dot.  The remaining portion of the name should be looked up in
121   // the context of the object that was found in the dictionary.
122   return result.ResolveName(name.substr(dot_pos + 1));
123 }
124 
125 PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
126   // Resolve the name in the context of the specified object.  If,
127   // for example, `this` refers to a PyModule, then this will look for
128   // `name` in this module.  If `this` refers to a PyType, then it will
129   // resolve `name` as an attribute of that type.  If `this` refers to
130   // an instance of an object, then it will resolve `name` as the value
131   // of the specified field.
132   //
133   // This function handles dotted names so that, for example, if `m_py_obj`
134   // refers to the `sys` module, and `name` == "path.append", then it
135   // will find the function `sys.path.append`.
136 
137   size_t dot_pos = name.find_first_of('.');
138   if (dot_pos == llvm::StringRef::npos) {
139     // No dots in the name, we should be able to find the value immediately
140     // as an attribute of `m_py_obj`.
141     return GetAttributeValue(name);
142   }
143 
144   // Look up the first piece of the name, and resolve the rest as a child of
145   // that.
146   PythonObject parent = ResolveName(name.substr(0, dot_pos));
147   if (!parent.IsAllocated())
148     return PythonObject();
149 
150   // Tail recursion.. should be optimized by the compiler
151   return parent.ResolveName(name.substr(dot_pos + 1));
152 }
153 
154 bool PythonObject::HasAttribute(llvm::StringRef attr) const {
155   if (!IsValid())
156     return false;
157   PythonString py_attr(attr);
158   return !!PyObject_HasAttr(m_py_obj, py_attr.get());
159 }
160 
161 PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
162   if (!IsValid())
163     return PythonObject();
164 
165   PythonString py_attr(attr);
166   if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
167     return PythonObject();
168 
169   return PythonObject(PyRefType::Owned,
170                       PyObject_GetAttr(m_py_obj, py_attr.get()));
171 }
172 
173 bool PythonObject::IsNone() const { return m_py_obj == Py_None; }
174 
175 bool PythonObject::IsValid() const { return m_py_obj != nullptr; }
176 
177 bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); }
178 
179 StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
180   switch (GetObjectType()) {
181   case PyObjectType::Dictionary:
182     return PythonDictionary(PyRefType::Borrowed, m_py_obj)
183         .CreateStructuredDictionary();
184   case PyObjectType::Integer:
185     return PythonInteger(PyRefType::Borrowed, m_py_obj)
186         .CreateStructuredInteger();
187   case PyObjectType::List:
188     return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
189   case PyObjectType::String:
190     return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
191   case PyObjectType::Bytes:
192     return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
193   case PyObjectType::ByteArray:
194     return PythonByteArray(PyRefType::Borrowed, m_py_obj)
195         .CreateStructuredString();
196   case PyObjectType::None:
197     return StructuredData::ObjectSP();
198   default:
199     return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
200   }
201 }
202 
203 //----------------------------------------------------------------------
204 // PythonString
205 //----------------------------------------------------------------------
206 PythonBytes::PythonBytes() : PythonObject() {}
207 
208 PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() {
209   SetBytes(bytes);
210 }
211 
212 PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() {
213   SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
214 }
215 
216 PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() {
217   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
218 }
219 
220 PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) {}
221 
222 PythonBytes::~PythonBytes() {}
223 
224 bool PythonBytes::Check(PyObject *py_obj) {
225   if (!py_obj)
226     return false;
227   if (PyBytes_Check(py_obj))
228     return true;
229   return false;
230 }
231 
232 void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
233   // Grab the desired reference type so that if we end up rejecting
234   // `py_obj` it still gets decremented if necessary.
235   PythonObject result(type, py_obj);
236 
237   if (!PythonBytes::Check(py_obj)) {
238     PythonObject::Reset();
239     return;
240   }
241 
242   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
243   // overflow since it calls
244   // back into the virtual implementation.
245   PythonObject::Reset(PyRefType::Borrowed, result.get());
246 }
247 
248 llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
249   if (!IsValid())
250     return llvm::ArrayRef<uint8_t>();
251 
252   Py_ssize_t size;
253   char *c;
254 
255   PyBytes_AsStringAndSize(m_py_obj, &c, &size);
256   return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
257 }
258 
259 size_t PythonBytes::GetSize() const {
260   if (!IsValid())
261     return 0;
262   return PyBytes_Size(m_py_obj);
263 }
264 
265 void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
266   const char *data = reinterpret_cast<const char *>(bytes.data());
267   PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
268   PythonObject::Reset(PyRefType::Owned, py_bytes);
269 }
270 
271 StructuredData::StringSP PythonBytes::CreateStructuredString() const {
272   StructuredData::StringSP result(new StructuredData::String);
273   Py_ssize_t size;
274   char *c;
275   PyBytes_AsStringAndSize(m_py_obj, &c, &size);
276   result->SetValue(std::string(c, size));
277   return result;
278 }
279 
280 PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
281     : PythonByteArray(bytes.data(), bytes.size()) {}
282 
283 PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
284   const char *str = reinterpret_cast<const char *>(bytes);
285   Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
286 }
287 
288 PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) {
289   Reset(type, o);
290 }
291 
292 PythonByteArray::PythonByteArray(const PythonBytes &object)
293     : PythonObject(object) {}
294 
295 PythonByteArray::~PythonByteArray() {}
296 
297 bool PythonByteArray::Check(PyObject *py_obj) {
298   if (!py_obj)
299     return false;
300   if (PyByteArray_Check(py_obj))
301     return true;
302   return false;
303 }
304 
305 void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
306   // Grab the desired reference type so that if we end up rejecting
307   // `py_obj` it still gets decremented if necessary.
308   PythonObject result(type, py_obj);
309 
310   if (!PythonByteArray::Check(py_obj)) {
311     PythonObject::Reset();
312     return;
313   }
314 
315   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
316   // overflow since it calls
317   // back into the virtual implementation.
318   PythonObject::Reset(PyRefType::Borrowed, result.get());
319 }
320 
321 llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
322   if (!IsValid())
323     return llvm::ArrayRef<uint8_t>();
324 
325   char *c = PyByteArray_AsString(m_py_obj);
326   size_t size = GetSize();
327   return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
328 }
329 
330 size_t PythonByteArray::GetSize() const {
331   if (!IsValid())
332     return 0;
333 
334   return PyByteArray_Size(m_py_obj);
335 }
336 
337 StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
338   StructuredData::StringSP result(new StructuredData::String);
339   llvm::ArrayRef<uint8_t> bytes = GetBytes();
340   const char *str = reinterpret_cast<const char *>(bytes.data());
341   result->SetValue(std::string(str, bytes.size()));
342   return result;
343 }
344 
345 //----------------------------------------------------------------------
346 // PythonString
347 //----------------------------------------------------------------------
348 
349 PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() {
350   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
351 }
352 
353 PythonString::PythonString(const PythonString &object) : PythonObject(object) {}
354 
355 PythonString::PythonString(llvm::StringRef string) : PythonObject() {
356   SetString(string);
357 }
358 
359 PythonString::PythonString(const char *string) : PythonObject() {
360   SetString(llvm::StringRef(string));
361 }
362 
363 PythonString::PythonString() : PythonObject() {}
364 
365 PythonString::~PythonString() {}
366 
367 bool PythonString::Check(PyObject *py_obj) {
368   if (!py_obj)
369     return false;
370 
371   if (PyUnicode_Check(py_obj))
372     return true;
373 #if PY_MAJOR_VERSION < 3
374   if (PyString_Check(py_obj))
375     return true;
376 #endif
377   return false;
378 }
379 
380 void PythonString::Reset(PyRefType type, PyObject *py_obj) {
381   // Grab the desired reference type so that if we end up rejecting
382   // `py_obj` it still gets decremented if necessary.
383   PythonObject result(type, py_obj);
384 
385   if (!PythonString::Check(py_obj)) {
386     PythonObject::Reset();
387     return;
388   }
389 #if PY_MAJOR_VERSION < 3
390   // In Python 2, Don't store PyUnicode objects directly, because we need
391   // access to their underlying character buffers which Python 2 doesn't
392   // provide.
393   if (PyUnicode_Check(py_obj))
394     result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
395 #endif
396   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
397   // overflow since it calls
398   // back into the virtual implementation.
399   PythonObject::Reset(PyRefType::Borrowed, result.get());
400 }
401 
402 llvm::StringRef PythonString::GetString() const {
403   if (!IsValid())
404     return llvm::StringRef();
405 
406   Py_ssize_t size;
407   char *c;
408 
409 #if PY_MAJOR_VERSION >= 3
410   c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
411 #else
412   PyString_AsStringAndSize(m_py_obj, &c, &size);
413 #endif
414   return llvm::StringRef(c, size);
415 }
416 
417 size_t PythonString::GetSize() const {
418   if (IsValid()) {
419 #if PY_MAJOR_VERSION >= 3
420     return PyUnicode_GetSize(m_py_obj);
421 #else
422     return PyString_Size(m_py_obj);
423 #endif
424   }
425   return 0;
426 }
427 
428 void PythonString::SetString(llvm::StringRef string) {
429 #if PY_MAJOR_VERSION >= 3
430   PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
431   PythonObject::Reset(PyRefType::Owned, unicode);
432 #else
433   PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
434   PythonObject::Reset(PyRefType::Owned, str);
435 #endif
436 }
437 
438 StructuredData::StringSP PythonString::CreateStructuredString() const {
439   StructuredData::StringSP result(new StructuredData::String);
440   result->SetValue(GetString());
441   return result;
442 }
443 
444 //----------------------------------------------------------------------
445 // PythonInteger
446 //----------------------------------------------------------------------
447 
448 PythonInteger::PythonInteger() : PythonObject() {}
449 
450 PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
451     : PythonObject() {
452   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
453 }
454 
455 PythonInteger::PythonInteger(const PythonInteger &object)
456     : PythonObject(object) {}
457 
458 PythonInteger::PythonInteger(int64_t value) : PythonObject() {
459   SetInteger(value);
460 }
461 
462 PythonInteger::~PythonInteger() {}
463 
464 bool PythonInteger::Check(PyObject *py_obj) {
465   if (!py_obj)
466     return false;
467 
468 #if PY_MAJOR_VERSION >= 3
469   // Python 3 does not have PyInt_Check.  There is only one type of
470   // integral value, long.
471   return PyLong_Check(py_obj);
472 #else
473   return PyLong_Check(py_obj) || PyInt_Check(py_obj);
474 #endif
475 }
476 
477 void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
478   // Grab the desired reference type so that if we end up rejecting
479   // `py_obj` it still gets decremented if necessary.
480   PythonObject result(type, py_obj);
481 
482   if (!PythonInteger::Check(py_obj)) {
483     PythonObject::Reset();
484     return;
485   }
486 
487 #if PY_MAJOR_VERSION < 3
488   // Always store this as a PyLong, which makes interoperability between
489   // Python 2.x and Python 3.x easier.  This is only necessary in 2.x,
490   // since 3.x doesn't even have a PyInt.
491   if (PyInt_Check(py_obj)) {
492     // Since we converted the original object to a different type, the new
493     // object is an owned object regardless of the ownership semantics requested
494     // by the user.
495     result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
496   }
497 #endif
498 
499   assert(PyLong_Check(result.get()) &&
500          "Couldn't get a PyLong from this PyObject");
501 
502   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
503   // overflow since it calls
504   // back into the virtual implementation.
505   PythonObject::Reset(PyRefType::Borrowed, result.get());
506 }
507 
508 int64_t PythonInteger::GetInteger() const {
509   if (m_py_obj) {
510     assert(PyLong_Check(m_py_obj) &&
511            "PythonInteger::GetInteger has a PyObject that isn't a PyLong");
512 
513     int overflow = 0;
514     int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
515     if (overflow != 0) {
516       // We got an integer that overflows, like 18446744072853913392L
517       // we can't use PyLong_AsLongLong() as it will return
518       // 0xffffffffffffffff. If we use the unsigned long long
519       // it will work as expected.
520       const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
521       result = *((int64_t *)&uval);
522     }
523     return result;
524   }
525   return UINT64_MAX;
526 }
527 
528 void PythonInteger::SetInteger(int64_t value) {
529   PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
530 }
531 
532 StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
533   StructuredData::IntegerSP result(new StructuredData::Integer);
534   result->SetValue(GetInteger());
535   return result;
536 }
537 
538 //----------------------------------------------------------------------
539 // PythonList
540 //----------------------------------------------------------------------
541 
542 PythonList::PythonList(PyInitialValue value) : PythonObject() {
543   if (value == PyInitialValue::Empty)
544     Reset(PyRefType::Owned, PyList_New(0));
545 }
546 
547 PythonList::PythonList(int list_size) : PythonObject() {
548   Reset(PyRefType::Owned, PyList_New(list_size));
549 }
550 
551 PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() {
552   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
553 }
554 
555 PythonList::PythonList(const PythonList &list) : PythonObject(list) {}
556 
557 PythonList::~PythonList() {}
558 
559 bool PythonList::Check(PyObject *py_obj) {
560   if (!py_obj)
561     return false;
562   return PyList_Check(py_obj);
563 }
564 
565 void PythonList::Reset(PyRefType type, PyObject *py_obj) {
566   // Grab the desired reference type so that if we end up rejecting
567   // `py_obj` it still gets decremented if necessary.
568   PythonObject result(type, py_obj);
569 
570   if (!PythonList::Check(py_obj)) {
571     PythonObject::Reset();
572     return;
573   }
574 
575   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
576   // overflow since it calls
577   // back into the virtual implementation.
578   PythonObject::Reset(PyRefType::Borrowed, result.get());
579 }
580 
581 uint32_t PythonList::GetSize() const {
582   if (IsValid())
583     return PyList_GET_SIZE(m_py_obj);
584   return 0;
585 }
586 
587 PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
588   if (IsValid())
589     return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
590   return PythonObject();
591 }
592 
593 void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
594   if (IsAllocated() && object.IsValid()) {
595     // PyList_SetItem is documented to "steal" a reference, so we need to
596     // convert it to an owned reference by incrementing it.
597     Py_INCREF(object.get());
598     PyList_SetItem(m_py_obj, index, object.get());
599   }
600 }
601 
602 void PythonList::AppendItem(const PythonObject &object) {
603   if (IsAllocated() && object.IsValid()) {
604     // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
605     // here like we do with `PyList_SetItem`.
606     PyList_Append(m_py_obj, object.get());
607   }
608 }
609 
610 StructuredData::ArraySP PythonList::CreateStructuredArray() const {
611   StructuredData::ArraySP result(new StructuredData::Array);
612   uint32_t count = GetSize();
613   for (uint32_t i = 0; i < count; ++i) {
614     PythonObject obj = GetItemAtIndex(i);
615     result->AddItem(obj.CreateStructuredObject());
616   }
617   return result;
618 }
619 
620 //----------------------------------------------------------------------
621 // PythonTuple
622 //----------------------------------------------------------------------
623 
624 PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() {
625   if (value == PyInitialValue::Empty)
626     Reset(PyRefType::Owned, PyTuple_New(0));
627 }
628 
629 PythonTuple::PythonTuple(int tuple_size) : PythonObject() {
630   Reset(PyRefType::Owned, PyTuple_New(tuple_size));
631 }
632 
633 PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() {
634   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
635 }
636 
637 PythonTuple::PythonTuple(const PythonTuple &tuple) : PythonObject(tuple) {}
638 
639 PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
640   m_py_obj = PyTuple_New(objects.size());
641 
642   uint32_t idx = 0;
643   for (auto object : objects) {
644     if (object.IsValid())
645       SetItemAtIndex(idx, object);
646     idx++;
647   }
648 }
649 
650 PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
651   m_py_obj = PyTuple_New(objects.size());
652 
653   uint32_t idx = 0;
654   for (auto py_object : objects) {
655     PythonObject object(PyRefType::Borrowed, py_object);
656     if (object.IsValid())
657       SetItemAtIndex(idx, object);
658     idx++;
659   }
660 }
661 
662 PythonTuple::~PythonTuple() {}
663 
664 bool PythonTuple::Check(PyObject *py_obj) {
665   if (!py_obj)
666     return false;
667   return PyTuple_Check(py_obj);
668 }
669 
670 void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
671   // Grab the desired reference type so that if we end up rejecting
672   // `py_obj` it still gets decremented if necessary.
673   PythonObject result(type, py_obj);
674 
675   if (!PythonTuple::Check(py_obj)) {
676     PythonObject::Reset();
677     return;
678   }
679 
680   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
681   // overflow since it calls
682   // back into the virtual implementation.
683   PythonObject::Reset(PyRefType::Borrowed, result.get());
684 }
685 
686 uint32_t PythonTuple::GetSize() const {
687   if (IsValid())
688     return PyTuple_GET_SIZE(m_py_obj);
689   return 0;
690 }
691 
692 PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
693   if (IsValid())
694     return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
695   return PythonObject();
696 }
697 
698 void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
699   if (IsAllocated() && object.IsValid()) {
700     // PyTuple_SetItem is documented to "steal" a reference, so we need to
701     // convert it to an owned reference by incrementing it.
702     Py_INCREF(object.get());
703     PyTuple_SetItem(m_py_obj, index, object.get());
704   }
705 }
706 
707 StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
708   StructuredData::ArraySP result(new StructuredData::Array);
709   uint32_t count = GetSize();
710   for (uint32_t i = 0; i < count; ++i) {
711     PythonObject obj = GetItemAtIndex(i);
712     result->AddItem(obj.CreateStructuredObject());
713   }
714   return result;
715 }
716 
717 //----------------------------------------------------------------------
718 // PythonDictionary
719 //----------------------------------------------------------------------
720 
721 PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() {
722   if (value == PyInitialValue::Empty)
723     Reset(PyRefType::Owned, PyDict_New());
724 }
725 
726 PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
727     : PythonObject() {
728   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
729 }
730 
731 PythonDictionary::PythonDictionary(const PythonDictionary &object)
732     : PythonObject(object) {}
733 
734 PythonDictionary::~PythonDictionary() {}
735 
736 bool PythonDictionary::Check(PyObject *py_obj) {
737   if (!py_obj)
738     return false;
739 
740   return PyDict_Check(py_obj);
741 }
742 
743 void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
744   // Grab the desired reference type so that if we end up rejecting
745   // `py_obj` it still gets decremented if necessary.
746   PythonObject result(type, py_obj);
747 
748   if (!PythonDictionary::Check(py_obj)) {
749     PythonObject::Reset();
750     return;
751   }
752 
753   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
754   // overflow since it calls
755   // back into the virtual implementation.
756   PythonObject::Reset(PyRefType::Borrowed, result.get());
757 }
758 
759 uint32_t PythonDictionary::GetSize() const {
760   if (IsValid())
761     return PyDict_Size(m_py_obj);
762   return 0;
763 }
764 
765 PythonList PythonDictionary::GetKeys() const {
766   if (IsValid())
767     return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
768   return PythonList(PyInitialValue::Invalid);
769 }
770 
771 PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
772   if (IsAllocated() && key.IsValid())
773     return PythonObject(PyRefType::Borrowed,
774                         PyDict_GetItem(m_py_obj, key.get()));
775   return PythonObject();
776 }
777 
778 void PythonDictionary::SetItemForKey(const PythonObject &key,
779                                      const PythonObject &value) {
780   if (IsAllocated() && key.IsValid() && value.IsValid())
781     PyDict_SetItem(m_py_obj, key.get(), value.get());
782 }
783 
784 StructuredData::DictionarySP
785 PythonDictionary::CreateStructuredDictionary() const {
786   StructuredData::DictionarySP result(new StructuredData::Dictionary);
787   PythonList keys(GetKeys());
788   uint32_t num_keys = keys.GetSize();
789   for (uint32_t i = 0; i < num_keys; ++i) {
790     PythonObject key = keys.GetItemAtIndex(i);
791     PythonObject value = GetItemForKey(key);
792     StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
793     result->AddItem(key.Str().GetString(), structured_value);
794   }
795   return result;
796 }
797 
798 PythonModule::PythonModule() : PythonObject() {}
799 
800 PythonModule::PythonModule(PyRefType type, PyObject *py_obj) {
801   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
802 }
803 
804 PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict) {}
805 
806 PythonModule::~PythonModule() {}
807 
808 PythonModule PythonModule::BuiltinsModule() {
809 #if PY_MAJOR_VERSION >= 3
810   return AddModule("builtins");
811 #else
812   return AddModule("__builtin__");
813 #endif
814 }
815 
816 PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
817 
818 PythonModule PythonModule::AddModule(llvm::StringRef module) {
819   std::string str = module.str();
820   return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
821 }
822 
823 PythonModule PythonModule::ImportModule(llvm::StringRef module) {
824   std::string str = module.str();
825   return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
826 }
827 
828 bool PythonModule::Check(PyObject *py_obj) {
829   if (!py_obj)
830     return false;
831 
832   return PyModule_Check(py_obj);
833 }
834 
835 void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
836   // Grab the desired reference type so that if we end up rejecting
837   // `py_obj` it still gets decremented if necessary.
838   PythonObject result(type, py_obj);
839 
840   if (!PythonModule::Check(py_obj)) {
841     PythonObject::Reset();
842     return;
843   }
844 
845   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
846   // overflow since it calls
847   // back into the virtual implementation.
848   PythonObject::Reset(PyRefType::Borrowed, result.get());
849 }
850 
851 PythonDictionary PythonModule::GetDictionary() const {
852   return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
853 }
854 
855 PythonCallable::PythonCallable() : PythonObject() {}
856 
857 PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) {
858   Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
859 }
860 
861 PythonCallable::PythonCallable(const PythonCallable &callable)
862     : PythonObject(callable) {}
863 
864 PythonCallable::~PythonCallable() {}
865 
866 bool PythonCallable::Check(PyObject *py_obj) {
867   if (!py_obj)
868     return false;
869 
870   return PyCallable_Check(py_obj);
871 }
872 
873 void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
874   // Grab the desired reference type so that if we end up rejecting
875   // `py_obj` it still gets decremented if necessary.
876   PythonObject result(type, py_obj);
877 
878   if (!PythonCallable::Check(py_obj)) {
879     PythonObject::Reset();
880     return;
881   }
882 
883   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
884   // overflow since it calls
885   // back into the virtual implementation.
886   PythonObject::Reset(PyRefType::Borrowed, result.get());
887 }
888 
889 PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
890   ArgInfo result = {0, false, false, false};
891   if (!IsValid())
892     return result;
893 
894   PyObject *py_func_obj = m_py_obj;
895   if (PyMethod_Check(py_func_obj)) {
896     py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
897     PythonObject im_self = GetAttributeValue("im_self");
898     if (im_self.IsValid() && !im_self.IsNone())
899       result.is_bound_method = true;
900   } else {
901     // see if this is a callable object with an __call__ method
902     if (!PyFunction_Check(py_func_obj)) {
903       PythonObject __call__ = GetAttributeValue("__call__");
904       if (__call__.IsValid()) {
905         auto __callable__ = __call__.AsType<PythonCallable>();
906         if (__callable__.IsValid()) {
907           py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
908           PythonObject im_self = GetAttributeValue("im_self");
909           if (im_self.IsValid() && !im_self.IsNone())
910             result.is_bound_method = true;
911         }
912       }
913     }
914   }
915 
916   if (!py_func_obj)
917     return result;
918 
919   PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
920   if (!code)
921     return result;
922 
923   result.count = code->co_argcount;
924   result.has_varargs = !!(code->co_flags & CO_VARARGS);
925   result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
926   return result;
927 }
928 
929 PythonObject PythonCallable::operator()() {
930   return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
931 }
932 
933 PythonObject PythonCallable::
934 operator()(std::initializer_list<PyObject *> args) {
935   PythonTuple arg_tuple(args);
936   return PythonObject(PyRefType::Owned,
937                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
938 }
939 
940 PythonObject PythonCallable::
941 operator()(std::initializer_list<PythonObject> args) {
942   PythonTuple arg_tuple(args);
943   return PythonObject(PyRefType::Owned,
944                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
945 }
946 
947 PythonFile::PythonFile() : PythonObject() {}
948 
949 PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
950 
951 PythonFile::PythonFile(const char *path, const char *mode) {
952   lldb_private::File file(path, GetOptionsFromMode(mode));
953   Reset(file, mode);
954 }
955 
956 PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }
957 
958 PythonFile::~PythonFile() {}
959 
960 bool PythonFile::Check(PyObject *py_obj) {
961 #if PY_MAJOR_VERSION < 3
962   return PyFile_Check(py_obj);
963 #else
964   // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
965   // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
966   // over `io.open()`, which returns some object derived from `io.IOBase`.
967   // As a result, the only way to detect a file in Python 3 is to check whether
968   // it inherits from `io.IOBase`.  Since it is possible for non-files to also
969   // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
970   // attribute, which should guarantee that it is backed by the file system.
971   PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
972   PythonDictionary io_dict(PyRefType::Borrowed,
973                            PyModule_GetDict(io_module.get()));
974   PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
975 
976   PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
977 
978   if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
979     return false;
980   if (!object_type.HasAttribute("fileno"))
981     return false;
982 
983   return true;
984 #endif
985 }
986 
987 void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
988   // Grab the desired reference type so that if we end up rejecting
989   // `py_obj` it still gets decremented if necessary.
990   PythonObject result(type, py_obj);
991 
992   if (!PythonFile::Check(py_obj)) {
993     PythonObject::Reset();
994     return;
995   }
996 
997   // Calling PythonObject::Reset(const PythonObject&) will lead to stack
998   // overflow since it calls back into the virtual implementation.
999   PythonObject::Reset(PyRefType::Borrowed, result.get());
1000 }
1001 
1002 void PythonFile::Reset(File &file, const char *mode) {
1003   if (!file.IsValid()) {
1004     Reset();
1005     return;
1006   }
1007 
1008   char *cmode = const_cast<char *>(mode);
1009 #if PY_MAJOR_VERSION >= 3
1010   Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
1011                                         -1, nullptr, "ignore", nullptr, 0));
1012 #else
1013   // Read through the Python source, doesn't seem to modify these strings
1014   Reset(PyRefType::Owned,
1015         PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
1016                         nullptr));
1017 #endif
1018 }
1019 
1020 uint32_t PythonFile::GetOptionsFromMode(llvm::StringRef mode) {
1021   if (mode.empty())
1022     return 0;
1023 
1024   return llvm::StringSwitch<uint32_t>(mode.str().c_str())
1025       .Case("r", File::eOpenOptionRead)
1026       .Case("w", File::eOpenOptionWrite)
1027       .Case("a", File::eOpenOptionWrite | File::eOpenOptionAppend |
1028                      File::eOpenOptionCanCreate)
1029       .Case("r+", File::eOpenOptionRead | File::eOpenOptionWrite)
1030       .Case("w+", File::eOpenOptionRead | File::eOpenOptionWrite |
1031                       File::eOpenOptionCanCreate | File::eOpenOptionTruncate)
1032       .Case("a+", File::eOpenOptionRead | File::eOpenOptionWrite |
1033                       File::eOpenOptionAppend | File::eOpenOptionCanCreate)
1034       .Default(0);
1035 }
1036 
1037 bool PythonFile::GetUnderlyingFile(File &file) const {
1038   if (!IsValid())
1039     return false;
1040 
1041   file.Close();
1042   // We don't own the file descriptor returned by this function, make sure the
1043   // File object knows about that.
1044   file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
1045   PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
1046   file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
1047   return file.IsValid();
1048 }
1049 
1050 #endif
1051