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