diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 | 
| commit | e81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch) | |
| tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h | |
| parent | 85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h')
| -rw-r--r-- | source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h | 498 | 
1 files changed, 498 insertions, 0 deletions
| diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h new file mode 100644 index 0000000000000..c9d17c0f0fad4 --- /dev/null +++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -0,0 +1,498 @@ +//===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H + +#ifndef LLDB_DISABLE_PYTHON + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-defines.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/StructuredData.h" +#include "lldb/Core/Flags.h" +#include "lldb/Host/File.h" +#include "lldb/Interpreter/OptionValue.h" + +namespace lldb_private { + +class PythonString; +class PythonList; +class PythonDictionary; +class PythonInteger; + +class StructuredPythonObject : public StructuredData::Generic +{ +public: +    StructuredPythonObject() +        : StructuredData::Generic() +    { +    } + +    StructuredPythonObject(void *obj) +        : StructuredData::Generic(obj) +    { +        Py_XINCREF(GetValue()); +    } + +    ~StructuredPythonObject() override +    { +        if (Py_IsInitialized()) +            Py_XDECREF(GetValue()); +        SetValue(nullptr); +    } + +    bool +    IsValid() const override +    { +        return GetValue() && GetValue() != Py_None; +    } + +    void Dump(Stream &s) const override; + +private: +    DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); +}; + +enum class PyObjectType +{ +    Unknown, +    None, +    Integer, +    Dictionary, +    List, +    String, +    Module, +    Callable, +    Tuple, +    File +}; + +enum class PyRefType +{ +    Borrowed, // We are not given ownership of the incoming PyObject. +              // We cannot safely hold it without calling Py_INCREF. +    Owned     // We have ownership of the incoming PyObject.  We should +              // not call Py_INCREF. +}; + +enum class PyInitialValue +{ +    Invalid, +    Empty +}; + +class PythonObject +{ +public: +    PythonObject() +        : m_py_obj(nullptr) +    { +    } + +    PythonObject(PyRefType type, PyObject *py_obj) +        : m_py_obj(nullptr) +    { +        Reset(type, py_obj); +    } + +    PythonObject(const PythonObject &rhs) +        : m_py_obj(nullptr) +    { +        Reset(rhs); +    } + +    virtual ~PythonObject() +    { +        Reset(); +    } + +    void +    Reset() +    { +        // Avoid calling the virtual method since it's not necessary +        // to actually validate the type of the PyObject if we're +        // just setting to null. +        if (Py_IsInitialized()) +            Py_XDECREF(m_py_obj); +        m_py_obj = nullptr; +    } + +    void +    Reset(const PythonObject &rhs) +    { +        // Avoid calling the virtual method if it's not necessary +        // to actually validate the type of the PyObject. +        if (!rhs.IsValid()) +            Reset(); +        else +            Reset(PyRefType::Borrowed, rhs.m_py_obj); +    } + +    // PythonObject is implicitly convertible to PyObject *, which will call the +    // wrong overload.  We want to explicitly disallow this, since a PyObject +    // *always* owns its reference.  Therefore the overload which takes a +    // PyRefType doesn't make sense, and the copy constructor should be used. +    void +    Reset(PyRefType type, const PythonObject &ref) = delete; + +    virtual void +    Reset(PyRefType type, PyObject *py_obj) +    { +        if (py_obj == m_py_obj) +            return; + +        if (Py_IsInitialized()) +            Py_XDECREF(m_py_obj); + +        m_py_obj = py_obj; + +        // If this is a borrowed reference, we need to convert it to +        // an owned reference by incrementing it.  If it is an owned +        // reference (for example the caller allocated it with PyDict_New() +        // then we must *not* increment it. +        if (Py_IsInitialized() && type == PyRefType::Borrowed) +            Py_XINCREF(m_py_obj); +    } +         +    void +    Dump () const +    { +        if (m_py_obj) +            _PyObject_Dump (m_py_obj); +        else +            puts ("NULL"); +    } +         +    void +    Dump (Stream &strm) const; + +    PyObject* +    get() const +    { +        return m_py_obj; +    } + +    PyObject* +    release() +    { +        PyObject *result = m_py_obj; +        m_py_obj = nullptr; +        return result; +    } + +    PythonObject & +    operator=(const PythonObject &other) +    { +        Reset(PyRefType::Borrowed, other.get()); +        return *this; +    } + +    PyObjectType +    GetObjectType() const; + +    PythonString +    Repr() const; + +    PythonString +    Str() const; + +    static PythonObject +    ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict); + +    template<typename T> +    static T +    ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict) +    { +        return ResolveNameWithDictionary(name, dict).AsType<T>(); +    } + +    PythonObject +    ResolveName(llvm::StringRef name) const; + +    template<typename T> +    T +    ResolveName(llvm::StringRef name) const +    { +        return ResolveName(name).AsType<T>(); +    } + +    bool +    HasAttribute(llvm::StringRef attribute) const; + +    PythonObject +    GetAttributeValue(llvm::StringRef attribute) const; + +    bool +    IsValid() const; + +    bool +    IsAllocated() const; + +    bool +    IsNone() const; + +    template<typename T> +    T AsType() const +    { +        if (!T::Check(m_py_obj)) +            return T(); +        return T(PyRefType::Borrowed, m_py_obj); +    } + +    StructuredData::ObjectSP +    CreateStructuredObject() const; + +protected: +    PyObject* m_py_obj; +}; + +class PythonString : public PythonObject +{ +public: +    PythonString(); +    explicit PythonString(llvm::StringRef string); +    explicit PythonString(const char *string); +    PythonString(PyRefType type, PyObject *o); +    PythonString(const PythonString &object); + +    ~PythonString() override; + +    static bool Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; + +    llvm::StringRef +    GetString() const; + +    size_t +    GetSize() const; + +    void SetString(llvm::StringRef string); + +    StructuredData::StringSP CreateStructuredString() const; +}; + +class PythonInteger : public PythonObject +{ +public: +    PythonInteger(); +    explicit PythonInteger(int64_t value); +    PythonInteger(PyRefType type, PyObject *o); +    PythonInteger(const PythonInteger &object); + +    ~PythonInteger() override; + +    static bool Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; + +    int64_t GetInteger() const; + +    void +    SetInteger (int64_t value); + +    StructuredData::IntegerSP CreateStructuredInteger() const; +}; + +class PythonList : public PythonObject +{ +public: +    PythonList() {} +    explicit PythonList(PyInitialValue value); +    explicit PythonList(int list_size); +    PythonList(PyRefType type, PyObject *o); +    PythonList(const PythonList &list); + +    ~PythonList() override; + +    static bool Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; + +    uint32_t GetSize() const; + +    PythonObject GetItemAtIndex(uint32_t index) const; + +    void SetItemAtIndex(uint32_t index, const PythonObject &object); + +    void AppendItem(const PythonObject &object); + +    StructuredData::ArraySP CreateStructuredArray() const; +}; + +class PythonTuple : public PythonObject +{ +public: +    PythonTuple() {} +    explicit PythonTuple(PyInitialValue value); +    explicit PythonTuple(int tuple_size); +    PythonTuple(PyRefType type, PyObject *o); +    PythonTuple(const PythonTuple &tuple); +    PythonTuple(std::initializer_list<PythonObject> objects); +    PythonTuple(std::initializer_list<PyObject*> objects); + +    ~PythonTuple() override; + +    static bool Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; + +    uint32_t GetSize() const; + +    PythonObject GetItemAtIndex(uint32_t index) const; + +    void SetItemAtIndex(uint32_t index, const PythonObject &object); + +    StructuredData::ArraySP CreateStructuredArray() const; +}; + +class PythonDictionary : public PythonObject +{ +public: +    PythonDictionary() {} +    explicit PythonDictionary(PyInitialValue value); +    PythonDictionary(PyRefType type, PyObject *o); +    PythonDictionary(const PythonDictionary &dict); + +    ~PythonDictionary() override; + +    static bool Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; + +    uint32_t GetSize() const; + +    PythonList GetKeys() const; + +    PythonObject GetItemForKey(const PythonObject &key) const; +    void SetItemForKey(const PythonObject &key, const PythonObject &value); + +    StructuredData::DictionarySP CreateStructuredDictionary() const; +}; + +class PythonModule : public PythonObject +{ +  public: +    PythonModule(); +    PythonModule(PyRefType type, PyObject *o); +    PythonModule(const PythonModule &dict); + +    ~PythonModule() override; + +    static bool Check(PyObject *py_obj); + +    static PythonModule +    BuiltinsModule(); + +    static PythonModule +    MainModule(); + +    static PythonModule +    AddModule(llvm::StringRef module); + +    static PythonModule +    ImportModule(llvm::StringRef module); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; + +    PythonDictionary GetDictionary() const; +}; + +class PythonCallable : public PythonObject +{ +public: +    struct ArgInfo { +        size_t count; +        bool has_varargs : 1; +        bool has_kwargs : 1; +    }; + +    PythonCallable(); +    PythonCallable(PyRefType type, PyObject *o); +    PythonCallable(const PythonCallable &dict); + +    ~PythonCallable() override; + +    static bool +    Check(PyObject *py_obj); + +    // Bring in the no-argument base class version +    using PythonObject::Reset; + +    void +    Reset(PyRefType type, PyObject *py_obj) override; + +    ArgInfo +    GetNumArguments() const; + +    PythonObject +    operator ()(); + +    PythonObject +    operator ()(std::initializer_list<PyObject*> args); + +    PythonObject +    operator ()(std::initializer_list<PythonObject> args); + +    template<typename Arg, typename... Args> +    PythonObject +    operator ()(const Arg &arg, Args... args) +    { +        return operator()({ arg, args... }); +    } +}; + + +class PythonFile : public PythonObject +{ +  public: +    PythonFile(); +    PythonFile(File &file, const char *mode); +    PythonFile(const char *path, const char *mode); +    PythonFile(PyRefType type, PyObject *o); + +    ~PythonFile() override; + +    static bool Check(PyObject *py_obj); + +    using PythonObject::Reset; + +    void Reset(PyRefType type, PyObject *py_obj) override; +    void Reset(File &file, const char *mode); + +    bool GetUnderlyingFile(File &file) const; +}; + +} // namespace lldb_private + +#endif + +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H | 
