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