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