A first version of a bunch of classes that wrap commonly used Python objects in a ref-counting and type-safe C++ API
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@162481 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Interpreter/PythonDataObjects.h b/include/lldb/Interpreter/PythonDataObjects.h
new file mode 100644
index 0000000..70c1a5f
--- /dev/null
+++ b/include/lldb/Interpreter/PythonDataObjects.h
@@ -0,0 +1,214 @@
+//===-- 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 liblldb_PythonDataObjects_h_
+#define liblldb_PythonDataObjects_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-defines.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+ class PythonRefCountedObject
+ {
+ public:
+ PythonRefCountedObject (PyObject* obj) : m_object(obj)
+ {
+ Py_XINCREF(m_object);
+ }
+
+ ~PythonRefCountedObject ()
+ {
+ Py_XDECREF(m_object);
+ }
+
+ void
+ Reset (PyObject* object = NULL)
+ {
+ Py_XDECREF(m_object);
+ m_object = object;
+ Py_XINCREF(m_object);
+ }
+
+ PyObject*
+ GetPyhonObject ()
+ {
+ return m_object;
+ }
+
+ operator bool ()
+ {
+ return m_object != NULL;
+ }
+
+ private:
+ PyObject* m_object;
+ };
+
+ class PythonDataString
+ {
+ public:
+
+ PythonDataString (PyObject* object);
+ PythonDataString (const char* string);
+ ~PythonDataString ();
+
+ const char*
+ GetString();
+
+ void
+ SetString (const char* string);
+
+ operator bool ()
+ {
+ return m_object.operator bool();
+ }
+
+ PyObject*
+ GetPythonObject() { return m_object.GetPyhonObject(); }
+ private:
+ PythonRefCountedObject m_object;
+ };
+
+ class PythonDataInteger
+ {
+ public:
+
+ PythonDataInteger (PyObject* object);
+ PythonDataInteger (int64_t value);
+ ~PythonDataInteger ();
+
+ int64_t
+ GetInteger();
+
+ void
+ SetInteger (int64_t value);
+
+ operator bool ()
+ {
+ return m_object.operator bool();
+ }
+
+ PyObject*
+ GetPythonObject() { return m_object.GetPyhonObject(); }
+ private:
+ PythonRefCountedObject m_object;
+ };
+
+ class PythonDataArray
+ {
+ public:
+
+ PythonDataArray (uint32_t count);
+ PythonDataArray (PyObject* object);
+ ~PythonDataArray ();
+
+ uint32_t
+ GetSize();
+
+ PythonDataObject*
+ GetItemAtIndex (uint32_t index);
+
+ void
+ SetItemAtIndex (uint32_t index, PythonDataObject* object);
+
+ void
+ AppendItem (PythonDataObject* object);
+
+ operator bool ()
+ {
+ return m_object.operator bool();
+ }
+
+ PyObject*
+ GetPythonObject() { return m_object.GetPyhonObject(); }
+ private:
+ PythonRefCountedObject m_object;
+ };
+
+ class PythonDataDictionary
+ {
+ public:
+
+ PythonDataDictionary ();
+ PythonDataDictionary (PyObject* object);
+ ~PythonDataDictionary ();
+
+ uint32_t GetSize();
+
+ PythonDataObject*
+ GetItemForKey (PythonDataString* key);
+
+ typedef bool (*DictionaryIteratorCallback)(PythonDataString* key, PythonDataDictionary* dict);
+
+ PythonDataArray*
+ GetKeys ();
+
+ PythonDataString*
+ GetKeyAtPosition (uint32_t pos);
+
+ PythonDataObject*
+ GetValueAtPosition (uint32_t pos);
+
+ void
+ SetItemForKey (PythonDataString* key, PythonDataObject* value);
+
+ operator bool ()
+ {
+ return m_object.operator bool();
+ }
+
+ PyObject*
+ GetPythonObject() { return m_object.GetPyhonObject(); }
+ private:
+ PythonRefCountedObject m_object;
+ };
+
+ class PythonDataObject
+ {
+ public:
+
+ PythonDataObject (PyObject* object);
+
+ ~PythonDataObject ();
+
+ PythonDataString*
+ GetStringObject ();
+
+ PythonDataInteger*
+ GetIntegerObject ();
+
+ PythonDataArray*
+ GetArrayObject();
+
+ PythonDataDictionary*
+ GetDictionaryObject();
+
+ operator bool ()
+ {
+ return m_object.operator bool();
+ }
+
+ PyObject*
+ GetPythonObject() { return m_object.GetPyhonObject(); }
+
+ private:
+ PythonRefCountedObject m_object;
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_PythonDataObjects_h_
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index b69593b..7607385 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -162,6 +162,11 @@
class ProcessLaunchInfo;
class Property;
struct PropertyDefinition;
+class PythonDataArray;
+class PythonDataDictionary;
+class PythonDataInteger;
+class PythonDataObject;
+class PythonDataString;
class RegisterContext;
class RegisterLocation;
class RegisterLocationList;
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index 8ffc0cd..75bcda7 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -528,6 +528,7 @@
9475C18F14E5F858001BFC6D /* SBTypeNameSpecifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18C14E5F826001BFC6D /* SBTypeNameSpecifier.h */; settings = {ATTRIBUTES = (Public, ); }; };
949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; };
94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
+ 94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */; };
94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; };
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; };
@@ -1534,6 +1535,8 @@
94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectSyntheticFilter.cpp; path = source/Core/ValueObjectSyntheticFilter.cpp; sourceTree = "<group>"; };
94E367CC140C4EC4001C7A5A /* modify-python-lldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "modify-python-lldb.py"; sourceTree = "<group>"; };
94E367CE140C4EEA001C7A5A /* python-typemaps.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-typemaps.swig"; sourceTree = "<group>"; };
+ 94EA1D5A15E6C99B00D4171A /* PythonDataObjects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonDataObjects.h; path = include/lldb/Interpreter/PythonDataObjects.h; sourceTree = "<group>"; };
+ 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PythonDataObjects.cpp; path = source/Interpreter/PythonDataObjects.cpp; sourceTree = "<group>"; };
94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = "<group>"; };
94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultChild.h; path = include/lldb/Core/ValueObjectConstResultChild.h; sourceTree = "<group>"; };
94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultChild.cpp; path = source/Core/ValueObjectConstResultChild.cpp; sourceTree = "<group>"; };
@@ -2907,6 +2910,8 @@
B2462246141AD37D00F3D409 /* OptionGroupWatchpoint.cpp */,
26ACEC2715E077AE00E94760 /* Property.h */,
2640E19E15DC78FD00F23B50 /* Property.cpp */,
+ 94EA1D5A15E6C99B00D4171A /* PythonDataObjects.h */,
+ 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */,
26BC7DE510F1B7F900F91463 /* ScriptInterpreter.h */,
9A82010B10FFB49800182560 /* ScriptInterpreter.cpp */,
9A2771FB1135A35C00E6ADB6 /* ScriptInterpreterNone.h */,
@@ -4100,6 +4105,7 @@
2640E19F15DC78FD00F23B50 /* Property.cpp in Sources */,
26491E3E15E1DB9F00CBFFC2 /* OptionValueRegex.cpp in Sources */,
2697A39315E404B1003E682C /* OptionValueArch.cpp in Sources */,
+ 94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/source/Interpreter/PythonDataObjects.cpp b/source/Interpreter/PythonDataObjects.cpp
new file mode 100644
index 0000000..ba4ba23
--- /dev/null
+++ b/source/Interpreter/PythonDataObjects.cpp
@@ -0,0 +1,234 @@
+//===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// In order to guarantee correct working with Python, Python.h *MUST* be
+// the *FIRST* header file included here.
+#ifdef LLDB_DISABLE_PYTHON
+
+// Python is disabled in this build
+
+#else
+
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+#include "PythonDataObjects.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+PythonDataObject::PythonDataObject (PyObject* object) : m_object(object)
+{
+}
+
+PythonDataString*
+PythonDataObject::GetStringObject ()
+{
+ return new PythonDataString(GetPythonObject());
+}
+
+PythonDataInteger*
+PythonDataObject::GetIntegerObject ()
+{
+ return new PythonDataInteger(GetPythonObject());
+}
+
+PythonDataArray*
+PythonDataObject::GetArrayObject()
+{
+ return new PythonDataArray(GetPythonObject());
+}
+
+PythonDataDictionary*
+PythonDataObject::GetDictionaryObject()
+{
+ return new PythonDataDictionary(GetPythonObject());
+}
+
+PythonDataInteger::PythonDataInteger (PyObject* object) : m_object(object)
+{
+ if (!PyInt_Check(GetPythonObject()))
+ m_object.Reset();
+}
+
+PythonDataInteger::~PythonDataInteger ()
+{
+}
+
+PythonDataInteger::PythonDataInteger (int64_t value) : m_object(PyInt_FromLong(value))
+{
+}
+
+int64_t
+PythonDataInteger::GetInteger()
+{
+ if (m_object)
+ return PyInt_AsLong(GetPythonObject());
+ else
+ return UINT64_MAX;
+}
+
+void
+PythonDataInteger::SetInteger (int64_t value)
+{
+ m_object.Reset(PyInt_FromLong(value));
+}
+
+PythonDataString::PythonDataString (PyObject* object) : m_object(object)
+{
+ if (!PyString_Check(GetPythonObject()))
+ m_object.Reset();}
+
+PythonDataString::PythonDataString (const char* string) : m_object(PyString_FromString(string))
+{
+}
+
+PythonDataString::~PythonDataString ()
+{
+}
+
+const char*
+PythonDataString::GetString()
+{
+ if (m_object)
+ return PyString_AsString(GetPythonObject());
+ return NULL;
+}
+
+void
+PythonDataString::SetString (const char* string)
+{
+ m_object.Reset(PyString_FromString(string));
+}
+
+PythonDataArray::PythonDataArray (uint32_t count) : m_object(PyList_New(count))
+{
+}
+
+PythonDataArray::PythonDataArray (PyObject* object) : m_object(object)
+{
+ if (!PyList_Check(GetPythonObject()))
+ m_object.Reset();
+}
+
+PythonDataArray::~PythonDataArray ()
+{
+}
+
+uint32_t
+PythonDataArray::GetSize()
+{
+ if (m_object)
+ return PyList_GET_SIZE(GetPythonObject());
+ return 0;
+}
+
+PythonDataObject*
+PythonDataArray::GetItemAtIndex (uint32_t index)
+{
+ if (m_object)
+ return new PythonDataObject(PyList_GetItem(GetPythonObject(), index));
+ return NULL;
+}
+
+void
+PythonDataArray::SetItemAtIndex (uint32_t index, PythonDataObject* object)
+{
+ if (m_object && object && *object)
+ PyList_SetItem(GetPythonObject(), index, object->GetPythonObject());
+}
+
+void
+PythonDataArray::AppendItem (PythonDataObject* object)
+{
+ if (m_object && object && *object)
+ PyList_Append(GetPythonObject(), object->GetPythonObject());
+}
+
+PythonDataDictionary::PythonDataDictionary () : m_object(PyDict_New())
+{
+}
+
+PythonDataDictionary::PythonDataDictionary (PyObject* object) : m_object(object)
+{
+ if (!PyDict_Check(GetPythonObject()))
+ m_object.Reset();
+}
+
+PythonDataDictionary::~PythonDataDictionary ()
+{
+}
+
+uint32_t
+PythonDataDictionary::GetSize()
+{
+ if (m_object)
+ return PyDict_Size(GetPythonObject());
+ return 0;
+}
+
+PythonDataObject*
+PythonDataDictionary::GetItemForKey (PythonDataString* key)
+{
+ if (m_object && key && *key)
+ return new PythonDataObject(PyDict_GetItem(GetPythonObject(), key->GetPythonObject()));
+ return NULL;
+}
+
+PythonDataArray*
+PythonDataDictionary::GetKeys ()
+{
+ if (m_object)
+ return new PythonDataArray(PyDict_Keys(GetPythonObject()));
+ return NULL;
+}
+
+PythonDataString*
+PythonDataDictionary::GetKeyAtPosition (uint32_t pos)
+{
+ PyObject *key, *value;
+ Py_ssize_t pos_iter = 0;
+
+ if (!m_object)
+ return NULL;
+
+ while (PyDict_Next(GetPythonObject(), &pos_iter, &key, &value)) {
+ if (pos-- == 0)
+ return new PythonDataString(key);
+ }
+ return NULL;
+}
+
+PythonDataObject*
+PythonDataDictionary::GetValueAtPosition (uint32_t pos)
+{
+ PyObject *key, *value;
+ Py_ssize_t pos_iter = 0;
+
+ if (!m_object)
+ return NULL;
+
+ while (PyDict_Next(GetPythonObject(), &pos_iter, &key, &value)) {
+ if (pos-- == 0)
+ return new PythonDataObject(value);
+ }
+ return NULL;
+}
+
+void
+PythonDataDictionary::SetItemForKey (PythonDataString* key, PythonDataObject* value)
+{
+ if (m_object && key && value && *key && *value)
+ PyDict_SetItem(GetPythonObject(), key->GetPythonObject(), value->GetPythonObject());
+}
+
+#endif