diff --git a/lldb/include/lldb/Interpreter/PythonDataObjects.h b/lldb/include/lldb/Interpreter/PythonDataObjects.h new file mode 100644 index 000000000000..70c1a5fe4590 --- /dev/null +++ b/lldb/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/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index b69593bd738e..7607385a0e8d 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -162,6 +162,11 @@ class ProcessInstanceInfoMatch; 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/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 8ffc0cdc5001..75bcda706863 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/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 = ""; }; 94E367CC140C4EC4001C7A5A /* modify-python-lldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "modify-python-lldb.py"; sourceTree = ""; }; 94E367CE140C4EEA001C7A5A /* python-typemaps.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-typemaps.swig"; sourceTree = ""; }; + 94EA1D5A15E6C99B00D4171A /* PythonDataObjects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonDataObjects.h; path = include/lldb/Interpreter/PythonDataObjects.h; sourceTree = ""; }; + 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PythonDataObjects.cpp; path = source/Interpreter/PythonDataObjects.cpp; sourceTree = ""; }; 94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = ""; }; 94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultChild.h; path = include/lldb/Core/ValueObjectConstResultChild.h; sourceTree = ""; }; 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultChild.cpp; path = source/Core/ValueObjectConstResultChild.cpp; sourceTree = ""; }; @@ -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/lldb/source/Interpreter/PythonDataObjects.cpp b/lldb/source/Interpreter/PythonDataObjects.cpp new file mode 100644 index 000000000000..ba4ba23e8a2f --- /dev/null +++ b/lldb/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 +#else +#include +#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