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