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