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