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