xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision a140514733e0ab0310688c727b70ba3e2a4a8ddc)
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 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/lldb-defines.h"
18 #include "lldb/Core/ConstString.h"
19 #include "lldb/Core/StructuredData.h"
20 #include "lldb/Core/Flags.h"
21 #include "lldb/Host/File.h"
22 #include "lldb/Interpreter/OptionValue.h"
23 
24 namespace lldb_private {
25 
26 class PythonString;
27 class PythonList;
28 class PythonDictionary;
29 class PythonInteger;
30 
31 class StructuredPythonObject : public StructuredData::Generic
32 {
33 public:
34     StructuredPythonObject()
35         : StructuredData::Generic()
36     {
37     }
38 
39     StructuredPythonObject(void *obj)
40         : StructuredData::Generic(obj)
41     {
42         Py_XINCREF(GetValue());
43     }
44 
45     ~StructuredPythonObject() override
46     {
47         if (Py_IsInitialized())
48             Py_XDECREF(GetValue());
49         SetValue(nullptr);
50     }
51 
52     bool
53     IsValid() const override
54     {
55         return GetValue() && GetValue() != Py_None;
56     }
57 
58     void Dump(Stream &s) const override;
59 
60 private:
61     DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
62 };
63 
64 enum class PyObjectType
65 {
66     Unknown,
67     None,
68     Integer,
69     Dictionary,
70     List,
71     String,
72     Module,
73     Callable,
74     Tuple,
75     File
76 };
77 
78 enum class PyRefType
79 {
80     Borrowed, // We are not given ownership of the incoming PyObject.
81               // We cannot safely hold it without calling Py_INCREF.
82     Owned     // We have ownership of the incoming PyObject.  We should
83               // not call Py_INCREF.
84 };
85 
86 enum class PyInitialValue
87 {
88     Invalid,
89     Empty
90 };
91 
92 class PythonObject
93 {
94 public:
95     PythonObject()
96         : m_py_obj(nullptr)
97     {
98     }
99 
100     PythonObject(PyRefType type, PyObject *py_obj)
101         : m_py_obj(nullptr)
102     {
103         Reset(type, py_obj);
104     }
105 
106     PythonObject(const PythonObject &rhs)
107         : m_py_obj(nullptr)
108     {
109         Reset(rhs);
110     }
111 
112     virtual ~PythonObject()
113     {
114         Reset();
115     }
116 
117     void
118     Reset()
119     {
120         // Avoid calling the virtual method since it's not necessary
121         // to actually validate the type of the PyObject if we're
122         // just setting to null.
123         if (Py_IsInitialized())
124             Py_XDECREF(m_py_obj);
125         m_py_obj = nullptr;
126     }
127 
128     void
129     Reset(const PythonObject &rhs)
130     {
131         // Avoid calling the virtual method if it's not necessary
132         // to actually validate the type of the PyObject.
133         if (!rhs.IsValid())
134             Reset();
135         else
136             Reset(PyRefType::Borrowed, rhs.m_py_obj);
137     }
138 
139     // PythonObject is implicitly convertible to PyObject *, which will call the
140     // wrong overload.  We want to explicitly disallow this, since a PyObject
141     // *always* owns its reference.  Therefore the overload which takes a
142     // PyRefType doesn't make sense, and the copy constructor should be used.
143     void
144     Reset(PyRefType type, const PythonObject &ref) = delete;
145 
146     virtual void
147     Reset(PyRefType type, PyObject *py_obj)
148     {
149         if (py_obj == m_py_obj)
150             return;
151 
152         if (Py_IsInitialized())
153             Py_XDECREF(m_py_obj);
154 
155         m_py_obj = py_obj;
156 
157         // If this is a borrowed reference, we need to convert it to
158         // an owned reference by incrementing it.  If it is an owned
159         // reference (for example the caller allocated it with PyDict_New()
160         // then we must *not* increment it.
161         if (Py_IsInitialized() && type == PyRefType::Borrowed)
162             Py_XINCREF(m_py_obj);
163     }
164 
165     void
166     Dump () const
167     {
168         if (m_py_obj)
169             _PyObject_Dump (m_py_obj);
170         else
171             puts ("NULL");
172     }
173 
174     void
175     Dump (Stream &strm) const;
176 
177     PyObject*
178     get() const
179     {
180         return m_py_obj;
181     }
182 
183     PyObject*
184     release()
185     {
186         PyObject *result = m_py_obj;
187         m_py_obj = nullptr;
188         return result;
189     }
190 
191     PythonObject &
192     operator=(const PythonObject &other)
193     {
194         Reset(PyRefType::Borrowed, other.get());
195         return *this;
196     }
197 
198     PyObjectType
199     GetObjectType() const;
200 
201     PythonString
202     Repr() const;
203 
204     PythonString
205     Str() const;
206 
207     static PythonObject
208     ResolveNameWithDictionary(llvm::StringRef name, PythonDictionary dict);
209 
210     PythonObject
211     ResolveName(llvm::StringRef name) const;
212 
213     bool
214     HasAttribute(llvm::StringRef attribute) const;
215 
216     PythonObject
217     GetAttributeValue(llvm::StringRef attribute) const;
218 
219     bool
220     IsValid() const;
221 
222     bool
223     IsAllocated() const;
224 
225     bool
226     IsNone() const;
227 
228     template<typename T>
229     T AsType() const
230     {
231         if (!T::Check(m_py_obj))
232             return T();
233         return T(PyRefType::Borrowed, m_py_obj);
234     }
235 
236     StructuredData::ObjectSP
237     CreateStructuredObject() const;
238 
239 protected:
240     PyObject* m_py_obj;
241 };
242 
243 class PythonString : public PythonObject
244 {
245 public:
246     PythonString();
247     explicit PythonString(llvm::StringRef string);
248     explicit PythonString(const char *string);
249     PythonString(PyRefType type, PyObject *o);
250     PythonString(const PythonString &object);
251 
252     ~PythonString() override;
253 
254     static bool Check(PyObject *py_obj);
255 
256     // Bring in the no-argument base class version
257     using PythonObject::Reset;
258 
259     void Reset(PyRefType type, PyObject *py_obj) override;
260 
261     llvm::StringRef
262     GetString() const;
263 
264     size_t
265     GetSize() const;
266 
267     void SetString(llvm::StringRef string);
268 
269     StructuredData::StringSP CreateStructuredString() const;
270 };
271 
272 class PythonInteger : public PythonObject
273 {
274 public:
275     PythonInteger();
276     explicit PythonInteger(int64_t value);
277     PythonInteger(PyRefType type, PyObject *o);
278     PythonInteger(const PythonInteger &object);
279 
280     ~PythonInteger() override;
281 
282     static bool Check(PyObject *py_obj);
283 
284     // Bring in the no-argument base class version
285     using PythonObject::Reset;
286 
287     void Reset(PyRefType type, PyObject *py_obj) override;
288 
289     int64_t GetInteger() const;
290 
291     void
292     SetInteger (int64_t value);
293 
294     StructuredData::IntegerSP CreateStructuredInteger() const;
295 };
296 
297 class PythonList : public PythonObject
298 {
299 public:
300     PythonList() {}
301     explicit PythonList(PyInitialValue value);
302     explicit PythonList(int list_size);
303     PythonList(PyRefType type, PyObject *o);
304     PythonList(const PythonList &list);
305 
306     ~PythonList() override;
307 
308     static bool Check(PyObject *py_obj);
309 
310     // Bring in the no-argument base class version
311     using PythonObject::Reset;
312 
313     void Reset(PyRefType type, PyObject *py_obj) override;
314 
315     uint32_t GetSize() const;
316 
317     PythonObject GetItemAtIndex(uint32_t index) const;
318 
319     void SetItemAtIndex(uint32_t index, const PythonObject &object);
320 
321     void AppendItem(const PythonObject &object);
322 
323     StructuredData::ArraySP CreateStructuredArray() const;
324 };
325 
326 class PythonTuple : public PythonObject
327 {
328 public:
329     PythonTuple() {}
330     explicit PythonTuple(PyInitialValue value);
331     explicit PythonTuple(int tuple_size);
332     PythonTuple(PyRefType type, PyObject *o);
333     PythonTuple(const PythonTuple &tuple);
334     PythonTuple(std::initializer_list<PythonObject> objects);
335     PythonTuple(std::initializer_list<PyObject*> objects);
336 
337     ~PythonTuple() override;
338 
339     static bool Check(PyObject *py_obj);
340 
341     // Bring in the no-argument base class version
342     using PythonObject::Reset;
343 
344     void Reset(PyRefType type, PyObject *py_obj) override;
345 
346     uint32_t GetSize() const;
347 
348     PythonObject GetItemAtIndex(uint32_t index) const;
349 
350     void SetItemAtIndex(uint32_t index, const PythonObject &object);
351 
352     StructuredData::ArraySP CreateStructuredArray() const;
353 };
354 
355 class PythonDictionary : public PythonObject
356 {
357 public:
358     PythonDictionary() {}
359     explicit PythonDictionary(PyInitialValue value);
360     PythonDictionary(PyRefType type, PyObject *o);
361     PythonDictionary(const PythonDictionary &dict);
362 
363     ~PythonDictionary() override;
364 
365     static bool Check(PyObject *py_obj);
366 
367     // Bring in the no-argument base class version
368     using PythonObject::Reset;
369 
370     void Reset(PyRefType type, PyObject *py_obj) override;
371 
372     uint32_t GetSize() const;
373 
374     PythonList GetKeys() const;
375 
376     PythonObject GetItemForKey(const PythonObject &key) const;
377     void SetItemForKey(const PythonObject &key, const PythonObject &value);
378 
379     StructuredData::DictionarySP CreateStructuredDictionary() const;
380 };
381 
382 class PythonModule : public PythonObject
383 {
384   public:
385     PythonModule();
386     PythonModule(PyRefType type, PyObject *o);
387     PythonModule(const PythonModule &dict);
388 
389     ~PythonModule() override;
390 
391     static bool Check(PyObject *py_obj);
392 
393     static PythonModule
394     BuiltinsModule();
395 
396     static PythonModule
397     MainModule();
398 
399     static PythonModule
400     AddModule(llvm::StringRef module);
401 
402     // Bring in the no-argument base class version
403     using PythonObject::Reset;
404 
405     void Reset(PyRefType type, PyObject *py_obj) override;
406 
407     PythonDictionary GetDictionary() const;
408 };
409 
410 class PythonCallable : public PythonObject
411 {
412 public:
413     PythonCallable();
414     PythonCallable(PyRefType type, PyObject *o);
415     PythonCallable(const PythonCallable &dict);
416 
417     ~PythonCallable() override;
418 
419     static bool
420     Check(PyObject *py_obj);
421 
422     // Bring in the no-argument base class version
423     using PythonObject::Reset;
424 
425     void
426     Reset(PyRefType type, PyObject *py_obj) override;
427 
428     void
429     GetNumArguments(size_t &num_args, bool &has_varargs, bool &has_kwargs) const;
430 
431     PythonObject
432     operator ()(std::initializer_list<PyObject*> args);
433 
434     PythonObject
435     operator ()(std::initializer_list<PythonObject> args);
436 };
437 
438 
439 class PythonFile : public PythonObject
440 {
441   public:
442     PythonFile();
443     PythonFile(File &file, const char *mode);
444     PythonFile(const char *path, const char *mode);
445     PythonFile(PyRefType type, PyObject *o);
446 
447     ~PythonFile() override;
448 
449     static bool Check(PyObject *py_obj);
450 
451     using PythonObject::Reset;
452 
453     void Reset(PyRefType type, PyObject *py_obj) override;
454     void Reset(File &file, const char *mode);
455 
456     bool GetUnderlyingFile(File &file) const;
457 };
458 
459 } // namespace lldb_private
460 
461 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
462