xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision 60c24f70fe1f7f37ae34e0ff47cd60db39094a88)
1 //===-- PythonDataObjects.h----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
11 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
12 
13 // C Includes
14 // C++ Includes
15 
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/lldb-defines.h"
19 #include "lldb/Core/ConstString.h"
20 #include "lldb/Core/StructuredData.h"
21 #include "lldb/Core/Flags.h"
22 #include "lldb/Interpreter/OptionValue.h"
23 
24 namespace lldb_private {
25 class PythonString;
26 class PythonList;
27 class PythonDictionary;
28 class PythonInteger;
29 
30 class StructuredPythonObject : public StructuredData::Generic
31 {
32   public:
33     StructuredPythonObject()
34         : StructuredData::Generic()
35     {
36     }
37 
38     StructuredPythonObject(void *obj)
39         : StructuredData::Generic(obj)
40     {
41         Py_XINCREF(GetValue());
42     }
43 
44     virtual ~StructuredPythonObject()
45     {
46         if (Py_IsInitialized())
47             Py_XDECREF(GetValue());
48         SetValue(nullptr);
49     }
50 
51     bool
52     IsValid() const override
53     {
54         return GetValue() && GetValue() != Py_None;
55     }
56 
57     void Dump(Stream &s) const override;
58 
59   private:
60     DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
61 };
62 
63 enum class PyObjectType
64 {
65     Unknown,
66     None,
67     Integer,
68     Dictionary,
69     List,
70     String
71 };
72 
73 enum class PyRefType
74 {
75     Borrowed, // We are not given ownership of the incoming PyObject.
76               // We cannot safely hold it without calling Py_INCREF.
77     Owned     // We have ownership of the incoming PyObject.  We should
78               // not call Py_INCREF.
79 };
80 
81 enum class PyInitialValue
82 {
83     Invalid,
84     Empty
85 };
86 
87 class PythonObject
88 {
89 public:
90     PythonObject()
91         : m_py_obj(nullptr)
92     {
93     }
94 
95     PythonObject(PyRefType type, PyObject *py_obj)
96         : m_py_obj(nullptr)
97     {
98         Reset(type, py_obj);
99     }
100 
101     PythonObject(const PythonObject &rhs)
102         : m_py_obj(nullptr)
103     {
104         Reset(rhs);
105     }
106 
107     virtual ~PythonObject() { Reset(); }
108 
109     void
110     Reset()
111     {
112         // Avoid calling the virtual method since it's not necessary
113         // to actually validate the type of the PyObject if we're
114         // just setting to null.
115         if (Py_IsInitialized())
116             Py_XDECREF(m_py_obj);
117         m_py_obj = nullptr;
118     }
119 
120     void
121     Reset(const PythonObject &rhs)
122     {
123         // Avoid calling the virtual method if it's not necessary
124         // to actually validate the type of the PyObject.
125         if (!rhs.IsValid())
126             Reset();
127         else
128             Reset(PyRefType::Borrowed, rhs.m_py_obj);
129     }
130 
131     // PythonObject is implicitly convertible to PyObject *, which will call the
132     // wrong overload.  We want to explicitly disallow this, since a PyObject
133     // *always* owns its reference.  Therefore the overload which takes a
134     // PyRefType doesn't make sense, and the copy constructor should be used.
135     void
136     Reset(PyRefType type, const PythonObject &ref) = delete;
137 
138     virtual void
139     Reset(PyRefType type, PyObject *py_obj)
140     {
141         if (py_obj == m_py_obj)
142             return;
143 
144         if (Py_IsInitialized())
145             Py_XDECREF(m_py_obj);
146 
147         m_py_obj = py_obj;
148 
149         // If this is a borrowed reference, we need to convert it to
150         // an owned reference by incrementing it.  If it is an owned
151         // reference (for example the caller allocated it with PyDict_New()
152         // then we must *not* increment it.
153         if (Py_IsInitialized() && type == PyRefType::Borrowed)
154             Py_XINCREF(m_py_obj);
155     }
156 
157     void
158     Dump () const
159     {
160         if (m_py_obj)
161             _PyObject_Dump (m_py_obj);
162         else
163             puts ("NULL");
164     }
165 
166     void
167     Dump (Stream &strm) const;
168 
169     PyObject*
170     get() const
171     {
172         return m_py_obj;
173     }
174 
175     PyObject*
176     release()
177     {
178         PyObject *result = m_py_obj;
179         m_py_obj = nullptr;
180         return result;
181     }
182 
183     PyObjectType
184     GetObjectType() const;
185 
186     PythonString
187     Repr ();
188 
189     PythonString
190     Str ();
191 
192     PythonObject &
193     operator=(const PythonObject &other)
194     {
195         Reset(PyRefType::Borrowed, other.get());
196         return *this;
197     }
198 
199     bool
200     IsValid() const;
201 
202     bool
203     IsAllocated() const;
204 
205     bool
206     IsNone() const;
207 
208     StructuredData::ObjectSP CreateStructuredObject() const;
209 
210 protected:
211     PyObject* m_py_obj;
212 };
213 
214 class PythonString : public PythonObject
215 {
216 public:
217     PythonString();
218     PythonString(PyRefType type, PyObject *o);
219     PythonString(const PythonString &object);
220     explicit PythonString(llvm::StringRef string);
221     explicit PythonString(const char *string);
222     ~PythonString() override;
223 
224     static bool Check(PyObject *py_obj);
225 
226     // Bring in the no-argument base class version
227     using PythonObject::Reset;
228 
229     void Reset(PyRefType type, PyObject *py_obj) override;
230 
231     llvm::StringRef
232     GetString() const;
233 
234     size_t
235     GetSize() const;
236 
237     void SetString(llvm::StringRef string);
238 
239     StructuredData::StringSP CreateStructuredString() const;
240 };
241 
242 class PythonInteger : public PythonObject
243 {
244 public:
245     PythonInteger();
246     PythonInteger(PyRefType type, PyObject *o);
247     PythonInteger(const PythonInteger &object);
248     explicit PythonInteger(int64_t value);
249     ~PythonInteger() override;
250 
251     static bool Check(PyObject *py_obj);
252 
253     // Bring in the no-argument base class version
254     using PythonObject::Reset;
255 
256     void Reset(PyRefType type, PyObject *py_obj) override;
257 
258     int64_t GetInteger() const;
259 
260     void
261     SetInteger (int64_t value);
262 
263     StructuredData::IntegerSP CreateStructuredInteger() const;
264 };
265 
266 class PythonList : public PythonObject
267 {
268 public:
269     PythonList(PyInitialValue value);
270     PythonList(PyRefType type, PyObject *o);
271     PythonList(const PythonList &list);
272     ~PythonList() override;
273 
274     static bool Check(PyObject *py_obj);
275 
276     // Bring in the no-argument base class version
277     using PythonObject::Reset;
278 
279     void Reset(PyRefType type, PyObject *py_obj) override;
280 
281     uint32_t GetSize() const;
282 
283     PythonObject GetItemAtIndex(uint32_t index) const;
284 
285     void SetItemAtIndex(uint32_t index, const PythonObject &object);
286 
287     void AppendItem(const PythonObject &object);
288 
289     StructuredData::ArraySP CreateStructuredArray() const;
290 };
291 
292 class PythonDictionary : public PythonObject
293 {
294 public:
295     PythonDictionary(PyInitialValue value);
296     PythonDictionary(PyRefType type, PyObject *o);
297     PythonDictionary(const PythonDictionary &dict);
298     ~PythonDictionary() override;
299 
300     static bool Check(PyObject *py_obj);
301 
302     // Bring in the no-argument base class version
303     using PythonObject::Reset;
304 
305     void Reset(PyRefType type, PyObject *py_obj) override;
306 
307     uint32_t GetSize() const;
308 
309     PythonList GetKeys() const;
310 
311     PythonObject GetItemForKey(const PythonObject &key) const;
312     void SetItemForKey(const PythonObject &key, const PythonObject &value);
313 
314     StructuredData::DictionarySP CreateStructuredDictionary() const;
315 };
316 } // namespace lldb_private
317 
318 #endif  // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
319