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