15ffd83dbSDimitry Andric //===-- PythonDataObjects.cpp ---------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 9480093f4SDimitry Andric #include "lldb/Host/Config.h" 100b57cec5SDimitry Andric 11480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "PythonDataObjects.h" 140b57cec5SDimitry Andric #include "ScriptInterpreterPython.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "lldb/Host/File.h" 170b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h" 180b57cec5SDimitry Andric #include "lldb/Interpreter/ScriptInterpreter.h" 1981ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 209dba64beSDimitry Andric #include "lldb/Utility/Log.h" 210b57cec5SDimitry Andric #include "lldb/Utility/Stream.h" 220b57cec5SDimitry Andric 239dba64beSDimitry Andric #include "llvm/Support/Casting.h" 240b57cec5SDimitry Andric #include "llvm/Support/ConvertUTF.h" 250b57cec5SDimitry Andric #include "llvm/Support/Errno.h" 260b57cec5SDimitry Andric 27fe6060f1SDimitry Andric #include <cstdio> 2806c3fb27SDimitry Andric #include <variant> 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric using namespace lldb_private; 310b57cec5SDimitry Andric using namespace lldb; 329dba64beSDimitry Andric using namespace lldb_private::python; 339dba64beSDimitry Andric using llvm::cantFail; 349dba64beSDimitry Andric using llvm::Error; 359dba64beSDimitry Andric using llvm::Expected; 369dba64beSDimitry Andric using llvm::Twine; 370b57cec5SDimitry Andric 389dba64beSDimitry Andric template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) { 399dba64beSDimitry Andric if (!obj) 409dba64beSDimitry Andric return obj.takeError(); 419dba64beSDimitry Andric return obj.get().IsTrue(); 429dba64beSDimitry Andric } 439dba64beSDimitry Andric 449dba64beSDimitry Andric template <> 459dba64beSDimitry Andric Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) { 469dba64beSDimitry Andric if (!obj) 479dba64beSDimitry Andric return obj.takeError(); 485ffd83dbSDimitry Andric return obj->AsLongLong(); 495ffd83dbSDimitry Andric } 505ffd83dbSDimitry Andric 515ffd83dbSDimitry Andric template <> 525ffd83dbSDimitry Andric Expected<unsigned long long> 535ffd83dbSDimitry Andric python::As<unsigned long long>(Expected<PythonObject> &&obj) { 545ffd83dbSDimitry Andric if (!obj) 555ffd83dbSDimitry Andric return obj.takeError(); 565ffd83dbSDimitry Andric return obj->AsUnsignedLongLong(); 579dba64beSDimitry Andric } 589dba64beSDimitry Andric 599dba64beSDimitry Andric template <> 609dba64beSDimitry Andric Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) { 619dba64beSDimitry Andric if (!obj) 629dba64beSDimitry Andric return obj.takeError(); 639dba64beSDimitry Andric PyObject *str_obj = PyObject_Str(obj.get().get()); 64*0fca6ea1SDimitry Andric if (!str_obj) 659dba64beSDimitry Andric return llvm::make_error<PythonException>(); 669dba64beSDimitry Andric auto str = Take<PythonString>(str_obj); 679dba64beSDimitry Andric auto utf8 = str.AsUTF8(); 689dba64beSDimitry Andric if (!utf8) 699dba64beSDimitry Andric return utf8.takeError(); 705ffd83dbSDimitry Andric return std::string(utf8.get()); 715ffd83dbSDimitry Andric } 725ffd83dbSDimitry Andric 7304eeddc0SDimitry Andric static bool python_is_finalizing() { 745f757f3fSDimitry Andric #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13) || (PY_MAJOR_VERSION > 3) 755f757f3fSDimitry Andric return Py_IsFinalizing(); 765f757f3fSDimitry Andric #elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7 7704eeddc0SDimitry Andric return _Py_Finalizing != nullptr; 7804eeddc0SDimitry Andric #else 7904eeddc0SDimitry Andric return _Py_IsFinalizing(); 8004eeddc0SDimitry Andric #endif 8104eeddc0SDimitry Andric } 8204eeddc0SDimitry Andric 8304eeddc0SDimitry Andric void PythonObject::Reset() { 8404eeddc0SDimitry Andric if (m_py_obj && Py_IsInitialized()) { 8504eeddc0SDimitry Andric if (python_is_finalizing()) { 8604eeddc0SDimitry Andric // Leak m_py_obj rather than crashing the process. 8704eeddc0SDimitry Andric // https://docs.python.org/3/c-api/init.html#c.PyGILState_Ensure 8804eeddc0SDimitry Andric } else { 8904eeddc0SDimitry Andric PyGILState_STATE state = PyGILState_Ensure(); 9004eeddc0SDimitry Andric Py_DECREF(m_py_obj); 9104eeddc0SDimitry Andric PyGILState_Release(state); 9204eeddc0SDimitry Andric } 9304eeddc0SDimitry Andric } 9404eeddc0SDimitry Andric m_py_obj = nullptr; 9504eeddc0SDimitry Andric } 9604eeddc0SDimitry Andric 975ffd83dbSDimitry Andric Expected<long long> PythonObject::AsLongLong() const { 985ffd83dbSDimitry Andric if (!m_py_obj) 995ffd83dbSDimitry Andric return nullDeref(); 1005ffd83dbSDimitry Andric assert(!PyErr_Occurred()); 1015ffd83dbSDimitry Andric long long r = PyLong_AsLongLong(m_py_obj); 1025ffd83dbSDimitry Andric if (PyErr_Occurred()) 1035ffd83dbSDimitry Andric return exception(); 1045ffd83dbSDimitry Andric return r; 1055ffd83dbSDimitry Andric } 1065ffd83dbSDimitry Andric 10706c3fb27SDimitry Andric Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const { 1085ffd83dbSDimitry Andric if (!m_py_obj) 1095ffd83dbSDimitry Andric return nullDeref(); 1105ffd83dbSDimitry Andric assert(!PyErr_Occurred()); 1115ffd83dbSDimitry Andric long long r = PyLong_AsUnsignedLongLong(m_py_obj); 1125ffd83dbSDimitry Andric if (PyErr_Occurred()) 1135ffd83dbSDimitry Andric return exception(); 1145ffd83dbSDimitry Andric return r; 1155ffd83dbSDimitry Andric } 1165ffd83dbSDimitry Andric 1175ffd83dbSDimitry Andric // wraps on overflow, instead of raising an error. 1185ffd83dbSDimitry Andric Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const { 1195ffd83dbSDimitry Andric if (!m_py_obj) 1205ffd83dbSDimitry Andric return nullDeref(); 1215ffd83dbSDimitry Andric assert(!PyErr_Occurred()); 1225ffd83dbSDimitry Andric unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj); 12306c3fb27SDimitry Andric // FIXME: We should fetch the exception message and hoist it. 1245ffd83dbSDimitry Andric if (PyErr_Occurred()) 1255ffd83dbSDimitry Andric return exception(); 1265ffd83dbSDimitry Andric return r; 1279dba64beSDimitry Andric } 1289dba64beSDimitry Andric 1299dba64beSDimitry Andric void StructuredPythonObject::Serialize(llvm::json::OStream &s) const { 1309dba64beSDimitry Andric s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str()); 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric // PythonObject 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric void PythonObject::Dump(Stream &strm) const { 1360b57cec5SDimitry Andric if (m_py_obj) { 1370b57cec5SDimitry Andric FILE *file = llvm::sys::RetryAfterSignal(nullptr, ::tmpfile); 1380b57cec5SDimitry Andric if (file) { 1390b57cec5SDimitry Andric ::PyObject_Print(m_py_obj, file, 0); 1400b57cec5SDimitry Andric const long length = ftell(file); 1410b57cec5SDimitry Andric if (length) { 1420b57cec5SDimitry Andric ::rewind(file); 1430b57cec5SDimitry Andric std::vector<char> file_contents(length, '\0'); 1440b57cec5SDimitry Andric const size_t length_read = 1450b57cec5SDimitry Andric ::fread(file_contents.data(), 1, file_contents.size(), file); 1460b57cec5SDimitry Andric if (length_read > 0) 1470b57cec5SDimitry Andric strm.Write(file_contents.data(), length_read); 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric ::fclose(file); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric } else 1520b57cec5SDimitry Andric strm.PutCString("NULL"); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric PyObjectType PythonObject::GetObjectType() const { 1560b57cec5SDimitry Andric if (!IsAllocated()) 1570b57cec5SDimitry Andric return PyObjectType::None; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric if (PythonModule::Check(m_py_obj)) 1600b57cec5SDimitry Andric return PyObjectType::Module; 1610b57cec5SDimitry Andric if (PythonList::Check(m_py_obj)) 1620b57cec5SDimitry Andric return PyObjectType::List; 1630b57cec5SDimitry Andric if (PythonTuple::Check(m_py_obj)) 1640b57cec5SDimitry Andric return PyObjectType::Tuple; 1650b57cec5SDimitry Andric if (PythonDictionary::Check(m_py_obj)) 1660b57cec5SDimitry Andric return PyObjectType::Dictionary; 1670b57cec5SDimitry Andric if (PythonString::Check(m_py_obj)) 1680b57cec5SDimitry Andric return PyObjectType::String; 1690b57cec5SDimitry Andric if (PythonBytes::Check(m_py_obj)) 1700b57cec5SDimitry Andric return PyObjectType::Bytes; 1710b57cec5SDimitry Andric if (PythonByteArray::Check(m_py_obj)) 1720b57cec5SDimitry Andric return PyObjectType::ByteArray; 1730b57cec5SDimitry Andric if (PythonBoolean::Check(m_py_obj)) 1740b57cec5SDimitry Andric return PyObjectType::Boolean; 1750b57cec5SDimitry Andric if (PythonInteger::Check(m_py_obj)) 1760b57cec5SDimitry Andric return PyObjectType::Integer; 1770b57cec5SDimitry Andric if (PythonFile::Check(m_py_obj)) 1780b57cec5SDimitry Andric return PyObjectType::File; 1790b57cec5SDimitry Andric if (PythonCallable::Check(m_py_obj)) 1800b57cec5SDimitry Andric return PyObjectType::Callable; 1810b57cec5SDimitry Andric return PyObjectType::Unknown; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric PythonString PythonObject::Repr() const { 1850b57cec5SDimitry Andric if (!m_py_obj) 1860b57cec5SDimitry Andric return PythonString(); 1870b57cec5SDimitry Andric PyObject *repr = PyObject_Repr(m_py_obj); 1880b57cec5SDimitry Andric if (!repr) 1890b57cec5SDimitry Andric return PythonString(); 1900b57cec5SDimitry Andric return PythonString(PyRefType::Owned, repr); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric PythonString PythonObject::Str() const { 1940b57cec5SDimitry Andric if (!m_py_obj) 1950b57cec5SDimitry Andric return PythonString(); 1960b57cec5SDimitry Andric PyObject *str = PyObject_Str(m_py_obj); 1970b57cec5SDimitry Andric if (!str) 1980b57cec5SDimitry Andric return PythonString(); 1990b57cec5SDimitry Andric return PythonString(PyRefType::Owned, str); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric PythonObject 2030b57cec5SDimitry Andric PythonObject::ResolveNameWithDictionary(llvm::StringRef name, 2040b57cec5SDimitry Andric const PythonDictionary &dict) { 2050b57cec5SDimitry Andric size_t dot_pos = name.find('.'); 2060b57cec5SDimitry Andric llvm::StringRef piece = name.substr(0, dot_pos); 2070b57cec5SDimitry Andric PythonObject result = dict.GetItemForKey(PythonString(piece)); 2080b57cec5SDimitry Andric if (dot_pos == llvm::StringRef::npos) { 2090b57cec5SDimitry Andric // There was no dot, we're done. 2100b57cec5SDimitry Andric return result; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // There was a dot. The remaining portion of the name should be looked up in 2140b57cec5SDimitry Andric // the context of the object that was found in the dictionary. 2150b57cec5SDimitry Andric return result.ResolveName(name.substr(dot_pos + 1)); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric PythonObject PythonObject::ResolveName(llvm::StringRef name) const { 2190b57cec5SDimitry Andric // Resolve the name in the context of the specified object. If, for example, 2200b57cec5SDimitry Andric // `this` refers to a PyModule, then this will look for `name` in this 2210b57cec5SDimitry Andric // module. If `this` refers to a PyType, then it will resolve `name` as an 2220b57cec5SDimitry Andric // attribute of that type. If `this` refers to an instance of an object, 2230b57cec5SDimitry Andric // then it will resolve `name` as the value of the specified field. 2240b57cec5SDimitry Andric // 2250b57cec5SDimitry Andric // This function handles dotted names so that, for example, if `m_py_obj` 2260b57cec5SDimitry Andric // refers to the `sys` module, and `name` == "path.append", then it will find 2270b57cec5SDimitry Andric // the function `sys.path.append`. 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric size_t dot_pos = name.find('.'); 2300b57cec5SDimitry Andric if (dot_pos == llvm::StringRef::npos) { 2310b57cec5SDimitry Andric // No dots in the name, we should be able to find the value immediately as 2320b57cec5SDimitry Andric // an attribute of `m_py_obj`. 2330b57cec5SDimitry Andric return GetAttributeValue(name); 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Look up the first piece of the name, and resolve the rest as a child of 2370b57cec5SDimitry Andric // that. 2380b57cec5SDimitry Andric PythonObject parent = ResolveName(name.substr(0, dot_pos)); 2390b57cec5SDimitry Andric if (!parent.IsAllocated()) 2400b57cec5SDimitry Andric return PythonObject(); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric // Tail recursion.. should be optimized by the compiler 2430b57cec5SDimitry Andric return parent.ResolveName(name.substr(dot_pos + 1)); 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric bool PythonObject::HasAttribute(llvm::StringRef attr) const { 2470b57cec5SDimitry Andric if (!IsValid()) 2480b57cec5SDimitry Andric return false; 2490b57cec5SDimitry Andric PythonString py_attr(attr); 2500b57cec5SDimitry Andric return !!PyObject_HasAttr(m_py_obj, py_attr.get()); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const { 2540b57cec5SDimitry Andric if (!IsValid()) 2550b57cec5SDimitry Andric return PythonObject(); 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric PythonString py_attr(attr); 2580b57cec5SDimitry Andric if (!PyObject_HasAttr(m_py_obj, py_attr.get())) 2590b57cec5SDimitry Andric return PythonObject(); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric return PythonObject(PyRefType::Owned, 2620b57cec5SDimitry Andric PyObject_GetAttr(m_py_obj, py_attr.get())); 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric StructuredData::ObjectSP PythonObject::CreateStructuredObject() const { 26604eeddc0SDimitry Andric assert(PyGILState_Check()); 2670b57cec5SDimitry Andric switch (GetObjectType()) { 2680b57cec5SDimitry Andric case PyObjectType::Dictionary: 2690b57cec5SDimitry Andric return PythonDictionary(PyRefType::Borrowed, m_py_obj) 2700b57cec5SDimitry Andric .CreateStructuredDictionary(); 2710b57cec5SDimitry Andric case PyObjectType::Boolean: 2720b57cec5SDimitry Andric return PythonBoolean(PyRefType::Borrowed, m_py_obj) 2730b57cec5SDimitry Andric .CreateStructuredBoolean(); 27406c3fb27SDimitry Andric case PyObjectType::Integer: { 27506c3fb27SDimitry Andric StructuredData::IntegerSP int_sp = 27606c3fb27SDimitry Andric PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger(); 27706c3fb27SDimitry Andric if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp)) 27806c3fb27SDimitry Andric return std::get<StructuredData::UnsignedIntegerSP>(int_sp); 27906c3fb27SDimitry Andric if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp)) 28006c3fb27SDimitry Andric return std::get<StructuredData::SignedIntegerSP>(int_sp); 28106c3fb27SDimitry Andric return nullptr; 28206c3fb27SDimitry Andric }; 2830b57cec5SDimitry Andric case PyObjectType::List: 2840b57cec5SDimitry Andric return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); 2850b57cec5SDimitry Andric case PyObjectType::String: 2860b57cec5SDimitry Andric return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 2870b57cec5SDimitry Andric case PyObjectType::Bytes: 2880b57cec5SDimitry Andric return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 2890b57cec5SDimitry Andric case PyObjectType::ByteArray: 2900b57cec5SDimitry Andric return PythonByteArray(PyRefType::Borrowed, m_py_obj) 2910b57cec5SDimitry Andric .CreateStructuredString(); 2920b57cec5SDimitry Andric case PyObjectType::None: 2930b57cec5SDimitry Andric return StructuredData::ObjectSP(); 2940b57cec5SDimitry Andric default: 29504eeddc0SDimitry Andric return StructuredData::ObjectSP(new StructuredPythonObject( 29604eeddc0SDimitry Andric PythonObject(PyRefType::Borrowed, m_py_obj))); 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric // PythonString 3010b57cec5SDimitry Andric 3029dba64beSDimitry Andric PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); } 3030b57cec5SDimitry Andric 3049dba64beSDimitry Andric PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) { 3050b57cec5SDimitry Andric SetBytes(llvm::ArrayRef<uint8_t>(bytes, length)); 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric bool PythonBytes::Check(PyObject *py_obj) { 3090b57cec5SDimitry Andric if (!py_obj) 3100b57cec5SDimitry Andric return false; 3110b57cec5SDimitry Andric return PyBytes_Check(py_obj); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const { 3150b57cec5SDimitry Andric if (!IsValid()) 3160b57cec5SDimitry Andric return llvm::ArrayRef<uint8_t>(); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric Py_ssize_t size; 3190b57cec5SDimitry Andric char *c; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric PyBytes_AsStringAndSize(m_py_obj, &c, &size); 3220b57cec5SDimitry Andric return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric size_t PythonBytes::GetSize() const { 3260b57cec5SDimitry Andric if (!IsValid()) 3270b57cec5SDimitry Andric return 0; 3280b57cec5SDimitry Andric return PyBytes_Size(m_py_obj); 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) { 3320b57cec5SDimitry Andric const char *data = reinterpret_cast<const char *>(bytes.data()); 3339dba64beSDimitry Andric *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size())); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric StructuredData::StringSP PythonBytes::CreateStructuredString() const { 3370b57cec5SDimitry Andric StructuredData::StringSP result(new StructuredData::String); 3380b57cec5SDimitry Andric Py_ssize_t size; 3390b57cec5SDimitry Andric char *c; 3400b57cec5SDimitry Andric PyBytes_AsStringAndSize(m_py_obj, &c, &size); 3410b57cec5SDimitry Andric result->SetValue(std::string(c, size)); 3420b57cec5SDimitry Andric return result; 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) 3460b57cec5SDimitry Andric : PythonByteArray(bytes.data(), bytes.size()) {} 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) { 3490b57cec5SDimitry Andric const char *str = reinterpret_cast<const char *>(bytes); 3509dba64beSDimitry Andric *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length)); 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric bool PythonByteArray::Check(PyObject *py_obj) { 3540b57cec5SDimitry Andric if (!py_obj) 3550b57cec5SDimitry Andric return false; 3560b57cec5SDimitry Andric return PyByteArray_Check(py_obj); 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const { 3600b57cec5SDimitry Andric if (!IsValid()) 3610b57cec5SDimitry Andric return llvm::ArrayRef<uint8_t>(); 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric char *c = PyByteArray_AsString(m_py_obj); 3640b57cec5SDimitry Andric size_t size = GetSize(); 3650b57cec5SDimitry Andric return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size); 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric size_t PythonByteArray::GetSize() const { 3690b57cec5SDimitry Andric if (!IsValid()) 3700b57cec5SDimitry Andric return 0; 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric return PyByteArray_Size(m_py_obj); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric StructuredData::StringSP PythonByteArray::CreateStructuredString() const { 3760b57cec5SDimitry Andric StructuredData::StringSP result(new StructuredData::String); 3770b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> bytes = GetBytes(); 3780b57cec5SDimitry Andric const char *str = reinterpret_cast<const char *>(bytes.data()); 3790b57cec5SDimitry Andric result->SetValue(std::string(str, bytes.size())); 3800b57cec5SDimitry Andric return result; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric // PythonString 3840b57cec5SDimitry Andric 3859dba64beSDimitry Andric Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) { 3869dba64beSDimitry Andric PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size()); 3879dba64beSDimitry Andric if (!str) 3889dba64beSDimitry Andric return llvm::make_error<PythonException>(); 3899dba64beSDimitry Andric return Take<PythonString>(str); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3929dba64beSDimitry Andric PythonString::PythonString(llvm::StringRef string) { SetString(string); } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric bool PythonString::Check(PyObject *py_obj) { 3950b57cec5SDimitry Andric if (!py_obj) 3960b57cec5SDimitry Andric return false; 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric if (PyUnicode_Check(py_obj)) 3990b57cec5SDimitry Andric return true; 4000b57cec5SDimitry Andric return false; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric llvm::StringRef PythonString::GetString() const { 4049dba64beSDimitry Andric auto s = AsUTF8(); 4059dba64beSDimitry Andric if (!s) { 4069dba64beSDimitry Andric llvm::consumeError(s.takeError()); 4079dba64beSDimitry Andric return llvm::StringRef(""); 4089dba64beSDimitry Andric } 4099dba64beSDimitry Andric return s.get(); 4109dba64beSDimitry Andric } 4119dba64beSDimitry Andric 4129dba64beSDimitry Andric Expected<llvm::StringRef> PythonString::AsUTF8() const { 4130b57cec5SDimitry Andric if (!IsValid()) 4149dba64beSDimitry Andric return nullDeref(); 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric Py_ssize_t size; 4170b57cec5SDimitry Andric const char *data; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric data = PyUnicode_AsUTF8AndSize(m_py_obj, &size); 4209dba64beSDimitry Andric 4219dba64beSDimitry Andric if (!data) 4229dba64beSDimitry Andric return exception(); 4239dba64beSDimitry Andric 4240b57cec5SDimitry Andric return llvm::StringRef(data, size); 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric size_t PythonString::GetSize() const { 4280b57cec5SDimitry Andric if (IsValid()) { 429e8d8bef9SDimitry Andric #if PY_MINOR_VERSION >= 3 430e8d8bef9SDimitry Andric return PyUnicode_GetLength(m_py_obj); 431e8d8bef9SDimitry Andric #else 4320b57cec5SDimitry Andric return PyUnicode_GetSize(m_py_obj); 433e8d8bef9SDimitry Andric #endif 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric return 0; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric void PythonString::SetString(llvm::StringRef string) { 4399dba64beSDimitry Andric auto s = FromUTF8(string); 4409dba64beSDimitry Andric if (!s) { 4419dba64beSDimitry Andric llvm::consumeError(s.takeError()); 4429dba64beSDimitry Andric Reset(); 4439dba64beSDimitry Andric } else { 4449dba64beSDimitry Andric *this = std::move(s.get()); 4459dba64beSDimitry Andric } 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric StructuredData::StringSP PythonString::CreateStructuredString() const { 4490b57cec5SDimitry Andric StructuredData::StringSP result(new StructuredData::String); 4500b57cec5SDimitry Andric result->SetValue(GetString()); 4510b57cec5SDimitry Andric return result; 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric // PythonInteger 4550b57cec5SDimitry Andric 4569dba64beSDimitry Andric PythonInteger::PythonInteger(int64_t value) { SetInteger(value); } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric bool PythonInteger::Check(PyObject *py_obj) { 4590b57cec5SDimitry Andric if (!py_obj) 4600b57cec5SDimitry Andric return false; 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric // Python 3 does not have PyInt_Check. There is only one type of integral 4630b57cec5SDimitry Andric // value, long. 4640b57cec5SDimitry Andric return PyLong_Check(py_obj); 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric void PythonInteger::SetInteger(int64_t value) { 4689dba64beSDimitry Andric *this = Take<PythonInteger>(PyLong_FromLongLong(value)); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const { 47206c3fb27SDimitry Andric StructuredData::UnsignedIntegerSP uint_sp = CreateStructuredUnsignedInteger(); 47306c3fb27SDimitry Andric return uint_sp ? StructuredData::IntegerSP(uint_sp) 47406c3fb27SDimitry Andric : CreateStructuredSignedInteger(); 4755ffd83dbSDimitry Andric } 47606c3fb27SDimitry Andric 47706c3fb27SDimitry Andric StructuredData::UnsignedIntegerSP 47806c3fb27SDimitry Andric PythonInteger::CreateStructuredUnsignedInteger() const { 47906c3fb27SDimitry Andric StructuredData::UnsignedIntegerSP result = nullptr; 48006c3fb27SDimitry Andric llvm::Expected<unsigned long long> value = AsUnsignedLongLong(); 48106c3fb27SDimitry Andric if (!value) 48206c3fb27SDimitry Andric llvm::consumeError(value.takeError()); 48306c3fb27SDimitry Andric else 48406c3fb27SDimitry Andric result = std::make_shared<StructuredData::UnsignedInteger>(value.get()); 48506c3fb27SDimitry Andric 48606c3fb27SDimitry Andric return result; 48706c3fb27SDimitry Andric } 48806c3fb27SDimitry Andric 48906c3fb27SDimitry Andric StructuredData::SignedIntegerSP 49006c3fb27SDimitry Andric PythonInteger::CreateStructuredSignedInteger() const { 49106c3fb27SDimitry Andric StructuredData::SignedIntegerSP result = nullptr; 49206c3fb27SDimitry Andric llvm::Expected<long long> value = AsLongLong(); 49306c3fb27SDimitry Andric if (!value) 49406c3fb27SDimitry Andric llvm::consumeError(value.takeError()); 49506c3fb27SDimitry Andric else 49606c3fb27SDimitry Andric result = std::make_shared<StructuredData::SignedInteger>(value.get()); 49706c3fb27SDimitry Andric 4980b57cec5SDimitry Andric return result; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // PythonBoolean 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric PythonBoolean::PythonBoolean(bool value) { 5040b57cec5SDimitry Andric SetValue(value); 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric bool PythonBoolean::Check(PyObject *py_obj) { 5080b57cec5SDimitry Andric return py_obj ? PyBool_Check(py_obj) : false; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric bool PythonBoolean::GetValue() const { 5120b57cec5SDimitry Andric return m_py_obj ? PyObject_IsTrue(m_py_obj) : false; 5130b57cec5SDimitry Andric } 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric void PythonBoolean::SetValue(bool value) { 5169dba64beSDimitry Andric *this = Take<PythonBoolean>(PyBool_FromLong(value)); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const { 5200b57cec5SDimitry Andric StructuredData::BooleanSP result(new StructuredData::Boolean); 5210b57cec5SDimitry Andric result->SetValue(GetValue()); 5220b57cec5SDimitry Andric return result; 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric // PythonList 5260b57cec5SDimitry Andric 5279dba64beSDimitry Andric PythonList::PythonList(PyInitialValue value) { 5280b57cec5SDimitry Andric if (value == PyInitialValue::Empty) 5299dba64beSDimitry Andric *this = Take<PythonList>(PyList_New(0)); 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric 5329dba64beSDimitry Andric PythonList::PythonList(int list_size) { 5339dba64beSDimitry Andric *this = Take<PythonList>(PyList_New(list_size)); 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric bool PythonList::Check(PyObject *py_obj) { 5370b57cec5SDimitry Andric if (!py_obj) 5380b57cec5SDimitry Andric return false; 5390b57cec5SDimitry Andric return PyList_Check(py_obj); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric uint32_t PythonList::GetSize() const { 5430b57cec5SDimitry Andric if (IsValid()) 5440b57cec5SDimitry Andric return PyList_GET_SIZE(m_py_obj); 5450b57cec5SDimitry Andric return 0; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric PythonObject PythonList::GetItemAtIndex(uint32_t index) const { 5490b57cec5SDimitry Andric if (IsValid()) 5500b57cec5SDimitry Andric return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index)); 5510b57cec5SDimitry Andric return PythonObject(); 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) { 5550b57cec5SDimitry Andric if (IsAllocated() && object.IsValid()) { 5560b57cec5SDimitry Andric // PyList_SetItem is documented to "steal" a reference, so we need to 5570b57cec5SDimitry Andric // convert it to an owned reference by incrementing it. 5580b57cec5SDimitry Andric Py_INCREF(object.get()); 5590b57cec5SDimitry Andric PyList_SetItem(m_py_obj, index, object.get()); 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric void PythonList::AppendItem(const PythonObject &object) { 5640b57cec5SDimitry Andric if (IsAllocated() && object.IsValid()) { 5650b57cec5SDimitry Andric // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF` 5660b57cec5SDimitry Andric // here like we do with `PyList_SetItem`. 5670b57cec5SDimitry Andric PyList_Append(m_py_obj, object.get()); 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric StructuredData::ArraySP PythonList::CreateStructuredArray() const { 5720b57cec5SDimitry Andric StructuredData::ArraySP result(new StructuredData::Array); 5730b57cec5SDimitry Andric uint32_t count = GetSize(); 5740b57cec5SDimitry Andric for (uint32_t i = 0; i < count; ++i) { 5750b57cec5SDimitry Andric PythonObject obj = GetItemAtIndex(i); 5760b57cec5SDimitry Andric result->AddItem(obj.CreateStructuredObject()); 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric return result; 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric // PythonTuple 5820b57cec5SDimitry Andric 5839dba64beSDimitry Andric PythonTuple::PythonTuple(PyInitialValue value) { 5840b57cec5SDimitry Andric if (value == PyInitialValue::Empty) 5859dba64beSDimitry Andric *this = Take<PythonTuple>(PyTuple_New(0)); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5889dba64beSDimitry Andric PythonTuple::PythonTuple(int tuple_size) { 5899dba64beSDimitry Andric *this = Take<PythonTuple>(PyTuple_New(tuple_size)); 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) { 5930b57cec5SDimitry Andric m_py_obj = PyTuple_New(objects.size()); 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric uint32_t idx = 0; 5960b57cec5SDimitry Andric for (auto object : objects) { 5970b57cec5SDimitry Andric if (object.IsValid()) 5980b57cec5SDimitry Andric SetItemAtIndex(idx, object); 5990b57cec5SDimitry Andric idx++; 6000b57cec5SDimitry Andric } 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) { 6040b57cec5SDimitry Andric m_py_obj = PyTuple_New(objects.size()); 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric uint32_t idx = 0; 6070b57cec5SDimitry Andric for (auto py_object : objects) { 6080b57cec5SDimitry Andric PythonObject object(PyRefType::Borrowed, py_object); 6090b57cec5SDimitry Andric if (object.IsValid()) 6100b57cec5SDimitry Andric SetItemAtIndex(idx, object); 6110b57cec5SDimitry Andric idx++; 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric bool PythonTuple::Check(PyObject *py_obj) { 6160b57cec5SDimitry Andric if (!py_obj) 6170b57cec5SDimitry Andric return false; 6180b57cec5SDimitry Andric return PyTuple_Check(py_obj); 6190b57cec5SDimitry Andric } 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric uint32_t PythonTuple::GetSize() const { 6220b57cec5SDimitry Andric if (IsValid()) 6230b57cec5SDimitry Andric return PyTuple_GET_SIZE(m_py_obj); 6240b57cec5SDimitry Andric return 0; 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const { 6280b57cec5SDimitry Andric if (IsValid()) 6290b57cec5SDimitry Andric return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index)); 6300b57cec5SDimitry Andric return PythonObject(); 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) { 6340b57cec5SDimitry Andric if (IsAllocated() && object.IsValid()) { 6350b57cec5SDimitry Andric // PyTuple_SetItem is documented to "steal" a reference, so we need to 6360b57cec5SDimitry Andric // convert it to an owned reference by incrementing it. 6370b57cec5SDimitry Andric Py_INCREF(object.get()); 6380b57cec5SDimitry Andric PyTuple_SetItem(m_py_obj, index, object.get()); 6390b57cec5SDimitry Andric } 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric StructuredData::ArraySP PythonTuple::CreateStructuredArray() const { 6430b57cec5SDimitry Andric StructuredData::ArraySP result(new StructuredData::Array); 6440b57cec5SDimitry Andric uint32_t count = GetSize(); 6450b57cec5SDimitry Andric for (uint32_t i = 0; i < count; ++i) { 6460b57cec5SDimitry Andric PythonObject obj = GetItemAtIndex(i); 6470b57cec5SDimitry Andric result->AddItem(obj.CreateStructuredObject()); 6480b57cec5SDimitry Andric } 6490b57cec5SDimitry Andric return result; 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric // PythonDictionary 6530b57cec5SDimitry Andric 6549dba64beSDimitry Andric PythonDictionary::PythonDictionary(PyInitialValue value) { 6550b57cec5SDimitry Andric if (value == PyInitialValue::Empty) 6569dba64beSDimitry Andric *this = Take<PythonDictionary>(PyDict_New()); 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric 6590b57cec5SDimitry Andric bool PythonDictionary::Check(PyObject *py_obj) { 6600b57cec5SDimitry Andric if (!py_obj) 6610b57cec5SDimitry Andric return false; 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric return PyDict_Check(py_obj); 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6665f757f3fSDimitry Andric bool PythonDictionary::HasKey(const llvm::Twine &key) const { 6675f757f3fSDimitry Andric if (!IsValid()) 6685f757f3fSDimitry Andric return false; 6695f757f3fSDimitry Andric 6705f757f3fSDimitry Andric PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef() 6715f757f3fSDimitry Andric : key.str()); 6725f757f3fSDimitry Andric 6735f757f3fSDimitry Andric if (int res = PyDict_Contains(m_py_obj, key_object.get()) > 0) 6745f757f3fSDimitry Andric return res; 6755f757f3fSDimitry Andric 6765f757f3fSDimitry Andric PyErr_Print(); 6775f757f3fSDimitry Andric return false; 6785f757f3fSDimitry Andric } 6795f757f3fSDimitry Andric 6800b57cec5SDimitry Andric uint32_t PythonDictionary::GetSize() const { 6810b57cec5SDimitry Andric if (IsValid()) 6820b57cec5SDimitry Andric return PyDict_Size(m_py_obj); 6830b57cec5SDimitry Andric return 0; 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric PythonList PythonDictionary::GetKeys() const { 6870b57cec5SDimitry Andric if (IsValid()) 6880b57cec5SDimitry Andric return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj)); 6890b57cec5SDimitry Andric return PythonList(PyInitialValue::Invalid); 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const { 6939dba64beSDimitry Andric auto item = GetItem(key); 6949dba64beSDimitry Andric if (!item) { 6959dba64beSDimitry Andric llvm::consumeError(item.takeError()); 6960b57cec5SDimitry Andric return PythonObject(); 6970b57cec5SDimitry Andric } 6989dba64beSDimitry Andric return std::move(item.get()); 6999dba64beSDimitry Andric } 7009dba64beSDimitry Andric 7019dba64beSDimitry Andric Expected<PythonObject> 7029dba64beSDimitry Andric PythonDictionary::GetItem(const PythonObject &key) const { 7039dba64beSDimitry Andric if (!IsValid()) 7049dba64beSDimitry Andric return nullDeref(); 7059dba64beSDimitry Andric PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get()); 7069dba64beSDimitry Andric if (PyErr_Occurred()) 7079dba64beSDimitry Andric return exception(); 7089dba64beSDimitry Andric if (!o) 7099dba64beSDimitry Andric return keyError(); 7109dba64beSDimitry Andric return Retain<PythonObject>(o); 7119dba64beSDimitry Andric } 7129dba64beSDimitry Andric 7139dba64beSDimitry Andric Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const { 7149dba64beSDimitry Andric if (!IsValid()) 7159dba64beSDimitry Andric return nullDeref(); 7169dba64beSDimitry Andric PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key)); 7179dba64beSDimitry Andric if (PyErr_Occurred()) 7189dba64beSDimitry Andric return exception(); 7199dba64beSDimitry Andric if (!o) 7209dba64beSDimitry Andric return keyError(); 7219dba64beSDimitry Andric return Retain<PythonObject>(o); 7229dba64beSDimitry Andric } 7239dba64beSDimitry Andric 7249dba64beSDimitry Andric Error PythonDictionary::SetItem(const PythonObject &key, 7259dba64beSDimitry Andric const PythonObject &value) const { 7269dba64beSDimitry Andric if (!IsValid() || !value.IsValid()) 7279dba64beSDimitry Andric return nullDeref(); 7289dba64beSDimitry Andric int r = PyDict_SetItem(m_py_obj, key.get(), value.get()); 7299dba64beSDimitry Andric if (r < 0) 7309dba64beSDimitry Andric return exception(); 7319dba64beSDimitry Andric return Error::success(); 7329dba64beSDimitry Andric } 7339dba64beSDimitry Andric 7349dba64beSDimitry Andric Error PythonDictionary::SetItem(const Twine &key, 7359dba64beSDimitry Andric const PythonObject &value) const { 7369dba64beSDimitry Andric if (!IsValid() || !value.IsValid()) 7379dba64beSDimitry Andric return nullDeref(); 7389dba64beSDimitry Andric int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get()); 7399dba64beSDimitry Andric if (r < 0) 7409dba64beSDimitry Andric return exception(); 7419dba64beSDimitry Andric return Error::success(); 7429dba64beSDimitry Andric } 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric void PythonDictionary::SetItemForKey(const PythonObject &key, 7450b57cec5SDimitry Andric const PythonObject &value) { 7469dba64beSDimitry Andric Error error = SetItem(key, value); 7479dba64beSDimitry Andric if (error) 7489dba64beSDimitry Andric llvm::consumeError(std::move(error)); 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric StructuredData::DictionarySP 7520b57cec5SDimitry Andric PythonDictionary::CreateStructuredDictionary() const { 7530b57cec5SDimitry Andric StructuredData::DictionarySP result(new StructuredData::Dictionary); 7540b57cec5SDimitry Andric PythonList keys(GetKeys()); 7550b57cec5SDimitry Andric uint32_t num_keys = keys.GetSize(); 7560b57cec5SDimitry Andric for (uint32_t i = 0; i < num_keys; ++i) { 7570b57cec5SDimitry Andric PythonObject key = keys.GetItemAtIndex(i); 7580b57cec5SDimitry Andric PythonObject value = GetItemForKey(key); 7590b57cec5SDimitry Andric StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 7600b57cec5SDimitry Andric result->AddItem(key.Str().GetString(), structured_value); 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric return result; 7630b57cec5SDimitry Andric } 7640b57cec5SDimitry Andric 76581ad6265SDimitry Andric PythonModule PythonModule::BuiltinsModule() { return AddModule("builtins"); } 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric PythonModule PythonModule::MainModule() { return AddModule("__main__"); } 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric PythonModule PythonModule::AddModule(llvm::StringRef module) { 7700b57cec5SDimitry Andric std::string str = module.str(); 7710b57cec5SDimitry Andric return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str())); 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7749dba64beSDimitry Andric Expected<PythonModule> PythonModule::Import(const Twine &name) { 7759dba64beSDimitry Andric PyObject *mod = PyImport_ImportModule(NullTerminated(name)); 7769dba64beSDimitry Andric if (!mod) 7779dba64beSDimitry Andric return exception(); 7789dba64beSDimitry Andric return Take<PythonModule>(mod); 7799dba64beSDimitry Andric } 7809dba64beSDimitry Andric 7819dba64beSDimitry Andric Expected<PythonObject> PythonModule::Get(const Twine &name) { 7829dba64beSDimitry Andric if (!IsValid()) 7839dba64beSDimitry Andric return nullDeref(); 7849dba64beSDimitry Andric PyObject *dict = PyModule_GetDict(m_py_obj); 7859dba64beSDimitry Andric if (!dict) 7869dba64beSDimitry Andric return exception(); 7879dba64beSDimitry Andric PyObject *item = PyDict_GetItemString(dict, NullTerminated(name)); 7889dba64beSDimitry Andric if (!item) 7899dba64beSDimitry Andric return exception(); 7909dba64beSDimitry Andric return Retain<PythonObject>(item); 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric bool PythonModule::Check(PyObject *py_obj) { 7940b57cec5SDimitry Andric if (!py_obj) 7950b57cec5SDimitry Andric return false; 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric return PyModule_Check(py_obj); 7980b57cec5SDimitry Andric } 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric PythonDictionary PythonModule::GetDictionary() const { 8019dba64beSDimitry Andric if (!IsValid()) 8029dba64beSDimitry Andric return PythonDictionary(); 8039dba64beSDimitry Andric return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj)); 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric bool PythonCallable::Check(PyObject *py_obj) { 8070b57cec5SDimitry Andric if (!py_obj) 8080b57cec5SDimitry Andric return false; 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric return PyCallable_Check(py_obj); 8110b57cec5SDimitry Andric } 8120b57cec5SDimitry Andric 8139dba64beSDimitry Andric #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 8149dba64beSDimitry Andric static const char get_arg_info_script[] = R"( 8159dba64beSDimitry Andric from inspect import signature, Parameter, ismethod 8169dba64beSDimitry Andric from collections import namedtuple 817480093f4SDimitry Andric ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs']) 8189dba64beSDimitry Andric def main(f): 8199dba64beSDimitry Andric count = 0 8209dba64beSDimitry Andric varargs = False 8219dba64beSDimitry Andric for parameter in signature(f).parameters.values(): 8229dba64beSDimitry Andric kind = parameter.kind 8239dba64beSDimitry Andric if kind in (Parameter.POSITIONAL_ONLY, 8249dba64beSDimitry Andric Parameter.POSITIONAL_OR_KEYWORD): 8259dba64beSDimitry Andric count += 1 8269dba64beSDimitry Andric elif kind == Parameter.VAR_POSITIONAL: 8279dba64beSDimitry Andric varargs = True 8289dba64beSDimitry Andric elif kind in (Parameter.KEYWORD_ONLY, 8299dba64beSDimitry Andric Parameter.VAR_KEYWORD): 8309dba64beSDimitry Andric pass 8319dba64beSDimitry Andric else: 8329dba64beSDimitry Andric raise Exception(f'unknown parameter kind: {kind}') 833480093f4SDimitry Andric return ArgInfo(count, varargs) 8349dba64beSDimitry Andric )"; 8359dba64beSDimitry Andric #endif 8369dba64beSDimitry Andric 8379dba64beSDimitry Andric Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const { 8389dba64beSDimitry Andric ArgInfo result = {}; 8399dba64beSDimitry Andric if (!IsValid()) 8409dba64beSDimitry Andric return nullDeref(); 8419dba64beSDimitry Andric 8429dba64beSDimitry Andric #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 8439dba64beSDimitry Andric 8449dba64beSDimitry Andric // no need to synchronize access to this global, we already have the GIL 8459dba64beSDimitry Andric static PythonScript get_arg_info(get_arg_info_script); 8469dba64beSDimitry Andric Expected<PythonObject> pyarginfo = get_arg_info(*this); 8479dba64beSDimitry Andric if (!pyarginfo) 8489dba64beSDimitry Andric return pyarginfo.takeError(); 849480093f4SDimitry Andric long long count = 850480093f4SDimitry Andric cantFail(As<long long>(pyarginfo.get().GetAttribute("count"))); 851480093f4SDimitry Andric bool has_varargs = 8529dba64beSDimitry Andric cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs"))); 853480093f4SDimitry Andric result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count; 8549dba64beSDimitry Andric 8559dba64beSDimitry Andric #else 856480093f4SDimitry Andric PyObject *py_func_obj; 8579dba64beSDimitry Andric bool is_bound_method = false; 858480093f4SDimitry Andric bool is_class = false; 859480093f4SDimitry Andric 860480093f4SDimitry Andric if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) { 861480093f4SDimitry Andric auto init = GetAttribute("__init__"); 862480093f4SDimitry Andric if (!init) 863480093f4SDimitry Andric return init.takeError(); 864480093f4SDimitry Andric py_func_obj = init.get().get(); 865480093f4SDimitry Andric is_class = true; 866480093f4SDimitry Andric } else { 867480093f4SDimitry Andric py_func_obj = m_py_obj; 868480093f4SDimitry Andric } 869480093f4SDimitry Andric 8700b57cec5SDimitry Andric if (PyMethod_Check(py_func_obj)) { 8710b57cec5SDimitry Andric py_func_obj = PyMethod_GET_FUNCTION(py_func_obj); 8720b57cec5SDimitry Andric PythonObject im_self = GetAttributeValue("im_self"); 8730b57cec5SDimitry Andric if (im_self.IsValid() && !im_self.IsNone()) 8749dba64beSDimitry Andric is_bound_method = true; 8750b57cec5SDimitry Andric } else { 8760b57cec5SDimitry Andric // see if this is a callable object with an __call__ method 8770b57cec5SDimitry Andric if (!PyFunction_Check(py_func_obj)) { 8780b57cec5SDimitry Andric PythonObject __call__ = GetAttributeValue("__call__"); 8790b57cec5SDimitry Andric if (__call__.IsValid()) { 8800b57cec5SDimitry Andric auto __callable__ = __call__.AsType<PythonCallable>(); 8810b57cec5SDimitry Andric if (__callable__.IsValid()) { 8820b57cec5SDimitry Andric py_func_obj = PyMethod_GET_FUNCTION(__callable__.get()); 8839dba64beSDimitry Andric PythonObject im_self = __callable__.GetAttributeValue("im_self"); 8840b57cec5SDimitry Andric if (im_self.IsValid() && !im_self.IsNone()) 8859dba64beSDimitry Andric is_bound_method = true; 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric if (!py_func_obj) 8920b57cec5SDimitry Andric return result; 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj); 8950b57cec5SDimitry Andric if (!code) 8960b57cec5SDimitry Andric return result; 8970b57cec5SDimitry Andric 898480093f4SDimitry Andric auto count = code->co_argcount; 899480093f4SDimitry Andric bool has_varargs = !!(code->co_flags & CO_VARARGS); 900480093f4SDimitry Andric result.max_positional_args = 901480093f4SDimitry Andric has_varargs ? ArgInfo::UNBOUNDED 902480093f4SDimitry Andric : (count - (int)is_bound_method) - (int)is_class; 9039dba64beSDimitry Andric 9049dba64beSDimitry Andric #endif 9059dba64beSDimitry Andric 9060b57cec5SDimitry Andric return result; 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9099dba64beSDimitry Andric constexpr unsigned 9109dba64beSDimitry Andric PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17 9119dba64beSDimitry Andric 9120b57cec5SDimitry Andric PythonObject PythonCallable::operator()() { 9130b57cec5SDimitry Andric return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr)); 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric PythonObject PythonCallable:: 9170b57cec5SDimitry Andric operator()(std::initializer_list<PyObject *> args) { 9180b57cec5SDimitry Andric PythonTuple arg_tuple(args); 9190b57cec5SDimitry Andric return PythonObject(PyRefType::Owned, 9200b57cec5SDimitry Andric PyObject_CallObject(m_py_obj, arg_tuple.get())); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric PythonObject PythonCallable:: 9240b57cec5SDimitry Andric operator()(std::initializer_list<PythonObject> args) { 9250b57cec5SDimitry Andric PythonTuple arg_tuple(args); 9260b57cec5SDimitry Andric return PythonObject(PyRefType::Owned, 9270b57cec5SDimitry Andric PyObject_CallObject(m_py_obj, arg_tuple.get())); 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric 9300b57cec5SDimitry Andric bool PythonFile::Check(PyObject *py_obj) { 9319dba64beSDimitry Andric if (!py_obj) 9329dba64beSDimitry Andric return false; 9330b57cec5SDimitry Andric // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a 9340b57cec5SDimitry Andric // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper 9350b57cec5SDimitry Andric // over `io.open()`, which returns some object derived from `io.IOBase`. As a 9360b57cec5SDimitry Andric // result, the only way to detect a file in Python 3 is to check whether it 9379dba64beSDimitry Andric // inherits from `io.IOBase`. 9389dba64beSDimitry Andric auto io_module = PythonModule::Import("io"); 9399dba64beSDimitry Andric if (!io_module) { 9409dba64beSDimitry Andric llvm::consumeError(io_module.takeError()); 9410b57cec5SDimitry Andric return false; 9429dba64beSDimitry Andric } 9439dba64beSDimitry Andric auto iobase = io_module.get().Get("IOBase"); 9449dba64beSDimitry Andric if (!iobase) { 9459dba64beSDimitry Andric llvm::consumeError(iobase.takeError()); 9460b57cec5SDimitry Andric return false; 9479dba64beSDimitry Andric } 9489dba64beSDimitry Andric int r = PyObject_IsInstance(py_obj, iobase.get().get()); 9499dba64beSDimitry Andric if (r < 0) { 9509dba64beSDimitry Andric llvm::consumeError(exception()); // clear the exception and log it. 9519dba64beSDimitry Andric return false; 9529dba64beSDimitry Andric } 9539dba64beSDimitry Andric return !!r; 9540b57cec5SDimitry Andric } 9550b57cec5SDimitry Andric 9569dba64beSDimitry Andric const char *PythonException::toCString() const { 9579dba64beSDimitry Andric if (!m_repr_bytes) 9589dba64beSDimitry Andric return "unknown exception"; 9599dba64beSDimitry Andric return PyBytes_AS_STRING(m_repr_bytes); 9600b57cec5SDimitry Andric } 9610b57cec5SDimitry Andric 9629dba64beSDimitry Andric PythonException::PythonException(const char *caller) { 9639dba64beSDimitry Andric assert(PyErr_Occurred()); 964bdd1243dSDimitry Andric m_exception_type = m_exception = m_traceback = m_repr_bytes = nullptr; 9659dba64beSDimitry Andric PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback); 9669dba64beSDimitry Andric PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback); 9679dba64beSDimitry Andric PyErr_Clear(); 9689dba64beSDimitry Andric if (m_exception) { 9699dba64beSDimitry Andric PyObject *repr = PyObject_Repr(m_exception); 9709dba64beSDimitry Andric if (repr) { 9719dba64beSDimitry Andric m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr); 9729dba64beSDimitry Andric if (!m_repr_bytes) { 9739dba64beSDimitry Andric PyErr_Clear(); 9749dba64beSDimitry Andric } 9759dba64beSDimitry Andric Py_XDECREF(repr); 9769dba64beSDimitry Andric } else { 9779dba64beSDimitry Andric PyErr_Clear(); 9789dba64beSDimitry Andric } 9799dba64beSDimitry Andric } 98081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 9819dba64beSDimitry Andric if (caller) 9829dba64beSDimitry Andric LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString()); 9839dba64beSDimitry Andric else 9849dba64beSDimitry Andric LLDB_LOGF(log, "python exception: %s", toCString()); 9859dba64beSDimitry Andric } 9869dba64beSDimitry Andric void PythonException::Restore() { 9879dba64beSDimitry Andric if (m_exception_type && m_exception) { 9889dba64beSDimitry Andric PyErr_Restore(m_exception_type, m_exception, m_traceback); 9899dba64beSDimitry Andric } else { 9909dba64beSDimitry Andric PyErr_SetString(PyExc_Exception, toCString()); 9919dba64beSDimitry Andric } 992bdd1243dSDimitry Andric m_exception_type = m_exception = m_traceback = nullptr; 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric 9959dba64beSDimitry Andric PythonException::~PythonException() { 9969dba64beSDimitry Andric Py_XDECREF(m_exception_type); 9979dba64beSDimitry Andric Py_XDECREF(m_exception); 9989dba64beSDimitry Andric Py_XDECREF(m_traceback); 9999dba64beSDimitry Andric Py_XDECREF(m_repr_bytes); 10000b57cec5SDimitry Andric } 10010b57cec5SDimitry Andric 10029dba64beSDimitry Andric void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); } 10039dba64beSDimitry Andric 10049dba64beSDimitry Andric std::error_code PythonException::convertToErrorCode() const { 10059dba64beSDimitry Andric return llvm::inconvertibleErrorCode(); 10069dba64beSDimitry Andric } 10079dba64beSDimitry Andric 10089dba64beSDimitry Andric bool PythonException::Matches(PyObject *exc) const { 10099dba64beSDimitry Andric return PyErr_GivenExceptionMatches(m_exception_type, exc); 10109dba64beSDimitry Andric } 10119dba64beSDimitry Andric 10129dba64beSDimitry Andric const char read_exception_script[] = R"( 10139dba64beSDimitry Andric import sys 10149dba64beSDimitry Andric from traceback import print_exception 10159dba64beSDimitry Andric if sys.version_info.major < 3: 10169dba64beSDimitry Andric from StringIO import StringIO 10179dba64beSDimitry Andric else: 10189dba64beSDimitry Andric from io import StringIO 10199dba64beSDimitry Andric def main(exc_type, exc_value, tb): 10209dba64beSDimitry Andric f = StringIO() 10219dba64beSDimitry Andric print_exception(exc_type, exc_value, tb, file=f) 10229dba64beSDimitry Andric return f.getvalue() 10239dba64beSDimitry Andric )"; 10249dba64beSDimitry Andric 10259dba64beSDimitry Andric std::string PythonException::ReadBacktrace() const { 10269dba64beSDimitry Andric 10279dba64beSDimitry Andric if (!m_traceback) 10289dba64beSDimitry Andric return toCString(); 10299dba64beSDimitry Andric 10309dba64beSDimitry Andric // no need to synchronize access to this global, we already have the GIL 10319dba64beSDimitry Andric static PythonScript read_exception(read_exception_script); 10329dba64beSDimitry Andric 10339dba64beSDimitry Andric Expected<std::string> backtrace = As<std::string>( 10349dba64beSDimitry Andric read_exception(m_exception_type, m_exception, m_traceback)); 10359dba64beSDimitry Andric 10369dba64beSDimitry Andric if (!backtrace) { 10379dba64beSDimitry Andric std::string message = 10389dba64beSDimitry Andric std::string(toCString()) + "\n" + 10395ffd83dbSDimitry Andric "Traceback unavailable, an error occurred while reading it:\n"; 10409dba64beSDimitry Andric return (message + llvm::toString(backtrace.takeError())); 10419dba64beSDimitry Andric } 10429dba64beSDimitry Andric 10439dba64beSDimitry Andric return std::move(backtrace.get()); 10449dba64beSDimitry Andric } 10459dba64beSDimitry Andric 10469dba64beSDimitry Andric char PythonException::ID = 0; 10479dba64beSDimitry Andric 10489dba64beSDimitry Andric llvm::Expected<File::OpenOptions> 10499dba64beSDimitry Andric GetOptionsForPyObject(const PythonObject &obj) { 10509dba64beSDimitry Andric auto options = File::OpenOptions(0); 10519dba64beSDimitry Andric auto readable = As<bool>(obj.CallMethod("readable")); 10529dba64beSDimitry Andric if (!readable) 10539dba64beSDimitry Andric return readable.takeError(); 10549dba64beSDimitry Andric auto writable = As<bool>(obj.CallMethod("writable")); 10559dba64beSDimitry Andric if (!writable) 10569dba64beSDimitry Andric return writable.takeError(); 1057349cc55cSDimitry Andric if (readable.get() && writable.get()) 1058349cc55cSDimitry Andric options |= File::eOpenOptionReadWrite; 1059349cc55cSDimitry Andric else if (writable.get()) 1060349cc55cSDimitry Andric options |= File::eOpenOptionWriteOnly; 1061349cc55cSDimitry Andric else if (readable.get()) 1062349cc55cSDimitry Andric options |= File::eOpenOptionReadOnly; 10639dba64beSDimitry Andric return options; 10649dba64beSDimitry Andric } 10659dba64beSDimitry Andric 10669dba64beSDimitry Andric // Base class template for python files. All it knows how to do 10679dba64beSDimitry Andric // is hold a reference to the python object and close or flush it 10689dba64beSDimitry Andric // when the File is closed. 10699dba64beSDimitry Andric namespace { 10709dba64beSDimitry Andric template <typename Base> class OwnedPythonFile : public Base { 10719dba64beSDimitry Andric public: 10729dba64beSDimitry Andric template <typename... Args> 10739dba64beSDimitry Andric OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args) 10749dba64beSDimitry Andric : Base(args...), m_py_obj(file), m_borrowed(borrowed) { 10759dba64beSDimitry Andric assert(m_py_obj); 10769dba64beSDimitry Andric } 10779dba64beSDimitry Andric 10789dba64beSDimitry Andric ~OwnedPythonFile() override { 10799dba64beSDimitry Andric assert(m_py_obj); 10809dba64beSDimitry Andric GIL takeGIL; 10819dba64beSDimitry Andric Close(); 10829dba64beSDimitry Andric // we need to ensure the python object is released while we still 10839dba64beSDimitry Andric // hold the GIL 10849dba64beSDimitry Andric m_py_obj.Reset(); 10859dba64beSDimitry Andric } 10869dba64beSDimitry Andric 10879dba64beSDimitry Andric bool IsPythonSideValid() const { 10889dba64beSDimitry Andric GIL takeGIL; 10899dba64beSDimitry Andric auto closed = As<bool>(m_py_obj.GetAttribute("closed")); 10909dba64beSDimitry Andric if (!closed) { 10919dba64beSDimitry Andric llvm::consumeError(closed.takeError()); 10929dba64beSDimitry Andric return false; 10939dba64beSDimitry Andric } 10949dba64beSDimitry Andric return !closed.get(); 10959dba64beSDimitry Andric } 10969dba64beSDimitry Andric 10979dba64beSDimitry Andric bool IsValid() const override { 10989dba64beSDimitry Andric return IsPythonSideValid() && Base::IsValid(); 10999dba64beSDimitry Andric } 11009dba64beSDimitry Andric 11019dba64beSDimitry Andric Status Close() override { 11029dba64beSDimitry Andric assert(m_py_obj); 11039dba64beSDimitry Andric Status py_error, base_error; 11049dba64beSDimitry Andric GIL takeGIL; 11059dba64beSDimitry Andric if (!m_borrowed) { 11069dba64beSDimitry Andric auto r = m_py_obj.CallMethod("close"); 11079dba64beSDimitry Andric if (!r) 11089dba64beSDimitry Andric py_error = Status(r.takeError()); 11099dba64beSDimitry Andric } 11109dba64beSDimitry Andric base_error = Base::Close(); 11119dba64beSDimitry Andric if (py_error.Fail()) 11129dba64beSDimitry Andric return py_error; 11139dba64beSDimitry Andric return base_error; 11149dba64beSDimitry Andric }; 11159dba64beSDimitry Andric 11169dba64beSDimitry Andric PyObject *GetPythonObject() const { 11179dba64beSDimitry Andric assert(m_py_obj.IsValid()); 11189dba64beSDimitry Andric return m_py_obj.get(); 11199dba64beSDimitry Andric } 11209dba64beSDimitry Andric 11219dba64beSDimitry Andric static bool classof(const File *file) = delete; 11229dba64beSDimitry Andric 11239dba64beSDimitry Andric protected: 11249dba64beSDimitry Andric PythonFile m_py_obj; 11259dba64beSDimitry Andric bool m_borrowed; 11269dba64beSDimitry Andric }; 11279dba64beSDimitry Andric } // namespace 11289dba64beSDimitry Andric 11299dba64beSDimitry Andric // A SimplePythonFile is a OwnedPythonFile that just does all I/O as 11309dba64beSDimitry Andric // a NativeFile 11319dba64beSDimitry Andric namespace { 11329dba64beSDimitry Andric class SimplePythonFile : public OwnedPythonFile<NativeFile> { 11339dba64beSDimitry Andric public: 11349dba64beSDimitry Andric SimplePythonFile(const PythonFile &file, bool borrowed, int fd, 11359dba64beSDimitry Andric File::OpenOptions options) 11369dba64beSDimitry Andric : OwnedPythonFile(file, borrowed, fd, options, false) {} 11379dba64beSDimitry Andric 11389dba64beSDimitry Andric static char ID; 11399dba64beSDimitry Andric bool isA(const void *classID) const override { 11409dba64beSDimitry Andric return classID == &ID || NativeFile::isA(classID); 11419dba64beSDimitry Andric } 11429dba64beSDimitry Andric static bool classof(const File *file) { return file->isA(&ID); } 11439dba64beSDimitry Andric }; 11449dba64beSDimitry Andric char SimplePythonFile::ID = 0; 11459dba64beSDimitry Andric } // namespace 11469dba64beSDimitry Andric 11479dba64beSDimitry Andric namespace { 11489dba64beSDimitry Andric class PythonBuffer { 11499dba64beSDimitry Andric public: 11509dba64beSDimitry Andric PythonBuffer &operator=(const PythonBuffer &) = delete; 11519dba64beSDimitry Andric PythonBuffer(const PythonBuffer &) = delete; 11529dba64beSDimitry Andric 11539dba64beSDimitry Andric static Expected<PythonBuffer> Create(PythonObject &obj, 11549dba64beSDimitry Andric int flags = PyBUF_SIMPLE) { 11559dba64beSDimitry Andric Py_buffer py_buffer = {}; 11569dba64beSDimitry Andric PyObject_GetBuffer(obj.get(), &py_buffer, flags); 11579dba64beSDimitry Andric if (!py_buffer.obj) 11589dba64beSDimitry Andric return llvm::make_error<PythonException>(); 11599dba64beSDimitry Andric return PythonBuffer(py_buffer); 11609dba64beSDimitry Andric } 11619dba64beSDimitry Andric 11629dba64beSDimitry Andric PythonBuffer(PythonBuffer &&other) { 11639dba64beSDimitry Andric m_buffer = other.m_buffer; 11649dba64beSDimitry Andric other.m_buffer.obj = nullptr; 11659dba64beSDimitry Andric } 11669dba64beSDimitry Andric 11679dba64beSDimitry Andric ~PythonBuffer() { 11689dba64beSDimitry Andric if (m_buffer.obj) 11699dba64beSDimitry Andric PyBuffer_Release(&m_buffer); 11709dba64beSDimitry Andric } 11719dba64beSDimitry Andric 11729dba64beSDimitry Andric Py_buffer &get() { return m_buffer; } 11739dba64beSDimitry Andric 11749dba64beSDimitry Andric private: 11759dba64beSDimitry Andric // takes ownership of the buffer. 11769dba64beSDimitry Andric PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {} 11779dba64beSDimitry Andric Py_buffer m_buffer; 11789dba64beSDimitry Andric }; 11799dba64beSDimitry Andric } // namespace 11809dba64beSDimitry Andric 11819dba64beSDimitry Andric // Shared methods between TextPythonFile and BinaryPythonFile 11829dba64beSDimitry Andric namespace { 11839dba64beSDimitry Andric class PythonIOFile : public OwnedPythonFile<File> { 11849dba64beSDimitry Andric public: 11859dba64beSDimitry Andric PythonIOFile(const PythonFile &file, bool borrowed) 11869dba64beSDimitry Andric : OwnedPythonFile(file, borrowed) {} 11879dba64beSDimitry Andric 11889dba64beSDimitry Andric ~PythonIOFile() override { Close(); } 11899dba64beSDimitry Andric 11909dba64beSDimitry Andric bool IsValid() const override { return IsPythonSideValid(); } 11919dba64beSDimitry Andric 11929dba64beSDimitry Andric Status Close() override { 11939dba64beSDimitry Andric assert(m_py_obj); 11949dba64beSDimitry Andric GIL takeGIL; 11959dba64beSDimitry Andric if (m_borrowed) 11969dba64beSDimitry Andric return Flush(); 11979dba64beSDimitry Andric auto r = m_py_obj.CallMethod("close"); 11989dba64beSDimitry Andric if (!r) 11999dba64beSDimitry Andric return Status(r.takeError()); 12009dba64beSDimitry Andric return Status(); 12019dba64beSDimitry Andric } 12029dba64beSDimitry Andric 12039dba64beSDimitry Andric Status Flush() override { 12049dba64beSDimitry Andric GIL takeGIL; 12059dba64beSDimitry Andric auto r = m_py_obj.CallMethod("flush"); 12069dba64beSDimitry Andric if (!r) 12079dba64beSDimitry Andric return Status(r.takeError()); 12089dba64beSDimitry Andric return Status(); 12099dba64beSDimitry Andric } 12109dba64beSDimitry Andric 12119dba64beSDimitry Andric Expected<File::OpenOptions> GetOptions() const override { 12129dba64beSDimitry Andric GIL takeGIL; 12139dba64beSDimitry Andric return GetOptionsForPyObject(m_py_obj); 12149dba64beSDimitry Andric } 12159dba64beSDimitry Andric 12169dba64beSDimitry Andric static char ID; 12179dba64beSDimitry Andric bool isA(const void *classID) const override { 12189dba64beSDimitry Andric return classID == &ID || File::isA(classID); 12199dba64beSDimitry Andric } 12209dba64beSDimitry Andric static bool classof(const File *file) { return file->isA(&ID); } 12219dba64beSDimitry Andric }; 12229dba64beSDimitry Andric char PythonIOFile::ID = 0; 12239dba64beSDimitry Andric } // namespace 12249dba64beSDimitry Andric 12259dba64beSDimitry Andric namespace { 12269dba64beSDimitry Andric class BinaryPythonFile : public PythonIOFile { 12279dba64beSDimitry Andric protected: 12289dba64beSDimitry Andric int m_descriptor; 12299dba64beSDimitry Andric 12309dba64beSDimitry Andric public: 12319dba64beSDimitry Andric BinaryPythonFile(int fd, const PythonFile &file, bool borrowed) 12329dba64beSDimitry Andric : PythonIOFile(file, borrowed), 12339dba64beSDimitry Andric m_descriptor(File::DescriptorIsValid(fd) ? fd 12349dba64beSDimitry Andric : File::kInvalidDescriptor) {} 12359dba64beSDimitry Andric 12369dba64beSDimitry Andric int GetDescriptor() const override { return m_descriptor; } 12379dba64beSDimitry Andric 12389dba64beSDimitry Andric Status Write(const void *buf, size_t &num_bytes) override { 12399dba64beSDimitry Andric GIL takeGIL; 12409dba64beSDimitry Andric PyObject *pybuffer_p = PyMemoryView_FromMemory( 12419dba64beSDimitry Andric const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ); 12429dba64beSDimitry Andric if (!pybuffer_p) 12439dba64beSDimitry Andric return Status(llvm::make_error<PythonException>()); 12449dba64beSDimitry Andric auto pybuffer = Take<PythonObject>(pybuffer_p); 12459dba64beSDimitry Andric num_bytes = 0; 12469dba64beSDimitry Andric auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer)); 12479dba64beSDimitry Andric if (!bytes_written) 12489dba64beSDimitry Andric return Status(bytes_written.takeError()); 12499dba64beSDimitry Andric if (bytes_written.get() < 0) 12509dba64beSDimitry Andric return Status(".write() method returned a negative number!"); 12519dba64beSDimitry Andric static_assert(sizeof(long long) >= sizeof(size_t), "overflow"); 12529dba64beSDimitry Andric num_bytes = bytes_written.get(); 12539dba64beSDimitry Andric return Status(); 12549dba64beSDimitry Andric } 12559dba64beSDimitry Andric 12569dba64beSDimitry Andric Status Read(void *buf, size_t &num_bytes) override { 12579dba64beSDimitry Andric GIL takeGIL; 12589dba64beSDimitry Andric static_assert(sizeof(long long) >= sizeof(size_t), "overflow"); 12599dba64beSDimitry Andric auto pybuffer_obj = 12609dba64beSDimitry Andric m_py_obj.CallMethod("read", (unsigned long long)num_bytes); 12619dba64beSDimitry Andric if (!pybuffer_obj) 12629dba64beSDimitry Andric return Status(pybuffer_obj.takeError()); 12639dba64beSDimitry Andric num_bytes = 0; 12649dba64beSDimitry Andric if (pybuffer_obj.get().IsNone()) { 12659dba64beSDimitry Andric // EOF 12669dba64beSDimitry Andric num_bytes = 0; 12679dba64beSDimitry Andric return Status(); 12689dba64beSDimitry Andric } 12699dba64beSDimitry Andric auto pybuffer = PythonBuffer::Create(pybuffer_obj.get()); 12709dba64beSDimitry Andric if (!pybuffer) 12719dba64beSDimitry Andric return Status(pybuffer.takeError()); 12729dba64beSDimitry Andric memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len); 12739dba64beSDimitry Andric num_bytes = pybuffer.get().get().len; 12749dba64beSDimitry Andric return Status(); 12759dba64beSDimitry Andric } 12769dba64beSDimitry Andric }; 12779dba64beSDimitry Andric } // namespace 12789dba64beSDimitry Andric 12799dba64beSDimitry Andric namespace { 12809dba64beSDimitry Andric class TextPythonFile : public PythonIOFile { 12819dba64beSDimitry Andric protected: 12829dba64beSDimitry Andric int m_descriptor; 12839dba64beSDimitry Andric 12849dba64beSDimitry Andric public: 12859dba64beSDimitry Andric TextPythonFile(int fd, const PythonFile &file, bool borrowed) 12869dba64beSDimitry Andric : PythonIOFile(file, borrowed), 12879dba64beSDimitry Andric m_descriptor(File::DescriptorIsValid(fd) ? fd 12889dba64beSDimitry Andric : File::kInvalidDescriptor) {} 12899dba64beSDimitry Andric 12909dba64beSDimitry Andric int GetDescriptor() const override { return m_descriptor; } 12919dba64beSDimitry Andric 12929dba64beSDimitry Andric Status Write(const void *buf, size_t &num_bytes) override { 12939dba64beSDimitry Andric GIL takeGIL; 12949dba64beSDimitry Andric auto pystring = 12959dba64beSDimitry Andric PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes)); 12969dba64beSDimitry Andric if (!pystring) 12979dba64beSDimitry Andric return Status(pystring.takeError()); 12989dba64beSDimitry Andric num_bytes = 0; 12999dba64beSDimitry Andric auto bytes_written = 13009dba64beSDimitry Andric As<long long>(m_py_obj.CallMethod("write", pystring.get())); 13019dba64beSDimitry Andric if (!bytes_written) 13029dba64beSDimitry Andric return Status(bytes_written.takeError()); 13039dba64beSDimitry Andric if (bytes_written.get() < 0) 13049dba64beSDimitry Andric return Status(".write() method returned a negative number!"); 13059dba64beSDimitry Andric static_assert(sizeof(long long) >= sizeof(size_t), "overflow"); 13069dba64beSDimitry Andric num_bytes = bytes_written.get(); 13079dba64beSDimitry Andric return Status(); 13089dba64beSDimitry Andric } 13099dba64beSDimitry Andric 13109dba64beSDimitry Andric Status Read(void *buf, size_t &num_bytes) override { 13119dba64beSDimitry Andric GIL takeGIL; 13129dba64beSDimitry Andric size_t num_chars = num_bytes / 6; 13139dba64beSDimitry Andric size_t orig_num_bytes = num_bytes; 13149dba64beSDimitry Andric num_bytes = 0; 13159dba64beSDimitry Andric if (orig_num_bytes < 6) { 13169dba64beSDimitry Andric return Status("can't read less than 6 bytes from a utf8 text stream"); 13179dba64beSDimitry Andric } 13189dba64beSDimitry Andric auto pystring = As<PythonString>( 13199dba64beSDimitry Andric m_py_obj.CallMethod("read", (unsigned long long)num_chars)); 13209dba64beSDimitry Andric if (!pystring) 13219dba64beSDimitry Andric return Status(pystring.takeError()); 13229dba64beSDimitry Andric if (pystring.get().IsNone()) { 13239dba64beSDimitry Andric // EOF 13249dba64beSDimitry Andric return Status(); 13259dba64beSDimitry Andric } 13269dba64beSDimitry Andric auto stringref = pystring.get().AsUTF8(); 13279dba64beSDimitry Andric if (!stringref) 13289dba64beSDimitry Andric return Status(stringref.takeError()); 13299dba64beSDimitry Andric num_bytes = stringref.get().size(); 13309dba64beSDimitry Andric memcpy(buf, stringref.get().begin(), num_bytes); 13319dba64beSDimitry Andric return Status(); 13329dba64beSDimitry Andric } 13339dba64beSDimitry Andric }; 13349dba64beSDimitry Andric } // namespace 13359dba64beSDimitry Andric 13369dba64beSDimitry Andric llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) { 13379dba64beSDimitry Andric if (!IsValid()) 13389dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 13399dba64beSDimitry Andric "invalid PythonFile"); 13409dba64beSDimitry Andric 13419dba64beSDimitry Andric int fd = PyObject_AsFileDescriptor(m_py_obj); 13429dba64beSDimitry Andric if (fd < 0) { 13439dba64beSDimitry Andric PyErr_Clear(); 13449dba64beSDimitry Andric return ConvertToFileForcingUseOfScriptingIOMethods(borrowed); 13459dba64beSDimitry Andric } 13469dba64beSDimitry Andric auto options = GetOptionsForPyObject(*this); 13479dba64beSDimitry Andric if (!options) 13489dba64beSDimitry Andric return options.takeError(); 13499dba64beSDimitry Andric 1350349cc55cSDimitry Andric File::OpenOptions rw = 1351349cc55cSDimitry Andric options.get() & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | 1352349cc55cSDimitry Andric File::eOpenOptionReadWrite); 1353349cc55cSDimitry Andric if (rw == File::eOpenOptionWriteOnly || rw == File::eOpenOptionReadWrite) { 13549dba64beSDimitry Andric // LLDB and python will not share I/O buffers. We should probably 13559dba64beSDimitry Andric // flush the python buffers now. 13569dba64beSDimitry Andric auto r = CallMethod("flush"); 13579dba64beSDimitry Andric if (!r) 13589dba64beSDimitry Andric return r.takeError(); 1359480093f4SDimitry Andric } 13609dba64beSDimitry Andric 13619dba64beSDimitry Andric FileSP file_sp; 13629dba64beSDimitry Andric if (borrowed) { 13635f757f3fSDimitry Andric // In this case we don't need to retain the python 13649dba64beSDimitry Andric // object at all. 13659dba64beSDimitry Andric file_sp = std::make_shared<NativeFile>(fd, options.get(), false); 13669dba64beSDimitry Andric } else { 13679dba64beSDimitry Andric file_sp = std::static_pointer_cast<File>( 13689dba64beSDimitry Andric std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get())); 13699dba64beSDimitry Andric } 13709dba64beSDimitry Andric if (!file_sp->IsValid()) 13719dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 13729dba64beSDimitry Andric "invalid File"); 13739dba64beSDimitry Andric 13749dba64beSDimitry Andric return file_sp; 13759dba64beSDimitry Andric } 13769dba64beSDimitry Andric 13779dba64beSDimitry Andric llvm::Expected<FileSP> 13789dba64beSDimitry Andric PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) { 13799dba64beSDimitry Andric 13809dba64beSDimitry Andric assert(!PyErr_Occurred()); 13819dba64beSDimitry Andric 13829dba64beSDimitry Andric if (!IsValid()) 13839dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 13849dba64beSDimitry Andric "invalid PythonFile"); 13859dba64beSDimitry Andric 13869dba64beSDimitry Andric int fd = PyObject_AsFileDescriptor(m_py_obj); 13879dba64beSDimitry Andric if (fd < 0) { 13889dba64beSDimitry Andric PyErr_Clear(); 13899dba64beSDimitry Andric fd = File::kInvalidDescriptor; 13909dba64beSDimitry Andric } 13919dba64beSDimitry Andric 13929dba64beSDimitry Andric auto io_module = PythonModule::Import("io"); 13939dba64beSDimitry Andric if (!io_module) 13949dba64beSDimitry Andric return io_module.takeError(); 13959dba64beSDimitry Andric auto textIOBase = io_module.get().Get("TextIOBase"); 13969dba64beSDimitry Andric if (!textIOBase) 13979dba64beSDimitry Andric return textIOBase.takeError(); 13989dba64beSDimitry Andric auto rawIOBase = io_module.get().Get("RawIOBase"); 13999dba64beSDimitry Andric if (!rawIOBase) 14009dba64beSDimitry Andric return rawIOBase.takeError(); 14019dba64beSDimitry Andric auto bufferedIOBase = io_module.get().Get("BufferedIOBase"); 14029dba64beSDimitry Andric if (!bufferedIOBase) 14039dba64beSDimitry Andric return bufferedIOBase.takeError(); 14049dba64beSDimitry Andric 14059dba64beSDimitry Andric FileSP file_sp; 14069dba64beSDimitry Andric 14079dba64beSDimitry Andric auto isTextIO = IsInstance(textIOBase.get()); 14089dba64beSDimitry Andric if (!isTextIO) 14099dba64beSDimitry Andric return isTextIO.takeError(); 14109dba64beSDimitry Andric if (isTextIO.get()) 14119dba64beSDimitry Andric file_sp = std::static_pointer_cast<File>( 14129dba64beSDimitry Andric std::make_shared<TextPythonFile>(fd, *this, borrowed)); 14139dba64beSDimitry Andric 14149dba64beSDimitry Andric auto isRawIO = IsInstance(rawIOBase.get()); 14159dba64beSDimitry Andric if (!isRawIO) 14169dba64beSDimitry Andric return isRawIO.takeError(); 14179dba64beSDimitry Andric auto isBufferedIO = IsInstance(bufferedIOBase.get()); 14189dba64beSDimitry Andric if (!isBufferedIO) 14199dba64beSDimitry Andric return isBufferedIO.takeError(); 14209dba64beSDimitry Andric 14219dba64beSDimitry Andric if (isRawIO.get() || isBufferedIO.get()) { 14229dba64beSDimitry Andric file_sp = std::static_pointer_cast<File>( 14239dba64beSDimitry Andric std::make_shared<BinaryPythonFile>(fd, *this, borrowed)); 14249dba64beSDimitry Andric } 14259dba64beSDimitry Andric 14269dba64beSDimitry Andric if (!file_sp) 14279dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 14289dba64beSDimitry Andric "python file is neither text nor binary"); 14299dba64beSDimitry Andric 14309dba64beSDimitry Andric if (!file_sp->IsValid()) 14319dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 14329dba64beSDimitry Andric "invalid File"); 14339dba64beSDimitry Andric 14349dba64beSDimitry Andric return file_sp; 14359dba64beSDimitry Andric } 14369dba64beSDimitry Andric 14379dba64beSDimitry Andric Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) { 14389dba64beSDimitry Andric if (!file.IsValid()) 14399dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 14409dba64beSDimitry Andric "invalid file"); 14419dba64beSDimitry Andric 14429dba64beSDimitry Andric if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file)) 14439dba64beSDimitry Andric return Retain<PythonFile>(simple->GetPythonObject()); 14449dba64beSDimitry Andric if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file)) 14459dba64beSDimitry Andric return Retain<PythonFile>(pythonio->GetPythonObject()); 14469dba64beSDimitry Andric 14479dba64beSDimitry Andric if (!mode) { 14489dba64beSDimitry Andric auto m = file.GetOpenMode(); 14499dba64beSDimitry Andric if (!m) 14509dba64beSDimitry Andric return m.takeError(); 14519dba64beSDimitry Andric mode = m.get(); 14529dba64beSDimitry Andric } 14539dba64beSDimitry Andric 14549dba64beSDimitry Andric PyObject *file_obj; 14559dba64beSDimitry Andric file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr, 1456480093f4SDimitry Andric "ignore", nullptr, /*closefd=*/0); 14579dba64beSDimitry Andric 14589dba64beSDimitry Andric if (!file_obj) 14599dba64beSDimitry Andric return exception(); 14609dba64beSDimitry Andric 14619dba64beSDimitry Andric return Take<PythonFile>(file_obj); 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric 14649dba64beSDimitry Andric Error PythonScript::Init() { 14659dba64beSDimitry Andric if (function.IsValid()) 14669dba64beSDimitry Andric return Error::success(); 14670b57cec5SDimitry Andric 14689dba64beSDimitry Andric PythonDictionary globals(PyInitialValue::Empty); 14699dba64beSDimitry Andric auto builtins = PythonModule::BuiltinsModule(); 14709dba64beSDimitry Andric if (Error error = globals.SetItem("__builtins__", builtins)) 14719dba64beSDimitry Andric return error; 14729dba64beSDimitry Andric PyObject *o = 14739dba64beSDimitry Andric PyRun_String(script, Py_file_input, globals.get(), globals.get()); 14749dba64beSDimitry Andric if (!o) 14759dba64beSDimitry Andric return exception(); 14769dba64beSDimitry Andric Take<PythonObject>(o); 14779dba64beSDimitry Andric auto f = As<PythonCallable>(globals.GetItem("main")); 14789dba64beSDimitry Andric if (!f) 14799dba64beSDimitry Andric return f.takeError(); 14809dba64beSDimitry Andric function = std::move(f.get()); 14819dba64beSDimitry Andric 14829dba64beSDimitry Andric return Error::success(); 14830b57cec5SDimitry Andric } 14840b57cec5SDimitry Andric 14859dba64beSDimitry Andric llvm::Expected<PythonObject> 14869dba64beSDimitry Andric python::runStringOneLine(const llvm::Twine &string, 14879dba64beSDimitry Andric const PythonDictionary &globals, 14889dba64beSDimitry Andric const PythonDictionary &locals) { 14899dba64beSDimitry Andric if (!globals.IsValid() || !locals.IsValid()) 14909dba64beSDimitry Andric return nullDeref(); 14910b57cec5SDimitry Andric 14929dba64beSDimitry Andric PyObject *code = 14939dba64beSDimitry Andric Py_CompileString(NullTerminated(string), "<string>", Py_eval_input); 14949dba64beSDimitry Andric if (!code) { 14959dba64beSDimitry Andric PyErr_Clear(); 14969dba64beSDimitry Andric code = 14979dba64beSDimitry Andric Py_CompileString(NullTerminated(string), "<string>", Py_single_input); 14989dba64beSDimitry Andric } 14999dba64beSDimitry Andric if (!code) 15009dba64beSDimitry Andric return exception(); 15019dba64beSDimitry Andric auto code_ref = Take<PythonObject>(code); 15029dba64beSDimitry Andric 15039dba64beSDimitry Andric PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get()); 15049dba64beSDimitry Andric 15059dba64beSDimitry Andric if (!result) 15069dba64beSDimitry Andric return exception(); 15079dba64beSDimitry Andric 15089dba64beSDimitry Andric return Take<PythonObject>(result); 15099dba64beSDimitry Andric } 15109dba64beSDimitry Andric 15119dba64beSDimitry Andric llvm::Expected<PythonObject> 15129dba64beSDimitry Andric python::runStringMultiLine(const llvm::Twine &string, 15139dba64beSDimitry Andric const PythonDictionary &globals, 15149dba64beSDimitry Andric const PythonDictionary &locals) { 15159dba64beSDimitry Andric if (!globals.IsValid() || !locals.IsValid()) 15169dba64beSDimitry Andric return nullDeref(); 15179dba64beSDimitry Andric PyObject *result = PyRun_String(NullTerminated(string), Py_file_input, 15189dba64beSDimitry Andric globals.get(), locals.get()); 15199dba64beSDimitry Andric if (!result) 15209dba64beSDimitry Andric return exception(); 15219dba64beSDimitry Andric return Take<PythonObject>(result); 15220b57cec5SDimitry Andric } 15230b57cec5SDimitry Andric 15240b57cec5SDimitry Andric #endif 1525