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