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 //
10 // !! FIXME FIXME FIXME !!
11 //
12 // Python APIs nearly all can return an exception.   They do this
13 // by returning NULL, or -1, or some such value and setting
14 // the exception state with PyErr_Set*().   Exceptions must be
15 // handled before further python API functions are called.   Failure
16 // to do so will result in asserts on debug builds of python.
17 // It will also sometimes, but not usually result in crashes of
18 // release builds.
19 //
20 // Nearly all the code in this header does not handle python exceptions
21 // correctly.  It should all be converted to return Expected<> or
22 // Error types to capture the exception.
23 //
24 // Everything in this file except functions that return Error or
25 // Expected<> is considered deprecated and should not be
26 // used in new code.  If you need to use it, fix it first.
27 //
28 //
29 // TODOs for this file
30 //
31 // * Make all methods safe for exceptions.
32 //
33 // * Eliminate method signatures that must translate exceptions into
34 //   empty objects or NULLs.   Almost everything here should return
35 //   Expected<>.   It should be acceptable for certain operations that
36 //   can never fail to assert instead, such as the creation of
37 //   PythonString from a string literal.
38 //
39 // * Eliminate Reset(), and make all non-default constructors private.
40 //   Python objects should be created with Retain<> or Take<>, and they
41 //   should be assigned with operator=
42 //
43 // * Eliminate default constructors, make python objects always
44 //   nonnull, and use optionals where necessary.
45 //
46 
47 
48 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
49 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
50 
51 #include "lldb/Host/Config.h"
52 
53 #if LLDB_ENABLE_PYTHON
54 
55 // LLDB Python header must be included first
56 #include "lldb-python.h"
57 
58 #include "lldb/Host/File.h"
59 #include "lldb/Utility/StructuredData.h"
60 
61 #include "llvm/ADT/ArrayRef.h"
62 
63 namespace lldb_private {
64 namespace python {
65 
66 class PythonObject;
67 class PythonBytes;
68 class PythonString;
69 class PythonList;
70 class PythonDictionary;
71 class PythonInteger;
72 class PythonException;
73 
74 class GIL {
75 public:
76   GIL() {
77     m_state = PyGILState_Ensure();
78     assert(!PyErr_Occurred());
79   }
80   ~GIL() { PyGILState_Release(m_state); }
81 
82 protected:
83   PyGILState_STATE m_state;
84 };
85 
86 enum class PyObjectType {
87   Unknown,
88   None,
89   Boolean,
90   Integer,
91   Dictionary,
92   List,
93   String,
94   Bytes,
95   ByteArray,
96   Module,
97   Callable,
98   Tuple,
99   File
100 };
101 
102 enum class PyRefType {
103   Borrowed, // We are not given ownership of the incoming PyObject.
104             // We cannot safely hold it without calling Py_INCREF.
105   Owned     // We have ownership of the incoming PyObject.  We should
106             // not call Py_INCREF.
107 };
108 
109 
110 // Take a reference that you already own, and turn it into
111 // a PythonObject.
112 //
113 // Most python API methods will return a +1 reference
114 // if they succeed or NULL if and only if
115 // they set an exception.   Use this to collect such return
116 // values, after checking for NULL.
117 //
118 // If T is not just PythonObject, then obj must be already be
119 // checked to be of the correct type.
120 template <typename T> T Take(PyObject *obj) {
121   assert(obj);
122   assert(!PyErr_Occurred());
123   T thing(PyRefType::Owned, obj);
124   assert(thing.IsValid());
125   return thing;
126 }
127 
128 // Retain a reference you have borrowed, and turn it into
129 // a PythonObject.
130 //
131 // A minority of python APIs return a borrowed reference
132 // instead of a +1.   They will also return NULL if and only
133 // if they set an exception.   Use this to collect such return
134 // values, after checking for NULL.
135 //
136 // If T is not just PythonObject, then obj must be already be
137 // checked to be of the correct type.
138 template <typename T> T Retain(PyObject *obj) {
139   assert(obj);
140   assert(!PyErr_Occurred());
141   T thing(PyRefType::Borrowed, obj);
142   assert(thing.IsValid());
143   return thing;
144 }
145 
146 // This class can be used like a utility function to convert from
147 // a llvm-friendly Twine into a null-terminated const char *,
148 // which is the form python C APIs want their strings in.
149 //
150 // Example:
151 // const llvm::Twine &some_twine;
152 // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
153 //
154 // Why a class instead of a function?  If the twine isn't already null
155 // terminated, it will need a temporary buffer to copy the string
156 // into.   We need that buffer to stick around for the lifetime of the
157 // statement.
158 class NullTerminated {
159   const char *str;
160   llvm::SmallString<32> storage;
161 
162 public:
163   NullTerminated(const llvm::Twine &twine) {
164     llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
165     str = ref.begin();
166   }
167   operator const char *() { return str; }
168 };
169 
170 inline llvm::Error nullDeref() {
171   return llvm::createStringError(llvm::inconvertibleErrorCode(),
172                                  "A NULL PyObject* was dereferenced");
173 }
174 
175 inline llvm::Error exception(const char *s = nullptr) {
176   return llvm::make_error<PythonException>(s);
177 }
178 
179 inline llvm::Error keyError() {
180   return llvm::createStringError(llvm::inconvertibleErrorCode(),
181                                  "key not in dict");
182 }
183 
184 inline const char *py2_const_cast(const char *s) { return s; }
185 
186 enum class PyInitialValue { Invalid, Empty };
187 
188 // DOC: https://docs.python.org/3/c-api/arg.html#building-values
189 template <typename T, typename Enable = void> struct PythonFormat;
190 
191 template <typename T, char F> struct PassthroughFormat {
192   static constexpr char format = F;
193   static constexpr T get(T t) { return t; }
194 };
195 
196 template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
197 template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
198 template <>
199 struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
200 template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
201 template <>
202 struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
203 template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
204 template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
205 template <>
206 struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
207 template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
208 template <>
209 struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {};
210 template <>
211 struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {};
212 template <>
213 struct PythonFormat<unsigned long long>
214     : PassthroughFormat<unsigned long long, 'K'> {};
215 template <>
216 struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {};
217 
218 template <typename T>
219 struct PythonFormat<
220     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
221   static constexpr char format = 'O';
222   static auto get(const T &value) { return value.get(); }
223 };
224 
225 class PythonObject {
226 public:
227   PythonObject() = default;
228 
229   PythonObject(PyRefType type, PyObject *py_obj) {
230     m_py_obj = py_obj;
231     // If this is a borrowed reference, we need to convert it to
232     // an owned reference by incrementing it.  If it is an owned
233     // reference (for example the caller allocated it with PyDict_New()
234     // then we must *not* increment it.
235     if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
236       Py_XINCREF(m_py_obj);
237   }
238 
239   PythonObject(const PythonObject &rhs)
240       : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
241 
242   PythonObject(PythonObject &&rhs) {
243     m_py_obj = rhs.m_py_obj;
244     rhs.m_py_obj = nullptr;
245   }
246 
247   ~PythonObject() { Reset(); }
248 
249   void Reset();
250 
251   void Dump() const {
252     if (m_py_obj)
253       _PyObject_Dump(m_py_obj);
254     else
255       puts("NULL");
256   }
257 
258   void Dump(Stream &strm) const;
259 
260   PyObject *get() const { return m_py_obj; }
261 
262   PyObject *release() {
263     PyObject *result = m_py_obj;
264     m_py_obj = nullptr;
265     return result;
266   }
267 
268   PythonObject &operator=(PythonObject other) {
269     Reset();
270     m_py_obj = std::exchange(other.m_py_obj, nullptr);
271     return *this;
272   }
273 
274   PyObjectType GetObjectType() const;
275 
276   PythonString Repr() const;
277 
278   PythonString Str() const;
279 
280   static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
281                                                 const PythonDictionary &dict);
282 
283   template <typename T>
284   static T ResolveNameWithDictionary(llvm::StringRef name,
285                                      const PythonDictionary &dict) {
286     return ResolveNameWithDictionary(name, dict).AsType<T>();
287   }
288 
289   PythonObject ResolveName(llvm::StringRef name) const;
290 
291   template <typename T> T ResolveName(llvm::StringRef name) const {
292     return ResolveName(name).AsType<T>();
293   }
294 
295   bool HasAttribute(llvm::StringRef attribute) const;
296 
297   PythonObject GetAttributeValue(llvm::StringRef attribute) const;
298 
299   bool IsNone() const { return m_py_obj == Py_None; }
300 
301   bool IsValid() const { return m_py_obj != nullptr; }
302 
303   bool IsAllocated() const { return IsValid() && !IsNone(); }
304 
305   explicit operator bool() const { return IsValid() && !IsNone(); }
306 
307   template <typename T> T AsType() const {
308     if (!T::Check(m_py_obj))
309       return T();
310     return T(PyRefType::Borrowed, m_py_obj);
311   }
312 
313   StructuredData::ObjectSP CreateStructuredObject() const;
314 
315   template <typename... T>
316   llvm::Expected<PythonObject> CallMethod(const char *name,
317                                           const T &... t) const {
318     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
319     PyObject *obj =
320         PyObject_CallMethod(m_py_obj, py2_const_cast(name),
321                             py2_const_cast(format), PythonFormat<T>::get(t)...);
322     if (!obj)
323       return exception();
324     return python::Take<PythonObject>(obj);
325   }
326 
327   template <typename... T>
328   llvm::Expected<PythonObject> Call(const T &... t) const {
329     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
330     PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
331                                           PythonFormat<T>::get(t)...);
332     if (!obj)
333       return exception();
334     return python::Take<PythonObject>(obj);
335   }
336 
337   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
338     if (!m_py_obj)
339       return nullDeref();
340     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
341     if (!obj)
342       return exception();
343     return python::Take<PythonObject>(obj);
344   }
345 
346   llvm::Expected<PythonObject> GetType() const {
347     if (!m_py_obj)
348       return nullDeref();
349     PyObject *obj = PyObject_Type(m_py_obj);
350     if (!obj)
351       return exception();
352     return python::Take<PythonObject>(obj);
353   }
354 
355   llvm::Expected<bool> IsTrue() {
356     if (!m_py_obj)
357       return nullDeref();
358     int r = PyObject_IsTrue(m_py_obj);
359     if (r < 0)
360       return exception();
361     return !!r;
362   }
363 
364   llvm::Expected<long long> AsLongLong() const;
365 
366   llvm::Expected<unsigned long long> AsUnsignedLongLong() const;
367 
368   // wraps on overflow, instead of raising an error.
369   llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
370 
371   llvm::Expected<bool> IsInstance(const PythonObject &cls) {
372     if (!m_py_obj || !cls.IsValid())
373       return nullDeref();
374     int r = PyObject_IsInstance(m_py_obj, cls.get());
375     if (r < 0)
376       return exception();
377     return !!r;
378   }
379 
380 protected:
381   PyObject *m_py_obj = nullptr;
382 };
383 
384 
385 // This is why C++ needs monads.
386 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
387   if (!obj)
388     return obj.takeError();
389   if (!T::Check(obj.get().get()))
390     return llvm::createStringError(llvm::inconvertibleErrorCode(),
391                                    "type error");
392   return T(PyRefType::Borrowed, std::move(obj.get().get()));
393 }
394 
395 template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
396 
397 template <>
398 llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
399 
400 template <>
401 llvm::Expected<unsigned long long>
402 As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
403 
404 template <>
405 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
406 
407 
408 template <class T> class TypedPythonObject : public PythonObject {
409 public:
410   TypedPythonObject(PyRefType type, PyObject *py_obj) {
411     if (!py_obj)
412       return;
413     if (T::Check(py_obj))
414       PythonObject::operator=(PythonObject(type, py_obj));
415     else if (type == PyRefType::Owned)
416       Py_DECREF(py_obj);
417   }
418 
419   TypedPythonObject() = default;
420 };
421 
422 class PythonBytes : public TypedPythonObject<PythonBytes> {
423 public:
424   using TypedPythonObject::TypedPythonObject;
425   explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
426   PythonBytes(const uint8_t *bytes, size_t length);
427 
428   static bool Check(PyObject *py_obj);
429 
430   llvm::ArrayRef<uint8_t> GetBytes() const;
431 
432   size_t GetSize() const;
433 
434   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
435 
436   StructuredData::StringSP CreateStructuredString() const;
437 };
438 
439 class PythonByteArray : public TypedPythonObject<PythonByteArray> {
440 public:
441   using TypedPythonObject::TypedPythonObject;
442   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
443   PythonByteArray(const uint8_t *bytes, size_t length);
444   PythonByteArray(const PythonBytes &object);
445 
446   static bool Check(PyObject *py_obj);
447 
448   llvm::ArrayRef<uint8_t> GetBytes() const;
449 
450   size_t GetSize() const;
451 
452   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
453 
454   StructuredData::StringSP CreateStructuredString() const;
455 };
456 
457 class PythonString : public TypedPythonObject<PythonString> {
458 public:
459   using TypedPythonObject::TypedPythonObject;
460   static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
461 
462   PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
463 
464   explicit PythonString(llvm::StringRef string); // safe, null on error
465 
466   static bool Check(PyObject *py_obj);
467 
468   llvm::StringRef GetString() const; // safe, empty string on error
469 
470   llvm::Expected<llvm::StringRef> AsUTF8() const;
471 
472   size_t GetSize() const;
473 
474   void SetString(llvm::StringRef string); // safe, null on error
475 
476   StructuredData::StringSP CreateStructuredString() const;
477 };
478 
479 class PythonInteger : public TypedPythonObject<PythonInteger> {
480 public:
481   using TypedPythonObject::TypedPythonObject;
482 
483   PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
484 
485   explicit PythonInteger(int64_t value);
486 
487   static bool Check(PyObject *py_obj);
488 
489   void SetInteger(int64_t value);
490 
491   StructuredData::IntegerSP CreateStructuredInteger() const;
492 
493   StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const;
494 
495   StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const;
496 };
497 
498 class PythonBoolean : public TypedPythonObject<PythonBoolean> {
499 public:
500   using TypedPythonObject::TypedPythonObject;
501 
502   explicit PythonBoolean(bool value);
503 
504   static bool Check(PyObject *py_obj);
505 
506   bool GetValue() const;
507 
508   void SetValue(bool value);
509 
510   StructuredData::BooleanSP CreateStructuredBoolean() const;
511 };
512 
513 class PythonList : public TypedPythonObject<PythonList> {
514 public:
515   using TypedPythonObject::TypedPythonObject;
516 
517   PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
518 
519   explicit PythonList(PyInitialValue value);
520   explicit PythonList(int list_size);
521 
522   static bool Check(PyObject *py_obj);
523 
524   uint32_t GetSize() const;
525 
526   PythonObject GetItemAtIndex(uint32_t index) const;
527 
528   void SetItemAtIndex(uint32_t index, const PythonObject &object);
529 
530   void AppendItem(const PythonObject &object);
531 
532   StructuredData::ArraySP CreateStructuredArray() const;
533 };
534 
535 class PythonTuple : public TypedPythonObject<PythonTuple> {
536 public:
537   using TypedPythonObject::TypedPythonObject;
538 
539   explicit PythonTuple(PyInitialValue value);
540   explicit PythonTuple(int tuple_size);
541   PythonTuple(std::initializer_list<PythonObject> objects);
542   PythonTuple(std::initializer_list<PyObject *> objects);
543 
544   static bool Check(PyObject *py_obj);
545 
546   uint32_t GetSize() const;
547 
548   PythonObject GetItemAtIndex(uint32_t index) const;
549 
550   void SetItemAtIndex(uint32_t index, const PythonObject &object);
551 
552   StructuredData::ArraySP CreateStructuredArray() const;
553 };
554 
555 class PythonDictionary : public TypedPythonObject<PythonDictionary> {
556 public:
557   using TypedPythonObject::TypedPythonObject;
558 
559   PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
560 
561   explicit PythonDictionary(PyInitialValue value);
562 
563   static bool Check(PyObject *py_obj);
564 
565   uint32_t GetSize() const;
566 
567   PythonList GetKeys() const;
568 
569   PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
570   void SetItemForKey(const PythonObject &key,
571                      const PythonObject &value); // DEPRECATED
572 
573   llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
574   llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
575   llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
576   llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
577 
578   StructuredData::DictionarySP CreateStructuredDictionary() const;
579 };
580 
581 class PythonModule : public TypedPythonObject<PythonModule> {
582 public:
583   using TypedPythonObject::TypedPythonObject;
584 
585   static bool Check(PyObject *py_obj);
586 
587   static PythonModule BuiltinsModule();
588 
589   static PythonModule MainModule();
590 
591   static PythonModule AddModule(llvm::StringRef module);
592 
593   // safe, returns invalid on error;
594   static PythonModule ImportModule(llvm::StringRef name) {
595     std::string s = std::string(name);
596     auto mod = Import(s.c_str());
597     if (!mod) {
598       llvm::consumeError(mod.takeError());
599       return PythonModule();
600     }
601     return std::move(mod.get());
602   }
603 
604   static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
605 
606   llvm::Expected<PythonObject> Get(const llvm::Twine &name);
607 
608   PythonDictionary GetDictionary() const;
609 };
610 
611 class PythonCallable : public TypedPythonObject<PythonCallable> {
612 public:
613   using TypedPythonObject::TypedPythonObject;
614 
615   struct ArgInfo {
616     /* the largest number of positional arguments this callable
617      * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
618      * function and can accept an arbitrary number */
619     unsigned max_positional_args;
620     static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
621   };
622 
623   static bool Check(PyObject *py_obj);
624 
625   llvm::Expected<ArgInfo> GetArgInfo() const;
626 
627   PythonObject operator()();
628 
629   PythonObject operator()(std::initializer_list<PyObject *> args);
630 
631   PythonObject operator()(std::initializer_list<PythonObject> args);
632 
633   template <typename Arg, typename... Args>
634   PythonObject operator()(const Arg &arg, Args... args) {
635     return operator()({arg, args...});
636   }
637 };
638 
639 class PythonFile : public TypedPythonObject<PythonFile> {
640 public:
641   using TypedPythonObject::TypedPythonObject;
642 
643   PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
644 
645   static bool Check(PyObject *py_obj);
646 
647   static llvm::Expected<PythonFile> FromFile(File &file,
648                                              const char *mode = nullptr);
649 
650   llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
651   llvm::Expected<lldb::FileSP>
652   ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
653 };
654 
655 class PythonException : public llvm::ErrorInfo<PythonException> {
656 private:
657   PyObject *m_exception_type, *m_exception, *m_traceback;
658   PyObject *m_repr_bytes;
659 
660 public:
661   static char ID;
662   const char *toCString() const;
663   PythonException(const char *caller = nullptr);
664   void Restore();
665   ~PythonException() override;
666   void log(llvm::raw_ostream &OS) const override;
667   std::error_code convertToErrorCode() const override;
668   bool Matches(PyObject *exc) const;
669   std::string ReadBacktrace() const;
670 };
671 
672 // This extracts the underlying T out of an Expected<T> and returns it.
673 // If the Expected is an Error instead of a T, that error will be converted
674 // into a python exception, and this will return a default-constructed T.
675 //
676 // This is appropriate for use right at the boundary of python calling into
677 // C++, such as in a SWIG typemap.   In such a context you should simply
678 // check if the returned T is valid, and if it is, return a NULL back
679 // to python.   This will result in the Error being raised as an exception
680 // from python code's point of view.
681 //
682 // For example:
683 // ```
684 // Expected<Foo *> efoop = some_cpp_function();
685 // Foo *foop = unwrapOrSetPythonException(efoop);
686 // if (!foop)
687 //    return NULL;
688 // do_something(*foop);
689 //
690 // If the Error returned was itself created because a python exception was
691 // raised when C++ code called into python, then the original exception
692 // will be restored.   Otherwise a simple string exception will be raised.
693 template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
694   if (expected)
695     return expected.get();
696   llvm::handleAllErrors(
697       expected.takeError(), [](PythonException &E) { E.Restore(); },
698       [](const llvm::ErrorInfoBase &E) {
699         PyErr_SetString(PyExc_Exception, E.message().c_str());
700       });
701   return T();
702 }
703 
704 // This is only here to help incrementally migrate old, exception-unsafe
705 // code.
706 template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
707   if (expected)
708     return std::move(expected.get());
709   llvm::consumeError(expected.takeError());
710   return T();
711 }
712 
713 llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
714                                               const PythonDictionary &globals,
715                                               const PythonDictionary &locals);
716 
717 llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
718                                                 const PythonDictionary &globals,
719                                                 const PythonDictionary &locals);
720 
721 // Sometimes the best way to interact with a python interpreter is
722 // to run some python code.   You construct a PythonScript with
723 // script string.   The script assigns some function to `_function_`
724 // and you get a C++ callable object that calls the python function.
725 //
726 // Example:
727 //
728 // const char script[] = R"(
729 // def main(x, y):
730 //    ....
731 // )";
732 //
733 // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
734 //   // no need to synchronize access to this global, we already have the GIL
735 //   static PythonScript foo(script)
736 //   return  foo(x, y);
737 // }
738 class PythonScript {
739   const char *script;
740   PythonCallable function;
741 
742   llvm::Error Init();
743 
744 public:
745   PythonScript(const char *script) : script(script), function() {}
746 
747   template <typename... Args>
748   llvm::Expected<PythonObject> operator()(Args &&... args) {
749     if (llvm::Error error = Init())
750       return std::move(error);
751     return function.Call(std::forward<Args>(args)...);
752   }
753 };
754 
755 class StructuredPythonObject : public StructuredData::Generic {
756 public:
757   StructuredPythonObject() : StructuredData::Generic() {}
758 
759   // Take ownership of the object we received.
760   StructuredPythonObject(PythonObject obj)
761       : StructuredData::Generic(obj.release()) {}
762 
763   ~StructuredPythonObject() override {
764     // Hand ownership back to a (temporary) PythonObject instance and let it
765     // take care of releasing it.
766     PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
767   }
768 
769   bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
770 
771   void Serialize(llvm::json::OStream &s) const override;
772 
773 private:
774   StructuredPythonObject(const StructuredPythonObject &) = delete;
775   const StructuredPythonObject &
776   operator=(const StructuredPythonObject &) = delete;
777 };
778 
779 } // namespace python
780 } // namespace lldb_private
781 
782 #endif
783 
784 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
785