[Lldb-commits] [lldb] r250530 - Convert SWIG typemap string operations to PythonObjects.
Zachary Turner via lldb-commits
lldb-commits at lists.llvm.org
Fri Oct 16 10:51:50 PDT 2015
Author: zturner
Date: Fri Oct 16 12:51:49 2015
New Revision: 250530
URL: http://llvm.org/viewvc/llvm-project?rev=250530&view=rev
Log:
Convert SWIG typemap string operations to PythonObjects.
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=250530&r1=250529&r2=250530&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-typemaps.swig (original)
+++ lldb/trunk/scripts/Python/python-typemaps.swig Fri Oct 16 12:51:49 2015
@@ -63,34 +63,38 @@
int i;
len = 0;
while ($1[len]) len++;
- lldb_private::PythonList list(len);
+ using namespace lldb_private;
+ PythonList list(len);
for (i = 0; i < len; i++)
- list.SetItemAtIndex(i, lldb_private::PythonString($1[i]));
+ list.SetItemAtIndex(i, PythonString($1[i]));
$result = list.release();
}
%typemap(in) char const ** {
/* Check if is a list */
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
- int i = 0;
- $1 = (char **) malloc((size+1) * sizeof(char*));
- for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (PyString_Check(o))
- $1[i] = PyString_AsString(o);
- else {
+ using namespace lldb_private;
+ if (PythonList::Check($input)) {
+ PythonList py_list(PyRefType::Borrowed, $input);
+ int size = py_list.GetSize();
+
+ $1 = (char**)malloc((size+1)*sizeof(char*));
+ for (int i = 0; i < size; i++) {
+ PythonObject o = py_list.GetItemAtIndex(i);
+ if (!PythonString::Check(o.get())) {
PyErr_SetString(PyExc_TypeError,"list must contain strings");
free($1);
- return NULL;
+ return nullptr;
}
+ auto py_str = o.AsType<PythonString>();
+ $1[i] = const_cast<char*>(py_str.GetString().data());
}
- $1[i] = 0;
+
+ $1[size] = 0;
} else if ($input == Py_None) {
- $1 = NULL;
+ $1 = nullptr;
} else {
PyErr_SetString(PyExc_TypeError,"not a list");
- return NULL;
+ return nullptr;
}
}
@@ -501,12 +505,13 @@
}
%typemap(in) FILE * {
+ using namespace lldb_private;
if ($input == Py_None)
- $1 = NULL;
+ $1 = nullptr;
else if (!lldb_private::PythonFile::Check($input)) {
int fd = PyObject_AsFileDescriptor($input);
- lldb_private::PythonString py_mode(lldb_private::PyRefType::Owned,
- PyObject_GetAttrString($input, "mode"));
+ PythonObject py_input(PyRefType::Borrowed, $input);
+ PythonString py_mode = py_input.GetAttributeValue("mode").AsType<PythonString>();
if (-1 != fd && py_mode.IsValid()) {
FILE *f;
@@ -521,10 +526,10 @@
}
else
{
- lldb_private::File file;
- lldb_private::PythonFile py_file(lldb_private::PyRefType::Borrowed, $input);
- if (!py_file.GetUnderlyingFile(file))
- return nullptr;
+ PythonFile py_file(PyRefType::Borrowed, $input);
+ File file;
+ if (!py_file.GetUnderlyingFile(file))
+ return nullptr;
$1 = file.GetStream();
}
@@ -543,26 +548,34 @@
else // if (flags & __SRW)
mode[i++] = 'a';
#endif
- lldb_private::File file($1, false);
- lldb_private::PythonFile py_file(file, mode);
+ using namespace lldb_private;
+ File file($1, false);
+ PythonFile py_file(file, mode);
$result = py_file.release();
}
%typemap(in) (const char* string, int len) {
+ using namespace lldb_private;
if ($input == Py_None)
{
$1 = NULL;
$2 = 0;
}
- else if (PyUnicode_Check($input))
- {
- $1 = PyString_AsString(PyUnicode_AsUTF8String($input));
- $2 = strlen($1);
- }
- else if (PyString_Check($input))
+ else if (PythonString::Check($input))
{
- $1 = PyString_AsString($input);
- $2 = PyString_Size($input);
+ PythonString py_str(PyRefType::Borrowed, $input);
+ llvm::StringRef str = py_str.GetString();
+ $1 = const_cast<char*>(str.data());
+ $2 = str.size();
+ // In Python 2, if $input is a PyUnicode object then this
+ // will trigger a Unicode -> String conversion, in which
+ // case the `PythonString` will now own the PyString. Thus
+ // if it goes out of scope, the data will be deleted. The
+ // only way to avoid this is to leak the Python object in
+ // that case. Note that if there was no conversion, then
+ // releasing the string will not leak anything, since we
+ // created this as a borrowed reference.
+ py_str.release();
}
else
{
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=250530&r1=250529&r2=250530&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp Fri Oct 16 12:51:49 2015
@@ -111,6 +111,20 @@ PythonObject::HasAttribute(llvm::StringR
return !!PyObject_HasAttr(m_py_obj, py_attr.get());
}
+PythonObject
+PythonObject::GetAttributeValue(llvm::StringRef attr) const
+{
+ if (!IsValid())
+ return PythonObject();
+
+ PythonString py_attr(attr);
+ if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
+ return PythonObject();
+
+ return PythonObject(PyRefType::Owned,
+ PyObject_GetAttr(m_py_obj, py_attr.get()));
+}
+
bool
PythonObject::IsNone() const
{
@@ -191,11 +205,13 @@ PythonString::Check(PyObject *py_obj)
if (!py_obj)
return false;
-#if PY_MAJOR_VERSION >= 3
- return PyUnicode_Check(py_obj);
-#else
- return PyString_Check(py_obj);
+ if (PyUnicode_Check(py_obj))
+ return true;
+#if PY_MAJOR_VERSION < 3
+ if (PyString_Check(py_obj))
+ return true;
#endif
+ return false;
}
void
@@ -210,7 +226,13 @@ PythonString::Reset(PyRefType type, PyOb
PythonObject::Reset();
return;
}
-
+#if PY_MAJOR_VERSION < 3
+ // In Python 2, Don't store PyUnicode objects directly, because we need
+ // access to their underlying character buffers which Python 2 doesn't
+ // provide.
+ if (PyUnicode_Check(py_obj))
+ result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
+#endif
// Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
// back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
@@ -271,6 +293,12 @@ PythonString::CreateStructuredString() c
// PythonInteger
//----------------------------------------------------------------------
+PythonInteger::PythonInteger()
+ : PythonObject()
+{
+
+}
+
PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
: PythonObject()
{
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=250530&r1=250529&r2=250530&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h Fri Oct 16 12:51:49 2015
@@ -201,6 +201,9 @@ public:
bool
HasAttribute(llvm::StringRef attribute) const;
+ PythonObject
+ GetAttributeValue(llvm::StringRef attribute) const;
+
bool
IsValid() const;
@@ -210,6 +213,14 @@ public:
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:
Modified: lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp?rev=250530&r1=250529&r2=250530&view=diff
==============================================================================
--- lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp (original)
+++ lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp Fri Oct 16 12:51:49 2015
@@ -382,3 +382,14 @@ TEST_F(PythonDataObjectsTest, TestPython
PythonFile py_file(file, "r");
EXPECT_TRUE(PythonFile::Check(py_file.get()));
}
+
+TEST_F(PythonDataObjectsTest, TestObjectAttributes)
+{
+ PythonInteger py_int(42);
+ EXPECT_TRUE(py_int.HasAttribute("numerator"));
+ EXPECT_FALSE(py_int.HasAttribute("this_should_not_exist"));
+
+ PythonInteger numerator_attr = py_int.GetAttributeValue("numerator").AsType<PythonInteger>();
+ EXPECT_TRUE(numerator_attr.IsAllocated());
+ EXPECT_EQ(42, numerator_attr.GetInteger());
+}
\ No newline at end of file
More information about the lldb-commits
mailing list