xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision 2fce1137c7c227f40edbb657c484797addba38ca)
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 
202   ~PythonBytes() override;
203 
204   static bool Check(PyObject *py_obj);
205 
206   // Bring in the no-argument base class version
207   using PythonObject::Reset;
208 
209   void Reset(PyRefType type, PyObject *py_obj) override;
210 
211   llvm::ArrayRef<uint8_t> GetBytes() const;
212 
213   size_t GetSize() const;
214 
215   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
216 
217   StructuredData::StringSP CreateStructuredString() const;
218 };
219 
220 class PythonByteArray : public PythonObject {
221 public:
222   PythonByteArray();
223   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
224   PythonByteArray(const uint8_t *bytes, size_t length);
225   PythonByteArray(PyRefType type, PyObject *o);
226   PythonByteArray(const PythonBytes &object);
227 
228   ~PythonByteArray() override;
229 
230   static bool Check(PyObject *py_obj);
231 
232   // Bring in the no-argument base class version
233   using PythonObject::Reset;
234 
235   void Reset(PyRefType type, PyObject *py_obj) override;
236 
237   llvm::ArrayRef<uint8_t> GetBytes() const;
238 
239   size_t GetSize() const;
240 
241   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
242 
243   StructuredData::StringSP CreateStructuredString() const;
244 };
245 
246 class PythonString : public PythonObject {
247 public:
248   PythonString();
249   explicit PythonString(llvm::StringRef string);
250   explicit PythonString(const char *string);
251   PythonString(PyRefType type, PyObject *o);
252 
253   ~PythonString() override;
254 
255   static bool Check(PyObject *py_obj);
256 
257   // Bring in the no-argument base class version
258   using PythonObject::Reset;
259 
260   void Reset(PyRefType type, PyObject *py_obj) override;
261 
262   llvm::StringRef GetString() const;
263 
264   size_t GetSize() const;
265 
266   void SetString(llvm::StringRef string);
267 
268   StructuredData::StringSP CreateStructuredString() const;
269 };
270 
271 class PythonInteger : public PythonObject {
272 public:
273   PythonInteger();
274   explicit PythonInteger(int64_t value);
275   PythonInteger(PyRefType type, PyObject *o);
276 
277   ~PythonInteger() override;
278 
279   static bool Check(PyObject *py_obj);
280 
281   // Bring in the no-argument base class version
282   using PythonObject::Reset;
283 
284   void Reset(PyRefType type, PyObject *py_obj) override;
285 
286   int64_t GetInteger() const;
287 
288   void SetInteger(int64_t value);
289 
290   StructuredData::IntegerSP CreateStructuredInteger() const;
291 };
292 
293 class PythonBoolean : public PythonObject {
294 public:
295   PythonBoolean() = default;
296   explicit PythonBoolean(bool value);
297   PythonBoolean(PyRefType type, PyObject *o);
298 
299   ~PythonBoolean() override = default;
300 
301   static bool Check(PyObject *py_obj);
302 
303   // Bring in the no-argument base class version
304   using PythonObject::Reset;
305 
306   void Reset(PyRefType type, PyObject *py_obj) override;
307 
308   bool GetValue() const;
309 
310   void SetValue(bool value);
311 
312   StructuredData::BooleanSP CreateStructuredBoolean() const;
313 };
314 
315 class PythonList : public PythonObject {
316 public:
317   PythonList() {}
318   explicit PythonList(PyInitialValue value);
319   explicit PythonList(int list_size);
320   PythonList(PyRefType type, PyObject *o);
321 
322   ~PythonList() override;
323 
324   static bool Check(PyObject *py_obj);
325 
326   // Bring in the no-argument base class version
327   using PythonObject::Reset;
328 
329   void Reset(PyRefType type, PyObject *py_obj) override;
330 
331   uint32_t GetSize() const;
332 
333   PythonObject GetItemAtIndex(uint32_t index) const;
334 
335   void SetItemAtIndex(uint32_t index, const PythonObject &object);
336 
337   void AppendItem(const PythonObject &object);
338 
339   StructuredData::ArraySP CreateStructuredArray() const;
340 };
341 
342 class PythonTuple : public PythonObject {
343 public:
344   PythonTuple() {}
345   explicit PythonTuple(PyInitialValue value);
346   explicit PythonTuple(int tuple_size);
347   PythonTuple(PyRefType type, PyObject *o);
348   PythonTuple(std::initializer_list<PythonObject> objects);
349   PythonTuple(std::initializer_list<PyObject *> objects);
350 
351   ~PythonTuple() override;
352 
353   static bool Check(PyObject *py_obj);
354 
355   // Bring in the no-argument base class version
356   using PythonObject::Reset;
357 
358   void Reset(PyRefType type, PyObject *py_obj) override;
359 
360   uint32_t GetSize() const;
361 
362   PythonObject GetItemAtIndex(uint32_t index) const;
363 
364   void SetItemAtIndex(uint32_t index, const PythonObject &object);
365 
366   StructuredData::ArraySP CreateStructuredArray() const;
367 };
368 
369 class PythonDictionary : public PythonObject {
370 public:
371   PythonDictionary() {}
372   explicit PythonDictionary(PyInitialValue value);
373   PythonDictionary(PyRefType type, PyObject *o);
374 
375   ~PythonDictionary() override;
376 
377   static bool Check(PyObject *py_obj);
378 
379   // Bring in the no-argument base class version
380   using PythonObject::Reset;
381 
382   void Reset(PyRefType type, PyObject *py_obj) override;
383 
384   uint32_t GetSize() const;
385 
386   PythonList GetKeys() const;
387 
388   PythonObject GetItemForKey(const PythonObject &key) const;
389   void SetItemForKey(const PythonObject &key, const PythonObject &value);
390 
391   StructuredData::DictionarySP CreateStructuredDictionary() const;
392 };
393 
394 class PythonModule : public PythonObject {
395 public:
396   PythonModule();
397   PythonModule(PyRefType type, PyObject *o);
398 
399   ~PythonModule() override;
400 
401   static bool Check(PyObject *py_obj);
402 
403   static PythonModule BuiltinsModule();
404 
405   static PythonModule MainModule();
406 
407   static PythonModule AddModule(llvm::StringRef module);
408 
409   static PythonModule ImportModule(llvm::StringRef module);
410 
411   // Bring in the no-argument base class version
412   using PythonObject::Reset;
413 
414   void Reset(PyRefType type, PyObject *py_obj) override;
415 
416   PythonDictionary GetDictionary() const;
417 };
418 
419 class PythonCallable : public PythonObject {
420 public:
421   struct ArgInfo {
422     size_t count;
423     bool is_bound_method : 1;
424     bool has_varargs : 1;
425     bool has_kwargs : 1;
426   };
427 
428   PythonCallable();
429   PythonCallable(PyRefType type, PyObject *o);
430 
431   ~PythonCallable() override;
432 
433   static bool Check(PyObject *py_obj);
434 
435   // Bring in the no-argument base class version
436   using PythonObject::Reset;
437 
438   void Reset(PyRefType type, PyObject *py_obj) override;
439 
440   ArgInfo GetNumArguments() const;
441 
442   PythonObject operator()();
443 
444   PythonObject operator()(std::initializer_list<PyObject *> args);
445 
446   PythonObject operator()(std::initializer_list<PythonObject> args);
447 
448   template <typename Arg, typename... Args>
449   PythonObject operator()(const Arg &arg, Args... args) {
450     return operator()({arg, args...});
451   }
452 };
453 
454 class PythonFile : public PythonObject {
455 public:
456   PythonFile();
457   PythonFile(File &file, const char *mode);
458   PythonFile(PyRefType type, PyObject *o);
459 
460   ~PythonFile() override;
461 
462   static bool Check(PyObject *py_obj);
463 
464   using PythonObject::Reset;
465 
466   void Reset(PyRefType type, PyObject *py_obj) override;
467   void Reset(File &file, const char *mode);
468 
469   static uint32_t GetOptionsFromMode(llvm::StringRef mode);
470 
471   lldb::FileUP GetUnderlyingFile() const;
472 };
473 
474 } // namespace lldb_private
475 
476 #endif
477 
478 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
479