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