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