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