diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
commit | 66b75430a93929d6fc6ed63db14ca28e3ad5b1f6 (patch) | |
tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h | |
parent | 23814158e5384f73c6fa951b66d5f807f9c24a2b (diff) | |
download | FreeBSD-src-66b75430a93929d6fc6ed63db14ca28e3ad5b1f6.zip FreeBSD-src-66b75430a93929d6fc6ed63db14ca28e3ad5b1f6.tar.gz |
Vendor import of stripped lldb trunk r256633:
https://llvm.org/svn/llvm-project/lldb/trunk@256633
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 0000000..c9d17c0 --- /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 |