10b57cec5SDimitry Andric //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// 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 9*9dba64beSDimitry Andric // 10*9dba64beSDimitry Andric // !! FIXME FIXME FIXME !! 11*9dba64beSDimitry Andric // 12*9dba64beSDimitry Andric // Python APIs nearly all can return an exception. They do this 13*9dba64beSDimitry Andric // by returning NULL, or -1, or some such value and setting 14*9dba64beSDimitry Andric // the exception state with PyErr_Set*(). Exceptions must be 15*9dba64beSDimitry Andric // handled before further python API functions are called. Failure 16*9dba64beSDimitry Andric // to do so will result in asserts on debug builds of python. 17*9dba64beSDimitry Andric // It will also sometimes, but not usually result in crashes of 18*9dba64beSDimitry Andric // release builds. 19*9dba64beSDimitry Andric // 20*9dba64beSDimitry Andric // Nearly all the code in this header does not handle python exceptions 21*9dba64beSDimitry Andric // correctly. It should all be converted to return Expected<> or 22*9dba64beSDimitry Andric // Error types to capture the exception. 23*9dba64beSDimitry Andric // 24*9dba64beSDimitry Andric // Everything in this file except functions that return Error or 25*9dba64beSDimitry Andric // Expected<> is considered deprecated and should not be 26*9dba64beSDimitry Andric // used in new code. If you need to use it, fix it first. 27*9dba64beSDimitry Andric // 28*9dba64beSDimitry Andric // 29*9dba64beSDimitry Andric // TODOs for this file 30*9dba64beSDimitry Andric // 31*9dba64beSDimitry Andric // * Make all methods safe for exceptions. 32*9dba64beSDimitry Andric // 33*9dba64beSDimitry Andric // * Eliminate method signatures that must translate exceptions into 34*9dba64beSDimitry Andric // empty objects or NULLs. Almost everything here should return 35*9dba64beSDimitry Andric // Expected<>. It should be acceptable for certain operations that 36*9dba64beSDimitry Andric // can never fail to assert instead, such as the creation of 37*9dba64beSDimitry Andric // PythonString from a string literal. 38*9dba64beSDimitry Andric // 39*9dba64beSDimitry Andric // * Elimintate Reset(), and make all non-default constructors private. 40*9dba64beSDimitry Andric // Python objects should be created with Retain<> or Take<>, and they 41*9dba64beSDimitry Andric // should be assigned with operator= 42*9dba64beSDimitry Andric // 43*9dba64beSDimitry Andric // * Eliminate default constructors, make python objects always 44*9dba64beSDimitry Andric // nonnull, and use optionals where necessary. 45*9dba64beSDimitry Andric // 46*9dba64beSDimitry Andric 47*9dba64beSDimitry Andric 480b57cec5SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 490b57cec5SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric #ifndef LLDB_DISABLE_PYTHON 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // LLDB Python header must be included first 540b57cec5SDimitry Andric #include "lldb-python.h" 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric #include "lldb/Host/File.h" 570b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h" 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric namespace lldb_private { 62*9dba64beSDimitry Andric namespace python { 630b57cec5SDimitry Andric 64*9dba64beSDimitry Andric class PythonObject; 650b57cec5SDimitry Andric class PythonBytes; 660b57cec5SDimitry Andric class PythonString; 670b57cec5SDimitry Andric class PythonList; 680b57cec5SDimitry Andric class PythonDictionary; 690b57cec5SDimitry Andric class PythonInteger; 70*9dba64beSDimitry Andric class PythonException; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric class StructuredPythonObject : public StructuredData::Generic { 730b57cec5SDimitry Andric public: 740b57cec5SDimitry Andric StructuredPythonObject() : StructuredData::Generic() {} 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 770b57cec5SDimitry Andric Py_XINCREF(GetValue()); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric ~StructuredPythonObject() override { 810b57cec5SDimitry Andric if (Py_IsInitialized()) 820b57cec5SDimitry Andric Py_XDECREF(GetValue()); 830b57cec5SDimitry Andric SetValue(nullptr); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 870b57cec5SDimitry Andric 88*9dba64beSDimitry Andric void Serialize(llvm::json::OStream &s) const override; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric private: 910b57cec5SDimitry Andric DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 920b57cec5SDimitry Andric }; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric enum class PyObjectType { 950b57cec5SDimitry Andric Unknown, 960b57cec5SDimitry Andric None, 970b57cec5SDimitry Andric Boolean, 980b57cec5SDimitry Andric Integer, 990b57cec5SDimitry Andric Dictionary, 1000b57cec5SDimitry Andric List, 1010b57cec5SDimitry Andric String, 1020b57cec5SDimitry Andric Bytes, 1030b57cec5SDimitry Andric ByteArray, 1040b57cec5SDimitry Andric Module, 1050b57cec5SDimitry Andric Callable, 1060b57cec5SDimitry Andric Tuple, 1070b57cec5SDimitry Andric File 1080b57cec5SDimitry Andric }; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric enum class PyRefType { 1110b57cec5SDimitry Andric Borrowed, // We are not given ownership of the incoming PyObject. 1120b57cec5SDimitry Andric // We cannot safely hold it without calling Py_INCREF. 1130b57cec5SDimitry Andric Owned // We have ownership of the incoming PyObject. We should 1140b57cec5SDimitry Andric // not call Py_INCREF. 1150b57cec5SDimitry Andric }; 1160b57cec5SDimitry Andric 117*9dba64beSDimitry Andric 118*9dba64beSDimitry Andric // Take a reference that you already own, and turn it into 119*9dba64beSDimitry Andric // a PythonObject. 120*9dba64beSDimitry Andric // 121*9dba64beSDimitry Andric // Most python API methods will return a +1 reference 122*9dba64beSDimitry Andric // if they succeed or NULL if and only if 123*9dba64beSDimitry Andric // they set an exception. Use this to collect such return 124*9dba64beSDimitry Andric // values, after checking for NULL. 125*9dba64beSDimitry Andric // 126*9dba64beSDimitry Andric // If T is not just PythonObject, then obj must be already be 127*9dba64beSDimitry Andric // checked to be of the correct type. 128*9dba64beSDimitry Andric template <typename T> T Take(PyObject *obj) { 129*9dba64beSDimitry Andric assert(obj); 130*9dba64beSDimitry Andric assert(!PyErr_Occurred()); 131*9dba64beSDimitry Andric T thing(PyRefType::Owned, obj); 132*9dba64beSDimitry Andric assert(thing.IsValid()); 133*9dba64beSDimitry Andric return std::move(thing); 134*9dba64beSDimitry Andric } 135*9dba64beSDimitry Andric 136*9dba64beSDimitry Andric // Retain a reference you have borrowed, and turn it into 137*9dba64beSDimitry Andric // a PythonObject. 138*9dba64beSDimitry Andric // 139*9dba64beSDimitry Andric // A minority of python APIs return a borrowed reference 140*9dba64beSDimitry Andric // instead of a +1. They will also return NULL if and only 141*9dba64beSDimitry Andric // if they set an exception. Use this to collect such return 142*9dba64beSDimitry Andric // values, after checking for NULL. 143*9dba64beSDimitry Andric // 144*9dba64beSDimitry Andric // If T is not just PythonObject, then obj must be already be 145*9dba64beSDimitry Andric // checked to be of the correct type. 146*9dba64beSDimitry Andric template <typename T> T Retain(PyObject *obj) { 147*9dba64beSDimitry Andric assert(obj); 148*9dba64beSDimitry Andric assert(!PyErr_Occurred()); 149*9dba64beSDimitry Andric T thing(PyRefType::Borrowed, obj); 150*9dba64beSDimitry Andric assert(thing.IsValid()); 151*9dba64beSDimitry Andric return std::move(thing); 152*9dba64beSDimitry Andric } 153*9dba64beSDimitry Andric 154*9dba64beSDimitry Andric // This class can be used like a utility function to convert from 155*9dba64beSDimitry Andric // a llvm-friendly Twine into a null-terminated const char *, 156*9dba64beSDimitry Andric // which is the form python C APIs want their strings in. 157*9dba64beSDimitry Andric // 158*9dba64beSDimitry Andric // Example: 159*9dba64beSDimitry Andric // const llvm::Twine &some_twine; 160*9dba64beSDimitry Andric // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 161*9dba64beSDimitry Andric // 162*9dba64beSDimitry Andric // Why a class instead of a function? If the twine isn't already null 163*9dba64beSDimitry Andric // terminated, it will need a temporary buffer to copy the string 164*9dba64beSDimitry Andric // into. We need that buffer to stick around for the lifetime of the 165*9dba64beSDimitry Andric // statement. 166*9dba64beSDimitry Andric class NullTerminated { 167*9dba64beSDimitry Andric const char *str; 168*9dba64beSDimitry Andric llvm::SmallString<32> storage; 169*9dba64beSDimitry Andric 170*9dba64beSDimitry Andric public: 171*9dba64beSDimitry Andric NullTerminated(const llvm::Twine &twine) { 172*9dba64beSDimitry Andric llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 173*9dba64beSDimitry Andric str = ref.begin(); 174*9dba64beSDimitry Andric } 175*9dba64beSDimitry Andric operator const char *() { return str; } 176*9dba64beSDimitry Andric }; 177*9dba64beSDimitry Andric 178*9dba64beSDimitry Andric inline llvm::Error nullDeref() { 179*9dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 180*9dba64beSDimitry Andric "A NULL PyObject* was dereferenced"); 181*9dba64beSDimitry Andric } 182*9dba64beSDimitry Andric 183*9dba64beSDimitry Andric inline llvm::Error exception(const char *s = nullptr) { 184*9dba64beSDimitry Andric return llvm::make_error<PythonException>(s); 185*9dba64beSDimitry Andric } 186*9dba64beSDimitry Andric 187*9dba64beSDimitry Andric inline llvm::Error keyError() { 188*9dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 189*9dba64beSDimitry Andric "key not in dict"); 190*9dba64beSDimitry Andric } 191*9dba64beSDimitry Andric 1920b57cec5SDimitry Andric enum class PyInitialValue { Invalid, Empty }; 1930b57cec5SDimitry Andric 194*9dba64beSDimitry Andric template <typename T, typename Enable = void> struct PythonFormat; 195*9dba64beSDimitry Andric 196*9dba64beSDimitry Andric template <> struct PythonFormat<unsigned long long> { 197*9dba64beSDimitry Andric static constexpr char format = 'K'; 198*9dba64beSDimitry Andric static auto get(unsigned long long value) { return value; } 199*9dba64beSDimitry Andric }; 200*9dba64beSDimitry Andric 201*9dba64beSDimitry Andric template <> struct PythonFormat<long long> { 202*9dba64beSDimitry Andric static constexpr char format = 'L'; 203*9dba64beSDimitry Andric static auto get(long long value) { return value; } 204*9dba64beSDimitry Andric }; 205*9dba64beSDimitry Andric 206*9dba64beSDimitry Andric template <> struct PythonFormat<PyObject *> { 207*9dba64beSDimitry Andric static constexpr char format = 'O'; 208*9dba64beSDimitry Andric static auto get(PyObject *value) { return value; } 209*9dba64beSDimitry Andric }; 210*9dba64beSDimitry Andric 211*9dba64beSDimitry Andric template <typename T> 212*9dba64beSDimitry Andric struct PythonFormat< 213*9dba64beSDimitry Andric T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 214*9dba64beSDimitry Andric static constexpr char format = 'O'; 215*9dba64beSDimitry Andric static auto get(const T &value) { return value.get(); } 216*9dba64beSDimitry Andric }; 217*9dba64beSDimitry Andric 2180b57cec5SDimitry Andric class PythonObject { 2190b57cec5SDimitry Andric public: 2200b57cec5SDimitry Andric PythonObject() : m_py_obj(nullptr) {} 2210b57cec5SDimitry Andric 222*9dba64beSDimitry Andric PythonObject(PyRefType type, PyObject *py_obj) { 2230b57cec5SDimitry Andric m_py_obj = py_obj; 2240b57cec5SDimitry Andric // If this is a borrowed reference, we need to convert it to 2250b57cec5SDimitry Andric // an owned reference by incrementing it. If it is an owned 2260b57cec5SDimitry Andric // reference (for example the caller allocated it with PyDict_New() 2270b57cec5SDimitry Andric // then we must *not* increment it. 228*9dba64beSDimitry Andric if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 2290b57cec5SDimitry Andric Py_XINCREF(m_py_obj); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 232*9dba64beSDimitry Andric PythonObject(const PythonObject &rhs) 233*9dba64beSDimitry Andric : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 234*9dba64beSDimitry Andric 235*9dba64beSDimitry Andric PythonObject(PythonObject &&rhs) { 236*9dba64beSDimitry Andric m_py_obj = rhs.m_py_obj; 237*9dba64beSDimitry Andric rhs.m_py_obj = nullptr; 238*9dba64beSDimitry Andric } 239*9dba64beSDimitry Andric 240*9dba64beSDimitry Andric ~PythonObject() { Reset(); } 241*9dba64beSDimitry Andric 242*9dba64beSDimitry Andric void Reset() { 243*9dba64beSDimitry Andric if (m_py_obj && Py_IsInitialized()) 244*9dba64beSDimitry Andric Py_DECREF(m_py_obj); 245*9dba64beSDimitry Andric m_py_obj = nullptr; 246*9dba64beSDimitry Andric } 247*9dba64beSDimitry Andric 2480b57cec5SDimitry Andric void Dump() const { 2490b57cec5SDimitry Andric if (m_py_obj) 2500b57cec5SDimitry Andric _PyObject_Dump(m_py_obj); 2510b57cec5SDimitry Andric else 2520b57cec5SDimitry Andric puts("NULL"); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric void Dump(Stream &strm) const; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric PyObject *get() const { return m_py_obj; } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric PyObject *release() { 2600b57cec5SDimitry Andric PyObject *result = m_py_obj; 2610b57cec5SDimitry Andric m_py_obj = nullptr; 2620b57cec5SDimitry Andric return result; 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 265*9dba64beSDimitry Andric PythonObject &operator=(PythonObject other) { 266*9dba64beSDimitry Andric Reset(); 267*9dba64beSDimitry Andric m_py_obj = std::exchange(other.m_py_obj, nullptr); 2680b57cec5SDimitry Andric return *this; 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric PyObjectType GetObjectType() const; 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric PythonString Repr() const; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric PythonString Str() const; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 2780b57cec5SDimitry Andric const PythonDictionary &dict); 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric template <typename T> 2810b57cec5SDimitry Andric static T ResolveNameWithDictionary(llvm::StringRef name, 2820b57cec5SDimitry Andric const PythonDictionary &dict) { 2830b57cec5SDimitry Andric return ResolveNameWithDictionary(name, dict).AsType<T>(); 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric PythonObject ResolveName(llvm::StringRef name) const; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric template <typename T> T ResolveName(llvm::StringRef name) const { 2890b57cec5SDimitry Andric return ResolveName(name).AsType<T>(); 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric bool HasAttribute(llvm::StringRef attribute) const; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric PythonObject GetAttributeValue(llvm::StringRef attribute) const; 2950b57cec5SDimitry Andric 296*9dba64beSDimitry Andric bool IsNone() const { return m_py_obj == Py_None; } 2970b57cec5SDimitry Andric 298*9dba64beSDimitry Andric bool IsValid() const { return m_py_obj != nullptr; } 2990b57cec5SDimitry Andric 300*9dba64beSDimitry Andric bool IsAllocated() const { return IsValid() && !IsNone(); } 301*9dba64beSDimitry Andric 302*9dba64beSDimitry Andric explicit operator bool() const { return IsValid() && !IsNone(); } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric template <typename T> T AsType() const { 3050b57cec5SDimitry Andric if (!T::Check(m_py_obj)) 3060b57cec5SDimitry Andric return T(); 3070b57cec5SDimitry Andric return T(PyRefType::Borrowed, m_py_obj); 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric StructuredData::ObjectSP CreateStructuredObject() const; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric protected: 313*9dba64beSDimitry Andric 314*9dba64beSDimitry Andric #if PY_MAJOR_VERSION < 3 315*9dba64beSDimitry Andric // The python 2 API declares some arguments as char* that should 316*9dba64beSDimitry Andric // be const char *, but it doesn't actually modify them. 317*9dba64beSDimitry Andric static char *py2_const_cast(const char *s) { return const_cast<char *>(s); } 318*9dba64beSDimitry Andric #else 319*9dba64beSDimitry Andric static const char *py2_const_cast(const char *s) { return s; } 320*9dba64beSDimitry Andric #endif 321*9dba64beSDimitry Andric 322*9dba64beSDimitry Andric public: 323*9dba64beSDimitry Andric template <typename... T> 324*9dba64beSDimitry Andric llvm::Expected<PythonObject> CallMethod(const char *name, 325*9dba64beSDimitry Andric const T &... t) const { 326*9dba64beSDimitry Andric const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 327*9dba64beSDimitry Andric PyObject *obj = 328*9dba64beSDimitry Andric PyObject_CallMethod(m_py_obj, py2_const_cast(name), 329*9dba64beSDimitry Andric py2_const_cast(format), PythonFormat<T>::get(t)...); 330*9dba64beSDimitry Andric if (!obj) 331*9dba64beSDimitry Andric return exception(); 332*9dba64beSDimitry Andric return python::Take<PythonObject>(obj); 333*9dba64beSDimitry Andric } 334*9dba64beSDimitry Andric 335*9dba64beSDimitry Andric template <typename... T> 336*9dba64beSDimitry Andric llvm::Expected<PythonObject> Call(const T &... t) const { 337*9dba64beSDimitry Andric const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 338*9dba64beSDimitry Andric PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 339*9dba64beSDimitry Andric PythonFormat<T>::get(t)...); 340*9dba64beSDimitry Andric if (!obj) 341*9dba64beSDimitry Andric return exception(); 342*9dba64beSDimitry Andric return python::Take<PythonObject>(obj); 343*9dba64beSDimitry Andric } 344*9dba64beSDimitry Andric 345*9dba64beSDimitry Andric llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 346*9dba64beSDimitry Andric if (!m_py_obj) 347*9dba64beSDimitry Andric return nullDeref(); 348*9dba64beSDimitry Andric PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 349*9dba64beSDimitry Andric if (!obj) 350*9dba64beSDimitry Andric return exception(); 351*9dba64beSDimitry Andric return python::Take<PythonObject>(obj); 352*9dba64beSDimitry Andric } 353*9dba64beSDimitry Andric 354*9dba64beSDimitry Andric llvm::Expected<bool> IsTrue() { 355*9dba64beSDimitry Andric if (!m_py_obj) 356*9dba64beSDimitry Andric return nullDeref(); 357*9dba64beSDimitry Andric int r = PyObject_IsTrue(m_py_obj); 358*9dba64beSDimitry Andric if (r < 0) 359*9dba64beSDimitry Andric return exception(); 360*9dba64beSDimitry Andric return !!r; 361*9dba64beSDimitry Andric } 362*9dba64beSDimitry Andric 363*9dba64beSDimitry Andric llvm::Expected<long long> AsLongLong() { 364*9dba64beSDimitry Andric if (!m_py_obj) 365*9dba64beSDimitry Andric return nullDeref(); 366*9dba64beSDimitry Andric assert(!PyErr_Occurred()); 367*9dba64beSDimitry Andric long long r = PyLong_AsLongLong(m_py_obj); 368*9dba64beSDimitry Andric if (PyErr_Occurred()) 369*9dba64beSDimitry Andric return exception(); 370*9dba64beSDimitry Andric return r; 371*9dba64beSDimitry Andric } 372*9dba64beSDimitry Andric 373*9dba64beSDimitry Andric llvm::Expected<bool> IsInstance(const PythonObject &cls) { 374*9dba64beSDimitry Andric if (!m_py_obj || !cls.IsValid()) 375*9dba64beSDimitry Andric return nullDeref(); 376*9dba64beSDimitry Andric int r = PyObject_IsInstance(m_py_obj, cls.get()); 377*9dba64beSDimitry Andric if (r < 0) 378*9dba64beSDimitry Andric return exception(); 379*9dba64beSDimitry Andric return !!r; 380*9dba64beSDimitry Andric } 381*9dba64beSDimitry Andric 382*9dba64beSDimitry Andric protected: 3830b57cec5SDimitry Andric PyObject *m_py_obj; 3840b57cec5SDimitry Andric }; 3850b57cec5SDimitry Andric 386*9dba64beSDimitry Andric 387*9dba64beSDimitry Andric // This is why C++ needs monads. 388*9dba64beSDimitry Andric template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 389*9dba64beSDimitry Andric if (!obj) 390*9dba64beSDimitry Andric return obj.takeError(); 391*9dba64beSDimitry Andric if (!T::Check(obj.get().get())) 392*9dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 393*9dba64beSDimitry Andric "type error"); 394*9dba64beSDimitry Andric return T(PyRefType::Borrowed, std::move(obj.get().get())); 395*9dba64beSDimitry Andric } 396*9dba64beSDimitry Andric 397*9dba64beSDimitry Andric template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 398*9dba64beSDimitry Andric 399*9dba64beSDimitry Andric template <> 400*9dba64beSDimitry Andric llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 401*9dba64beSDimitry Andric 402*9dba64beSDimitry Andric template <> 403*9dba64beSDimitry Andric llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 404*9dba64beSDimitry Andric 405*9dba64beSDimitry Andric 406*9dba64beSDimitry Andric template <class T> class TypedPythonObject : public PythonObject { 4070b57cec5SDimitry Andric public: 408*9dba64beSDimitry Andric // override to perform implicit type conversions on Reset 409*9dba64beSDimitry Andric // This can be eliminated once we drop python 2 support. 410*9dba64beSDimitry Andric static void Convert(PyRefType &type, PyObject *&py_obj) {} 411*9dba64beSDimitry Andric 412*9dba64beSDimitry Andric TypedPythonObject(PyRefType type, PyObject *py_obj) { 413*9dba64beSDimitry Andric if (!py_obj) 414*9dba64beSDimitry Andric return; 415*9dba64beSDimitry Andric T::Convert(type, py_obj); 416*9dba64beSDimitry Andric if (T::Check(py_obj)) 417*9dba64beSDimitry Andric PythonObject::operator=(PythonObject(type, py_obj)); 418*9dba64beSDimitry Andric else if (type == PyRefType::Owned) 419*9dba64beSDimitry Andric Py_DECREF(py_obj); 420*9dba64beSDimitry Andric } 421*9dba64beSDimitry Andric 422*9dba64beSDimitry Andric TypedPythonObject() {} 423*9dba64beSDimitry Andric }; 424*9dba64beSDimitry Andric 425*9dba64beSDimitry Andric class PythonBytes : public TypedPythonObject<PythonBytes> { 426*9dba64beSDimitry Andric public: 427*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 4280b57cec5SDimitry Andric explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 4290b57cec5SDimitry Andric PythonBytes(const uint8_t *bytes, size_t length); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> GetBytes() const; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric size_t GetSize() const; 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric StructuredData::StringSP CreateStructuredString() const; 4400b57cec5SDimitry Andric }; 4410b57cec5SDimitry Andric 442*9dba64beSDimitry Andric class PythonByteArray : public TypedPythonObject<PythonByteArray> { 4430b57cec5SDimitry Andric public: 444*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 4450b57cec5SDimitry Andric explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 4460b57cec5SDimitry Andric PythonByteArray(const uint8_t *bytes, size_t length); 4470b57cec5SDimitry Andric PythonByteArray(const PythonBytes &object); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> GetBytes() const; 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric size_t GetSize() const; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric StructuredData::StringSP CreateStructuredString() const; 4580b57cec5SDimitry Andric }; 4590b57cec5SDimitry Andric 460*9dba64beSDimitry Andric class PythonString : public TypedPythonObject<PythonString> { 4610b57cec5SDimitry Andric public: 462*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 463*9dba64beSDimitry Andric static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 4640b57cec5SDimitry Andric 465*9dba64beSDimitry Andric PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 466*9dba64beSDimitry Andric 467*9dba64beSDimitry Andric explicit PythonString(llvm::StringRef string); // safe, null on error 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 470*9dba64beSDimitry Andric static void Convert(PyRefType &type, PyObject *&py_obj); 4710b57cec5SDimitry Andric 472*9dba64beSDimitry Andric llvm::StringRef GetString() const; // safe, empty string on error 4730b57cec5SDimitry Andric 474*9dba64beSDimitry Andric llvm::Expected<llvm::StringRef> AsUTF8() const; 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric size_t GetSize() const; 4770b57cec5SDimitry Andric 478*9dba64beSDimitry Andric void SetString(llvm::StringRef string); // safe, null on error 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric StructuredData::StringSP CreateStructuredString() const; 4810b57cec5SDimitry Andric }; 4820b57cec5SDimitry Andric 483*9dba64beSDimitry Andric class PythonInteger : public TypedPythonObject<PythonInteger> { 4840b57cec5SDimitry Andric public: 485*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 4860b57cec5SDimitry Andric 487*9dba64beSDimitry Andric PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 488*9dba64beSDimitry Andric 489*9dba64beSDimitry Andric explicit PythonInteger(int64_t value); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 492*9dba64beSDimitry Andric static void Convert(PyRefType &type, PyObject *&py_obj); 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric int64_t GetInteger() const; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric void SetInteger(int64_t value); 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric StructuredData::IntegerSP CreateStructuredInteger() const; 4990b57cec5SDimitry Andric }; 5000b57cec5SDimitry Andric 501*9dba64beSDimitry Andric class PythonBoolean : public TypedPythonObject<PythonBoolean> { 5020b57cec5SDimitry Andric public: 503*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 5040b57cec5SDimitry Andric 505*9dba64beSDimitry Andric explicit PythonBoolean(bool value); 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric bool GetValue() const; 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric void SetValue(bool value); 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric StructuredData::BooleanSP CreateStructuredBoolean() const; 5140b57cec5SDimitry Andric }; 5150b57cec5SDimitry Andric 516*9dba64beSDimitry Andric class PythonList : public TypedPythonObject<PythonList> { 5170b57cec5SDimitry Andric public: 518*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 519*9dba64beSDimitry Andric 520*9dba64beSDimitry Andric PythonList() : TypedPythonObject() {} // MSVC requires this for some reason 521*9dba64beSDimitry Andric 5220b57cec5SDimitry Andric explicit PythonList(PyInitialValue value); 5230b57cec5SDimitry Andric explicit PythonList(int list_size); 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric uint32_t GetSize() const; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric PythonObject GetItemAtIndex(uint32_t index) const; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric void SetItemAtIndex(uint32_t index, const PythonObject &object); 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric void AppendItem(const PythonObject &object); 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric StructuredData::ArraySP CreateStructuredArray() const; 5360b57cec5SDimitry Andric }; 5370b57cec5SDimitry Andric 538*9dba64beSDimitry Andric class PythonTuple : public TypedPythonObject<PythonTuple> { 5390b57cec5SDimitry Andric public: 540*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 541*9dba64beSDimitry Andric 5420b57cec5SDimitry Andric explicit PythonTuple(PyInitialValue value); 5430b57cec5SDimitry Andric explicit PythonTuple(int tuple_size); 5440b57cec5SDimitry Andric PythonTuple(std::initializer_list<PythonObject> objects); 5450b57cec5SDimitry Andric PythonTuple(std::initializer_list<PyObject *> objects); 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric uint32_t GetSize() const; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric PythonObject GetItemAtIndex(uint32_t index) const; 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric void SetItemAtIndex(uint32_t index, const PythonObject &object); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric StructuredData::ArraySP CreateStructuredArray() const; 5560b57cec5SDimitry Andric }; 5570b57cec5SDimitry Andric 558*9dba64beSDimitry Andric class PythonDictionary : public TypedPythonObject<PythonDictionary> { 5590b57cec5SDimitry Andric public: 560*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 5610b57cec5SDimitry Andric 562*9dba64beSDimitry Andric PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason 563*9dba64beSDimitry Andric 564*9dba64beSDimitry Andric explicit PythonDictionary(PyInitialValue value); 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric uint32_t GetSize() const; 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric PythonList GetKeys() const; 5710b57cec5SDimitry Andric 572*9dba64beSDimitry Andric PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED 573*9dba64beSDimitry Andric void SetItemForKey(const PythonObject &key, 574*9dba64beSDimitry Andric const PythonObject &value); // DEPRECATED 575*9dba64beSDimitry Andric 576*9dba64beSDimitry Andric llvm::Expected<PythonObject> GetItem(const PythonObject &key) const; 577*9dba64beSDimitry Andric llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const; 578*9dba64beSDimitry Andric llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const; 579*9dba64beSDimitry Andric llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const; 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric StructuredData::DictionarySP CreateStructuredDictionary() const; 5820b57cec5SDimitry Andric }; 5830b57cec5SDimitry Andric 584*9dba64beSDimitry Andric class PythonModule : public TypedPythonObject<PythonModule> { 5850b57cec5SDimitry Andric public: 586*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric static PythonModule BuiltinsModule(); 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric static PythonModule MainModule(); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric static PythonModule AddModule(llvm::StringRef module); 5950b57cec5SDimitry Andric 596*9dba64beSDimitry Andric // safe, returns invalid on error; 597*9dba64beSDimitry Andric static PythonModule ImportModule(llvm::StringRef name) { 598*9dba64beSDimitry Andric std::string s = name; 599*9dba64beSDimitry Andric auto mod = Import(s.c_str()); 600*9dba64beSDimitry Andric if (!mod) { 601*9dba64beSDimitry Andric llvm::consumeError(mod.takeError()); 602*9dba64beSDimitry Andric return PythonModule(); 603*9dba64beSDimitry Andric } 604*9dba64beSDimitry Andric return std::move(mod.get()); 605*9dba64beSDimitry Andric } 6060b57cec5SDimitry Andric 607*9dba64beSDimitry Andric static llvm::Expected<PythonModule> Import(const llvm::Twine &name); 6080b57cec5SDimitry Andric 609*9dba64beSDimitry Andric llvm::Expected<PythonObject> Get(const llvm::Twine &name); 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric PythonDictionary GetDictionary() const; 6120b57cec5SDimitry Andric }; 6130b57cec5SDimitry Andric 614*9dba64beSDimitry Andric class PythonCallable : public TypedPythonObject<PythonCallable> { 6150b57cec5SDimitry Andric public: 616*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 617*9dba64beSDimitry Andric 6180b57cec5SDimitry Andric struct ArgInfo { 619*9dba64beSDimitry Andric /* the largest number of positional arguments this callable 620*9dba64beSDimitry Andric * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs 621*9dba64beSDimitry Andric * function and can accept an arbitrary number */ 622*9dba64beSDimitry Andric unsigned max_positional_args; 623*9dba64beSDimitry Andric static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline 624*9dba64beSDimitry Andric /* the number of positional arguments, including optional ones, 625*9dba64beSDimitry Andric * and excluding varargs. If this is a bound method, then the 626*9dba64beSDimitry Andric * count will still include a +1 for self. 627*9dba64beSDimitry Andric * 628*9dba64beSDimitry Andric * FIXME. That's crazy. This should be replaced with 629*9dba64beSDimitry Andric * an accurate min and max for positional args. 630*9dba64beSDimitry Andric */ 631*9dba64beSDimitry Andric int count; 632*9dba64beSDimitry Andric /* does the callable have positional varargs? */ 633*9dba64beSDimitry Andric bool has_varargs : 1; // FIXME delete this 6340b57cec5SDimitry Andric }; 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 6370b57cec5SDimitry Andric 638*9dba64beSDimitry Andric llvm::Expected<ArgInfo> GetArgInfo() const; 6390b57cec5SDimitry Andric 640*9dba64beSDimitry Andric llvm::Expected<ArgInfo> GetInitArgInfo() const; 6410b57cec5SDimitry Andric 642*9dba64beSDimitry Andric ArgInfo GetNumArguments() const; // DEPRECATED 643*9dba64beSDimitry Andric 644*9dba64beSDimitry Andric // If the callable is a Py_Class, then find the number of arguments 645*9dba64beSDimitry Andric // of the __init__ method. 646*9dba64beSDimitry Andric ArgInfo GetNumInitArguments() const; // DEPRECATED 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric PythonObject operator()(); 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric PythonObject operator()(std::initializer_list<PyObject *> args); 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric PythonObject operator()(std::initializer_list<PythonObject> args); 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric template <typename Arg, typename... Args> 6550b57cec5SDimitry Andric PythonObject operator()(const Arg &arg, Args... args) { 6560b57cec5SDimitry Andric return operator()({arg, args...}); 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric }; 6590b57cec5SDimitry Andric 660*9dba64beSDimitry Andric class PythonFile : public TypedPythonObject<PythonFile> { 6610b57cec5SDimitry Andric public: 662*9dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject; 6630b57cec5SDimitry Andric 664*9dba64beSDimitry Andric PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric static bool Check(PyObject *py_obj); 6670b57cec5SDimitry Andric 668*9dba64beSDimitry Andric static llvm::Expected<PythonFile> FromFile(File &file, 669*9dba64beSDimitry Andric const char *mode = nullptr); 6700b57cec5SDimitry Andric 671*9dba64beSDimitry Andric llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 672*9dba64beSDimitry Andric llvm::Expected<lldb::FileSP> 673*9dba64beSDimitry Andric ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 6740b57cec5SDimitry Andric }; 6750b57cec5SDimitry Andric 676*9dba64beSDimitry Andric class PythonException : public llvm::ErrorInfo<PythonException> { 677*9dba64beSDimitry Andric private: 678*9dba64beSDimitry Andric PyObject *m_exception_type, *m_exception, *m_traceback; 679*9dba64beSDimitry Andric PyObject *m_repr_bytes; 680*9dba64beSDimitry Andric 681*9dba64beSDimitry Andric public: 682*9dba64beSDimitry Andric static char ID; 683*9dba64beSDimitry Andric const char *toCString() const; 684*9dba64beSDimitry Andric PythonException(const char *caller = nullptr); 685*9dba64beSDimitry Andric void Restore(); 686*9dba64beSDimitry Andric ~PythonException(); 687*9dba64beSDimitry Andric void log(llvm::raw_ostream &OS) const override; 688*9dba64beSDimitry Andric std::error_code convertToErrorCode() const override; 689*9dba64beSDimitry Andric bool Matches(PyObject *exc) const; 690*9dba64beSDimitry Andric std::string ReadBacktrace() const; 691*9dba64beSDimitry Andric }; 692*9dba64beSDimitry Andric 693*9dba64beSDimitry Andric // This extracts the underlying T out of an Expected<T> and returns it. 694*9dba64beSDimitry Andric // If the Expected is an Error instead of a T, that error will be converted 695*9dba64beSDimitry Andric // into a python exception, and this will return a default-constructed T. 696*9dba64beSDimitry Andric // 697*9dba64beSDimitry Andric // This is appropriate for use right at the boundary of python calling into 698*9dba64beSDimitry Andric // C++, such as in a SWIG typemap. In such a context you should simply 699*9dba64beSDimitry Andric // check if the returned T is valid, and if it is, return a NULL back 700*9dba64beSDimitry Andric // to python. This will result in the Error being raised as an exception 701*9dba64beSDimitry Andric // from python code's point of view. 702*9dba64beSDimitry Andric // 703*9dba64beSDimitry Andric // For example: 704*9dba64beSDimitry Andric // ``` 705*9dba64beSDimitry Andric // Expected<Foo *> efoop = some_cpp_function(); 706*9dba64beSDimitry Andric // Foo *foop = unwrapOrSetPythonException(efoop); 707*9dba64beSDimitry Andric // if (!foop) 708*9dba64beSDimitry Andric // return NULL; 709*9dba64beSDimitry Andric // do_something(*foop); 710*9dba64beSDimitry Andric // 711*9dba64beSDimitry Andric // If the Error returned was itself created because a python exception was 712*9dba64beSDimitry Andric // raised when C++ code called into python, then the original exception 713*9dba64beSDimitry Andric // will be restored. Otherwise a simple string exception will be raised. 714*9dba64beSDimitry Andric template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 715*9dba64beSDimitry Andric if (expected) 716*9dba64beSDimitry Andric return expected.get(); 717*9dba64beSDimitry Andric llvm::handleAllErrors( 718*9dba64beSDimitry Andric expected.takeError(), [](PythonException &E) { E.Restore(); }, 719*9dba64beSDimitry Andric [](const llvm::ErrorInfoBase &E) { 720*9dba64beSDimitry Andric PyErr_SetString(PyExc_Exception, E.message().c_str()); 721*9dba64beSDimitry Andric }); 722*9dba64beSDimitry Andric return T(); 723*9dba64beSDimitry Andric } 724*9dba64beSDimitry Andric 725*9dba64beSDimitry Andric // This is only here to help incrementally migrate old, exception-unsafe 726*9dba64beSDimitry Andric // code. 727*9dba64beSDimitry Andric template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) { 728*9dba64beSDimitry Andric if (expected) 729*9dba64beSDimitry Andric return std::move(expected.get()); 730*9dba64beSDimitry Andric llvm::consumeError(expected.takeError()); 731*9dba64beSDimitry Andric return T(); 732*9dba64beSDimitry Andric } 733*9dba64beSDimitry Andric 734*9dba64beSDimitry Andric llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string, 735*9dba64beSDimitry Andric const PythonDictionary &globals, 736*9dba64beSDimitry Andric const PythonDictionary &locals); 737*9dba64beSDimitry Andric 738*9dba64beSDimitry Andric llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string, 739*9dba64beSDimitry Andric const PythonDictionary &globals, 740*9dba64beSDimitry Andric const PythonDictionary &locals); 741*9dba64beSDimitry Andric 742*9dba64beSDimitry Andric // Sometimes the best way to interact with a python interpreter is 743*9dba64beSDimitry Andric // to run some python code. You construct a PythonScript with 744*9dba64beSDimitry Andric // script string. The script assigns some function to `_function_` 745*9dba64beSDimitry Andric // and you get a C++ callable object that calls the python function. 746*9dba64beSDimitry Andric // 747*9dba64beSDimitry Andric // Example: 748*9dba64beSDimitry Andric // 749*9dba64beSDimitry Andric // const char script[] = R"( 750*9dba64beSDimitry Andric // def main(x, y): 751*9dba64beSDimitry Andric // .... 752*9dba64beSDimitry Andric // )"; 753*9dba64beSDimitry Andric // 754*9dba64beSDimitry Andric // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) { 755*9dba64beSDimitry Andric // // no need to synchronize access to this global, we already have the GIL 756*9dba64beSDimitry Andric // static PythonScript foo(script) 757*9dba64beSDimitry Andric // return foo(x, y); 758*9dba64beSDimitry Andric // } 759*9dba64beSDimitry Andric class PythonScript { 760*9dba64beSDimitry Andric const char *script; 761*9dba64beSDimitry Andric PythonCallable function; 762*9dba64beSDimitry Andric 763*9dba64beSDimitry Andric llvm::Error Init(); 764*9dba64beSDimitry Andric 765*9dba64beSDimitry Andric public: 766*9dba64beSDimitry Andric PythonScript(const char *script) : script(script), function() {} 767*9dba64beSDimitry Andric 768*9dba64beSDimitry Andric template <typename... Args> 769*9dba64beSDimitry Andric llvm::Expected<PythonObject> operator()(Args &&... args) { 770*9dba64beSDimitry Andric if (llvm::Error error = Init()) 771*9dba64beSDimitry Andric return std::move(error); 772*9dba64beSDimitry Andric return function.Call(std::forward<Args>(args)...); 773*9dba64beSDimitry Andric } 774*9dba64beSDimitry Andric }; 775*9dba64beSDimitry Andric 776*9dba64beSDimitry Andric } // namespace python 7770b57cec5SDimitry Andric } // namespace lldb_private 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric #endif 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 782