• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- PythonDataObjects.cpp ---------------------------------------------===//
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 #include "lldb/Host/Config.h"
10 
11 #if LLDB_ENABLE_PYTHON
12 
13 #include "PythonDataObjects.h"
14 #include "ScriptInterpreterPython.h"
15 
16 #include "lldb/Host/File.h"
17 #include "lldb/Host/FileSystem.h"
18 #include "lldb/Interpreter/ScriptInterpreter.h"
19 #include "lldb/Utility/Log.h"
20 #include "lldb/Utility/Stream.h"
21 
22 #include "llvm/ADT/StringSwitch.h"
23 #include "llvm/Support/Casting.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 using namespace lldb_private::python;
32 using llvm::cantFail;
33 using llvm::Error;
34 using llvm::Expected;
35 using llvm::Twine;
36 
As(Expected<PythonObject> && obj)37 template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
38   if (!obj)
39     return obj.takeError();
40   return obj.get().IsTrue();
41 }
42 
43 template <>
As(Expected<PythonObject> && obj)44 Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
45   if (!obj)
46     return obj.takeError();
47   return obj->AsLongLong();
48 }
49 
50 template <>
51 Expected<unsigned long long>
As(Expected<PythonObject> && obj)52 python::As<unsigned long long>(Expected<PythonObject> &&obj) {
53   if (!obj)
54     return obj.takeError();
55   return obj->AsUnsignedLongLong();
56 }
57 
58 template <>
As(Expected<PythonObject> && obj)59 Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
60   if (!obj)
61     return obj.takeError();
62   PyObject *str_obj = PyObject_Str(obj.get().get());
63   if (!obj)
64     return llvm::make_error<PythonException>();
65   auto str = Take<PythonString>(str_obj);
66   auto utf8 = str.AsUTF8();
67   if (!utf8)
68     return utf8.takeError();
69   return std::string(utf8.get());
70 }
71 
AsLongLong() const72 Expected<long long> PythonObject::AsLongLong() const {
73   if (!m_py_obj)
74     return nullDeref();
75 #if PY_MAJOR_VERSION < 3
76   if (!PyLong_Check(m_py_obj)) {
77     PythonInteger i(PyRefType::Borrowed, m_py_obj);
78     return i.AsLongLong();
79   }
80 #endif
81   assert(!PyErr_Occurred());
82   long long r = PyLong_AsLongLong(m_py_obj);
83   if (PyErr_Occurred())
84     return exception();
85   return r;
86 }
87 
AsUnsignedLongLong() const88 Expected<long long> PythonObject::AsUnsignedLongLong() const {
89   if (!m_py_obj)
90     return nullDeref();
91 #if PY_MAJOR_VERSION < 3
92   if (!PyLong_Check(m_py_obj)) {
93     PythonInteger i(PyRefType::Borrowed, m_py_obj);
94     return i.AsUnsignedLongLong();
95   }
96 #endif
97   assert(!PyErr_Occurred());
98   long long r = PyLong_AsUnsignedLongLong(m_py_obj);
99   if (PyErr_Occurred())
100     return exception();
101   return r;
102 }
103 
104 // wraps on overflow, instead of raising an error.
AsModuloUnsignedLongLong() const105 Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
106   if (!m_py_obj)
107     return nullDeref();
108 #if PY_MAJOR_VERSION < 3
109   if (!PyLong_Check(m_py_obj)) {
110     PythonInteger i(PyRefType::Borrowed, m_py_obj);
111     return i.AsModuloUnsignedLongLong();
112   }
113 #endif
114   assert(!PyErr_Occurred());
115   unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
116   if (PyErr_Occurred())
117     return exception();
118   return r;
119 }
120 
Serialize(llvm::json::OStream & s) const121 void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
122   s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str());
123 }
124 
125 // PythonObject
126 
Dump(Stream & strm) const127 void PythonObject::Dump(Stream &strm) const {
128   if (m_py_obj) {
129     FILE *file = llvm::sys::RetryAfterSignal(nullptr, ::tmpfile);
130     if (file) {
131       ::PyObject_Print(m_py_obj, file, 0);
132       const long length = ftell(file);
133       if (length) {
134         ::rewind(file);
135         std::vector<char> file_contents(length, '\0');
136         const size_t length_read =
137             ::fread(file_contents.data(), 1, file_contents.size(), file);
138         if (length_read > 0)
139           strm.Write(file_contents.data(), length_read);
140       }
141       ::fclose(file);
142     }
143   } else
144     strm.PutCString("NULL");
145 }
146 
GetObjectType() const147 PyObjectType PythonObject::GetObjectType() const {
148   if (!IsAllocated())
149     return PyObjectType::None;
150 
151   if (PythonModule::Check(m_py_obj))
152     return PyObjectType::Module;
153   if (PythonList::Check(m_py_obj))
154     return PyObjectType::List;
155   if (PythonTuple::Check(m_py_obj))
156     return PyObjectType::Tuple;
157   if (PythonDictionary::Check(m_py_obj))
158     return PyObjectType::Dictionary;
159   if (PythonString::Check(m_py_obj))
160     return PyObjectType::String;
161 #if PY_MAJOR_VERSION >= 3
162   if (PythonBytes::Check(m_py_obj))
163     return PyObjectType::Bytes;
164 #endif
165   if (PythonByteArray::Check(m_py_obj))
166     return PyObjectType::ByteArray;
167   if (PythonBoolean::Check(m_py_obj))
168     return PyObjectType::Boolean;
169   if (PythonInteger::Check(m_py_obj))
170     return PyObjectType::Integer;
171   if (PythonFile::Check(m_py_obj))
172     return PyObjectType::File;
173   if (PythonCallable::Check(m_py_obj))
174     return PyObjectType::Callable;
175   return PyObjectType::Unknown;
176 }
177 
Repr() const178 PythonString PythonObject::Repr() const {
179   if (!m_py_obj)
180     return PythonString();
181   PyObject *repr = PyObject_Repr(m_py_obj);
182   if (!repr)
183     return PythonString();
184   return PythonString(PyRefType::Owned, repr);
185 }
186 
Str() const187 PythonString PythonObject::Str() const {
188   if (!m_py_obj)
189     return PythonString();
190   PyObject *str = PyObject_Str(m_py_obj);
191   if (!str)
192     return PythonString();
193   return PythonString(PyRefType::Owned, str);
194 }
195 
196 PythonObject
ResolveNameWithDictionary(llvm::StringRef name,const PythonDictionary & dict)197 PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
198                                         const PythonDictionary &dict) {
199   size_t dot_pos = name.find('.');
200   llvm::StringRef piece = name.substr(0, dot_pos);
201   PythonObject result = dict.GetItemForKey(PythonString(piece));
202   if (dot_pos == llvm::StringRef::npos) {
203     // There was no dot, we're done.
204     return result;
205   }
206 
207   // There was a dot.  The remaining portion of the name should be looked up in
208   // the context of the object that was found in the dictionary.
209   return result.ResolveName(name.substr(dot_pos + 1));
210 }
211 
ResolveName(llvm::StringRef name) const212 PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
213   // Resolve the name in the context of the specified object.  If, for example,
214   // `this` refers to a PyModule, then this will look for `name` in this
215   // module.  If `this` refers to a PyType, then it will resolve `name` as an
216   // attribute of that type.  If `this` refers to an instance of an object,
217   // then it will resolve `name` as the value of the specified field.
218   //
219   // This function handles dotted names so that, for example, if `m_py_obj`
220   // refers to the `sys` module, and `name` == "path.append", then it will find
221   // the function `sys.path.append`.
222 
223   size_t dot_pos = name.find('.');
224   if (dot_pos == llvm::StringRef::npos) {
225     // No dots in the name, we should be able to find the value immediately as
226     // an attribute of `m_py_obj`.
227     return GetAttributeValue(name);
228   }
229 
230   // Look up the first piece of the name, and resolve the rest as a child of
231   // that.
232   PythonObject parent = ResolveName(name.substr(0, dot_pos));
233   if (!parent.IsAllocated())
234     return PythonObject();
235 
236   // Tail recursion.. should be optimized by the compiler
237   return parent.ResolveName(name.substr(dot_pos + 1));
238 }
239 
HasAttribute(llvm::StringRef attr) const240 bool PythonObject::HasAttribute(llvm::StringRef attr) const {
241   if (!IsValid())
242     return false;
243   PythonString py_attr(attr);
244   return !!PyObject_HasAttr(m_py_obj, py_attr.get());
245 }
246 
GetAttributeValue(llvm::StringRef attr) const247 PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
248   if (!IsValid())
249     return PythonObject();
250 
251   PythonString py_attr(attr);
252   if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
253     return PythonObject();
254 
255   return PythonObject(PyRefType::Owned,
256                       PyObject_GetAttr(m_py_obj, py_attr.get()));
257 }
258 
CreateStructuredObject() const259 StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
260   switch (GetObjectType()) {
261   case PyObjectType::Dictionary:
262     return PythonDictionary(PyRefType::Borrowed, m_py_obj)
263         .CreateStructuredDictionary();
264   case PyObjectType::Boolean:
265     return PythonBoolean(PyRefType::Borrowed, m_py_obj)
266         .CreateStructuredBoolean();
267   case PyObjectType::Integer:
268     return PythonInteger(PyRefType::Borrowed, m_py_obj)
269         .CreateStructuredInteger();
270   case PyObjectType::List:
271     return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
272   case PyObjectType::String:
273     return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
274   case PyObjectType::Bytes:
275     return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
276   case PyObjectType::ByteArray:
277     return PythonByteArray(PyRefType::Borrowed, m_py_obj)
278         .CreateStructuredString();
279   case PyObjectType::None:
280     return StructuredData::ObjectSP();
281   default:
282     return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
283   }
284 }
285 
286 // PythonString
287 
PythonBytes(llvm::ArrayRef<uint8_t> bytes)288 PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
289 
PythonBytes(const uint8_t * bytes,size_t length)290 PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) {
291   SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
292 }
293 
Check(PyObject * py_obj)294 bool PythonBytes::Check(PyObject *py_obj) {
295   if (!py_obj)
296     return false;
297   return PyBytes_Check(py_obj);
298 }
299 
GetBytes() const300 llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
301   if (!IsValid())
302     return llvm::ArrayRef<uint8_t>();
303 
304   Py_ssize_t size;
305   char *c;
306 
307   PyBytes_AsStringAndSize(m_py_obj, &c, &size);
308   return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
309 }
310 
GetSize() const311 size_t PythonBytes::GetSize() const {
312   if (!IsValid())
313     return 0;
314   return PyBytes_Size(m_py_obj);
315 }
316 
SetBytes(llvm::ArrayRef<uint8_t> bytes)317 void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
318   const char *data = reinterpret_cast<const char *>(bytes.data());
319   *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
320 }
321 
CreateStructuredString() const322 StructuredData::StringSP PythonBytes::CreateStructuredString() const {
323   StructuredData::StringSP result(new StructuredData::String);
324   Py_ssize_t size;
325   char *c;
326   PyBytes_AsStringAndSize(m_py_obj, &c, &size);
327   result->SetValue(std::string(c, size));
328   return result;
329 }
330 
PythonByteArray(llvm::ArrayRef<uint8_t> bytes)331 PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
332     : PythonByteArray(bytes.data(), bytes.size()) {}
333 
PythonByteArray(const uint8_t * bytes,size_t length)334 PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
335   const char *str = reinterpret_cast<const char *>(bytes);
336   *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
337 }
338 
Check(PyObject * py_obj)339 bool PythonByteArray::Check(PyObject *py_obj) {
340   if (!py_obj)
341     return false;
342   return PyByteArray_Check(py_obj);
343 }
344 
GetBytes() const345 llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
346   if (!IsValid())
347     return llvm::ArrayRef<uint8_t>();
348 
349   char *c = PyByteArray_AsString(m_py_obj);
350   size_t size = GetSize();
351   return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
352 }
353 
GetSize() const354 size_t PythonByteArray::GetSize() const {
355   if (!IsValid())
356     return 0;
357 
358   return PyByteArray_Size(m_py_obj);
359 }
360 
CreateStructuredString() const361 StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
362   StructuredData::StringSP result(new StructuredData::String);
363   llvm::ArrayRef<uint8_t> bytes = GetBytes();
364   const char *str = reinterpret_cast<const char *>(bytes.data());
365   result->SetValue(std::string(str, bytes.size()));
366   return result;
367 }
368 
369 // PythonString
370 
FromUTF8(llvm::StringRef string)371 Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
372 #if PY_MAJOR_VERSION >= 3
373   PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
374 #else
375   PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
376 #endif
377   if (!str)
378     return llvm::make_error<PythonException>();
379   return Take<PythonString>(str);
380 }
381 
PythonString(llvm::StringRef string)382 PythonString::PythonString(llvm::StringRef string) { SetString(string); }
383 
Check(PyObject * py_obj)384 bool PythonString::Check(PyObject *py_obj) {
385   if (!py_obj)
386     return false;
387 
388   if (PyUnicode_Check(py_obj))
389     return true;
390 #if PY_MAJOR_VERSION < 3
391   if (PyString_Check(py_obj))
392     return true;
393 #endif
394   return false;
395 }
396 
Convert(PyRefType & type,PyObject * & py_obj)397 void PythonString::Convert(PyRefType &type, PyObject *&py_obj) {
398 #if PY_MAJOR_VERSION < 3
399   // In Python 2, Don't store PyUnicode objects directly, because we need
400   // access to their underlying character buffers which Python 2 doesn't
401   // provide.
402   if (PyUnicode_Check(py_obj)) {
403     PyObject *s = PyUnicode_AsUTF8String(py_obj);
404     if (s == nullptr) {
405       PyErr_Clear();
406       if (type == PyRefType::Owned)
407         Py_DECREF(py_obj);
408       return;
409     }
410     if (type == PyRefType::Owned)
411       Py_DECREF(py_obj);
412     else
413       type = PyRefType::Owned;
414     py_obj = s;
415   }
416 #endif
417 }
418 
GetString() const419 llvm::StringRef PythonString::GetString() const {
420   auto s = AsUTF8();
421   if (!s) {
422     llvm::consumeError(s.takeError());
423     return llvm::StringRef("");
424   }
425   return s.get();
426 }
427 
AsUTF8() const428 Expected<llvm::StringRef> PythonString::AsUTF8() const {
429   if (!IsValid())
430     return nullDeref();
431 
432   Py_ssize_t size;
433   const char *data;
434 
435 #if PY_MAJOR_VERSION >= 3
436   data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
437 #else
438   char *c = NULL;
439   int r = PyString_AsStringAndSize(m_py_obj, &c, &size);
440   if (r < 0)
441     c = NULL;
442   data = c;
443 #endif
444 
445   if (!data)
446     return exception();
447 
448   return llvm::StringRef(data, size);
449 }
450 
GetSize() const451 size_t PythonString::GetSize() const {
452   if (IsValid()) {
453 #if PY_MAJOR_VERSION >= 3
454 #if PY_MINOR_VERSION >= 3
455     return PyUnicode_GetLength(m_py_obj);
456 #else
457     return PyUnicode_GetSize(m_py_obj);
458 #endif
459 #else
460     return PyString_Size(m_py_obj);
461 #endif
462   }
463   return 0;
464 }
465 
SetString(llvm::StringRef string)466 void PythonString::SetString(llvm::StringRef string) {
467   auto s = FromUTF8(string);
468   if (!s) {
469     llvm::consumeError(s.takeError());
470     Reset();
471   } else {
472     *this = std::move(s.get());
473   }
474 }
475 
CreateStructuredString() const476 StructuredData::StringSP PythonString::CreateStructuredString() const {
477   StructuredData::StringSP result(new StructuredData::String);
478   result->SetValue(GetString());
479   return result;
480 }
481 
482 // PythonInteger
483 
PythonInteger(int64_t value)484 PythonInteger::PythonInteger(int64_t value) { SetInteger(value); }
485 
Check(PyObject * py_obj)486 bool PythonInteger::Check(PyObject *py_obj) {
487   if (!py_obj)
488     return false;
489 
490 #if PY_MAJOR_VERSION >= 3
491   // Python 3 does not have PyInt_Check.  There is only one type of integral
492   // value, long.
493   return PyLong_Check(py_obj);
494 #else
495   return PyLong_Check(py_obj) || PyInt_Check(py_obj);
496 #endif
497 }
498 
Convert(PyRefType & type,PyObject * & py_obj)499 void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) {
500 #if PY_MAJOR_VERSION < 3
501   // Always store this as a PyLong, which makes interoperability between Python
502   // 2.x and Python 3.x easier.  This is only necessary in 2.x, since 3.x
503   // doesn't even have a PyInt.
504   if (PyInt_Check(py_obj)) {
505     // Since we converted the original object to a different type, the new
506     // object is an owned object regardless of the ownership semantics
507     // requested by the user.
508     long long value = PyInt_AsLong(py_obj);
509     PyObject *l = nullptr;
510     if (!PyErr_Occurred())
511       l = PyLong_FromLongLong(value);
512     if (l == nullptr) {
513       PyErr_Clear();
514       if (type == PyRefType::Owned)
515         Py_DECREF(py_obj);
516       return;
517     }
518     if (type == PyRefType::Owned)
519       Py_DECREF(py_obj);
520     else
521       type = PyRefType::Owned;
522     py_obj = l;
523   }
524 #endif
525 }
526 
SetInteger(int64_t value)527 void PythonInteger::SetInteger(int64_t value) {
528   *this = Take<PythonInteger>(PyLong_FromLongLong(value));
529 }
530 
CreateStructuredInteger() const531 StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
532   StructuredData::IntegerSP result(new StructuredData::Integer);
533   // FIXME this is really not ideal.   Errors are silently converted to 0
534   // and overflows are silently wrapped.   But we'd need larger changes
535   // to StructuredData to fix it, so that's how it is for now.
536   llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong();
537   if (!value) {
538     llvm::consumeError(value.takeError());
539     result->SetValue(0);
540   } else {
541     result->SetValue(value.get());
542   }
543   return result;
544 }
545 
546 // PythonBoolean
547 
PythonBoolean(bool value)548 PythonBoolean::PythonBoolean(bool value) {
549   SetValue(value);
550 }
551 
Check(PyObject * py_obj)552 bool PythonBoolean::Check(PyObject *py_obj) {
553   return py_obj ? PyBool_Check(py_obj) : false;
554 }
555 
GetValue() const556 bool PythonBoolean::GetValue() const {
557   return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
558 }
559 
SetValue(bool value)560 void PythonBoolean::SetValue(bool value) {
561   *this = Take<PythonBoolean>(PyBool_FromLong(value));
562 }
563 
CreateStructuredBoolean() const564 StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
565   StructuredData::BooleanSP result(new StructuredData::Boolean);
566   result->SetValue(GetValue());
567   return result;
568 }
569 
570 // PythonList
571 
PythonList(PyInitialValue value)572 PythonList::PythonList(PyInitialValue value) {
573   if (value == PyInitialValue::Empty)
574     *this = Take<PythonList>(PyList_New(0));
575 }
576 
PythonList(int list_size)577 PythonList::PythonList(int list_size) {
578   *this = Take<PythonList>(PyList_New(list_size));
579 }
580 
Check(PyObject * py_obj)581 bool PythonList::Check(PyObject *py_obj) {
582   if (!py_obj)
583     return false;
584   return PyList_Check(py_obj);
585 }
586 
GetSize() const587 uint32_t PythonList::GetSize() const {
588   if (IsValid())
589     return PyList_GET_SIZE(m_py_obj);
590   return 0;
591 }
592 
GetItemAtIndex(uint32_t index) const593 PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
594   if (IsValid())
595     return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
596   return PythonObject();
597 }
598 
SetItemAtIndex(uint32_t index,const PythonObject & object)599 void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
600   if (IsAllocated() && object.IsValid()) {
601     // PyList_SetItem is documented to "steal" a reference, so we need to
602     // convert it to an owned reference by incrementing it.
603     Py_INCREF(object.get());
604     PyList_SetItem(m_py_obj, index, object.get());
605   }
606 }
607 
AppendItem(const PythonObject & object)608 void PythonList::AppendItem(const PythonObject &object) {
609   if (IsAllocated() && object.IsValid()) {
610     // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
611     // here like we do with `PyList_SetItem`.
612     PyList_Append(m_py_obj, object.get());
613   }
614 }
615 
CreateStructuredArray() const616 StructuredData::ArraySP PythonList::CreateStructuredArray() const {
617   StructuredData::ArraySP result(new StructuredData::Array);
618   uint32_t count = GetSize();
619   for (uint32_t i = 0; i < count; ++i) {
620     PythonObject obj = GetItemAtIndex(i);
621     result->AddItem(obj.CreateStructuredObject());
622   }
623   return result;
624 }
625 
626 // PythonTuple
627 
PythonTuple(PyInitialValue value)628 PythonTuple::PythonTuple(PyInitialValue value) {
629   if (value == PyInitialValue::Empty)
630     *this = Take<PythonTuple>(PyTuple_New(0));
631 }
632 
PythonTuple(int tuple_size)633 PythonTuple::PythonTuple(int tuple_size) {
634   *this = Take<PythonTuple>(PyTuple_New(tuple_size));
635 }
636 
PythonTuple(std::initializer_list<PythonObject> objects)637 PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
638   m_py_obj = PyTuple_New(objects.size());
639 
640   uint32_t idx = 0;
641   for (auto object : objects) {
642     if (object.IsValid())
643       SetItemAtIndex(idx, object);
644     idx++;
645   }
646 }
647 
PythonTuple(std::initializer_list<PyObject * > objects)648 PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
649   m_py_obj = PyTuple_New(objects.size());
650 
651   uint32_t idx = 0;
652   for (auto py_object : objects) {
653     PythonObject object(PyRefType::Borrowed, py_object);
654     if (object.IsValid())
655       SetItemAtIndex(idx, object);
656     idx++;
657   }
658 }
659 
Check(PyObject * py_obj)660 bool PythonTuple::Check(PyObject *py_obj) {
661   if (!py_obj)
662     return false;
663   return PyTuple_Check(py_obj);
664 }
665 
GetSize() const666 uint32_t PythonTuple::GetSize() const {
667   if (IsValid())
668     return PyTuple_GET_SIZE(m_py_obj);
669   return 0;
670 }
671 
GetItemAtIndex(uint32_t index) const672 PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
673   if (IsValid())
674     return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
675   return PythonObject();
676 }
677 
SetItemAtIndex(uint32_t index,const PythonObject & object)678 void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
679   if (IsAllocated() && object.IsValid()) {
680     // PyTuple_SetItem is documented to "steal" a reference, so we need to
681     // convert it to an owned reference by incrementing it.
682     Py_INCREF(object.get());
683     PyTuple_SetItem(m_py_obj, index, object.get());
684   }
685 }
686 
CreateStructuredArray() const687 StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
688   StructuredData::ArraySP result(new StructuredData::Array);
689   uint32_t count = GetSize();
690   for (uint32_t i = 0; i < count; ++i) {
691     PythonObject obj = GetItemAtIndex(i);
692     result->AddItem(obj.CreateStructuredObject());
693   }
694   return result;
695 }
696 
697 // PythonDictionary
698 
PythonDictionary(PyInitialValue value)699 PythonDictionary::PythonDictionary(PyInitialValue value) {
700   if (value == PyInitialValue::Empty)
701     *this = Take<PythonDictionary>(PyDict_New());
702 }
703 
Check(PyObject * py_obj)704 bool PythonDictionary::Check(PyObject *py_obj) {
705   if (!py_obj)
706     return false;
707 
708   return PyDict_Check(py_obj);
709 }
710 
GetSize() const711 uint32_t PythonDictionary::GetSize() const {
712   if (IsValid())
713     return PyDict_Size(m_py_obj);
714   return 0;
715 }
716 
GetKeys() const717 PythonList PythonDictionary::GetKeys() const {
718   if (IsValid())
719     return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
720   return PythonList(PyInitialValue::Invalid);
721 }
722 
GetItemForKey(const PythonObject & key) const723 PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
724   auto item = GetItem(key);
725   if (!item) {
726     llvm::consumeError(item.takeError());
727     return PythonObject();
728   }
729   return std::move(item.get());
730 }
731 
732 Expected<PythonObject>
GetItem(const PythonObject & key) const733 PythonDictionary::GetItem(const PythonObject &key) const {
734   if (!IsValid())
735     return nullDeref();
736 #if PY_MAJOR_VERSION >= 3
737   PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
738   if (PyErr_Occurred())
739     return exception();
740 #else
741   PyObject *o = PyDict_GetItem(m_py_obj, key.get());
742 #endif
743   if (!o)
744     return keyError();
745   return Retain<PythonObject>(o);
746 }
747 
GetItem(const Twine & key) const748 Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const {
749   if (!IsValid())
750     return nullDeref();
751   PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
752   if (PyErr_Occurred())
753     return exception();
754   if (!o)
755     return keyError();
756   return Retain<PythonObject>(o);
757 }
758 
SetItem(const PythonObject & key,const PythonObject & value) const759 Error PythonDictionary::SetItem(const PythonObject &key,
760                                 const PythonObject &value) const {
761   if (!IsValid() || !value.IsValid())
762     return nullDeref();
763   int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
764   if (r < 0)
765     return exception();
766   return Error::success();
767 }
768 
SetItem(const Twine & key,const PythonObject & value) const769 Error PythonDictionary::SetItem(const Twine &key,
770                                 const PythonObject &value) const {
771   if (!IsValid() || !value.IsValid())
772     return nullDeref();
773   int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
774   if (r < 0)
775     return exception();
776   return Error::success();
777 }
778 
SetItemForKey(const PythonObject & key,const PythonObject & value)779 void PythonDictionary::SetItemForKey(const PythonObject &key,
780                                      const PythonObject &value) {
781   Error error = SetItem(key, value);
782   if (error)
783     llvm::consumeError(std::move(error));
784 }
785 
786 StructuredData::DictionarySP
CreateStructuredDictionary() const787 PythonDictionary::CreateStructuredDictionary() const {
788   StructuredData::DictionarySP result(new StructuredData::Dictionary);
789   PythonList keys(GetKeys());
790   uint32_t num_keys = keys.GetSize();
791   for (uint32_t i = 0; i < num_keys; ++i) {
792     PythonObject key = keys.GetItemAtIndex(i);
793     PythonObject value = GetItemForKey(key);
794     StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
795     result->AddItem(key.Str().GetString(), structured_value);
796   }
797   return result;
798 }
799 
BuiltinsModule()800 PythonModule PythonModule::BuiltinsModule() {
801 #if PY_MAJOR_VERSION >= 3
802   return AddModule("builtins");
803 #else
804   return AddModule("__builtin__");
805 #endif
806 }
807 
MainModule()808 PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
809 
AddModule(llvm::StringRef module)810 PythonModule PythonModule::AddModule(llvm::StringRef module) {
811   std::string str = module.str();
812   return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
813 }
814 
Import(const Twine & name)815 Expected<PythonModule> PythonModule::Import(const Twine &name) {
816   PyObject *mod = PyImport_ImportModule(NullTerminated(name));
817   if (!mod)
818     return exception();
819   return Take<PythonModule>(mod);
820 }
821 
Get(const Twine & name)822 Expected<PythonObject> PythonModule::Get(const Twine &name) {
823   if (!IsValid())
824     return nullDeref();
825   PyObject *dict = PyModule_GetDict(m_py_obj);
826   if (!dict)
827     return exception();
828   PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
829   if (!item)
830     return exception();
831   return Retain<PythonObject>(item);
832 }
833 
Check(PyObject * py_obj)834 bool PythonModule::Check(PyObject *py_obj) {
835   if (!py_obj)
836     return false;
837 
838   return PyModule_Check(py_obj);
839 }
840 
GetDictionary() const841 PythonDictionary PythonModule::GetDictionary() const {
842   if (!IsValid())
843     return PythonDictionary();
844   return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
845 }
846 
Check(PyObject * py_obj)847 bool PythonCallable::Check(PyObject *py_obj) {
848   if (!py_obj)
849     return false;
850 
851   return PyCallable_Check(py_obj);
852 }
853 
854 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
855 static const char get_arg_info_script[] = R"(
856 from inspect import signature, Parameter, ismethod
857 from collections import namedtuple
858 ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
859 def main(f):
860     count = 0
861     varargs = False
862     for parameter in signature(f).parameters.values():
863         kind = parameter.kind
864         if kind in (Parameter.POSITIONAL_ONLY,
865                     Parameter.POSITIONAL_OR_KEYWORD):
866             count += 1
867         elif kind == Parameter.VAR_POSITIONAL:
868             varargs = True
869         elif kind in (Parameter.KEYWORD_ONLY,
870                       Parameter.VAR_KEYWORD):
871             pass
872         else:
873             raise Exception(f'unknown parameter kind: {kind}')
874     return ArgInfo(count, varargs)
875 )";
876 #endif
877 
GetArgInfo() const878 Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
879   ArgInfo result = {};
880   if (!IsValid())
881     return nullDeref();
882 
883 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
884 
885   // no need to synchronize access to this global, we already have the GIL
886   static PythonScript get_arg_info(get_arg_info_script);
887   Expected<PythonObject> pyarginfo = get_arg_info(*this);
888   if (!pyarginfo)
889     return pyarginfo.takeError();
890   long long count =
891       cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
892   bool has_varargs =
893       cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
894   result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
895 
896 #else
897   PyObject *py_func_obj;
898   bool is_bound_method = false;
899   bool is_class = false;
900 
901   if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) {
902     auto init = GetAttribute("__init__");
903     if (!init)
904       return init.takeError();
905     py_func_obj = init.get().get();
906     is_class = true;
907   } else {
908     py_func_obj = m_py_obj;
909   }
910 
911   if (PyMethod_Check(py_func_obj)) {
912     py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
913     PythonObject im_self = GetAttributeValue("im_self");
914     if (im_self.IsValid() && !im_self.IsNone())
915       is_bound_method = true;
916   } else {
917     // see if this is a callable object with an __call__ method
918     if (!PyFunction_Check(py_func_obj)) {
919       PythonObject __call__ = GetAttributeValue("__call__");
920       if (__call__.IsValid()) {
921         auto __callable__ = __call__.AsType<PythonCallable>();
922         if (__callable__.IsValid()) {
923           py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
924           PythonObject im_self = __callable__.GetAttributeValue("im_self");
925           if (im_self.IsValid() && !im_self.IsNone())
926             is_bound_method = true;
927         }
928       }
929     }
930   }
931 
932   if (!py_func_obj)
933     return result;
934 
935   PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
936   if (!code)
937     return result;
938 
939   auto count = code->co_argcount;
940   bool has_varargs = !!(code->co_flags & CO_VARARGS);
941   result.max_positional_args =
942       has_varargs ? ArgInfo::UNBOUNDED
943                   : (count - (int)is_bound_method) - (int)is_class;
944 
945 #endif
946 
947   return result;
948 }
949 
950 constexpr unsigned
951     PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17
952 
operator ()()953 PythonObject PythonCallable::operator()() {
954   return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
955 }
956 
957 PythonObject PythonCallable::
operator ()(std::initializer_list<PyObject * > args)958 operator()(std::initializer_list<PyObject *> args) {
959   PythonTuple arg_tuple(args);
960   return PythonObject(PyRefType::Owned,
961                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
962 }
963 
964 PythonObject PythonCallable::
operator ()(std::initializer_list<PythonObject> args)965 operator()(std::initializer_list<PythonObject> args) {
966   PythonTuple arg_tuple(args);
967   return PythonObject(PyRefType::Owned,
968                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
969 }
970 
Check(PyObject * py_obj)971 bool PythonFile::Check(PyObject *py_obj) {
972   if (!py_obj)
973     return false;
974 #if PY_MAJOR_VERSION < 3
975   return PyFile_Check(py_obj);
976 #else
977   // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
978   // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
979   // over `io.open()`, which returns some object derived from `io.IOBase`. As a
980   // result, the only way to detect a file in Python 3 is to check whether it
981   // inherits from `io.IOBase`.
982   auto io_module = PythonModule::Import("io");
983   if (!io_module) {
984     llvm::consumeError(io_module.takeError());
985     return false;
986   }
987   auto iobase = io_module.get().Get("IOBase");
988   if (!iobase) {
989     llvm::consumeError(iobase.takeError());
990     return false;
991   }
992   int r = PyObject_IsInstance(py_obj, iobase.get().get());
993   if (r < 0) {
994     llvm::consumeError(exception()); // clear the exception and log it.
995     return false;
996   }
997   return !!r;
998 #endif
999 }
1000 
1001 namespace {
1002 class GIL {
1003 public:
GIL()1004   GIL() {
1005     m_state = PyGILState_Ensure();
1006     assert(!PyErr_Occurred());
1007   }
~GIL()1008   ~GIL() { PyGILState_Release(m_state); }
1009 
1010 protected:
1011   PyGILState_STATE m_state;
1012 };
1013 } // namespace
1014 
toCString() const1015 const char *PythonException::toCString() const {
1016   if (!m_repr_bytes)
1017     return "unknown exception";
1018   return PyBytes_AS_STRING(m_repr_bytes);
1019 }
1020 
PythonException(const char * caller)1021 PythonException::PythonException(const char *caller) {
1022   assert(PyErr_Occurred());
1023   m_exception_type = m_exception = m_traceback = m_repr_bytes = NULL;
1024   PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
1025   PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
1026   PyErr_Clear();
1027   if (m_exception) {
1028     PyObject *repr = PyObject_Repr(m_exception);
1029     if (repr) {
1030       m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr);
1031       if (!m_repr_bytes) {
1032         PyErr_Clear();
1033       }
1034       Py_XDECREF(repr);
1035     } else {
1036       PyErr_Clear();
1037     }
1038   }
1039   Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT);
1040   if (caller)
1041     LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString());
1042   else
1043     LLDB_LOGF(log, "python exception: %s", toCString());
1044 }
Restore()1045 void PythonException::Restore() {
1046   if (m_exception_type && m_exception) {
1047     PyErr_Restore(m_exception_type, m_exception, m_traceback);
1048   } else {
1049     PyErr_SetString(PyExc_Exception, toCString());
1050   }
1051   m_exception_type = m_exception = m_traceback = NULL;
1052 }
1053 
~PythonException()1054 PythonException::~PythonException() {
1055   Py_XDECREF(m_exception_type);
1056   Py_XDECREF(m_exception);
1057   Py_XDECREF(m_traceback);
1058   Py_XDECREF(m_repr_bytes);
1059 }
1060 
log(llvm::raw_ostream & OS) const1061 void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); }
1062 
convertToErrorCode() const1063 std::error_code PythonException::convertToErrorCode() const {
1064   return llvm::inconvertibleErrorCode();
1065 }
1066 
Matches(PyObject * exc) const1067 bool PythonException::Matches(PyObject *exc) const {
1068   return PyErr_GivenExceptionMatches(m_exception_type, exc);
1069 }
1070 
1071 const char read_exception_script[] = R"(
1072 import sys
1073 from traceback import print_exception
1074 if sys.version_info.major < 3:
1075   from StringIO import StringIO
1076 else:
1077   from io import StringIO
1078 def main(exc_type, exc_value, tb):
1079   f = StringIO()
1080   print_exception(exc_type, exc_value, tb, file=f)
1081   return f.getvalue()
1082 )";
1083 
ReadBacktrace() const1084 std::string PythonException::ReadBacktrace() const {
1085 
1086   if (!m_traceback)
1087     return toCString();
1088 
1089   // no need to synchronize access to this global, we already have the GIL
1090   static PythonScript read_exception(read_exception_script);
1091 
1092   Expected<std::string> backtrace = As<std::string>(
1093       read_exception(m_exception_type, m_exception, m_traceback));
1094 
1095   if (!backtrace) {
1096     std::string message =
1097         std::string(toCString()) + "\n" +
1098         "Traceback unavailable, an error occurred while reading it:\n";
1099     return (message + llvm::toString(backtrace.takeError()));
1100   }
1101 
1102   return std::move(backtrace.get());
1103 }
1104 
1105 char PythonException::ID = 0;
1106 
1107 llvm::Expected<File::OpenOptions>
GetOptionsForPyObject(const PythonObject & obj)1108 GetOptionsForPyObject(const PythonObject &obj) {
1109 #if PY_MAJOR_VERSION >= 3
1110   auto options = File::OpenOptions(0);
1111   auto readable = As<bool>(obj.CallMethod("readable"));
1112   if (!readable)
1113     return readable.takeError();
1114   auto writable = As<bool>(obj.CallMethod("writable"));
1115   if (!writable)
1116     return writable.takeError();
1117   if (readable.get())
1118     options |= File::eOpenOptionRead;
1119   if (writable.get())
1120     options |= File::eOpenOptionWrite;
1121   return options;
1122 #else
1123   PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
1124   return File::GetOptionsFromMode(py_mode.GetString());
1125 #endif
1126 }
1127 
1128 // Base class template for python files.   All it knows how to do
1129 // is hold a reference to the python object and close or flush it
1130 // when the File is closed.
1131 namespace {
1132 template <typename Base> class OwnedPythonFile : public Base {
1133 public:
1134   template <typename... Args>
OwnedPythonFile(const PythonFile & file,bool borrowed,Args...args)1135   OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args)
1136       : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1137     assert(m_py_obj);
1138   }
1139 
~OwnedPythonFile()1140   ~OwnedPythonFile() override {
1141     assert(m_py_obj);
1142     GIL takeGIL;
1143     Close();
1144     // we need to ensure the python object is released while we still
1145     // hold the GIL
1146     m_py_obj.Reset();
1147   }
1148 
IsPythonSideValid() const1149   bool IsPythonSideValid() const {
1150     GIL takeGIL;
1151     auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
1152     if (!closed) {
1153       llvm::consumeError(closed.takeError());
1154       return false;
1155     }
1156     return !closed.get();
1157   }
1158 
IsValid() const1159   bool IsValid() const override {
1160     return IsPythonSideValid() && Base::IsValid();
1161   }
1162 
Close()1163   Status Close() override {
1164     assert(m_py_obj);
1165     Status py_error, base_error;
1166     GIL takeGIL;
1167     if (!m_borrowed) {
1168       auto r = m_py_obj.CallMethod("close");
1169       if (!r)
1170         py_error = Status(r.takeError());
1171     }
1172     base_error = Base::Close();
1173     if (py_error.Fail())
1174       return py_error;
1175     return base_error;
1176   };
1177 
GetPythonObject() const1178   PyObject *GetPythonObject() const {
1179     assert(m_py_obj.IsValid());
1180     return m_py_obj.get();
1181   }
1182 
1183   static bool classof(const File *file) = delete;
1184 
1185 protected:
1186   PythonFile m_py_obj;
1187   bool m_borrowed;
1188 };
1189 } // namespace
1190 
1191 // A SimplePythonFile is a OwnedPythonFile that just does all I/O as
1192 // a NativeFile
1193 namespace {
1194 class SimplePythonFile : public OwnedPythonFile<NativeFile> {
1195 public:
SimplePythonFile(const PythonFile & file,bool borrowed,int fd,File::OpenOptions options)1196   SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
1197                    File::OpenOptions options)
1198       : OwnedPythonFile(file, borrowed, fd, options, false) {}
1199 
1200   static char ID;
isA(const void * classID) const1201   bool isA(const void *classID) const override {
1202     return classID == &ID || NativeFile::isA(classID);
1203   }
classof(const File * file)1204   static bool classof(const File *file) { return file->isA(&ID); }
1205 };
1206 char SimplePythonFile::ID = 0;
1207 } // namespace
1208 
1209 #if PY_MAJOR_VERSION >= 3
1210 
1211 namespace {
1212 class PythonBuffer {
1213 public:
1214   PythonBuffer &operator=(const PythonBuffer &) = delete;
1215   PythonBuffer(const PythonBuffer &) = delete;
1216 
Create(PythonObject & obj,int flags=PyBUF_SIMPLE)1217   static Expected<PythonBuffer> Create(PythonObject &obj,
1218                                        int flags = PyBUF_SIMPLE) {
1219     Py_buffer py_buffer = {};
1220     PyObject_GetBuffer(obj.get(), &py_buffer, flags);
1221     if (!py_buffer.obj)
1222       return llvm::make_error<PythonException>();
1223     return PythonBuffer(py_buffer);
1224   }
1225 
PythonBuffer(PythonBuffer && other)1226   PythonBuffer(PythonBuffer &&other) {
1227     m_buffer = other.m_buffer;
1228     other.m_buffer.obj = nullptr;
1229   }
1230 
~PythonBuffer()1231   ~PythonBuffer() {
1232     if (m_buffer.obj)
1233       PyBuffer_Release(&m_buffer);
1234   }
1235 
get()1236   Py_buffer &get() { return m_buffer; }
1237 
1238 private:
1239   // takes ownership of the buffer.
PythonBuffer(const Py_buffer & py_buffer)1240   PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {}
1241   Py_buffer m_buffer;
1242 };
1243 } // namespace
1244 
1245 // Shared methods between TextPythonFile and BinaryPythonFile
1246 namespace {
1247 class PythonIOFile : public OwnedPythonFile<File> {
1248 public:
PythonIOFile(const PythonFile & file,bool borrowed)1249   PythonIOFile(const PythonFile &file, bool borrowed)
1250       : OwnedPythonFile(file, borrowed) {}
1251 
~PythonIOFile()1252   ~PythonIOFile() override { Close(); }
1253 
IsValid() const1254   bool IsValid() const override { return IsPythonSideValid(); }
1255 
Close()1256   Status Close() override {
1257     assert(m_py_obj);
1258     GIL takeGIL;
1259     if (m_borrowed)
1260       return Flush();
1261     auto r = m_py_obj.CallMethod("close");
1262     if (!r)
1263       return Status(r.takeError());
1264     return Status();
1265   }
1266 
Flush()1267   Status Flush() override {
1268     GIL takeGIL;
1269     auto r = m_py_obj.CallMethod("flush");
1270     if (!r)
1271       return Status(r.takeError());
1272     return Status();
1273   }
1274 
GetOptions() const1275   Expected<File::OpenOptions> GetOptions() const override {
1276     GIL takeGIL;
1277     return GetOptionsForPyObject(m_py_obj);
1278   }
1279 
1280   static char ID;
isA(const void * classID) const1281   bool isA(const void *classID) const override {
1282     return classID == &ID || File::isA(classID);
1283   }
classof(const File * file)1284   static bool classof(const File *file) { return file->isA(&ID); }
1285 };
1286 char PythonIOFile::ID = 0;
1287 } // namespace
1288 
1289 namespace {
1290 class BinaryPythonFile : public PythonIOFile {
1291 protected:
1292   int m_descriptor;
1293 
1294 public:
BinaryPythonFile(int fd,const PythonFile & file,bool borrowed)1295   BinaryPythonFile(int fd, const PythonFile &file, bool borrowed)
1296       : PythonIOFile(file, borrowed),
1297         m_descriptor(File::DescriptorIsValid(fd) ? fd
1298                                                  : File::kInvalidDescriptor) {}
1299 
GetDescriptor() const1300   int GetDescriptor() const override { return m_descriptor; }
1301 
Write(const void * buf,size_t & num_bytes)1302   Status Write(const void *buf, size_t &num_bytes) override {
1303     GIL takeGIL;
1304     PyObject *pybuffer_p = PyMemoryView_FromMemory(
1305         const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ);
1306     if (!pybuffer_p)
1307       return Status(llvm::make_error<PythonException>());
1308     auto pybuffer = Take<PythonObject>(pybuffer_p);
1309     num_bytes = 0;
1310     auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer));
1311     if (!bytes_written)
1312       return Status(bytes_written.takeError());
1313     if (bytes_written.get() < 0)
1314       return Status(".write() method returned a negative number!");
1315     static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1316     num_bytes = bytes_written.get();
1317     return Status();
1318   }
1319 
Read(void * buf,size_t & num_bytes)1320   Status Read(void *buf, size_t &num_bytes) override {
1321     GIL takeGIL;
1322     static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1323     auto pybuffer_obj =
1324         m_py_obj.CallMethod("read", (unsigned long long)num_bytes);
1325     if (!pybuffer_obj)
1326       return Status(pybuffer_obj.takeError());
1327     num_bytes = 0;
1328     if (pybuffer_obj.get().IsNone()) {
1329       // EOF
1330       num_bytes = 0;
1331       return Status();
1332     }
1333     auto pybuffer = PythonBuffer::Create(pybuffer_obj.get());
1334     if (!pybuffer)
1335       return Status(pybuffer.takeError());
1336     memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len);
1337     num_bytes = pybuffer.get().get().len;
1338     return Status();
1339   }
1340 };
1341 } // namespace
1342 
1343 namespace {
1344 class TextPythonFile : public PythonIOFile {
1345 protected:
1346   int m_descriptor;
1347 
1348 public:
TextPythonFile(int fd,const PythonFile & file,bool borrowed)1349   TextPythonFile(int fd, const PythonFile &file, bool borrowed)
1350       : PythonIOFile(file, borrowed),
1351         m_descriptor(File::DescriptorIsValid(fd) ? fd
1352                                                  : File::kInvalidDescriptor) {}
1353 
GetDescriptor() const1354   int GetDescriptor() const override { return m_descriptor; }
1355 
Write(const void * buf,size_t & num_bytes)1356   Status Write(const void *buf, size_t &num_bytes) override {
1357     GIL takeGIL;
1358     auto pystring =
1359         PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes));
1360     if (!pystring)
1361       return Status(pystring.takeError());
1362     num_bytes = 0;
1363     auto bytes_written =
1364         As<long long>(m_py_obj.CallMethod("write", pystring.get()));
1365     if (!bytes_written)
1366       return Status(bytes_written.takeError());
1367     if (bytes_written.get() < 0)
1368       return Status(".write() method returned a negative number!");
1369     static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1370     num_bytes = bytes_written.get();
1371     return Status();
1372   }
1373 
Read(void * buf,size_t & num_bytes)1374   Status Read(void *buf, size_t &num_bytes) override {
1375     GIL takeGIL;
1376     size_t num_chars = num_bytes / 6;
1377     size_t orig_num_bytes = num_bytes;
1378     num_bytes = 0;
1379     if (orig_num_bytes < 6) {
1380       return Status("can't read less than 6 bytes from a utf8 text stream");
1381     }
1382     auto pystring = As<PythonString>(
1383         m_py_obj.CallMethod("read", (unsigned long long)num_chars));
1384     if (!pystring)
1385       return Status(pystring.takeError());
1386     if (pystring.get().IsNone()) {
1387       // EOF
1388       return Status();
1389     }
1390     auto stringref = pystring.get().AsUTF8();
1391     if (!stringref)
1392       return Status(stringref.takeError());
1393     num_bytes = stringref.get().size();
1394     memcpy(buf, stringref.get().begin(), num_bytes);
1395     return Status();
1396   }
1397 };
1398 } // namespace
1399 
1400 #endif
1401 
ConvertToFile(bool borrowed)1402 llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
1403   if (!IsValid())
1404     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1405                                    "invalid PythonFile");
1406 
1407   int fd = PyObject_AsFileDescriptor(m_py_obj);
1408   if (fd < 0) {
1409     PyErr_Clear();
1410     return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1411   }
1412   auto options = GetOptionsForPyObject(*this);
1413   if (!options)
1414     return options.takeError();
1415 
1416   if (options.get() & File::eOpenOptionWrite) {
1417     // LLDB and python will not share I/O buffers.  We should probably
1418     // flush the python buffers now.
1419     auto r = CallMethod("flush");
1420     if (!r)
1421       return r.takeError();
1422   }
1423 
1424   FileSP file_sp;
1425   if (borrowed) {
1426     // In this case we we don't need to retain the python
1427     // object at all.
1428     file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
1429   } else {
1430     file_sp = std::static_pointer_cast<File>(
1431         std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get()));
1432   }
1433   if (!file_sp->IsValid())
1434     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1435                                    "invalid File");
1436 
1437   return file_sp;
1438 }
1439 
1440 llvm::Expected<FileSP>
ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed)1441 PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) {
1442 
1443   assert(!PyErr_Occurred());
1444 
1445   if (!IsValid())
1446     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1447                                    "invalid PythonFile");
1448 
1449 #if PY_MAJOR_VERSION < 3
1450 
1451   return llvm::createStringError(llvm::inconvertibleErrorCode(),
1452                                  "not supported on python 2");
1453 
1454 #else
1455 
1456   int fd = PyObject_AsFileDescriptor(m_py_obj);
1457   if (fd < 0) {
1458     PyErr_Clear();
1459     fd = File::kInvalidDescriptor;
1460   }
1461 
1462   auto io_module = PythonModule::Import("io");
1463   if (!io_module)
1464     return io_module.takeError();
1465   auto textIOBase = io_module.get().Get("TextIOBase");
1466   if (!textIOBase)
1467     return textIOBase.takeError();
1468   auto rawIOBase = io_module.get().Get("RawIOBase");
1469   if (!rawIOBase)
1470     return rawIOBase.takeError();
1471   auto bufferedIOBase = io_module.get().Get("BufferedIOBase");
1472   if (!bufferedIOBase)
1473     return bufferedIOBase.takeError();
1474 
1475   FileSP file_sp;
1476 
1477   auto isTextIO = IsInstance(textIOBase.get());
1478   if (!isTextIO)
1479     return isTextIO.takeError();
1480   if (isTextIO.get())
1481     file_sp = std::static_pointer_cast<File>(
1482         std::make_shared<TextPythonFile>(fd, *this, borrowed));
1483 
1484   auto isRawIO = IsInstance(rawIOBase.get());
1485   if (!isRawIO)
1486     return isRawIO.takeError();
1487   auto isBufferedIO = IsInstance(bufferedIOBase.get());
1488   if (!isBufferedIO)
1489     return isBufferedIO.takeError();
1490 
1491   if (isRawIO.get() || isBufferedIO.get()) {
1492     file_sp = std::static_pointer_cast<File>(
1493         std::make_shared<BinaryPythonFile>(fd, *this, borrowed));
1494   }
1495 
1496   if (!file_sp)
1497     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1498                                    "python file is neither text nor binary");
1499 
1500   if (!file_sp->IsValid())
1501     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1502                                    "invalid File");
1503 
1504   return file_sp;
1505 
1506 #endif
1507 }
1508 
FromFile(File & file,const char * mode)1509 Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
1510   if (!file.IsValid())
1511     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1512                                    "invalid file");
1513 
1514   if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1515     return Retain<PythonFile>(simple->GetPythonObject());
1516 #if PY_MAJOR_VERSION >= 3
1517   if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1518     return Retain<PythonFile>(pythonio->GetPythonObject());
1519 #endif
1520 
1521   if (!mode) {
1522     auto m = file.GetOpenMode();
1523     if (!m)
1524       return m.takeError();
1525     mode = m.get();
1526   }
1527 
1528   PyObject *file_obj;
1529 #if PY_MAJOR_VERSION >= 3
1530   file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
1531                            "ignore", nullptr, /*closefd=*/0);
1532 #else
1533   // I'd like to pass ::fflush here if the file is writable,  so that
1534   // when the python side destructs the file object it will be flushed.
1535   // However, this would be dangerous.    It can cause fflush to be called
1536   // after fclose if the python program keeps a reference to the file after
1537   // the original lldb_private::File has been destructed.
1538   //
1539   // It's all well and good to ask a python program not to use a closed file
1540   // but asking a python program to make sure objects get released in a
1541   // particular order is not safe.
1542   //
1543   // The tradeoff here is that if a python 2 program wants to make sure this
1544   // file gets flushed, they'll have to do it explicitly or wait untill the
1545   // original lldb File itself gets flushed.
1546   file_obj = PyFile_FromFile(file.GetStream(), py2_const_cast(""),
1547                              py2_const_cast(mode), [](FILE *) { return 0; });
1548 #endif
1549 
1550   if (!file_obj)
1551     return exception();
1552 
1553   return Take<PythonFile>(file_obj);
1554 }
1555 
Init()1556 Error PythonScript::Init() {
1557   if (function.IsValid())
1558     return Error::success();
1559 
1560   PythonDictionary globals(PyInitialValue::Empty);
1561   auto builtins = PythonModule::BuiltinsModule();
1562   if (Error error = globals.SetItem("__builtins__", builtins))
1563     return error;
1564   PyObject *o =
1565       PyRun_String(script, Py_file_input, globals.get(), globals.get());
1566   if (!o)
1567     return exception();
1568   Take<PythonObject>(o);
1569   auto f = As<PythonCallable>(globals.GetItem("main"));
1570   if (!f)
1571     return f.takeError();
1572   function = std::move(f.get());
1573 
1574   return Error::success();
1575 }
1576 
1577 llvm::Expected<PythonObject>
runStringOneLine(const llvm::Twine & string,const PythonDictionary & globals,const PythonDictionary & locals)1578 python::runStringOneLine(const llvm::Twine &string,
1579                          const PythonDictionary &globals,
1580                          const PythonDictionary &locals) {
1581   if (!globals.IsValid() || !locals.IsValid())
1582     return nullDeref();
1583 
1584   PyObject *code =
1585       Py_CompileString(NullTerminated(string), "<string>", Py_eval_input);
1586   if (!code) {
1587     PyErr_Clear();
1588     code =
1589         Py_CompileString(NullTerminated(string), "<string>", Py_single_input);
1590   }
1591   if (!code)
1592     return exception();
1593   auto code_ref = Take<PythonObject>(code);
1594 
1595 #if PY_MAJOR_VERSION < 3
1596   PyObject *result =
1597       PyEval_EvalCode((PyCodeObject *)code, globals.get(), locals.get());
1598 #else
1599   PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1600 #endif
1601 
1602   if (!result)
1603     return exception();
1604 
1605   return Take<PythonObject>(result);
1606 }
1607 
1608 llvm::Expected<PythonObject>
runStringMultiLine(const llvm::Twine & string,const PythonDictionary & globals,const PythonDictionary & locals)1609 python::runStringMultiLine(const llvm::Twine &string,
1610                            const PythonDictionary &globals,
1611                            const PythonDictionary &locals) {
1612   if (!globals.IsValid() || !locals.IsValid())
1613     return nullDeref();
1614   PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
1615                                   globals.get(), locals.get());
1616   if (!result)
1617     return exception();
1618   return Take<PythonObject>(result);
1619 }
1620 
1621 #endif
1622