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