1*dda28197Spatrick //===-- PythonDataObjects.cpp ---------------------------------------------===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick #include "lldb/Host/Config.h" 10061da546Spatrick 11061da546Spatrick #if LLDB_ENABLE_PYTHON 12061da546Spatrick 13061da546Spatrick #include "PythonDataObjects.h" 14061da546Spatrick #include "ScriptInterpreterPython.h" 15061da546Spatrick 16061da546Spatrick #include "lldb/Host/File.h" 17061da546Spatrick #include "lldb/Host/FileSystem.h" 18061da546Spatrick #include "lldb/Interpreter/ScriptInterpreter.h" 19061da546Spatrick #include "lldb/Utility/Log.h" 20061da546Spatrick #include "lldb/Utility/Stream.h" 21061da546Spatrick 22061da546Spatrick #include "llvm/ADT/StringSwitch.h" 23061da546Spatrick #include "llvm/Support/Casting.h" 24061da546Spatrick #include "llvm/Support/ConvertUTF.h" 25061da546Spatrick #include "llvm/Support/Errno.h" 26061da546Spatrick 27061da546Spatrick #include <stdio.h> 28061da546Spatrick 29061da546Spatrick using namespace lldb_private; 30061da546Spatrick using namespace lldb; 31061da546Spatrick using namespace lldb_private::python; 32061da546Spatrick using llvm::cantFail; 33061da546Spatrick using llvm::Error; 34061da546Spatrick using llvm::Expected; 35061da546Spatrick using llvm::Twine; 36061da546Spatrick 37061da546Spatrick template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) { 38061da546Spatrick if (!obj) 39061da546Spatrick return obj.takeError(); 40061da546Spatrick return obj.get().IsTrue(); 41061da546Spatrick } 42061da546Spatrick 43061da546Spatrick template <> 44061da546Spatrick Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) { 45061da546Spatrick if (!obj) 46061da546Spatrick return obj.takeError(); 47*dda28197Spatrick return obj->AsLongLong(); 48*dda28197Spatrick } 49*dda28197Spatrick 50*dda28197Spatrick template <> 51*dda28197Spatrick Expected<unsigned long long> 52*dda28197Spatrick python::As<unsigned long long>(Expected<PythonObject> &&obj) { 53*dda28197Spatrick if (!obj) 54*dda28197Spatrick return obj.takeError(); 55*dda28197Spatrick return obj->AsUnsignedLongLong(); 56061da546Spatrick } 57061da546Spatrick 58061da546Spatrick template <> 59061da546Spatrick Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) { 60061da546Spatrick if (!obj) 61061da546Spatrick return obj.takeError(); 62061da546Spatrick PyObject *str_obj = PyObject_Str(obj.get().get()); 63061da546Spatrick if (!obj) 64061da546Spatrick return llvm::make_error<PythonException>(); 65061da546Spatrick auto str = Take<PythonString>(str_obj); 66061da546Spatrick auto utf8 = str.AsUTF8(); 67061da546Spatrick if (!utf8) 68061da546Spatrick return utf8.takeError(); 69*dda28197Spatrick return std::string(utf8.get()); 70*dda28197Spatrick } 71*dda28197Spatrick 72*dda28197Spatrick Expected<long long> PythonObject::AsLongLong() const { 73*dda28197Spatrick if (!m_py_obj) 74*dda28197Spatrick return nullDeref(); 75*dda28197Spatrick #if PY_MAJOR_VERSION < 3 76*dda28197Spatrick if (!PyLong_Check(m_py_obj)) { 77*dda28197Spatrick PythonInteger i(PyRefType::Borrowed, m_py_obj); 78*dda28197Spatrick return i.AsLongLong(); 79*dda28197Spatrick } 80*dda28197Spatrick #endif 81*dda28197Spatrick assert(!PyErr_Occurred()); 82*dda28197Spatrick long long r = PyLong_AsLongLong(m_py_obj); 83*dda28197Spatrick if (PyErr_Occurred()) 84*dda28197Spatrick return exception(); 85*dda28197Spatrick return r; 86*dda28197Spatrick } 87*dda28197Spatrick 88*dda28197Spatrick Expected<long long> PythonObject::AsUnsignedLongLong() const { 89*dda28197Spatrick if (!m_py_obj) 90*dda28197Spatrick return nullDeref(); 91*dda28197Spatrick #if PY_MAJOR_VERSION < 3 92*dda28197Spatrick if (!PyLong_Check(m_py_obj)) { 93*dda28197Spatrick PythonInteger i(PyRefType::Borrowed, m_py_obj); 94*dda28197Spatrick return i.AsUnsignedLongLong(); 95*dda28197Spatrick } 96*dda28197Spatrick #endif 97*dda28197Spatrick assert(!PyErr_Occurred()); 98*dda28197Spatrick long long r = PyLong_AsUnsignedLongLong(m_py_obj); 99*dda28197Spatrick if (PyErr_Occurred()) 100*dda28197Spatrick return exception(); 101*dda28197Spatrick return r; 102*dda28197Spatrick } 103*dda28197Spatrick 104*dda28197Spatrick // wraps on overflow, instead of raising an error. 105*dda28197Spatrick Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const { 106*dda28197Spatrick if (!m_py_obj) 107*dda28197Spatrick return nullDeref(); 108*dda28197Spatrick #if PY_MAJOR_VERSION < 3 109*dda28197Spatrick if (!PyLong_Check(m_py_obj)) { 110*dda28197Spatrick PythonInteger i(PyRefType::Borrowed, m_py_obj); 111*dda28197Spatrick return i.AsModuloUnsignedLongLong(); 112*dda28197Spatrick } 113*dda28197Spatrick #endif 114*dda28197Spatrick assert(!PyErr_Occurred()); 115*dda28197Spatrick unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj); 116*dda28197Spatrick if (PyErr_Occurred()) 117*dda28197Spatrick return exception(); 118*dda28197Spatrick return r; 119061da546Spatrick } 120061da546Spatrick 121061da546Spatrick void StructuredPythonObject::Serialize(llvm::json::OStream &s) const { 122061da546Spatrick s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str()); 123061da546Spatrick } 124061da546Spatrick 125061da546Spatrick // PythonObject 126061da546Spatrick 127061da546Spatrick void PythonObject::Dump(Stream &strm) const { 128061da546Spatrick if (m_py_obj) { 129061da546Spatrick FILE *file = llvm::sys::RetryAfterSignal(nullptr, ::tmpfile); 130061da546Spatrick if (file) { 131061da546Spatrick ::PyObject_Print(m_py_obj, file, 0); 132061da546Spatrick const long length = ftell(file); 133061da546Spatrick if (length) { 134061da546Spatrick ::rewind(file); 135061da546Spatrick std::vector<char> file_contents(length, '\0'); 136061da546Spatrick const size_t length_read = 137061da546Spatrick ::fread(file_contents.data(), 1, file_contents.size(), file); 138061da546Spatrick if (length_read > 0) 139061da546Spatrick strm.Write(file_contents.data(), length_read); 140061da546Spatrick } 141061da546Spatrick ::fclose(file); 142061da546Spatrick } 143061da546Spatrick } else 144061da546Spatrick strm.PutCString("NULL"); 145061da546Spatrick } 146061da546Spatrick 147061da546Spatrick PyObjectType PythonObject::GetObjectType() const { 148061da546Spatrick if (!IsAllocated()) 149061da546Spatrick return PyObjectType::None; 150061da546Spatrick 151061da546Spatrick if (PythonModule::Check(m_py_obj)) 152061da546Spatrick return PyObjectType::Module; 153061da546Spatrick if (PythonList::Check(m_py_obj)) 154061da546Spatrick return PyObjectType::List; 155061da546Spatrick if (PythonTuple::Check(m_py_obj)) 156061da546Spatrick return PyObjectType::Tuple; 157061da546Spatrick if (PythonDictionary::Check(m_py_obj)) 158061da546Spatrick return PyObjectType::Dictionary; 159061da546Spatrick if (PythonString::Check(m_py_obj)) 160061da546Spatrick return PyObjectType::String; 161061da546Spatrick #if PY_MAJOR_VERSION >= 3 162061da546Spatrick if (PythonBytes::Check(m_py_obj)) 163061da546Spatrick return PyObjectType::Bytes; 164061da546Spatrick #endif 165061da546Spatrick if (PythonByteArray::Check(m_py_obj)) 166061da546Spatrick return PyObjectType::ByteArray; 167061da546Spatrick if (PythonBoolean::Check(m_py_obj)) 168061da546Spatrick return PyObjectType::Boolean; 169061da546Spatrick if (PythonInteger::Check(m_py_obj)) 170061da546Spatrick return PyObjectType::Integer; 171061da546Spatrick if (PythonFile::Check(m_py_obj)) 172061da546Spatrick return PyObjectType::File; 173061da546Spatrick if (PythonCallable::Check(m_py_obj)) 174061da546Spatrick return PyObjectType::Callable; 175061da546Spatrick return PyObjectType::Unknown; 176061da546Spatrick } 177061da546Spatrick 178061da546Spatrick PythonString PythonObject::Repr() const { 179061da546Spatrick if (!m_py_obj) 180061da546Spatrick return PythonString(); 181061da546Spatrick PyObject *repr = PyObject_Repr(m_py_obj); 182061da546Spatrick if (!repr) 183061da546Spatrick return PythonString(); 184061da546Spatrick return PythonString(PyRefType::Owned, repr); 185061da546Spatrick } 186061da546Spatrick 187061da546Spatrick PythonString PythonObject::Str() const { 188061da546Spatrick if (!m_py_obj) 189061da546Spatrick return PythonString(); 190061da546Spatrick PyObject *str = PyObject_Str(m_py_obj); 191061da546Spatrick if (!str) 192061da546Spatrick return PythonString(); 193061da546Spatrick return PythonString(PyRefType::Owned, str); 194061da546Spatrick } 195061da546Spatrick 196061da546Spatrick PythonObject 197061da546Spatrick PythonObject::ResolveNameWithDictionary(llvm::StringRef name, 198061da546Spatrick const PythonDictionary &dict) { 199061da546Spatrick size_t dot_pos = name.find('.'); 200061da546Spatrick llvm::StringRef piece = name.substr(0, dot_pos); 201061da546Spatrick PythonObject result = dict.GetItemForKey(PythonString(piece)); 202061da546Spatrick if (dot_pos == llvm::StringRef::npos) { 203061da546Spatrick // There was no dot, we're done. 204061da546Spatrick return result; 205061da546Spatrick } 206061da546Spatrick 207061da546Spatrick // There was a dot. The remaining portion of the name should be looked up in 208061da546Spatrick // the context of the object that was found in the dictionary. 209061da546Spatrick return result.ResolveName(name.substr(dot_pos + 1)); 210061da546Spatrick } 211061da546Spatrick 212061da546Spatrick PythonObject PythonObject::ResolveName(llvm::StringRef name) const { 213061da546Spatrick // Resolve the name in the context of the specified object. If, for example, 214061da546Spatrick // `this` refers to a PyModule, then this will look for `name` in this 215061da546Spatrick // module. If `this` refers to a PyType, then it will resolve `name` as an 216061da546Spatrick // attribute of that type. If `this` refers to an instance of an object, 217061da546Spatrick // then it will resolve `name` as the value of the specified field. 218061da546Spatrick // 219061da546Spatrick // This function handles dotted names so that, for example, if `m_py_obj` 220061da546Spatrick // refers to the `sys` module, and `name` == "path.append", then it will find 221061da546Spatrick // the function `sys.path.append`. 222061da546Spatrick 223061da546Spatrick size_t dot_pos = name.find('.'); 224061da546Spatrick if (dot_pos == llvm::StringRef::npos) { 225061da546Spatrick // No dots in the name, we should be able to find the value immediately as 226061da546Spatrick // an attribute of `m_py_obj`. 227061da546Spatrick return GetAttributeValue(name); 228061da546Spatrick } 229061da546Spatrick 230061da546Spatrick // Look up the first piece of the name, and resolve the rest as a child of 231061da546Spatrick // that. 232061da546Spatrick PythonObject parent = ResolveName(name.substr(0, dot_pos)); 233061da546Spatrick if (!parent.IsAllocated()) 234061da546Spatrick return PythonObject(); 235061da546Spatrick 236061da546Spatrick // Tail recursion.. should be optimized by the compiler 237061da546Spatrick return parent.ResolveName(name.substr(dot_pos + 1)); 238061da546Spatrick } 239061da546Spatrick 240061da546Spatrick bool PythonObject::HasAttribute(llvm::StringRef attr) const { 241061da546Spatrick if (!IsValid()) 242061da546Spatrick return false; 243061da546Spatrick PythonString py_attr(attr); 244061da546Spatrick return !!PyObject_HasAttr(m_py_obj, py_attr.get()); 245061da546Spatrick } 246061da546Spatrick 247061da546Spatrick PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const { 248061da546Spatrick if (!IsValid()) 249061da546Spatrick return PythonObject(); 250061da546Spatrick 251061da546Spatrick PythonString py_attr(attr); 252061da546Spatrick if (!PyObject_HasAttr(m_py_obj, py_attr.get())) 253061da546Spatrick return PythonObject(); 254061da546Spatrick 255061da546Spatrick return PythonObject(PyRefType::Owned, 256061da546Spatrick PyObject_GetAttr(m_py_obj, py_attr.get())); 257061da546Spatrick } 258061da546Spatrick 259061da546Spatrick StructuredData::ObjectSP PythonObject::CreateStructuredObject() const { 260061da546Spatrick switch (GetObjectType()) { 261061da546Spatrick case PyObjectType::Dictionary: 262061da546Spatrick return PythonDictionary(PyRefType::Borrowed, m_py_obj) 263061da546Spatrick .CreateStructuredDictionary(); 264061da546Spatrick case PyObjectType::Boolean: 265061da546Spatrick return PythonBoolean(PyRefType::Borrowed, m_py_obj) 266061da546Spatrick .CreateStructuredBoolean(); 267061da546Spatrick case PyObjectType::Integer: 268061da546Spatrick return PythonInteger(PyRefType::Borrowed, m_py_obj) 269061da546Spatrick .CreateStructuredInteger(); 270061da546Spatrick case PyObjectType::List: 271061da546Spatrick return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); 272061da546Spatrick case PyObjectType::String: 273061da546Spatrick return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 274061da546Spatrick case PyObjectType::Bytes: 275061da546Spatrick return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); 276061da546Spatrick case PyObjectType::ByteArray: 277061da546Spatrick return PythonByteArray(PyRefType::Borrowed, m_py_obj) 278061da546Spatrick .CreateStructuredString(); 279061da546Spatrick case PyObjectType::None: 280061da546Spatrick return StructuredData::ObjectSP(); 281061da546Spatrick default: 282061da546Spatrick return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj)); 283061da546Spatrick } 284061da546Spatrick } 285061da546Spatrick 286061da546Spatrick // PythonString 287061da546Spatrick 288061da546Spatrick PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); } 289061da546Spatrick 290061da546Spatrick PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) { 291061da546Spatrick SetBytes(llvm::ArrayRef<uint8_t>(bytes, length)); 292061da546Spatrick } 293061da546Spatrick 294061da546Spatrick bool PythonBytes::Check(PyObject *py_obj) { 295061da546Spatrick if (!py_obj) 296061da546Spatrick return false; 297061da546Spatrick return PyBytes_Check(py_obj); 298061da546Spatrick } 299061da546Spatrick 300061da546Spatrick llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const { 301061da546Spatrick if (!IsValid()) 302061da546Spatrick return llvm::ArrayRef<uint8_t>(); 303061da546Spatrick 304061da546Spatrick Py_ssize_t size; 305061da546Spatrick char *c; 306061da546Spatrick 307061da546Spatrick PyBytes_AsStringAndSize(m_py_obj, &c, &size); 308061da546Spatrick return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size); 309061da546Spatrick } 310061da546Spatrick 311061da546Spatrick size_t PythonBytes::GetSize() const { 312061da546Spatrick if (!IsValid()) 313061da546Spatrick return 0; 314061da546Spatrick return PyBytes_Size(m_py_obj); 315061da546Spatrick } 316061da546Spatrick 317061da546Spatrick void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) { 318061da546Spatrick const char *data = reinterpret_cast<const char *>(bytes.data()); 319061da546Spatrick *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size())); 320061da546Spatrick } 321061da546Spatrick 322061da546Spatrick StructuredData::StringSP PythonBytes::CreateStructuredString() const { 323061da546Spatrick StructuredData::StringSP result(new StructuredData::String); 324061da546Spatrick Py_ssize_t size; 325061da546Spatrick char *c; 326061da546Spatrick PyBytes_AsStringAndSize(m_py_obj, &c, &size); 327061da546Spatrick result->SetValue(std::string(c, size)); 328061da546Spatrick return result; 329061da546Spatrick } 330061da546Spatrick 331061da546Spatrick PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) 332061da546Spatrick : PythonByteArray(bytes.data(), bytes.size()) {} 333061da546Spatrick 334061da546Spatrick PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) { 335061da546Spatrick const char *str = reinterpret_cast<const char *>(bytes); 336061da546Spatrick *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length)); 337061da546Spatrick } 338061da546Spatrick 339061da546Spatrick bool PythonByteArray::Check(PyObject *py_obj) { 340061da546Spatrick if (!py_obj) 341061da546Spatrick return false; 342061da546Spatrick return PyByteArray_Check(py_obj); 343061da546Spatrick } 344061da546Spatrick 345061da546Spatrick llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const { 346061da546Spatrick if (!IsValid()) 347061da546Spatrick return llvm::ArrayRef<uint8_t>(); 348061da546Spatrick 349061da546Spatrick char *c = PyByteArray_AsString(m_py_obj); 350061da546Spatrick size_t size = GetSize(); 351061da546Spatrick return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size); 352061da546Spatrick } 353061da546Spatrick 354061da546Spatrick size_t PythonByteArray::GetSize() const { 355061da546Spatrick if (!IsValid()) 356061da546Spatrick return 0; 357061da546Spatrick 358061da546Spatrick return PyByteArray_Size(m_py_obj); 359061da546Spatrick } 360061da546Spatrick 361061da546Spatrick StructuredData::StringSP PythonByteArray::CreateStructuredString() const { 362061da546Spatrick StructuredData::StringSP result(new StructuredData::String); 363061da546Spatrick llvm::ArrayRef<uint8_t> bytes = GetBytes(); 364061da546Spatrick const char *str = reinterpret_cast<const char *>(bytes.data()); 365061da546Spatrick result->SetValue(std::string(str, bytes.size())); 366061da546Spatrick return result; 367061da546Spatrick } 368061da546Spatrick 369061da546Spatrick // PythonString 370061da546Spatrick 371061da546Spatrick Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) { 372061da546Spatrick #if PY_MAJOR_VERSION >= 3 373061da546Spatrick PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size()); 374061da546Spatrick #else 375061da546Spatrick PyObject *str = PyString_FromStringAndSize(string.data(), string.size()); 376061da546Spatrick #endif 377061da546Spatrick if (!str) 378061da546Spatrick return llvm::make_error<PythonException>(); 379061da546Spatrick return Take<PythonString>(str); 380061da546Spatrick } 381061da546Spatrick 382061da546Spatrick PythonString::PythonString(llvm::StringRef string) { SetString(string); } 383061da546Spatrick 384061da546Spatrick bool PythonString::Check(PyObject *py_obj) { 385061da546Spatrick if (!py_obj) 386061da546Spatrick return false; 387061da546Spatrick 388061da546Spatrick if (PyUnicode_Check(py_obj)) 389061da546Spatrick return true; 390061da546Spatrick #if PY_MAJOR_VERSION < 3 391061da546Spatrick if (PyString_Check(py_obj)) 392061da546Spatrick return true; 393061da546Spatrick #endif 394061da546Spatrick return false; 395061da546Spatrick } 396061da546Spatrick 397061da546Spatrick void PythonString::Convert(PyRefType &type, PyObject *&py_obj) { 398061da546Spatrick #if PY_MAJOR_VERSION < 3 399061da546Spatrick // In Python 2, Don't store PyUnicode objects directly, because we need 400061da546Spatrick // access to their underlying character buffers which Python 2 doesn't 401061da546Spatrick // provide. 402061da546Spatrick if (PyUnicode_Check(py_obj)) { 403061da546Spatrick PyObject *s = PyUnicode_AsUTF8String(py_obj); 404061da546Spatrick if (s == nullptr) { 405061da546Spatrick PyErr_Clear(); 406061da546Spatrick if (type == PyRefType::Owned) 407061da546Spatrick Py_DECREF(py_obj); 408061da546Spatrick return; 409061da546Spatrick } 410061da546Spatrick if (type == PyRefType::Owned) 411061da546Spatrick Py_DECREF(py_obj); 412061da546Spatrick else 413061da546Spatrick type = PyRefType::Owned; 414061da546Spatrick py_obj = s; 415061da546Spatrick } 416061da546Spatrick #endif 417061da546Spatrick } 418061da546Spatrick 419061da546Spatrick llvm::StringRef PythonString::GetString() const { 420061da546Spatrick auto s = AsUTF8(); 421061da546Spatrick if (!s) { 422061da546Spatrick llvm::consumeError(s.takeError()); 423061da546Spatrick return llvm::StringRef(""); 424061da546Spatrick } 425061da546Spatrick return s.get(); 426061da546Spatrick } 427061da546Spatrick 428061da546Spatrick Expected<llvm::StringRef> PythonString::AsUTF8() const { 429061da546Spatrick if (!IsValid()) 430061da546Spatrick return nullDeref(); 431061da546Spatrick 432061da546Spatrick Py_ssize_t size; 433061da546Spatrick const char *data; 434061da546Spatrick 435061da546Spatrick #if PY_MAJOR_VERSION >= 3 436061da546Spatrick data = PyUnicode_AsUTF8AndSize(m_py_obj, &size); 437061da546Spatrick #else 438061da546Spatrick char *c = NULL; 439061da546Spatrick int r = PyString_AsStringAndSize(m_py_obj, &c, &size); 440061da546Spatrick if (r < 0) 441061da546Spatrick c = NULL; 442061da546Spatrick data = c; 443061da546Spatrick #endif 444061da546Spatrick 445061da546Spatrick if (!data) 446061da546Spatrick return exception(); 447061da546Spatrick 448061da546Spatrick return llvm::StringRef(data, size); 449061da546Spatrick } 450061da546Spatrick 451061da546Spatrick size_t PythonString::GetSize() const { 452061da546Spatrick if (IsValid()) { 453061da546Spatrick #if PY_MAJOR_VERSION >= 3 454061da546Spatrick return PyUnicode_GetSize(m_py_obj); 455061da546Spatrick #else 456061da546Spatrick return PyString_Size(m_py_obj); 457061da546Spatrick #endif 458061da546Spatrick } 459061da546Spatrick return 0; 460061da546Spatrick } 461061da546Spatrick 462061da546Spatrick void PythonString::SetString(llvm::StringRef string) { 463061da546Spatrick auto s = FromUTF8(string); 464061da546Spatrick if (!s) { 465061da546Spatrick llvm::consumeError(s.takeError()); 466061da546Spatrick Reset(); 467061da546Spatrick } else { 468061da546Spatrick *this = std::move(s.get()); 469061da546Spatrick } 470061da546Spatrick } 471061da546Spatrick 472061da546Spatrick StructuredData::StringSP PythonString::CreateStructuredString() const { 473061da546Spatrick StructuredData::StringSP result(new StructuredData::String); 474061da546Spatrick result->SetValue(GetString()); 475061da546Spatrick return result; 476061da546Spatrick } 477061da546Spatrick 478061da546Spatrick // PythonInteger 479061da546Spatrick 480061da546Spatrick PythonInteger::PythonInteger(int64_t value) { SetInteger(value); } 481061da546Spatrick 482061da546Spatrick bool PythonInteger::Check(PyObject *py_obj) { 483061da546Spatrick if (!py_obj) 484061da546Spatrick return false; 485061da546Spatrick 486061da546Spatrick #if PY_MAJOR_VERSION >= 3 487061da546Spatrick // Python 3 does not have PyInt_Check. There is only one type of integral 488061da546Spatrick // value, long. 489061da546Spatrick return PyLong_Check(py_obj); 490061da546Spatrick #else 491061da546Spatrick return PyLong_Check(py_obj) || PyInt_Check(py_obj); 492061da546Spatrick #endif 493061da546Spatrick } 494061da546Spatrick 495061da546Spatrick void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) { 496061da546Spatrick #if PY_MAJOR_VERSION < 3 497061da546Spatrick // Always store this as a PyLong, which makes interoperability between Python 498061da546Spatrick // 2.x and Python 3.x easier. This is only necessary in 2.x, since 3.x 499061da546Spatrick // doesn't even have a PyInt. 500061da546Spatrick if (PyInt_Check(py_obj)) { 501061da546Spatrick // Since we converted the original object to a different type, the new 502061da546Spatrick // object is an owned object regardless of the ownership semantics 503061da546Spatrick // requested by the user. 504061da546Spatrick long long value = PyInt_AsLong(py_obj); 505061da546Spatrick PyObject *l = nullptr; 506061da546Spatrick if (!PyErr_Occurred()) 507061da546Spatrick l = PyLong_FromLongLong(value); 508061da546Spatrick if (l == nullptr) { 509061da546Spatrick PyErr_Clear(); 510061da546Spatrick if (type == PyRefType::Owned) 511061da546Spatrick Py_DECREF(py_obj); 512061da546Spatrick return; 513061da546Spatrick } 514061da546Spatrick if (type == PyRefType::Owned) 515061da546Spatrick Py_DECREF(py_obj); 516061da546Spatrick else 517061da546Spatrick type = PyRefType::Owned; 518061da546Spatrick py_obj = l; 519061da546Spatrick } 520061da546Spatrick #endif 521061da546Spatrick } 522061da546Spatrick 523061da546Spatrick void PythonInteger::SetInteger(int64_t value) { 524061da546Spatrick *this = Take<PythonInteger>(PyLong_FromLongLong(value)); 525061da546Spatrick } 526061da546Spatrick 527061da546Spatrick StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const { 528061da546Spatrick StructuredData::IntegerSP result(new StructuredData::Integer); 529*dda28197Spatrick // FIXME this is really not ideal. Errors are silently converted to 0 530*dda28197Spatrick // and overflows are silently wrapped. But we'd need larger changes 531*dda28197Spatrick // to StructuredData to fix it, so that's how it is for now. 532*dda28197Spatrick llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong(); 533*dda28197Spatrick if (!value) { 534*dda28197Spatrick llvm::consumeError(value.takeError()); 535*dda28197Spatrick result->SetValue(0); 536*dda28197Spatrick } else { 537*dda28197Spatrick result->SetValue(value.get()); 538*dda28197Spatrick } 539061da546Spatrick return result; 540061da546Spatrick } 541061da546Spatrick 542061da546Spatrick // PythonBoolean 543061da546Spatrick 544061da546Spatrick PythonBoolean::PythonBoolean(bool value) { 545061da546Spatrick SetValue(value); 546061da546Spatrick } 547061da546Spatrick 548061da546Spatrick bool PythonBoolean::Check(PyObject *py_obj) { 549061da546Spatrick return py_obj ? PyBool_Check(py_obj) : false; 550061da546Spatrick } 551061da546Spatrick 552061da546Spatrick bool PythonBoolean::GetValue() const { 553061da546Spatrick return m_py_obj ? PyObject_IsTrue(m_py_obj) : false; 554061da546Spatrick } 555061da546Spatrick 556061da546Spatrick void PythonBoolean::SetValue(bool value) { 557061da546Spatrick *this = Take<PythonBoolean>(PyBool_FromLong(value)); 558061da546Spatrick } 559061da546Spatrick 560061da546Spatrick StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const { 561061da546Spatrick StructuredData::BooleanSP result(new StructuredData::Boolean); 562061da546Spatrick result->SetValue(GetValue()); 563061da546Spatrick return result; 564061da546Spatrick } 565061da546Spatrick 566061da546Spatrick // PythonList 567061da546Spatrick 568061da546Spatrick PythonList::PythonList(PyInitialValue value) { 569061da546Spatrick if (value == PyInitialValue::Empty) 570061da546Spatrick *this = Take<PythonList>(PyList_New(0)); 571061da546Spatrick } 572061da546Spatrick 573061da546Spatrick PythonList::PythonList(int list_size) { 574061da546Spatrick *this = Take<PythonList>(PyList_New(list_size)); 575061da546Spatrick } 576061da546Spatrick 577061da546Spatrick bool PythonList::Check(PyObject *py_obj) { 578061da546Spatrick if (!py_obj) 579061da546Spatrick return false; 580061da546Spatrick return PyList_Check(py_obj); 581061da546Spatrick } 582061da546Spatrick 583061da546Spatrick uint32_t PythonList::GetSize() const { 584061da546Spatrick if (IsValid()) 585061da546Spatrick return PyList_GET_SIZE(m_py_obj); 586061da546Spatrick return 0; 587061da546Spatrick } 588061da546Spatrick 589061da546Spatrick PythonObject PythonList::GetItemAtIndex(uint32_t index) const { 590061da546Spatrick if (IsValid()) 591061da546Spatrick return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index)); 592061da546Spatrick return PythonObject(); 593061da546Spatrick } 594061da546Spatrick 595061da546Spatrick void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) { 596061da546Spatrick if (IsAllocated() && object.IsValid()) { 597061da546Spatrick // PyList_SetItem is documented to "steal" a reference, so we need to 598061da546Spatrick // convert it to an owned reference by incrementing it. 599061da546Spatrick Py_INCREF(object.get()); 600061da546Spatrick PyList_SetItem(m_py_obj, index, object.get()); 601061da546Spatrick } 602061da546Spatrick } 603061da546Spatrick 604061da546Spatrick void PythonList::AppendItem(const PythonObject &object) { 605061da546Spatrick if (IsAllocated() && object.IsValid()) { 606061da546Spatrick // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF` 607061da546Spatrick // here like we do with `PyList_SetItem`. 608061da546Spatrick PyList_Append(m_py_obj, object.get()); 609061da546Spatrick } 610061da546Spatrick } 611061da546Spatrick 612061da546Spatrick StructuredData::ArraySP PythonList::CreateStructuredArray() const { 613061da546Spatrick StructuredData::ArraySP result(new StructuredData::Array); 614061da546Spatrick uint32_t count = GetSize(); 615061da546Spatrick for (uint32_t i = 0; i < count; ++i) { 616061da546Spatrick PythonObject obj = GetItemAtIndex(i); 617061da546Spatrick result->AddItem(obj.CreateStructuredObject()); 618061da546Spatrick } 619061da546Spatrick return result; 620061da546Spatrick } 621061da546Spatrick 622061da546Spatrick // PythonTuple 623061da546Spatrick 624061da546Spatrick PythonTuple::PythonTuple(PyInitialValue value) { 625061da546Spatrick if (value == PyInitialValue::Empty) 626061da546Spatrick *this = Take<PythonTuple>(PyTuple_New(0)); 627061da546Spatrick } 628061da546Spatrick 629061da546Spatrick PythonTuple::PythonTuple(int tuple_size) { 630061da546Spatrick *this = Take<PythonTuple>(PyTuple_New(tuple_size)); 631061da546Spatrick } 632061da546Spatrick 633061da546Spatrick PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) { 634061da546Spatrick m_py_obj = PyTuple_New(objects.size()); 635061da546Spatrick 636061da546Spatrick uint32_t idx = 0; 637061da546Spatrick for (auto object : objects) { 638061da546Spatrick if (object.IsValid()) 639061da546Spatrick SetItemAtIndex(idx, object); 640061da546Spatrick idx++; 641061da546Spatrick } 642061da546Spatrick } 643061da546Spatrick 644061da546Spatrick PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) { 645061da546Spatrick m_py_obj = PyTuple_New(objects.size()); 646061da546Spatrick 647061da546Spatrick uint32_t idx = 0; 648061da546Spatrick for (auto py_object : objects) { 649061da546Spatrick PythonObject object(PyRefType::Borrowed, py_object); 650061da546Spatrick if (object.IsValid()) 651061da546Spatrick SetItemAtIndex(idx, object); 652061da546Spatrick idx++; 653061da546Spatrick } 654061da546Spatrick } 655061da546Spatrick 656061da546Spatrick bool PythonTuple::Check(PyObject *py_obj) { 657061da546Spatrick if (!py_obj) 658061da546Spatrick return false; 659061da546Spatrick return PyTuple_Check(py_obj); 660061da546Spatrick } 661061da546Spatrick 662061da546Spatrick uint32_t PythonTuple::GetSize() const { 663061da546Spatrick if (IsValid()) 664061da546Spatrick return PyTuple_GET_SIZE(m_py_obj); 665061da546Spatrick return 0; 666061da546Spatrick } 667061da546Spatrick 668061da546Spatrick PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const { 669061da546Spatrick if (IsValid()) 670061da546Spatrick return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index)); 671061da546Spatrick return PythonObject(); 672061da546Spatrick } 673061da546Spatrick 674061da546Spatrick void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) { 675061da546Spatrick if (IsAllocated() && object.IsValid()) { 676061da546Spatrick // PyTuple_SetItem is documented to "steal" a reference, so we need to 677061da546Spatrick // convert it to an owned reference by incrementing it. 678061da546Spatrick Py_INCREF(object.get()); 679061da546Spatrick PyTuple_SetItem(m_py_obj, index, object.get()); 680061da546Spatrick } 681061da546Spatrick } 682061da546Spatrick 683061da546Spatrick StructuredData::ArraySP PythonTuple::CreateStructuredArray() const { 684061da546Spatrick StructuredData::ArraySP result(new StructuredData::Array); 685061da546Spatrick uint32_t count = GetSize(); 686061da546Spatrick for (uint32_t i = 0; i < count; ++i) { 687061da546Spatrick PythonObject obj = GetItemAtIndex(i); 688061da546Spatrick result->AddItem(obj.CreateStructuredObject()); 689061da546Spatrick } 690061da546Spatrick return result; 691061da546Spatrick } 692061da546Spatrick 693061da546Spatrick // PythonDictionary 694061da546Spatrick 695061da546Spatrick PythonDictionary::PythonDictionary(PyInitialValue value) { 696061da546Spatrick if (value == PyInitialValue::Empty) 697061da546Spatrick *this = Take<PythonDictionary>(PyDict_New()); 698061da546Spatrick } 699061da546Spatrick 700061da546Spatrick bool PythonDictionary::Check(PyObject *py_obj) { 701061da546Spatrick if (!py_obj) 702061da546Spatrick return false; 703061da546Spatrick 704061da546Spatrick return PyDict_Check(py_obj); 705061da546Spatrick } 706061da546Spatrick 707061da546Spatrick uint32_t PythonDictionary::GetSize() const { 708061da546Spatrick if (IsValid()) 709061da546Spatrick return PyDict_Size(m_py_obj); 710061da546Spatrick return 0; 711061da546Spatrick } 712061da546Spatrick 713061da546Spatrick PythonList PythonDictionary::GetKeys() const { 714061da546Spatrick if (IsValid()) 715061da546Spatrick return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj)); 716061da546Spatrick return PythonList(PyInitialValue::Invalid); 717061da546Spatrick } 718061da546Spatrick 719061da546Spatrick PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const { 720061da546Spatrick auto item = GetItem(key); 721061da546Spatrick if (!item) { 722061da546Spatrick llvm::consumeError(item.takeError()); 723061da546Spatrick return PythonObject(); 724061da546Spatrick } 725061da546Spatrick return std::move(item.get()); 726061da546Spatrick } 727061da546Spatrick 728061da546Spatrick Expected<PythonObject> 729061da546Spatrick PythonDictionary::GetItem(const PythonObject &key) const { 730061da546Spatrick if (!IsValid()) 731061da546Spatrick return nullDeref(); 732061da546Spatrick #if PY_MAJOR_VERSION >= 3 733061da546Spatrick PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get()); 734061da546Spatrick if (PyErr_Occurred()) 735061da546Spatrick return exception(); 736061da546Spatrick #else 737061da546Spatrick PyObject *o = PyDict_GetItem(m_py_obj, key.get()); 738061da546Spatrick #endif 739061da546Spatrick if (!o) 740061da546Spatrick return keyError(); 741061da546Spatrick return Retain<PythonObject>(o); 742061da546Spatrick } 743061da546Spatrick 744061da546Spatrick Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const { 745061da546Spatrick if (!IsValid()) 746061da546Spatrick return nullDeref(); 747061da546Spatrick PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key)); 748061da546Spatrick if (PyErr_Occurred()) 749061da546Spatrick return exception(); 750061da546Spatrick if (!o) 751061da546Spatrick return keyError(); 752061da546Spatrick return Retain<PythonObject>(o); 753061da546Spatrick } 754061da546Spatrick 755061da546Spatrick Error PythonDictionary::SetItem(const PythonObject &key, 756061da546Spatrick const PythonObject &value) const { 757061da546Spatrick if (!IsValid() || !value.IsValid()) 758061da546Spatrick return nullDeref(); 759061da546Spatrick int r = PyDict_SetItem(m_py_obj, key.get(), value.get()); 760061da546Spatrick if (r < 0) 761061da546Spatrick return exception(); 762061da546Spatrick return Error::success(); 763061da546Spatrick } 764061da546Spatrick 765061da546Spatrick Error PythonDictionary::SetItem(const Twine &key, 766061da546Spatrick const PythonObject &value) const { 767061da546Spatrick if (!IsValid() || !value.IsValid()) 768061da546Spatrick return nullDeref(); 769061da546Spatrick int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get()); 770061da546Spatrick if (r < 0) 771061da546Spatrick return exception(); 772061da546Spatrick return Error::success(); 773061da546Spatrick } 774061da546Spatrick 775061da546Spatrick void PythonDictionary::SetItemForKey(const PythonObject &key, 776061da546Spatrick const PythonObject &value) { 777061da546Spatrick Error error = SetItem(key, value); 778061da546Spatrick if (error) 779061da546Spatrick llvm::consumeError(std::move(error)); 780061da546Spatrick } 781061da546Spatrick 782061da546Spatrick StructuredData::DictionarySP 783061da546Spatrick PythonDictionary::CreateStructuredDictionary() const { 784061da546Spatrick StructuredData::DictionarySP result(new StructuredData::Dictionary); 785061da546Spatrick PythonList keys(GetKeys()); 786061da546Spatrick uint32_t num_keys = keys.GetSize(); 787061da546Spatrick for (uint32_t i = 0; i < num_keys; ++i) { 788061da546Spatrick PythonObject key = keys.GetItemAtIndex(i); 789061da546Spatrick PythonObject value = GetItemForKey(key); 790061da546Spatrick StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); 791061da546Spatrick result->AddItem(key.Str().GetString(), structured_value); 792061da546Spatrick } 793061da546Spatrick return result; 794061da546Spatrick } 795061da546Spatrick 796061da546Spatrick PythonModule PythonModule::BuiltinsModule() { 797061da546Spatrick #if PY_MAJOR_VERSION >= 3 798061da546Spatrick return AddModule("builtins"); 799061da546Spatrick #else 800061da546Spatrick return AddModule("__builtin__"); 801061da546Spatrick #endif 802061da546Spatrick } 803061da546Spatrick 804061da546Spatrick PythonModule PythonModule::MainModule() { return AddModule("__main__"); } 805061da546Spatrick 806061da546Spatrick PythonModule PythonModule::AddModule(llvm::StringRef module) { 807061da546Spatrick std::string str = module.str(); 808061da546Spatrick return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str())); 809061da546Spatrick } 810061da546Spatrick 811061da546Spatrick Expected<PythonModule> PythonModule::Import(const Twine &name) { 812061da546Spatrick PyObject *mod = PyImport_ImportModule(NullTerminated(name)); 813061da546Spatrick if (!mod) 814061da546Spatrick return exception(); 815061da546Spatrick return Take<PythonModule>(mod); 816061da546Spatrick } 817061da546Spatrick 818061da546Spatrick Expected<PythonObject> PythonModule::Get(const Twine &name) { 819061da546Spatrick if (!IsValid()) 820061da546Spatrick return nullDeref(); 821061da546Spatrick PyObject *dict = PyModule_GetDict(m_py_obj); 822061da546Spatrick if (!dict) 823061da546Spatrick return exception(); 824061da546Spatrick PyObject *item = PyDict_GetItemString(dict, NullTerminated(name)); 825061da546Spatrick if (!item) 826061da546Spatrick return exception(); 827061da546Spatrick return Retain<PythonObject>(item); 828061da546Spatrick } 829061da546Spatrick 830061da546Spatrick bool PythonModule::Check(PyObject *py_obj) { 831061da546Spatrick if (!py_obj) 832061da546Spatrick return false; 833061da546Spatrick 834061da546Spatrick return PyModule_Check(py_obj); 835061da546Spatrick } 836061da546Spatrick 837061da546Spatrick PythonDictionary PythonModule::GetDictionary() const { 838061da546Spatrick if (!IsValid()) 839061da546Spatrick return PythonDictionary(); 840061da546Spatrick return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj)); 841061da546Spatrick } 842061da546Spatrick 843061da546Spatrick bool PythonCallable::Check(PyObject *py_obj) { 844061da546Spatrick if (!py_obj) 845061da546Spatrick return false; 846061da546Spatrick 847061da546Spatrick return PyCallable_Check(py_obj); 848061da546Spatrick } 849061da546Spatrick 850061da546Spatrick #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 851061da546Spatrick static const char get_arg_info_script[] = R"( 852061da546Spatrick from inspect import signature, Parameter, ismethod 853061da546Spatrick from collections import namedtuple 854061da546Spatrick ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs']) 855061da546Spatrick def main(f): 856061da546Spatrick count = 0 857061da546Spatrick varargs = False 858061da546Spatrick for parameter in signature(f).parameters.values(): 859061da546Spatrick kind = parameter.kind 860061da546Spatrick if kind in (Parameter.POSITIONAL_ONLY, 861061da546Spatrick Parameter.POSITIONAL_OR_KEYWORD): 862061da546Spatrick count += 1 863061da546Spatrick elif kind == Parameter.VAR_POSITIONAL: 864061da546Spatrick varargs = True 865061da546Spatrick elif kind in (Parameter.KEYWORD_ONLY, 866061da546Spatrick Parameter.VAR_KEYWORD): 867061da546Spatrick pass 868061da546Spatrick else: 869061da546Spatrick raise Exception(f'unknown parameter kind: {kind}') 870061da546Spatrick return ArgInfo(count, varargs) 871061da546Spatrick )"; 872061da546Spatrick #endif 873061da546Spatrick 874061da546Spatrick Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const { 875061da546Spatrick ArgInfo result = {}; 876061da546Spatrick if (!IsValid()) 877061da546Spatrick return nullDeref(); 878061da546Spatrick 879061da546Spatrick #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 880061da546Spatrick 881061da546Spatrick // no need to synchronize access to this global, we already have the GIL 882061da546Spatrick static PythonScript get_arg_info(get_arg_info_script); 883061da546Spatrick Expected<PythonObject> pyarginfo = get_arg_info(*this); 884061da546Spatrick if (!pyarginfo) 885061da546Spatrick return pyarginfo.takeError(); 886061da546Spatrick long long count = 887061da546Spatrick cantFail(As<long long>(pyarginfo.get().GetAttribute("count"))); 888061da546Spatrick bool has_varargs = 889061da546Spatrick cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs"))); 890061da546Spatrick result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count; 891061da546Spatrick 892061da546Spatrick #else 893061da546Spatrick PyObject *py_func_obj; 894061da546Spatrick bool is_bound_method = false; 895061da546Spatrick bool is_class = false; 896061da546Spatrick 897061da546Spatrick if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) { 898061da546Spatrick auto init = GetAttribute("__init__"); 899061da546Spatrick if (!init) 900061da546Spatrick return init.takeError(); 901061da546Spatrick py_func_obj = init.get().get(); 902061da546Spatrick is_class = true; 903061da546Spatrick } else { 904061da546Spatrick py_func_obj = m_py_obj; 905061da546Spatrick } 906061da546Spatrick 907061da546Spatrick if (PyMethod_Check(py_func_obj)) { 908061da546Spatrick py_func_obj = PyMethod_GET_FUNCTION(py_func_obj); 909061da546Spatrick PythonObject im_self = GetAttributeValue("im_self"); 910061da546Spatrick if (im_self.IsValid() && !im_self.IsNone()) 911061da546Spatrick is_bound_method = true; 912061da546Spatrick } else { 913061da546Spatrick // see if this is a callable object with an __call__ method 914061da546Spatrick if (!PyFunction_Check(py_func_obj)) { 915061da546Spatrick PythonObject __call__ = GetAttributeValue("__call__"); 916061da546Spatrick if (__call__.IsValid()) { 917061da546Spatrick auto __callable__ = __call__.AsType<PythonCallable>(); 918061da546Spatrick if (__callable__.IsValid()) { 919061da546Spatrick py_func_obj = PyMethod_GET_FUNCTION(__callable__.get()); 920061da546Spatrick PythonObject im_self = __callable__.GetAttributeValue("im_self"); 921061da546Spatrick if (im_self.IsValid() && !im_self.IsNone()) 922061da546Spatrick is_bound_method = true; 923061da546Spatrick } 924061da546Spatrick } 925061da546Spatrick } 926061da546Spatrick } 927061da546Spatrick 928061da546Spatrick if (!py_func_obj) 929061da546Spatrick return result; 930061da546Spatrick 931061da546Spatrick PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj); 932061da546Spatrick if (!code) 933061da546Spatrick return result; 934061da546Spatrick 935061da546Spatrick auto count = code->co_argcount; 936061da546Spatrick bool has_varargs = !!(code->co_flags & CO_VARARGS); 937061da546Spatrick result.max_positional_args = 938061da546Spatrick has_varargs ? ArgInfo::UNBOUNDED 939061da546Spatrick : (count - (int)is_bound_method) - (int)is_class; 940061da546Spatrick 941061da546Spatrick #endif 942061da546Spatrick 943061da546Spatrick return result; 944061da546Spatrick } 945061da546Spatrick 946061da546Spatrick constexpr unsigned 947061da546Spatrick PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17 948061da546Spatrick 949061da546Spatrick PythonObject PythonCallable::operator()() { 950061da546Spatrick return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr)); 951061da546Spatrick } 952061da546Spatrick 953061da546Spatrick PythonObject PythonCallable:: 954061da546Spatrick operator()(std::initializer_list<PyObject *> args) { 955061da546Spatrick PythonTuple arg_tuple(args); 956061da546Spatrick return PythonObject(PyRefType::Owned, 957061da546Spatrick PyObject_CallObject(m_py_obj, arg_tuple.get())); 958061da546Spatrick } 959061da546Spatrick 960061da546Spatrick PythonObject PythonCallable:: 961061da546Spatrick operator()(std::initializer_list<PythonObject> args) { 962061da546Spatrick PythonTuple arg_tuple(args); 963061da546Spatrick return PythonObject(PyRefType::Owned, 964061da546Spatrick PyObject_CallObject(m_py_obj, arg_tuple.get())); 965061da546Spatrick } 966061da546Spatrick 967061da546Spatrick bool PythonFile::Check(PyObject *py_obj) { 968061da546Spatrick if (!py_obj) 969061da546Spatrick return false; 970061da546Spatrick #if PY_MAJOR_VERSION < 3 971061da546Spatrick return PyFile_Check(py_obj); 972061da546Spatrick #else 973061da546Spatrick // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a 974061da546Spatrick // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper 975061da546Spatrick // over `io.open()`, which returns some object derived from `io.IOBase`. As a 976061da546Spatrick // result, the only way to detect a file in Python 3 is to check whether it 977061da546Spatrick // inherits from `io.IOBase`. 978061da546Spatrick auto io_module = PythonModule::Import("io"); 979061da546Spatrick if (!io_module) { 980061da546Spatrick llvm::consumeError(io_module.takeError()); 981061da546Spatrick return false; 982061da546Spatrick } 983061da546Spatrick auto iobase = io_module.get().Get("IOBase"); 984061da546Spatrick if (!iobase) { 985061da546Spatrick llvm::consumeError(iobase.takeError()); 986061da546Spatrick return false; 987061da546Spatrick } 988061da546Spatrick int r = PyObject_IsInstance(py_obj, iobase.get().get()); 989061da546Spatrick if (r < 0) { 990061da546Spatrick llvm::consumeError(exception()); // clear the exception and log it. 991061da546Spatrick return false; 992061da546Spatrick } 993061da546Spatrick return !!r; 994061da546Spatrick #endif 995061da546Spatrick } 996061da546Spatrick 997061da546Spatrick namespace { 998061da546Spatrick class GIL { 999061da546Spatrick public: 1000061da546Spatrick GIL() { 1001061da546Spatrick m_state = PyGILState_Ensure(); 1002061da546Spatrick assert(!PyErr_Occurred()); 1003061da546Spatrick } 1004061da546Spatrick ~GIL() { PyGILState_Release(m_state); } 1005061da546Spatrick 1006061da546Spatrick protected: 1007061da546Spatrick PyGILState_STATE m_state; 1008061da546Spatrick }; 1009061da546Spatrick } // namespace 1010061da546Spatrick 1011061da546Spatrick const char *PythonException::toCString() const { 1012061da546Spatrick if (!m_repr_bytes) 1013061da546Spatrick return "unknown exception"; 1014061da546Spatrick return PyBytes_AS_STRING(m_repr_bytes); 1015061da546Spatrick } 1016061da546Spatrick 1017061da546Spatrick PythonException::PythonException(const char *caller) { 1018061da546Spatrick assert(PyErr_Occurred()); 1019061da546Spatrick m_exception_type = m_exception = m_traceback = m_repr_bytes = NULL; 1020061da546Spatrick PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback); 1021061da546Spatrick PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback); 1022061da546Spatrick PyErr_Clear(); 1023061da546Spatrick if (m_exception) { 1024061da546Spatrick PyObject *repr = PyObject_Repr(m_exception); 1025061da546Spatrick if (repr) { 1026061da546Spatrick m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr); 1027061da546Spatrick if (!m_repr_bytes) { 1028061da546Spatrick PyErr_Clear(); 1029061da546Spatrick } 1030061da546Spatrick Py_XDECREF(repr); 1031061da546Spatrick } else { 1032061da546Spatrick PyErr_Clear(); 1033061da546Spatrick } 1034061da546Spatrick } 1035061da546Spatrick Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT); 1036061da546Spatrick if (caller) 1037061da546Spatrick LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString()); 1038061da546Spatrick else 1039061da546Spatrick LLDB_LOGF(log, "python exception: %s", toCString()); 1040061da546Spatrick } 1041061da546Spatrick void PythonException::Restore() { 1042061da546Spatrick if (m_exception_type && m_exception) { 1043061da546Spatrick PyErr_Restore(m_exception_type, m_exception, m_traceback); 1044061da546Spatrick } else { 1045061da546Spatrick PyErr_SetString(PyExc_Exception, toCString()); 1046061da546Spatrick } 1047061da546Spatrick m_exception_type = m_exception = m_traceback = NULL; 1048061da546Spatrick } 1049061da546Spatrick 1050061da546Spatrick PythonException::~PythonException() { 1051061da546Spatrick Py_XDECREF(m_exception_type); 1052061da546Spatrick Py_XDECREF(m_exception); 1053061da546Spatrick Py_XDECREF(m_traceback); 1054061da546Spatrick Py_XDECREF(m_repr_bytes); 1055061da546Spatrick } 1056061da546Spatrick 1057061da546Spatrick void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); } 1058061da546Spatrick 1059061da546Spatrick std::error_code PythonException::convertToErrorCode() const { 1060061da546Spatrick return llvm::inconvertibleErrorCode(); 1061061da546Spatrick } 1062061da546Spatrick 1063061da546Spatrick bool PythonException::Matches(PyObject *exc) const { 1064061da546Spatrick return PyErr_GivenExceptionMatches(m_exception_type, exc); 1065061da546Spatrick } 1066061da546Spatrick 1067061da546Spatrick const char read_exception_script[] = R"( 1068061da546Spatrick import sys 1069061da546Spatrick from traceback import print_exception 1070061da546Spatrick if sys.version_info.major < 3: 1071061da546Spatrick from StringIO import StringIO 1072061da546Spatrick else: 1073061da546Spatrick from io import StringIO 1074061da546Spatrick def main(exc_type, exc_value, tb): 1075061da546Spatrick f = StringIO() 1076061da546Spatrick print_exception(exc_type, exc_value, tb, file=f) 1077061da546Spatrick return f.getvalue() 1078061da546Spatrick )"; 1079061da546Spatrick 1080061da546Spatrick std::string PythonException::ReadBacktrace() const { 1081061da546Spatrick 1082061da546Spatrick if (!m_traceback) 1083061da546Spatrick return toCString(); 1084061da546Spatrick 1085061da546Spatrick // no need to synchronize access to this global, we already have the GIL 1086061da546Spatrick static PythonScript read_exception(read_exception_script); 1087061da546Spatrick 1088061da546Spatrick Expected<std::string> backtrace = As<std::string>( 1089061da546Spatrick read_exception(m_exception_type, m_exception, m_traceback)); 1090061da546Spatrick 1091061da546Spatrick if (!backtrace) { 1092061da546Spatrick std::string message = 1093061da546Spatrick std::string(toCString()) + "\n" + 1094*dda28197Spatrick "Traceback unavailable, an error occurred while reading it:\n"; 1095061da546Spatrick return (message + llvm::toString(backtrace.takeError())); 1096061da546Spatrick } 1097061da546Spatrick 1098061da546Spatrick return std::move(backtrace.get()); 1099061da546Spatrick } 1100061da546Spatrick 1101061da546Spatrick char PythonException::ID = 0; 1102061da546Spatrick 1103061da546Spatrick llvm::Expected<File::OpenOptions> 1104061da546Spatrick GetOptionsForPyObject(const PythonObject &obj) { 1105061da546Spatrick #if PY_MAJOR_VERSION >= 3 1106061da546Spatrick auto options = File::OpenOptions(0); 1107061da546Spatrick auto readable = As<bool>(obj.CallMethod("readable")); 1108061da546Spatrick if (!readable) 1109061da546Spatrick return readable.takeError(); 1110061da546Spatrick auto writable = As<bool>(obj.CallMethod("writable")); 1111061da546Spatrick if (!writable) 1112061da546Spatrick return writable.takeError(); 1113061da546Spatrick if (readable.get()) 1114061da546Spatrick options |= File::eOpenOptionRead; 1115061da546Spatrick if (writable.get()) 1116061da546Spatrick options |= File::eOpenOptionWrite; 1117061da546Spatrick return options; 1118061da546Spatrick #else 1119061da546Spatrick PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>(); 1120061da546Spatrick return File::GetOptionsFromMode(py_mode.GetString()); 1121061da546Spatrick #endif 1122061da546Spatrick } 1123061da546Spatrick 1124061da546Spatrick // Base class template for python files. All it knows how to do 1125061da546Spatrick // is hold a reference to the python object and close or flush it 1126061da546Spatrick // when the File is closed. 1127061da546Spatrick namespace { 1128061da546Spatrick template <typename Base> class OwnedPythonFile : public Base { 1129061da546Spatrick public: 1130061da546Spatrick template <typename... Args> 1131061da546Spatrick OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args) 1132061da546Spatrick : Base(args...), m_py_obj(file), m_borrowed(borrowed) { 1133061da546Spatrick assert(m_py_obj); 1134061da546Spatrick } 1135061da546Spatrick 1136061da546Spatrick ~OwnedPythonFile() override { 1137061da546Spatrick assert(m_py_obj); 1138061da546Spatrick GIL takeGIL; 1139061da546Spatrick Close(); 1140061da546Spatrick // we need to ensure the python object is released while we still 1141061da546Spatrick // hold the GIL 1142061da546Spatrick m_py_obj.Reset(); 1143061da546Spatrick } 1144061da546Spatrick 1145061da546Spatrick bool IsPythonSideValid() const { 1146061da546Spatrick GIL takeGIL; 1147061da546Spatrick auto closed = As<bool>(m_py_obj.GetAttribute("closed")); 1148061da546Spatrick if (!closed) { 1149061da546Spatrick llvm::consumeError(closed.takeError()); 1150061da546Spatrick return false; 1151061da546Spatrick } 1152061da546Spatrick return !closed.get(); 1153061da546Spatrick } 1154061da546Spatrick 1155061da546Spatrick bool IsValid() const override { 1156061da546Spatrick return IsPythonSideValid() && Base::IsValid(); 1157061da546Spatrick } 1158061da546Spatrick 1159061da546Spatrick Status Close() override { 1160061da546Spatrick assert(m_py_obj); 1161061da546Spatrick Status py_error, base_error; 1162061da546Spatrick GIL takeGIL; 1163061da546Spatrick if (!m_borrowed) { 1164061da546Spatrick auto r = m_py_obj.CallMethod("close"); 1165061da546Spatrick if (!r) 1166061da546Spatrick py_error = Status(r.takeError()); 1167061da546Spatrick } 1168061da546Spatrick base_error = Base::Close(); 1169061da546Spatrick if (py_error.Fail()) 1170061da546Spatrick return py_error; 1171061da546Spatrick return base_error; 1172061da546Spatrick }; 1173061da546Spatrick 1174061da546Spatrick PyObject *GetPythonObject() const { 1175061da546Spatrick assert(m_py_obj.IsValid()); 1176061da546Spatrick return m_py_obj.get(); 1177061da546Spatrick } 1178061da546Spatrick 1179061da546Spatrick static bool classof(const File *file) = delete; 1180061da546Spatrick 1181061da546Spatrick protected: 1182061da546Spatrick PythonFile m_py_obj; 1183061da546Spatrick bool m_borrowed; 1184061da546Spatrick }; 1185061da546Spatrick } // namespace 1186061da546Spatrick 1187061da546Spatrick // A SimplePythonFile is a OwnedPythonFile that just does all I/O as 1188061da546Spatrick // a NativeFile 1189061da546Spatrick namespace { 1190061da546Spatrick class SimplePythonFile : public OwnedPythonFile<NativeFile> { 1191061da546Spatrick public: 1192061da546Spatrick SimplePythonFile(const PythonFile &file, bool borrowed, int fd, 1193061da546Spatrick File::OpenOptions options) 1194061da546Spatrick : OwnedPythonFile(file, borrowed, fd, options, false) {} 1195061da546Spatrick 1196061da546Spatrick static char ID; 1197061da546Spatrick bool isA(const void *classID) const override { 1198061da546Spatrick return classID == &ID || NativeFile::isA(classID); 1199061da546Spatrick } 1200061da546Spatrick static bool classof(const File *file) { return file->isA(&ID); } 1201061da546Spatrick }; 1202061da546Spatrick char SimplePythonFile::ID = 0; 1203061da546Spatrick } // namespace 1204061da546Spatrick 1205061da546Spatrick #if PY_MAJOR_VERSION >= 3 1206061da546Spatrick 1207061da546Spatrick namespace { 1208061da546Spatrick class PythonBuffer { 1209061da546Spatrick public: 1210061da546Spatrick PythonBuffer &operator=(const PythonBuffer &) = delete; 1211061da546Spatrick PythonBuffer(const PythonBuffer &) = delete; 1212061da546Spatrick 1213061da546Spatrick static Expected<PythonBuffer> Create(PythonObject &obj, 1214061da546Spatrick int flags = PyBUF_SIMPLE) { 1215061da546Spatrick Py_buffer py_buffer = {}; 1216061da546Spatrick PyObject_GetBuffer(obj.get(), &py_buffer, flags); 1217061da546Spatrick if (!py_buffer.obj) 1218061da546Spatrick return llvm::make_error<PythonException>(); 1219061da546Spatrick return PythonBuffer(py_buffer); 1220061da546Spatrick } 1221061da546Spatrick 1222061da546Spatrick PythonBuffer(PythonBuffer &&other) { 1223061da546Spatrick m_buffer = other.m_buffer; 1224061da546Spatrick other.m_buffer.obj = nullptr; 1225061da546Spatrick } 1226061da546Spatrick 1227061da546Spatrick ~PythonBuffer() { 1228061da546Spatrick if (m_buffer.obj) 1229061da546Spatrick PyBuffer_Release(&m_buffer); 1230061da546Spatrick } 1231061da546Spatrick 1232061da546Spatrick Py_buffer &get() { return m_buffer; } 1233061da546Spatrick 1234061da546Spatrick private: 1235061da546Spatrick // takes ownership of the buffer. 1236061da546Spatrick PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {} 1237061da546Spatrick Py_buffer m_buffer; 1238061da546Spatrick }; 1239061da546Spatrick } // namespace 1240061da546Spatrick 1241061da546Spatrick // Shared methods between TextPythonFile and BinaryPythonFile 1242061da546Spatrick namespace { 1243061da546Spatrick class PythonIOFile : public OwnedPythonFile<File> { 1244061da546Spatrick public: 1245061da546Spatrick PythonIOFile(const PythonFile &file, bool borrowed) 1246061da546Spatrick : OwnedPythonFile(file, borrowed) {} 1247061da546Spatrick 1248061da546Spatrick ~PythonIOFile() override { Close(); } 1249061da546Spatrick 1250061da546Spatrick bool IsValid() const override { return IsPythonSideValid(); } 1251061da546Spatrick 1252061da546Spatrick Status Close() override { 1253061da546Spatrick assert(m_py_obj); 1254061da546Spatrick GIL takeGIL; 1255061da546Spatrick if (m_borrowed) 1256061da546Spatrick return Flush(); 1257061da546Spatrick auto r = m_py_obj.CallMethod("close"); 1258061da546Spatrick if (!r) 1259061da546Spatrick return Status(r.takeError()); 1260061da546Spatrick return Status(); 1261061da546Spatrick } 1262061da546Spatrick 1263061da546Spatrick Status Flush() override { 1264061da546Spatrick GIL takeGIL; 1265061da546Spatrick auto r = m_py_obj.CallMethod("flush"); 1266061da546Spatrick if (!r) 1267061da546Spatrick return Status(r.takeError()); 1268061da546Spatrick return Status(); 1269061da546Spatrick } 1270061da546Spatrick 1271061da546Spatrick Expected<File::OpenOptions> GetOptions() const override { 1272061da546Spatrick GIL takeGIL; 1273061da546Spatrick return GetOptionsForPyObject(m_py_obj); 1274061da546Spatrick } 1275061da546Spatrick 1276061da546Spatrick static char ID; 1277061da546Spatrick bool isA(const void *classID) const override { 1278061da546Spatrick return classID == &ID || File::isA(classID); 1279061da546Spatrick } 1280061da546Spatrick static bool classof(const File *file) { return file->isA(&ID); } 1281061da546Spatrick }; 1282061da546Spatrick char PythonIOFile::ID = 0; 1283061da546Spatrick } // namespace 1284061da546Spatrick 1285061da546Spatrick namespace { 1286061da546Spatrick class BinaryPythonFile : public PythonIOFile { 1287061da546Spatrick protected: 1288061da546Spatrick int m_descriptor; 1289061da546Spatrick 1290061da546Spatrick public: 1291061da546Spatrick BinaryPythonFile(int fd, const PythonFile &file, bool borrowed) 1292061da546Spatrick : PythonIOFile(file, borrowed), 1293061da546Spatrick m_descriptor(File::DescriptorIsValid(fd) ? fd 1294061da546Spatrick : File::kInvalidDescriptor) {} 1295061da546Spatrick 1296061da546Spatrick int GetDescriptor() const override { return m_descriptor; } 1297061da546Spatrick 1298061da546Spatrick Status Write(const void *buf, size_t &num_bytes) override { 1299061da546Spatrick GIL takeGIL; 1300061da546Spatrick PyObject *pybuffer_p = PyMemoryView_FromMemory( 1301061da546Spatrick const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ); 1302061da546Spatrick if (!pybuffer_p) 1303061da546Spatrick return Status(llvm::make_error<PythonException>()); 1304061da546Spatrick auto pybuffer = Take<PythonObject>(pybuffer_p); 1305061da546Spatrick num_bytes = 0; 1306061da546Spatrick auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer)); 1307061da546Spatrick if (!bytes_written) 1308061da546Spatrick return Status(bytes_written.takeError()); 1309061da546Spatrick if (bytes_written.get() < 0) 1310061da546Spatrick return Status(".write() method returned a negative number!"); 1311061da546Spatrick static_assert(sizeof(long long) >= sizeof(size_t), "overflow"); 1312061da546Spatrick num_bytes = bytes_written.get(); 1313061da546Spatrick return Status(); 1314061da546Spatrick } 1315061da546Spatrick 1316061da546Spatrick Status Read(void *buf, size_t &num_bytes) override { 1317061da546Spatrick GIL takeGIL; 1318061da546Spatrick static_assert(sizeof(long long) >= sizeof(size_t), "overflow"); 1319061da546Spatrick auto pybuffer_obj = 1320061da546Spatrick m_py_obj.CallMethod("read", (unsigned long long)num_bytes); 1321061da546Spatrick if (!pybuffer_obj) 1322061da546Spatrick return Status(pybuffer_obj.takeError()); 1323061da546Spatrick num_bytes = 0; 1324061da546Spatrick if (pybuffer_obj.get().IsNone()) { 1325061da546Spatrick // EOF 1326061da546Spatrick num_bytes = 0; 1327061da546Spatrick return Status(); 1328061da546Spatrick } 1329061da546Spatrick auto pybuffer = PythonBuffer::Create(pybuffer_obj.get()); 1330061da546Spatrick if (!pybuffer) 1331061da546Spatrick return Status(pybuffer.takeError()); 1332061da546Spatrick memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len); 1333061da546Spatrick num_bytes = pybuffer.get().get().len; 1334061da546Spatrick return Status(); 1335061da546Spatrick } 1336061da546Spatrick }; 1337061da546Spatrick } // namespace 1338061da546Spatrick 1339061da546Spatrick namespace { 1340061da546Spatrick class TextPythonFile : public PythonIOFile { 1341061da546Spatrick protected: 1342061da546Spatrick int m_descriptor; 1343061da546Spatrick 1344061da546Spatrick public: 1345061da546Spatrick TextPythonFile(int fd, const PythonFile &file, bool borrowed) 1346061da546Spatrick : PythonIOFile(file, borrowed), 1347061da546Spatrick m_descriptor(File::DescriptorIsValid(fd) ? fd 1348061da546Spatrick : File::kInvalidDescriptor) {} 1349061da546Spatrick 1350061da546Spatrick int GetDescriptor() const override { return m_descriptor; } 1351061da546Spatrick 1352061da546Spatrick Status Write(const void *buf, size_t &num_bytes) override { 1353061da546Spatrick GIL takeGIL; 1354061da546Spatrick auto pystring = 1355061da546Spatrick PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes)); 1356061da546Spatrick if (!pystring) 1357061da546Spatrick return Status(pystring.takeError()); 1358061da546Spatrick num_bytes = 0; 1359061da546Spatrick auto bytes_written = 1360061da546Spatrick As<long long>(m_py_obj.CallMethod("write", pystring.get())); 1361061da546Spatrick if (!bytes_written) 1362061da546Spatrick return Status(bytes_written.takeError()); 1363061da546Spatrick if (bytes_written.get() < 0) 1364061da546Spatrick return Status(".write() method returned a negative number!"); 1365061da546Spatrick static_assert(sizeof(long long) >= sizeof(size_t), "overflow"); 1366061da546Spatrick num_bytes = bytes_written.get(); 1367061da546Spatrick return Status(); 1368061da546Spatrick } 1369061da546Spatrick 1370061da546Spatrick Status Read(void *buf, size_t &num_bytes) override { 1371061da546Spatrick GIL takeGIL; 1372061da546Spatrick size_t num_chars = num_bytes / 6; 1373061da546Spatrick size_t orig_num_bytes = num_bytes; 1374061da546Spatrick num_bytes = 0; 1375061da546Spatrick if (orig_num_bytes < 6) { 1376061da546Spatrick return Status("can't read less than 6 bytes from a utf8 text stream"); 1377061da546Spatrick } 1378061da546Spatrick auto pystring = As<PythonString>( 1379061da546Spatrick m_py_obj.CallMethod("read", (unsigned long long)num_chars)); 1380061da546Spatrick if (!pystring) 1381061da546Spatrick return Status(pystring.takeError()); 1382061da546Spatrick if (pystring.get().IsNone()) { 1383061da546Spatrick // EOF 1384061da546Spatrick return Status(); 1385061da546Spatrick } 1386061da546Spatrick auto stringref = pystring.get().AsUTF8(); 1387061da546Spatrick if (!stringref) 1388061da546Spatrick return Status(stringref.takeError()); 1389061da546Spatrick num_bytes = stringref.get().size(); 1390061da546Spatrick memcpy(buf, stringref.get().begin(), num_bytes); 1391061da546Spatrick return Status(); 1392061da546Spatrick } 1393061da546Spatrick }; 1394061da546Spatrick } // namespace 1395061da546Spatrick 1396061da546Spatrick #endif 1397061da546Spatrick 1398061da546Spatrick llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) { 1399061da546Spatrick if (!IsValid()) 1400061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1401061da546Spatrick "invalid PythonFile"); 1402061da546Spatrick 1403061da546Spatrick int fd = PyObject_AsFileDescriptor(m_py_obj); 1404061da546Spatrick if (fd < 0) { 1405061da546Spatrick PyErr_Clear(); 1406061da546Spatrick return ConvertToFileForcingUseOfScriptingIOMethods(borrowed); 1407061da546Spatrick } 1408061da546Spatrick auto options = GetOptionsForPyObject(*this); 1409061da546Spatrick if (!options) 1410061da546Spatrick return options.takeError(); 1411061da546Spatrick 1412061da546Spatrick if (options.get() & File::eOpenOptionWrite) { 1413061da546Spatrick // LLDB and python will not share I/O buffers. We should probably 1414061da546Spatrick // flush the python buffers now. 1415061da546Spatrick auto r = CallMethod("flush"); 1416061da546Spatrick if (!r) 1417061da546Spatrick return r.takeError(); 1418061da546Spatrick } 1419061da546Spatrick 1420061da546Spatrick FileSP file_sp; 1421061da546Spatrick if (borrowed) { 1422061da546Spatrick // In this case we we don't need to retain the python 1423061da546Spatrick // object at all. 1424061da546Spatrick file_sp = std::make_shared<NativeFile>(fd, options.get(), false); 1425061da546Spatrick } else { 1426061da546Spatrick file_sp = std::static_pointer_cast<File>( 1427061da546Spatrick std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get())); 1428061da546Spatrick } 1429061da546Spatrick if (!file_sp->IsValid()) 1430061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1431061da546Spatrick "invalid File"); 1432061da546Spatrick 1433061da546Spatrick return file_sp; 1434061da546Spatrick } 1435061da546Spatrick 1436061da546Spatrick llvm::Expected<FileSP> 1437061da546Spatrick PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) { 1438061da546Spatrick 1439061da546Spatrick assert(!PyErr_Occurred()); 1440061da546Spatrick 1441061da546Spatrick if (!IsValid()) 1442061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1443061da546Spatrick "invalid PythonFile"); 1444061da546Spatrick 1445061da546Spatrick #if PY_MAJOR_VERSION < 3 1446061da546Spatrick 1447061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1448061da546Spatrick "not supported on python 2"); 1449061da546Spatrick 1450061da546Spatrick #else 1451061da546Spatrick 1452061da546Spatrick int fd = PyObject_AsFileDescriptor(m_py_obj); 1453061da546Spatrick if (fd < 0) { 1454061da546Spatrick PyErr_Clear(); 1455061da546Spatrick fd = File::kInvalidDescriptor; 1456061da546Spatrick } 1457061da546Spatrick 1458061da546Spatrick auto io_module = PythonModule::Import("io"); 1459061da546Spatrick if (!io_module) 1460061da546Spatrick return io_module.takeError(); 1461061da546Spatrick auto textIOBase = io_module.get().Get("TextIOBase"); 1462061da546Spatrick if (!textIOBase) 1463061da546Spatrick return textIOBase.takeError(); 1464061da546Spatrick auto rawIOBase = io_module.get().Get("RawIOBase"); 1465061da546Spatrick if (!rawIOBase) 1466061da546Spatrick return rawIOBase.takeError(); 1467061da546Spatrick auto bufferedIOBase = io_module.get().Get("BufferedIOBase"); 1468061da546Spatrick if (!bufferedIOBase) 1469061da546Spatrick return bufferedIOBase.takeError(); 1470061da546Spatrick 1471061da546Spatrick FileSP file_sp; 1472061da546Spatrick 1473061da546Spatrick auto isTextIO = IsInstance(textIOBase.get()); 1474061da546Spatrick if (!isTextIO) 1475061da546Spatrick return isTextIO.takeError(); 1476061da546Spatrick if (isTextIO.get()) 1477061da546Spatrick file_sp = std::static_pointer_cast<File>( 1478061da546Spatrick std::make_shared<TextPythonFile>(fd, *this, borrowed)); 1479061da546Spatrick 1480061da546Spatrick auto isRawIO = IsInstance(rawIOBase.get()); 1481061da546Spatrick if (!isRawIO) 1482061da546Spatrick return isRawIO.takeError(); 1483061da546Spatrick auto isBufferedIO = IsInstance(bufferedIOBase.get()); 1484061da546Spatrick if (!isBufferedIO) 1485061da546Spatrick return isBufferedIO.takeError(); 1486061da546Spatrick 1487061da546Spatrick if (isRawIO.get() || isBufferedIO.get()) { 1488061da546Spatrick file_sp = std::static_pointer_cast<File>( 1489061da546Spatrick std::make_shared<BinaryPythonFile>(fd, *this, borrowed)); 1490061da546Spatrick } 1491061da546Spatrick 1492061da546Spatrick if (!file_sp) 1493061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1494061da546Spatrick "python file is neither text nor binary"); 1495061da546Spatrick 1496061da546Spatrick if (!file_sp->IsValid()) 1497061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1498061da546Spatrick "invalid File"); 1499061da546Spatrick 1500061da546Spatrick return file_sp; 1501061da546Spatrick 1502061da546Spatrick #endif 1503061da546Spatrick } 1504061da546Spatrick 1505061da546Spatrick Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) { 1506061da546Spatrick if (!file.IsValid()) 1507061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 1508061da546Spatrick "invalid file"); 1509061da546Spatrick 1510061da546Spatrick if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file)) 1511061da546Spatrick return Retain<PythonFile>(simple->GetPythonObject()); 1512061da546Spatrick #if PY_MAJOR_VERSION >= 3 1513061da546Spatrick if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file)) 1514061da546Spatrick return Retain<PythonFile>(pythonio->GetPythonObject()); 1515061da546Spatrick #endif 1516061da546Spatrick 1517061da546Spatrick if (!mode) { 1518061da546Spatrick auto m = file.GetOpenMode(); 1519061da546Spatrick if (!m) 1520061da546Spatrick return m.takeError(); 1521061da546Spatrick mode = m.get(); 1522061da546Spatrick } 1523061da546Spatrick 1524061da546Spatrick PyObject *file_obj; 1525061da546Spatrick #if PY_MAJOR_VERSION >= 3 1526061da546Spatrick file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr, 1527061da546Spatrick "ignore", nullptr, /*closefd=*/0); 1528061da546Spatrick #else 1529061da546Spatrick // I'd like to pass ::fflush here if the file is writable, so that 1530061da546Spatrick // when the python side destructs the file object it will be flushed. 1531061da546Spatrick // However, this would be dangerous. It can cause fflush to be called 1532061da546Spatrick // after fclose if the python program keeps a reference to the file after 1533061da546Spatrick // the original lldb_private::File has been destructed. 1534061da546Spatrick // 1535061da546Spatrick // It's all well and good to ask a python program not to use a closed file 1536061da546Spatrick // but asking a python program to make sure objects get released in a 1537061da546Spatrick // particular order is not safe. 1538061da546Spatrick // 1539061da546Spatrick // The tradeoff here is that if a python 2 program wants to make sure this 1540061da546Spatrick // file gets flushed, they'll have to do it explicitly or wait untill the 1541061da546Spatrick // original lldb File itself gets flushed. 1542061da546Spatrick file_obj = PyFile_FromFile(file.GetStream(), py2_const_cast(""), 1543061da546Spatrick py2_const_cast(mode), [](FILE *) { return 0; }); 1544061da546Spatrick #endif 1545061da546Spatrick 1546061da546Spatrick if (!file_obj) 1547061da546Spatrick return exception(); 1548061da546Spatrick 1549061da546Spatrick return Take<PythonFile>(file_obj); 1550061da546Spatrick } 1551061da546Spatrick 1552061da546Spatrick Error PythonScript::Init() { 1553061da546Spatrick if (function.IsValid()) 1554061da546Spatrick return Error::success(); 1555061da546Spatrick 1556061da546Spatrick PythonDictionary globals(PyInitialValue::Empty); 1557061da546Spatrick auto builtins = PythonModule::BuiltinsModule(); 1558061da546Spatrick if (Error error = globals.SetItem("__builtins__", builtins)) 1559061da546Spatrick return error; 1560061da546Spatrick PyObject *o = 1561061da546Spatrick PyRun_String(script, Py_file_input, globals.get(), globals.get()); 1562061da546Spatrick if (!o) 1563061da546Spatrick return exception(); 1564061da546Spatrick Take<PythonObject>(o); 1565061da546Spatrick auto f = As<PythonCallable>(globals.GetItem("main")); 1566061da546Spatrick if (!f) 1567061da546Spatrick return f.takeError(); 1568061da546Spatrick function = std::move(f.get()); 1569061da546Spatrick 1570061da546Spatrick return Error::success(); 1571061da546Spatrick } 1572061da546Spatrick 1573061da546Spatrick llvm::Expected<PythonObject> 1574061da546Spatrick python::runStringOneLine(const llvm::Twine &string, 1575061da546Spatrick const PythonDictionary &globals, 1576061da546Spatrick const PythonDictionary &locals) { 1577061da546Spatrick if (!globals.IsValid() || !locals.IsValid()) 1578061da546Spatrick return nullDeref(); 1579061da546Spatrick 1580061da546Spatrick PyObject *code = 1581061da546Spatrick Py_CompileString(NullTerminated(string), "<string>", Py_eval_input); 1582061da546Spatrick if (!code) { 1583061da546Spatrick PyErr_Clear(); 1584061da546Spatrick code = 1585061da546Spatrick Py_CompileString(NullTerminated(string), "<string>", Py_single_input); 1586061da546Spatrick } 1587061da546Spatrick if (!code) 1588061da546Spatrick return exception(); 1589061da546Spatrick auto code_ref = Take<PythonObject>(code); 1590061da546Spatrick 1591061da546Spatrick #if PY_MAJOR_VERSION < 3 1592061da546Spatrick PyObject *result = 1593061da546Spatrick PyEval_EvalCode((PyCodeObject *)code, globals.get(), locals.get()); 1594061da546Spatrick #else 1595061da546Spatrick PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get()); 1596061da546Spatrick #endif 1597061da546Spatrick 1598061da546Spatrick if (!result) 1599061da546Spatrick return exception(); 1600061da546Spatrick 1601061da546Spatrick return Take<PythonObject>(result); 1602061da546Spatrick } 1603061da546Spatrick 1604061da546Spatrick llvm::Expected<PythonObject> 1605061da546Spatrick python::runStringMultiLine(const llvm::Twine &string, 1606061da546Spatrick const PythonDictionary &globals, 1607061da546Spatrick const PythonDictionary &locals) { 1608061da546Spatrick if (!globals.IsValid() || !locals.IsValid()) 1609061da546Spatrick return nullDeref(); 1610061da546Spatrick PyObject *result = PyRun_String(NullTerminated(string), Py_file_input, 1611061da546Spatrick globals.get(), locals.get()); 1612061da546Spatrick if (!result) 1613061da546Spatrick return exception(); 1614061da546Spatrick return Take<PythonObject>(result); 1615061da546Spatrick } 1616061da546Spatrick 1617061da546Spatrick #endif 1618