diff options
Diffstat (limited to 'source/Plugins/ScriptInterpreter/Python')
3 files changed, 144 insertions, 3 deletions
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 3107677..23bacc9 100644 --- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -77,6 +77,10 @@ PythonObject::GetObjectType() const return PyObjectType::Dictionary; if (PythonString::Check(m_py_obj)) return PyObjectType::String; +#if PY_MAJOR_VERSION >= 3 + if (PythonBytes::Check(m_py_obj)) + return PyObjectType::Bytes; +#endif if (PythonInteger::Check(m_py_obj)) return PyObjectType::Integer; if (PythonFile::Check(m_py_obj)) @@ -210,6 +214,8 @@ PythonObject::CreateStructuredObject() const return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); case PyObjectType::String: return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); + case PyObjectType::Bytes: + return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString(); case PyObjectType::None: return StructuredData::ObjectSP(); default: @@ -220,6 +226,104 @@ PythonObject::CreateStructuredObject() const //---------------------------------------------------------------------- // PythonString //---------------------------------------------------------------------- +PythonBytes::PythonBytes() : PythonObject() +{ +} + +PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() +{ + SetBytes(bytes); +} + +PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() +{ + SetBytes(llvm::ArrayRef<uint8_t>(bytes, length)); +} + +PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() +{ + Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string +} + +PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) +{ +} + +PythonBytes::~PythonBytes() +{ +} + +bool +PythonBytes::Check(PyObject *py_obj) +{ + if (!py_obj) + return false; + if (PyBytes_Check(py_obj)) + return true; + return false; +} + +void +PythonBytes::Reset(PyRefType type, PyObject *py_obj) +{ + // Grab the desired reference type so that if we end up rejecting + // `py_obj` it still gets decremented if necessary. + PythonObject result(type, py_obj); + + if (!PythonBytes::Check(py_obj)) + { + PythonObject::Reset(); + return; + } + + // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls + // back into the virtual implementation. + PythonObject::Reset(PyRefType::Borrowed, result.get()); +} + +llvm::ArrayRef<uint8_t> +PythonBytes::GetBytes() const +{ + if (!IsValid()) + return llvm::ArrayRef<uint8_t>(); + + Py_ssize_t size; + char *c; + + PyBytes_AsStringAndSize(m_py_obj, &c, &size); + return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size); +} + +size_t +PythonBytes::GetSize() const +{ + if (!IsValid()) + return 0; + return PyBytes_Size(m_py_obj); +} + +void +PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) +{ + const char *data = reinterpret_cast<const char *>(bytes.data()); + PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size()); + PythonObject::Reset(PyRefType::Owned, py_bytes); +} + +StructuredData::StringSP +PythonBytes::CreateStructuredString() const +{ + StructuredData::StringSP result(new StructuredData::String); + Py_ssize_t size; + char *c; + PyBytes_AsStringAndSize(m_py_obj, &c, &size); + result->SetValue(std::string(c, size)); + return result; +} + +//---------------------------------------------------------------------- +// PythonString +//---------------------------------------------------------------------- PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index c9d17c0..06264b6 100644 --- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -23,8 +23,11 @@ #include "lldb/Host/File.h" #include "lldb/Interpreter/OptionValue.h" +#include "llvm/ADT/ArrayRef.h" + namespace lldb_private { +class PythonBytes; class PythonString; class PythonList; class PythonDictionary; @@ -71,6 +74,7 @@ enum class PyObjectType Dictionary, List, String, + Bytes, Module, Callable, Tuple, @@ -256,6 +260,39 @@ protected: PyObject* m_py_obj; }; +class PythonBytes : public PythonObject +{ +public: + PythonBytes(); + explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); + PythonBytes(const uint8_t *bytes, size_t length); + PythonBytes(PyRefType type, PyObject *o); + PythonBytes(const PythonBytes &object); + + ~PythonBytes() 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::ArrayRef<uint8_t> + GetBytes() const; + + size_t + GetSize() const; + + void + SetBytes(llvm::ArrayRef<uint8_t> stringbytes); + + StructuredData::StringSP + CreateStructuredString() const; +}; + class PythonString : public PythonObject { public: diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index b1dd34b..19ad86d 100644 --- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1692,10 +1692,10 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP o PyErr_Clear(); } - assert(PythonString::Check(py_return.get()) && "get_register_data returned unknown object type!"); + assert(PythonBytes::Check(py_return.get()) && "get_register_data returned unknown object type!"); - PythonString result_string(PyRefType::Borrowed, py_return.get()); - return result_string.CreateStructuredString(); + PythonBytes result(PyRefType::Borrowed, py_return.get()); + return result.CreateStructuredString(); } StructuredData::DictionarySP |