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