xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision 02bf92d22651dd7feb2828974fdcc5dc0e23ddfb)
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, const PythonDictionary &dict);
209 
210     template<typename T>
211     static T
212     ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
213     {
214         return ResolveNameWithDictionary(name, dict).AsType<T>();
215     }
216 
217     PythonObject
218     ResolveName(llvm::StringRef name) const;
219 
220     template<typename T>
221     T
222     ResolveName(llvm::StringRef name) const
223     {
224         return ResolveName(name).AsType<T>();
225     }
226 
227     bool
228     HasAttribute(llvm::StringRef attribute) const;
229 
230     PythonObject
231     GetAttributeValue(llvm::StringRef attribute) const;
232 
233     bool
234     IsValid() const;
235 
236     bool
237     IsAllocated() const;
238 
239     bool
240     IsNone() const;
241 
242     template<typename T>
243     T AsType() const
244     {
245         if (!T::Check(m_py_obj))
246             return T();
247         return T(PyRefType::Borrowed, m_py_obj);
248     }
249 
250     StructuredData::ObjectSP
251     CreateStructuredObject() const;
252 
253 protected:
254     PyObject* m_py_obj;
255 };
256 
257 class PythonString : public PythonObject
258 {
259 public:
260     PythonString();
261     explicit PythonString(llvm::StringRef string);
262     explicit PythonString(const char *string);
263     PythonString(PyRefType type, PyObject *o);
264     PythonString(const PythonString &object);
265 
266     ~PythonString() override;
267 
268     static bool Check(PyObject *py_obj);
269 
270     // Bring in the no-argument base class version
271     using PythonObject::Reset;
272 
273     void Reset(PyRefType type, PyObject *py_obj) override;
274 
275     llvm::StringRef
276     GetString() const;
277 
278     size_t
279     GetSize() const;
280 
281     void SetString(llvm::StringRef string);
282 
283     StructuredData::StringSP CreateStructuredString() const;
284 };
285 
286 class PythonInteger : public PythonObject
287 {
288 public:
289     PythonInteger();
290     explicit PythonInteger(int64_t value);
291     PythonInteger(PyRefType type, PyObject *o);
292     PythonInteger(const PythonInteger &object);
293 
294     ~PythonInteger() override;
295 
296     static bool Check(PyObject *py_obj);
297 
298     // Bring in the no-argument base class version
299     using PythonObject::Reset;
300 
301     void Reset(PyRefType type, PyObject *py_obj) override;
302 
303     int64_t GetInteger() const;
304 
305     void
306     SetInteger (int64_t value);
307 
308     StructuredData::IntegerSP CreateStructuredInteger() const;
309 };
310 
311 class PythonList : public PythonObject
312 {
313 public:
314     PythonList() {}
315     explicit PythonList(PyInitialValue value);
316     explicit PythonList(int list_size);
317     PythonList(PyRefType type, PyObject *o);
318     PythonList(const PythonList &list);
319 
320     ~PythonList() override;
321 
322     static bool Check(PyObject *py_obj);
323 
324     // Bring in the no-argument base class version
325     using PythonObject::Reset;
326 
327     void Reset(PyRefType type, PyObject *py_obj) override;
328 
329     uint32_t GetSize() const;
330 
331     PythonObject GetItemAtIndex(uint32_t index) const;
332 
333     void SetItemAtIndex(uint32_t index, const PythonObject &object);
334 
335     void AppendItem(const PythonObject &object);
336 
337     StructuredData::ArraySP CreateStructuredArray() const;
338 };
339 
340 class PythonTuple : public PythonObject
341 {
342 public:
343     PythonTuple() {}
344     explicit PythonTuple(PyInitialValue value);
345     explicit PythonTuple(int tuple_size);
346     PythonTuple(PyRefType type, PyObject *o);
347     PythonTuple(const PythonTuple &tuple);
348     PythonTuple(std::initializer_list<PythonObject> objects);
349     PythonTuple(std::initializer_list<PyObject*> objects);
350 
351     ~PythonTuple() override;
352 
353     static bool Check(PyObject *py_obj);
354 
355     // Bring in the no-argument base class version
356     using PythonObject::Reset;
357 
358     void Reset(PyRefType type, PyObject *py_obj) override;
359 
360     uint32_t GetSize() const;
361 
362     PythonObject GetItemAtIndex(uint32_t index) const;
363 
364     void SetItemAtIndex(uint32_t index, const PythonObject &object);
365 
366     StructuredData::ArraySP CreateStructuredArray() const;
367 };
368 
369 class PythonDictionary : public PythonObject
370 {
371 public:
372     PythonDictionary() {}
373     explicit PythonDictionary(PyInitialValue value);
374     PythonDictionary(PyRefType type, PyObject *o);
375     PythonDictionary(const PythonDictionary &dict);
376 
377     ~PythonDictionary() override;
378 
379     static bool Check(PyObject *py_obj);
380 
381     // Bring in the no-argument base class version
382     using PythonObject::Reset;
383 
384     void Reset(PyRefType type, PyObject *py_obj) override;
385 
386     uint32_t GetSize() const;
387 
388     PythonList GetKeys() const;
389 
390     PythonObject GetItemForKey(const PythonObject &key) const;
391     void SetItemForKey(const PythonObject &key, const PythonObject &value);
392 
393     StructuredData::DictionarySP CreateStructuredDictionary() const;
394 };
395 
396 class PythonModule : public PythonObject
397 {
398   public:
399     PythonModule();
400     PythonModule(PyRefType type, PyObject *o);
401     PythonModule(const PythonModule &dict);
402 
403     ~PythonModule() override;
404 
405     static bool Check(PyObject *py_obj);
406 
407     static PythonModule
408     BuiltinsModule();
409 
410     static PythonModule
411     MainModule();
412 
413     static PythonModule
414     AddModule(llvm::StringRef module);
415 
416     // Bring in the no-argument base class version
417     using PythonObject::Reset;
418 
419     void Reset(PyRefType type, PyObject *py_obj) override;
420 
421     PythonDictionary GetDictionary() const;
422 };
423 
424 class PythonCallable : public PythonObject
425 {
426 public:
427     struct ArgInfo {
428         size_t count;
429         bool has_varargs : 1;
430         bool has_kwargs : 1;
431     };
432 
433     PythonCallable();
434     PythonCallable(PyRefType type, PyObject *o);
435     PythonCallable(const PythonCallable &dict);
436 
437     ~PythonCallable() override;
438 
439     static bool
440     Check(PyObject *py_obj);
441 
442     // Bring in the no-argument base class version
443     using PythonObject::Reset;
444 
445     void
446     Reset(PyRefType type, PyObject *py_obj) override;
447 
448     ArgInfo
449     GetNumArguments() const;
450 
451     PythonObject
452     operator ()();
453 
454     PythonObject
455     operator ()(std::initializer_list<PyObject*> args);
456 
457     PythonObject
458     operator ()(std::initializer_list<PythonObject> args);
459 
460     template<typename Arg, typename... Args>
461     PythonObject
462     operator ()(const Arg &arg, Args... args)
463     {
464         return operator()({ arg, args... });
465     }
466 };
467 
468 
469 class PythonFile : public PythonObject
470 {
471   public:
472     PythonFile();
473     PythonFile(File &file, const char *mode);
474     PythonFile(const char *path, const char *mode);
475     PythonFile(PyRefType type, PyObject *o);
476 
477     ~PythonFile() override;
478 
479     static bool Check(PyObject *py_obj);
480 
481     using PythonObject::Reset;
482 
483     void Reset(PyRefType type, PyObject *py_obj) override;
484     void Reset(File &file, const char *mode);
485 
486     bool GetUnderlyingFile(File &file) const;
487 };
488 
489 } // namespace lldb_private
490 
491 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
492