[Lldb-commits] [lldb] r258741 - Fix swig typemap for SBEvent.

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Mon Jan 25 15:21:09 PST 2016


Author: zturner
Date: Mon Jan 25 17:21:09 2016
New Revision: 258741

URL: http://llvm.org/viewvc/llvm-project?rev=258741&view=rev
Log:
Fix swig typemap for SBEvent.

This needs to be able to handle bytes, strings, and bytearray objects.
In Python 2 this was easy because bytes and strings are the same thing,
but in Python 3 the 2 cases need to be handled separately.  So as not
to mix raw Python C API code with PythonDataObjects code, I've also
introduced a PythonByteArray class to PythonDataObjects to make the
paradigm used here consistent.

Modified:
    lldb/trunk/scripts/Python/python-typemaps.swig
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
    lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Modified: lldb/trunk/scripts/Python/python-typemaps.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-typemaps.swig?rev=258741&r1=258740&r2=258741&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-typemaps.swig (original)
+++ lldb/trunk/scripts/Python/python-typemaps.swig Mon Jan 25 17:21:09 2016
@@ -113,13 +113,21 @@
 // typemap for an outgoing buffer
 // See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
 %typemap(in) (const char *cstr, uint32_t cstr_len) {
-   if (PyString_Check($input)) {
-      $1 = (char *) PyString_AsString($input);
-      $2 = PyString_Size($input);
+   using namespace lldb_private;
+   if (PythonString::Check($input)) {
+      PythonString str(PyRefType::Borrowed, $input);
+      $1 = (char*)str.GetString().data();
+      $2 = str.GetSize();
    }
-   else if(PyByteArray_Check($input)) {
-      $1 = (char *) PyByteArray_AsString($input);
-      $2 = PyByteArray_Size($input);
+   else if(PythonByteArray::Check($input)) {
+      PythonByteArray bytearray(PyRefType::Borrowed, $input);
+      $1 = (char*)bytearray.GetBytes().data();
+      $2 = bytearray.GetSize();
+   }
+   else if (PythonBytes::Check($input)) {
+      PythonBytes bytes(PyRefType::Borrowed, $input);
+      $1 = (char*)bytes.GetBytes().data();
+      $2 = bytes.GetSize();
    }
    else {
       PyErr_SetString(PyExc_ValueError, "Expecting a string");

Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp?rev=258741&r1=258740&r2=258741&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp Mon Jan 25 17:21:09 2016
@@ -83,6 +83,8 @@ PythonObject::GetObjectType() const
     if (PythonBytes::Check(m_py_obj))
         return PyObjectType::Bytes;
 #endif
+    if (PythonByteArray::Check(m_py_obj))
+        return PyObjectType::ByteArray;
     if (PythonInteger::Check(m_py_obj))
         return PyObjectType::Integer;
     if (PythonFile::Check(m_py_obj))
@@ -218,6 +220,8 @@ PythonObject::CreateStructuredObject() c
             return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
         case PyObjectType::Bytes:
             return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
+        case PyObjectType::ByteArray:
+            return PythonByteArray(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
         case PyObjectType::None:
             return StructuredData::ObjectSP();
         default:
@@ -323,6 +327,87 @@ PythonBytes::CreateStructuredString() co
     return result;
 }
 
+PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) : PythonByteArray(bytes.data(), bytes.size())
+{
+}
+
+PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length)
+{
+    const char *str = reinterpret_cast<const char *>(bytes);
+    Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
+}
+
+PythonByteArray::PythonByteArray(PyRefType type, PyObject *o)
+{
+    Reset(type, o);
+}
+
+PythonByteArray::PythonByteArray(const PythonBytes &object) : PythonObject(object)
+{
+}
+
+PythonByteArray::~PythonByteArray()
+{
+}
+
+bool
+PythonByteArray::Check(PyObject *py_obj)
+{
+    if (!py_obj)
+        return false;
+    if (PyByteArray_Check(py_obj))
+        return true;
+    return false;
+}
+
+void
+PythonByteArray::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 (!PythonByteArray::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>
+PythonByteArray::GetBytes() const
+{
+    if (!IsValid())
+        return llvm::ArrayRef<uint8_t>();
+
+    char *c = PyByteArray_AsString(m_py_obj);
+    size_t size = GetSize();
+    return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
+}
+
+size_t
+PythonByteArray::GetSize() const
+{
+    if (!IsValid())
+        return 0;
+
+    return PyByteArray_Size(m_py_obj);
+}
+
+StructuredData::StringSP
+PythonByteArray::CreateStructuredString() const
+{
+    StructuredData::StringSP result(new StructuredData::String);
+    llvm::ArrayRef<uint8_t> bytes = GetBytes();
+    const char *str = reinterpret_cast<const char *>(bytes.data());
+    result->SetValue(std::string(str, bytes.size()));
+    return result;
+}
+
 //----------------------------------------------------------------------
 // PythonString
 //----------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h?rev=258741&r1=258740&r2=258741&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h Mon Jan 25 17:21:09 2016
@@ -75,6 +75,7 @@ enum class PyObjectType
     List,
     String,
     Bytes,
+    ByteArray,
     Module,
     Callable,
     Tuple,
@@ -273,6 +274,39 @@ public:
 
     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 PythonByteArray : public PythonObject
+{
+public:
+    PythonByteArray();
+    explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
+    PythonByteArray(const uint8_t *bytes, size_t length);
+    PythonByteArray(PyRefType type, PyObject *o);
+    PythonByteArray(const PythonBytes &object);
+
+    ~PythonByteArray() override;
+
+    static bool
+    Check(PyObject *py_obj);
 
     // Bring in the no-argument base class version
     using PythonObject::Reset;

Modified: lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp?rev=258741&r1=258740&r2=258741&view=diff
==============================================================================
--- lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp (original)
+++ lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp Mon Jan 25 17:21:09 2016
@@ -224,6 +224,20 @@ TEST_F(PythonDataObjectsTest, TestPython
     EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size()));
 }
 
+TEST_F(PythonDataObjectsTest, TestPythonByteArray)
+{
+    static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray";
+    llvm::StringRef orig_bytes(test_bytes);
+    PyObject *py_bytes = PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size());
+    EXPECT_TRUE(PythonByteArray::Check(py_bytes));
+    PythonByteArray python_bytes(PyRefType::Owned, py_bytes);
+    EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType());
+
+    llvm::ArrayRef<uint8_t> after_bytes = python_bytes.GetBytes();
+    EXPECT_EQ(after_bytes.size(), orig_bytes.size());
+    EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size()));
+}
+
 TEST_F(PythonDataObjectsTest, TestPythonString)
 {
     // Test that strings behave correctly when wrapped by a PythonString.




More information about the lldb-commits mailing list