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