9#include "lldb/Host/Config.h"
23#include "llvm/ADT/ScopeExit.h"
24#include "llvm/Support/Casting.h"
25#include "llvm/Support/ConvertUTF.h"
26#include "llvm/Support/Errno.h"
39template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
41 return obj.takeError();
42 return obj.get().IsTrue();
46Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
48 return obj.takeError();
49 return obj->AsLongLong();
53Expected<unsigned long long>
54python::As<unsigned long long>(Expected<PythonObject> &&obj) {
56 return obj.takeError();
57 return obj->AsUnsignedLongLong();
61Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
63 return obj.takeError();
64 PyObject *str_obj = PyObject_Str(obj.get().get());
66 return llvm::make_error<PythonException>();
67 auto str = Take<PythonString>(str_obj);
68 auto utf8 = str.AsUTF8();
70 return utf8.takeError();
71 return std::string(utf8.get());
74void PythonObject::Reset() {
75 if (m_py_obj && Py_IsInitialized()) {
76 PyGILState_STATE state = PyGILState_Ensure();
78 PyGILState_Release(state);
83Expected<long long> PythonObject::AsLongLong()
const {
86 assert(!PyErr_Occurred());
87 long long r = PyLong_AsLongLong(m_py_obj);
93Expected<unsigned long long> PythonObject::AsUnsignedLongLong()
const {
96 assert(!PyErr_Occurred());
97 long long r = PyLong_AsUnsignedLongLong(m_py_obj);
104Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong()
const {
107 assert(!PyErr_Occurred());
108 unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
110 if (PyErr_Occurred())
115void StructuredPythonObject::Serialize(llvm::json::OStream &s)
const {
116 s.value(llvm::formatv(
"Python Obj: {0:X}", GetValue()).str());
121void PythonObject::Dump(
Stream &strm)
const {
127 PyObject *py_str = PyObject_Repr(m_py_obj);
131 auto release_py_str = llvm::make_scope_exit([py_str] { Py_DECREF(py_str); });
133 PyObject *py_bytes = PyUnicode_AsEncodedString(py_str,
"utf-8",
"replace");
137 auto release_py_bytes =
138 llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
140 char *buffer =
nullptr;
141 Py_ssize_t length = 0;
142 if (PyBytes_AsStringAndSize(py_bytes, &buffer, &length) == -1)
145 strm << llvm::StringRef(buffer, length);
148PyObjectType PythonObject::GetObjectType()
const {
150 return PyObjectType::None;
152 if (PythonModule::Check(m_py_obj))
153 return PyObjectType::Module;
154 if (PythonList::Check(m_py_obj))
155 return PyObjectType::List;
156 if (PythonTuple::Check(m_py_obj))
157 return PyObjectType::Tuple;
158 if (PythonDictionary::Check(m_py_obj))
159 return PyObjectType::Dictionary;
160 if (PythonString::Check(m_py_obj))
161 return PyObjectType::String;
162 if (PythonBytes::Check(m_py_obj))
163 return PyObjectType::Bytes;
164 if (PythonByteArray::Check(m_py_obj))
165 return PyObjectType::ByteArray;
166 if (PythonBoolean::Check(m_py_obj))
167 return PyObjectType::Boolean;
168 if (PythonInteger::Check(m_py_obj))
169 return PyObjectType::Integer;
170 if (PythonFile::Check(m_py_obj))
171 return PyObjectType::File;
172 if (PythonCallable::Check(m_py_obj))
173 return PyObjectType::Callable;
174 return PyObjectType::Unknown;
177PythonString PythonObject::Repr()
const {
179 return PythonString();
180 PyObject *repr = PyObject_Repr(m_py_obj);
182 return PythonString();
183 return PythonString(PyRefType::Owned, repr);
186PythonString PythonObject::Str()
const {
188 return PythonString();
189 PyObject *str = PyObject_Str(m_py_obj);
191 return PythonString();
192 return PythonString(PyRefType::Owned, str);
196PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
197 const PythonDictionary &dict) {
198 size_t dot_pos = name.find(
'.');
199 llvm::StringRef piece = name.substr(0, dot_pos);
200 PythonObject result = dict.GetItemForKey(PythonString(piece));
201 if (dot_pos == llvm::StringRef::npos) {
208 return result.ResolveName(name.substr(dot_pos + 1));
211PythonObject PythonObject::ResolveName(llvm::StringRef name)
const {
222 size_t dot_pos = name.find(
'.');
223 if (dot_pos == llvm::StringRef::npos) {
226 return GetAttributeValue(name);
231 PythonObject parent = ResolveName(name.substr(0, dot_pos));
232 if (!parent.IsAllocated())
233 return PythonObject();
236 return parent.ResolveName(name.substr(dot_pos + 1));
239bool PythonObject::HasAttribute(llvm::StringRef attr)
const {
242 PythonString py_attr(attr);
243 return !!PyObject_HasAttr(m_py_obj, py_attr.get());
246PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr)
const {
248 return PythonObject();
250 PythonString py_attr(attr);
251 if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
252 return PythonObject();
254 return PythonObject(PyRefType::Owned,
255 PyObject_GetAttr(m_py_obj, py_attr.get()));
259 switch (GetObjectType()) {
260 case PyObjectType::Dictionary:
261 return PythonDictionary(PyRefType::Borrowed, m_py_obj)
262 .CreateStructuredDictionary();
263 case PyObjectType::Boolean:
264 return PythonBoolean(PyRefType::Borrowed, m_py_obj)
265 .CreateStructuredBoolean();
266 case PyObjectType::Integer: {
268 PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
269 if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
270 return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
271 if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
272 return std::get<StructuredData::SignedIntegerSP>(int_sp);
275 case PyObjectType::List:
276 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
277 case PyObjectType::String:
278 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
279 case PyObjectType::Bytes:
280 return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
281 case PyObjectType::ByteArray:
282 return PythonByteArray(PyRefType::Borrowed, m_py_obj)
283 .CreateStructuredString();
284 case PyObjectType::None:
288 PythonObject(PyRefType::Borrowed, m_py_obj)));
294PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
296PythonBytes::PythonBytes(
const uint8_t *bytes,
size_t length) {
297 SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
300bool PythonBytes::Check(PyObject *py_obj) {
303 return PyBytes_Check(py_obj);
306llvm::ArrayRef<uint8_t> PythonBytes::GetBytes()
const {
308 return llvm::ArrayRef<uint8_t>();
313 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
314 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
317size_t PythonBytes::GetSize()
const {
320 return PyBytes_Size(m_py_obj);
323void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
324 const char *data =
reinterpret_cast<const char *
>(bytes.data());
325 *
this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
332 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
333 result->SetValue(std::string(c, size));
337PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
338 : PythonByteArray(bytes.data(), bytes.size()) {}
340PythonByteArray::PythonByteArray(
const uint8_t *bytes,
size_t length) {
341 const char *str =
reinterpret_cast<const char *
>(bytes);
342 *
this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
345bool PythonByteArray::Check(PyObject *py_obj) {
348 return PyByteArray_Check(py_obj);
351llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes()
const {
353 return llvm::ArrayRef<uint8_t>();
355 char *c = PyByteArray_AsString(m_py_obj);
356 size_t size = GetSize();
357 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
360size_t PythonByteArray::GetSize()
const {
364 return PyByteArray_Size(m_py_obj);
369 llvm::ArrayRef<uint8_t> bytes =
GetBytes();
370 const char *str =
reinterpret_cast<const char *
>(bytes.data());
371 result->SetValue(std::string(str, bytes.size()));
377Expected<PythonString> PythonString::FromUTF8(llvm::StringRef
string) {
378 PyObject *str = PyUnicode_FromStringAndSize(
string.data(),
string.size());
380 return llvm::make_error<PythonException>();
381 return Take<PythonString>(str);
384PythonString::PythonString(llvm::StringRef
string) { SetString(
string); }
386bool PythonString::Check(PyObject *py_obj) {
390 if (PyUnicode_Check(py_obj))
395llvm::StringRef PythonString::GetString()
const {
398 llvm::consumeError(s.takeError());
399 return llvm::StringRef(
"");
404Expected<llvm::StringRef> PythonString::AsUTF8()
const {
413#if defined(Py_LIMITED_API) && (Py_LIMITED_API < 0x030a0000)
414 PyObject *py_bytes = PyUnicode_AsUTF8String(m_py_obj);
417 auto release_py_str =
418 llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
419 Py_ssize_t size = PyBytes_Size(py_bytes);
420 const char *str = PyBytes_AsString(py_bytes);
428 const char *str = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
433 return llvm::StringRef(str, size);
437size_t PythonString::GetSize()
const {
439 return PyUnicode_GetLength(m_py_obj);
443void PythonString::SetString(llvm::StringRef
string) {
444 auto s = FromUTF8(
string);
446 llvm::consumeError(s.takeError());
449 *
this = std::move(s.get());
455 result->SetValue(GetString());
461PythonInteger::PythonInteger(int64_t value) {
SetInteger(value); }
463bool PythonInteger::Check(PyObject *py_obj) {
469 return PyLong_Check(py_obj);
472void PythonInteger::SetInteger(int64_t value) {
473 *
this = Take<PythonInteger>(PyLong_FromLongLong(value));
479 : CreateStructuredSignedInteger();
483PythonInteger::CreateStructuredUnsignedInteger()
const {
485 llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
487 llvm::consumeError(value.takeError());
489 result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
495PythonInteger::CreateStructuredSignedInteger()
const {
497 llvm::Expected<long long> value = AsLongLong();
499 llvm::consumeError(value.takeError());
501 result = std::make_shared<StructuredData::SignedInteger>(value.get());
508PythonBoolean::PythonBoolean(
bool value) { SetValue(value); }
510bool PythonBoolean::Check(PyObject *py_obj) {
511 return py_obj ? PyBool_Check(py_obj) : false;
514bool PythonBoolean::GetValue()
const {
515 return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
518void PythonBoolean::SetValue(
bool value) {
519 *
this = Take<PythonBoolean>(PyBool_FromLong(value));
524 result->SetValue(GetValue());
530PythonList::PythonList(PyInitialValue value) {
531 if (value == PyInitialValue::Empty)
532 *
this = Take<PythonList>(PyList_New(0));
535PythonList::PythonList(
int list_size) {
536 *
this = Take<PythonList>(PyList_New(list_size));
539bool PythonList::Check(PyObject *py_obj) {
542 return PyList_Check(py_obj);
545uint32_t PythonList::GetSize()
const {
547 return PyList_Size(m_py_obj);
551PythonObject PythonList::GetItemAtIndex(uint32_t index)
const {
553 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
554 return PythonObject();
557void PythonList::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
558 if (IsAllocated() &&
object.IsValid()) {
561 Py_INCREF(
object.get());
562 PyList_SetItem(m_py_obj, index,
object.get());
566void PythonList::AppendItem(
const PythonObject &
object) {
567 if (IsAllocated() &&
object.IsValid()) {
570 PyList_Append(m_py_obj,
object.get());
576 uint32_t count = GetSize();
577 for (uint32_t i = 0; i < count; ++i) {
578 PythonObject obj = GetItemAtIndex(i);
579 result->AddItem(obj.CreateStructuredObject());
586PythonTuple::PythonTuple(PyInitialValue value) {
587 if (value == PyInitialValue::Empty)
588 *
this = Take<PythonTuple>(PyTuple_New(0));
591PythonTuple::PythonTuple(
int tuple_size) {
592 *
this = Take<PythonTuple>(PyTuple_New(tuple_size));
595PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
596 m_py_obj = PyTuple_New(objects.size());
599 for (
auto object : objects) {
600 if (
object.IsValid())
601 SetItemAtIndex(idx,
object);
606PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
607 m_py_obj = PyTuple_New(objects.size());
610 for (
auto py_object : objects) {
611 PythonObject object(PyRefType::Borrowed, py_object);
612 if (
object.IsValid())
613 SetItemAtIndex(idx,
object);
618bool PythonTuple::Check(PyObject *py_obj) {
621 return PyTuple_Check(py_obj);
624uint32_t PythonTuple::GetSize()
const {
626 return PyTuple_Size(m_py_obj);
630PythonObject PythonTuple::GetItemAtIndex(uint32_t index)
const {
632 return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
633 return PythonObject();
636void PythonTuple::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
637 if (IsAllocated() &&
object.IsValid()) {
640 Py_INCREF(
object.get());
641 PyTuple_SetItem(m_py_obj, index,
object.get());
647 uint32_t count = GetSize();
648 for (uint32_t i = 0; i < count; ++i) {
649 PythonObject obj = GetItemAtIndex(i);
650 result->AddItem(obj.CreateStructuredObject());
657PythonDictionary::PythonDictionary(PyInitialValue value) {
658 if (value == PyInitialValue::Empty)
659 *
this = Take<PythonDictionary>(PyDict_New());
662bool PythonDictionary::Check(PyObject *py_obj) {
666 return PyDict_Check(py_obj);
669bool PythonDictionary::HasKey(
const llvm::Twine &key)
const {
673 PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef()
676 if (
int res = PyDict_Contains(m_py_obj, key_object.get()) > 0)
683uint32_t PythonDictionary::GetSize()
const {
685 return PyDict_Size(m_py_obj);
689PythonList PythonDictionary::GetKeys()
const {
691 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
692 return PythonList(PyInitialValue::Invalid);
695PythonObject PythonDictionary::GetItemForKey(
const PythonObject &key)
const {
696 auto item = GetItem(key);
698 llvm::consumeError(item.takeError());
699 return PythonObject();
701 return std::move(item.get());
704Expected<PythonObject>
705PythonDictionary::GetItem(
const PythonObject &key)
const {
708 PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
709 if (PyErr_Occurred())
713 return Retain<PythonObject>(o);
716Expected<PythonObject> PythonDictionary::GetItem(
const Twine &key)
const {
719 PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
720 if (PyErr_Occurred())
724 return Retain<PythonObject>(o);
727Error PythonDictionary::SetItem(
const PythonObject &key,
728 const PythonObject &value)
const {
729 if (!IsValid() || !value.IsValid())
731 int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
734 return Error::success();
737Error PythonDictionary::SetItem(
const Twine &key,
738 const PythonObject &value)
const {
739 if (!IsValid() || !value.IsValid())
741 int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
744 return Error::success();
747void PythonDictionary::SetItemForKey(
const PythonObject &key,
748 const PythonObject &value) {
751 llvm::consumeError(std::move(
error));
755PythonDictionary::CreateStructuredDictionary()
const {
757 PythonList keys(GetKeys());
758 uint32_t num_keys = keys.GetSize();
759 for (uint32_t i = 0; i < num_keys; ++i) {
760 PythonObject key = keys.GetItemAtIndex(i);
761 PythonObject value = GetItemForKey(key);
763 result->AddItem(key.Str().GetString(), structured_value);
768PythonModule PythonModule::BuiltinsModule() {
return AddModule(
"builtins"); }
770PythonModule PythonModule::MainModule() {
return AddModule(
"__main__"); }
772PythonModule PythonModule::AddModule(llvm::StringRef module) {
773 std::string str =
module.str();
774 return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
777Expected<PythonModule> PythonModule::Import(
const Twine &name) {
778 PyObject *mod = PyImport_ImportModule(NullTerminated(name));
781 return Take<PythonModule>(mod);
784Expected<PythonObject> PythonModule::Get(
const Twine &name) {
787 PyObject *dict = PyModule_GetDict(m_py_obj);
790 PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
793 return Retain<PythonObject>(item);
796bool PythonModule::Check(PyObject *py_obj) {
800 return PyModule_Check(py_obj);
803PythonDictionary PythonModule::GetDictionary()
const {
805 return PythonDictionary();
806 return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
809bool PythonCallable::Check(PyObject *py_obj) {
813 return PyCallable_Check(py_obj);
816static const char get_arg_info_script[] = R
"(
817from inspect import signature, Parameter, ismethod
818from collections import namedtuple
819ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
823 for parameter in signature(f).parameters.values():
824 kind = parameter.kind
825 if kind in (Parameter.POSITIONAL_ONLY,
826 Parameter.POSITIONAL_OR_KEYWORD):
828 elif kind == Parameter.VAR_POSITIONAL:
830 elif kind in (Parameter.KEYWORD_ONLY,
831 Parameter.VAR_KEYWORD):
834 raise Exception(f'unknown parameter kind: {kind}')
835 return ArgInfo(count, varargs)
838Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
844 static PythonScript get_arg_info(get_arg_info_script);
845 Expected<PythonObject> pyarginfo = get_arg_info(*
this);
847 return pyarginfo.takeError();
849 cantFail(As<long long>(pyarginfo.get().GetAttribute(
"count")));
851 cantFail(As<bool>(pyarginfo.get().GetAttribute(
"has_varargs")));
852 result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
858 PythonCallable::ArgInfo::UNBOUNDED;
860PythonObject PythonCallable::operator()() {
861 return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj,
nullptr));
865PythonCallable::operator()(std::initializer_list<PyObject *> args) {
866 PythonTuple arg_tuple(args);
867 return PythonObject(PyRefType::Owned,
868 PyObject_CallObject(m_py_obj, arg_tuple.get()));
872PythonCallable::operator()(std::initializer_list<PythonObject> args) {
873 PythonTuple arg_tuple(args);
874 return PythonObject(PyRefType::Owned,
875 PyObject_CallObject(m_py_obj, arg_tuple.get()));
878bool PythonFile::Check(PyObject *py_obj) {
886 auto io_module = PythonModule::Import(
"io");
888 llvm::consumeError(io_module.takeError());
891 auto iobase = io_module.get().Get(
"IOBase");
893 llvm::consumeError(iobase.takeError());
896 int r = PyObject_IsInstance(py_obj, iobase.get().get());
898 llvm::consumeError(exception());
904const char *PythonException::toCString()
const {
906 return "unknown exception";
907 return PyBytes_AsString(m_repr_bytes);
910PythonException::PythonException(
const char *caller) {
911 assert(PyErr_Occurred());
912 m_exception_type = m_exception = m_traceback = m_repr_bytes =
nullptr;
913 PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
914 PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
917 PyObject *repr = PyObject_Repr(m_exception);
919 m_repr_bytes = PyUnicode_AsEncodedString(repr,
"utf-8",
nullptr);
930 LLDB_LOGF(log,
"%s failed with exception: %s", caller, toCString());
932 LLDB_LOGF(log,
"python exception: %s", toCString());
934void PythonException::Restore() {
935 if (m_exception_type && m_exception) {
936 PyErr_Restore(m_exception_type, m_exception, m_traceback);
938 PyErr_SetString(PyExc_Exception, toCString());
940 m_exception_type = m_exception = m_traceback =
nullptr;
943PythonException::~PythonException() {
944 Py_XDECREF(m_exception_type);
945 Py_XDECREF(m_exception);
946 Py_XDECREF(m_traceback);
947 Py_XDECREF(m_repr_bytes);
950void PythonException::log(llvm::raw_ostream &
OS)
const {
OS << toCString(); }
952std::error_code PythonException::convertToErrorCode()
const {
953 return llvm::inconvertibleErrorCode();
956bool PythonException::Matches(PyObject *exc)
const {
957 return PyErr_GivenExceptionMatches(m_exception_type, exc);
960const char read_exception_script[] = R
"(
962from traceback import print_exception
963if sys.version_info.major < 3:
964 from StringIO import StringIO
966 from io import StringIO
967def main(exc_type, exc_value, tb):
969 print_exception(exc_type, exc_value, tb, file=f)
973std::string PythonException::ReadBacktrace() const {
979 static PythonScript read_exception(read_exception_script);
981 Expected<std::string> backtrace = As<std::string>(
982 read_exception(m_exception_type, m_exception, m_traceback));
985 std::string message =
986 std::string(toCString()) +
"\n" +
987 "Traceback unavailable, an error occurred while reading it:\n";
988 return (message + llvm::toString(backtrace.takeError()));
991 return std::move(backtrace.get());
994char PythonException::ID = 0;
996llvm::Expected<File::OpenOptions>
997GetOptionsForPyObject(
const PythonObject &obj) {
999 auto readable = As<bool>(obj.CallMethod(
"readable"));
1001 return readable.takeError();
1002 auto writable = As<bool>(obj.CallMethod(
"writable"));
1004 return writable.takeError();
1005 if (readable.get() && writable.get())
1007 else if (writable.get())
1009 else if (readable.get())
1018template <
typename Base>
class OwnedPythonFile :
public Base {
1020 template <
typename... Args>
1021 OwnedPythonFile(
const PythonFile &file,
bool borrowed, Args... args)
1022 : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1026 ~OwnedPythonFile()
override {
1035 bool IsPythonSideValid()
const {
1037 auto closed = As<bool>(m_py_obj.GetAttribute(
"closed"));
1039 llvm::consumeError(closed.takeError());
1042 return !closed.get();
1045 bool IsValid()
const override {
1046 return IsPythonSideValid() && Base::IsValid();
1049 Status Close()
override {
1051 Status py_error, base_error;
1054 auto r = m_py_obj.CallMethod(
"close");
1056 py_error = Status::FromError(r.takeError());
1058 base_error = Base::Close();
1060 if (py_error.Fail())
1061 return py_error.Clone();
1062 return base_error.Clone();
1065 PyObject *GetPythonObject()
const {
1066 assert(m_py_obj.IsValid());
1067 return m_py_obj.get();
1070 static bool classof(
const File *file) =
delete;
1073 PythonFile m_py_obj;
1081class SimplePythonFile :
public OwnedPythonFile<NativeFile> {
1083 SimplePythonFile(
const PythonFile &file,
bool borrowed,
int fd,
1084 File::OpenOptions options)
1085 : OwnedPythonFile(file, borrowed, fd, options, false) {}
1088 bool isA(
const void *classID)
const override {
1089 return classID == &
ID || NativeFile::isA(classID);
1091 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1093char SimplePythonFile::ID = 0;
1098class PythonIOFile :
public OwnedPythonFile<File> {
1100 PythonIOFile(
const PythonFile &file,
bool borrowed)
1101 : OwnedPythonFile(file, borrowed) {}
1103 ~PythonIOFile()
override { Close(); }
1105 bool IsValid()
const override {
return IsPythonSideValid(); }
1107 Status Close()
override {
1112 auto r = m_py_obj.CallMethod(
"close");
1115 return Status::FromError(r.takeError()).Clone();
1119 Status Flush()
override {
1121 auto r = m_py_obj.CallMethod(
"flush");
1124 return Status::FromError(r.takeError()).Clone();
1128 Expected<File::OpenOptions> GetOptions()
const override {
1130 return GetOptionsForPyObject(m_py_obj);
1134 bool isA(
const void *classID)
const override {
1135 return classID == &
ID || File::isA(classID);
1137 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1139char PythonIOFile::ID = 0;
1143class BinaryPythonFile :
public PythonIOFile {
1148 BinaryPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1149 : PythonIOFile(file, borrowed),
1150 m_descriptor(File::DescriptorIsValid(fd) ? fd
1151 : File::kInvalidDescriptor) {}
1153 int GetDescriptor()
const override {
return m_descriptor; }
1155 Status Write(
const void *buf,
size_t &num_bytes)
override {
1157 PyObject *pybuffer_p = PyMemoryView_FromMemory(
1158 const_cast<char *
>((
const char *)buf), num_bytes, PyBUF_READ);
1161 return Status::FromError(llvm::make_error<PythonException>()).Clone();
1162 auto pybuffer = Take<PythonObject>(pybuffer_p);
1164 auto bytes_written = As<long long>(m_py_obj.CallMethod(
"write", pybuffer));
1166 return Status::FromError(bytes_written.takeError());
1167 if (bytes_written.get() < 0)
1168 return Status::FromErrorString(
1169 ".write() method returned a negative number!");
1170 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1171 num_bytes = bytes_written.get();
1175 Status Read(
void *buf,
size_t &num_bytes)
override {
1177 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1179 m_py_obj.CallMethod(
"read", (
unsigned long long)num_bytes);
1182 return Status::FromError(pybuffer_obj.takeError()).Clone();
1184 if (pybuffer_obj.get().IsNone()) {
1189 PythonBytes pybytes(PyRefType::Borrowed, pybuffer_obj->get());
1191 return Status::FromError(llvm::make_error<PythonException>());
1192 llvm::ArrayRef<uint8_t> bytes = pybytes.GetBytes();
1193 memcpy(buf, bytes.begin(), bytes.size());
1194 num_bytes = bytes.size();
1201class TextPythonFile :
public PythonIOFile {
1206 TextPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1207 : PythonIOFile(file, borrowed),
1208 m_descriptor(File::DescriptorIsValid(fd) ? fd
1209 : File::kInvalidDescriptor) {}
1211 int GetDescriptor()
const override {
return m_descriptor; }
1213 Status Write(
const void *buf,
size_t &num_bytes)
override {
1216 PythonString::FromUTF8(llvm::StringRef((
const char *)buf, num_bytes));
1218 return Status::FromError(pystring.takeError());
1220 auto bytes_written =
1221 As<long long>(m_py_obj.CallMethod(
"write", pystring.get()));
1224 return Status::FromError(bytes_written.takeError()).Clone();
1225 if (bytes_written.get() < 0)
1226 return Status::FromErrorString(
1227 ".write() method returned a negative number!");
1228 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1229 num_bytes = bytes_written.get();
1233 Status Read(
void *buf,
size_t &num_bytes)
override {
1235 size_t num_chars = num_bytes / 6;
1236 size_t orig_num_bytes = num_bytes;
1238 if (orig_num_bytes < 6) {
1239 return Status::FromErrorString(
1240 "can't read less than 6 bytes from a utf8 text stream");
1242 auto pystring = As<PythonString>(
1243 m_py_obj.CallMethod(
"read", (
unsigned long long)num_chars));
1246 return Status::FromError(pystring.takeError()).Clone();
1247 if (pystring.get().IsNone()) {
1251 auto stringref = pystring.get().AsUTF8();
1254 return Status::FromError(stringref.takeError()).Clone();
1255 num_bytes = stringref.get().size();
1256 memcpy(buf, stringref.get().begin(), num_bytes);
1262llvm::Expected<FileSP> PythonFile::ConvertToFile(
bool borrowed) {
1264 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1265 "invalid PythonFile");
1267 int fd = PyObject_AsFileDescriptor(m_py_obj);
1270 return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1272 auto options = GetOptionsForPyObject(*
this);
1274 return options.takeError();
1282 auto r = CallMethod(
"flush");
1284 return r.takeError();
1291 file_sp = std::make_shared<NativeFile>(fd, options.get(),
false);
1293 file_sp = std::static_pointer_cast<File>(
1294 std::make_shared<SimplePythonFile>(*
this, borrowed, fd, options.get()));
1296 if (!file_sp->IsValid())
1297 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1303llvm::Expected<FileSP>
1304PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(
bool borrowed) {
1306 assert(!PyErr_Occurred());
1309 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1310 "invalid PythonFile");
1312 int fd = PyObject_AsFileDescriptor(m_py_obj);
1318 auto io_module = PythonModule::Import(
"io");
1320 return io_module.takeError();
1321 auto textIOBase = io_module.get().Get(
"TextIOBase");
1323 return textIOBase.takeError();
1324 auto rawIOBase = io_module.get().Get(
"RawIOBase");
1326 return rawIOBase.takeError();
1327 auto bufferedIOBase = io_module.get().Get(
"BufferedIOBase");
1328 if (!bufferedIOBase)
1329 return bufferedIOBase.takeError();
1333 auto isTextIO = IsInstance(textIOBase.get());
1335 return isTextIO.takeError();
1337 file_sp = std::static_pointer_cast<File>(
1338 std::make_shared<TextPythonFile>(fd, *
this, borrowed));
1340 auto isRawIO = IsInstance(rawIOBase.get());
1342 return isRawIO.takeError();
1343 auto isBufferedIO = IsInstance(bufferedIOBase.get());
1345 return isBufferedIO.takeError();
1347 if (isRawIO.get() || isBufferedIO.get()) {
1348 file_sp = std::static_pointer_cast<File>(
1349 std::make_shared<BinaryPythonFile>(fd, *
this, borrowed));
1353 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1354 "python file is neither text nor binary");
1356 if (!file_sp->IsValid())
1357 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1363Expected<PythonFile> PythonFile::FromFile(File &file,
const char *mode) {
1365 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1368 if (
auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1369 return Retain<PythonFile>(simple->GetPythonObject());
1370 if (
auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1371 return Retain<PythonFile>(pythonio->GetPythonObject());
1376 return m.takeError();
1381 file_obj = PyFile_FromFd(file.
GetDescriptor(),
nullptr, mode, -1,
nullptr,
1382 "ignore",
nullptr, 0);
1387 return Take<PythonFile>(file_obj);
1390Error PythonScript::Init() {
1391 if (function.IsValid())
1392 return Error::success();
1394 PythonDictionary globals(PyInitialValue::Empty);
1395 auto builtins = PythonModule::BuiltinsModule();
1396 if (
Error error = globals.SetItem(
"__builtins__", builtins))
1398 PyObject *o = RunString(script, Py_file_input, globals.get(), globals.get());
1401 Take<PythonObject>(o);
1402 auto f = As<PythonCallable>(globals.GetItem(
"main"));
1404 return f.takeError();
1405 function = std::move(f.get());
1407 return Error::success();
1410llvm::Expected<PythonObject>
1411python::runStringOneLine(
const llvm::Twine &
string,
1412 const PythonDictionary &globals,
1413 const PythonDictionary &locals) {
1414 if (!globals.IsValid() || !locals.IsValid())
1418 Py_CompileString(NullTerminated(
string),
"<string>", Py_eval_input);
1422 Py_CompileString(NullTerminated(
string),
"<string>", Py_single_input);
1426 auto code_ref = Take<PythonObject>(code);
1428 PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1433 return Take<PythonObject>(result);
1436llvm::Expected<PythonObject>
1437python::runStringMultiLine(
const llvm::Twine &
string,
1438 const PythonDictionary &globals,
1439 const PythonDictionary &locals) {
1440 if (!globals.IsValid() || !locals.IsValid())
1442 PyObject *result = RunString(NullTerminated(
string), Py_file_input,
1443 globals.get(), locals.get());
1446 return Take<PythonObject>(result);
1449PyObject *lldb_private::python::RunString(
const char *str,
int start,
1450 PyObject *globals, PyObject *locals) {
1451 const char *filename =
"<string>";
1454 PyObject *code = Py_CompileString(str, filename, start);
1459 PyObject *result = PyEval_EvalCode(code, globals, locals);
1467int lldb_private::python::RunSimpleString(
const char *str) {
1468 PyObject *main_module = PyImport_AddModule(
"__main__");
1472 PyObject *globals = PyModule_GetDict(main_module);
1476 PyObject *result = RunString(str, Py_file_input, globals, globals);
static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
static uint32_t GetBytes(uint32_t bits)
virtual bool isA(const void *classID) const
static int kInvalidDescriptor
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
llvm::Expected< const char * > GetOpenMode() const
bool IsValid() const override
IsValid.
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.
std::shared_ptr< lldb_private::File > FileSP