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