xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision 5a72c02be9a7a5ac5671f079997ec58a71b661ba)
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 // C Includes
16 // C++ Includes
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/lldb-defines.h"
20 #include "lldb/Core/ConstString.h"
21 #include "lldb/Core/StructuredData.h"
22 #include "lldb/Core/Flags.h"
23 #include "lldb/Host/File.h"
24 #include "lldb/Interpreter/OptionValue.h"
25 
26 #include "llvm/ADT/ArrayRef.h"
27 
28 namespace lldb_private {
29 
30 class PythonBytes;
31 class PythonString;
32 class PythonList;
33 class PythonDictionary;
34 class PythonInteger;
35 
36 class StructuredPythonObject : public StructuredData::Generic
37 {
38 public:
39     StructuredPythonObject()
40         : StructuredData::Generic()
41     {
42     }
43 
44     StructuredPythonObject(void *obj)
45         : StructuredData::Generic(obj)
46     {
47         Py_XINCREF(GetValue());
48     }
49 
50     ~StructuredPythonObject() override
51     {
52         if (Py_IsInitialized())
53             Py_XDECREF(GetValue());
54         SetValue(nullptr);
55     }
56 
57     bool
58     IsValid() const override
59     {
60         return GetValue() && GetValue() != Py_None;
61     }
62 
63     void Dump(Stream &s) const override;
64 
65 private:
66     DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
67 };
68 
69 enum class PyObjectType
70 {
71     Unknown,
72     None,
73     Integer,
74     Dictionary,
75     List,
76     String,
77 #if PY_MAJOR_VERSION >= 3
78     Bytes,
79 #else
80     Bytes = String,
81 #endif
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 PythonString : public PythonObject
301 {
302 public:
303     PythonString();
304     explicit PythonString(llvm::StringRef string);
305     explicit PythonString(const char *string);
306     PythonString(PyRefType type, PyObject *o);
307     PythonString(const PythonString &object);
308 
309     ~PythonString() override;
310 
311     static bool Check(PyObject *py_obj);
312 
313     // Bring in the no-argument base class version
314     using PythonObject::Reset;
315 
316     void Reset(PyRefType type, PyObject *py_obj) override;
317 
318     llvm::StringRef
319     GetString() const;
320 
321     size_t
322     GetSize() const;
323 
324     void SetString(llvm::StringRef string);
325 
326     StructuredData::StringSP CreateStructuredString() const;
327 };
328 
329 class PythonInteger : public PythonObject
330 {
331 public:
332     PythonInteger();
333     explicit PythonInteger(int64_t value);
334     PythonInteger(PyRefType type, PyObject *o);
335     PythonInteger(const PythonInteger &object);
336 
337     ~PythonInteger() 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     int64_t GetInteger() const;
347 
348     void
349     SetInteger (int64_t value);
350 
351     StructuredData::IntegerSP CreateStructuredInteger() const;
352 };
353 
354 class PythonList : public PythonObject
355 {
356 public:
357     PythonList() {}
358     explicit PythonList(PyInitialValue value);
359     explicit PythonList(int list_size);
360     PythonList(PyRefType type, PyObject *o);
361     PythonList(const PythonList &list);
362 
363     ~PythonList() 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     PythonObject GetItemAtIndex(uint32_t index) const;
375 
376     void SetItemAtIndex(uint32_t index, const PythonObject &object);
377 
378     void AppendItem(const PythonObject &object);
379 
380     StructuredData::ArraySP CreateStructuredArray() const;
381 };
382 
383 class PythonTuple : public PythonObject
384 {
385 public:
386     PythonTuple() {}
387     explicit PythonTuple(PyInitialValue value);
388     explicit PythonTuple(int tuple_size);
389     PythonTuple(PyRefType type, PyObject *o);
390     PythonTuple(const PythonTuple &tuple);
391     PythonTuple(std::initializer_list<PythonObject> objects);
392     PythonTuple(std::initializer_list<PyObject*> objects);
393 
394     ~PythonTuple() override;
395 
396     static bool Check(PyObject *py_obj);
397 
398     // Bring in the no-argument base class version
399     using PythonObject::Reset;
400 
401     void Reset(PyRefType type, PyObject *py_obj) override;
402 
403     uint32_t GetSize() const;
404 
405     PythonObject GetItemAtIndex(uint32_t index) const;
406 
407     void SetItemAtIndex(uint32_t index, const PythonObject &object);
408 
409     StructuredData::ArraySP CreateStructuredArray() const;
410 };
411 
412 class PythonDictionary : public PythonObject
413 {
414 public:
415     PythonDictionary() {}
416     explicit PythonDictionary(PyInitialValue value);
417     PythonDictionary(PyRefType type, PyObject *o);
418     PythonDictionary(const PythonDictionary &dict);
419 
420     ~PythonDictionary() override;
421 
422     static bool Check(PyObject *py_obj);
423 
424     // Bring in the no-argument base class version
425     using PythonObject::Reset;
426 
427     void Reset(PyRefType type, PyObject *py_obj) override;
428 
429     uint32_t GetSize() const;
430 
431     PythonList GetKeys() const;
432 
433     PythonObject GetItemForKey(const PythonObject &key) const;
434     void SetItemForKey(const PythonObject &key, const PythonObject &value);
435 
436     StructuredData::DictionarySP CreateStructuredDictionary() const;
437 };
438 
439 class PythonModule : public PythonObject
440 {
441   public:
442     PythonModule();
443     PythonModule(PyRefType type, PyObject *o);
444     PythonModule(const PythonModule &dict);
445 
446     ~PythonModule() override;
447 
448     static bool Check(PyObject *py_obj);
449 
450     static PythonModule
451     BuiltinsModule();
452 
453     static PythonModule
454     MainModule();
455 
456     static PythonModule
457     AddModule(llvm::StringRef module);
458 
459     static PythonModule
460     ImportModule(llvm::StringRef module);
461 
462     // Bring in the no-argument base class version
463     using PythonObject::Reset;
464 
465     void Reset(PyRefType type, PyObject *py_obj) override;
466 
467     PythonDictionary GetDictionary() const;
468 };
469 
470 class PythonCallable : public PythonObject
471 {
472 public:
473     struct ArgInfo {
474         size_t count;
475         bool has_varargs : 1;
476         bool has_kwargs : 1;
477     };
478 
479     PythonCallable();
480     PythonCallable(PyRefType type, PyObject *o);
481     PythonCallable(const PythonCallable &dict);
482 
483     ~PythonCallable() override;
484 
485     static bool
486     Check(PyObject *py_obj);
487 
488     // Bring in the no-argument base class version
489     using PythonObject::Reset;
490 
491     void
492     Reset(PyRefType type, PyObject *py_obj) override;
493 
494     ArgInfo
495     GetNumArguments() const;
496 
497     PythonObject
498     operator ()();
499 
500     PythonObject
501     operator ()(std::initializer_list<PyObject*> args);
502 
503     PythonObject
504     operator ()(std::initializer_list<PythonObject> args);
505 
506     template<typename Arg, typename... Args>
507     PythonObject
508     operator ()(const Arg &arg, Args... args)
509     {
510         return operator()({ arg, args... });
511     }
512 };
513 
514 
515 class PythonFile : public PythonObject
516 {
517   public:
518     PythonFile();
519     PythonFile(File &file, const char *mode);
520     PythonFile(const char *path, const char *mode);
521     PythonFile(PyRefType type, PyObject *o);
522 
523     ~PythonFile() override;
524 
525     static bool Check(PyObject *py_obj);
526 
527     using PythonObject::Reset;
528 
529     void Reset(PyRefType type, PyObject *py_obj) override;
530     void Reset(File &file, const char *mode);
531 
532     bool GetUnderlyingFile(File &file) const;
533 };
534 
535 } // namespace lldb_private
536 
537 #endif
538 
539 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
540