48#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
49#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
51#include "lldb/Host/Config.h"
61#include "llvm/ADT/ArrayRef.h"
70class PythonDictionary;
77 m_state = PyGILState_Ensure();
78 assert(!PyErr_Occurred());
80 ~GIL() { PyGILState_Release(m_state); }
83 PyGILState_STATE m_state;
86enum class PyObjectType {
102enum class PyRefType {
120template <
typename T> T Take(PyObject *obj) {
122 assert(!PyErr_Occurred());
123 T thing(PyRefType::Owned, obj);
124 assert(thing.IsValid());
138template <
typename T> T Retain(PyObject *obj) {
140 assert(!PyErr_Occurred());
141 T thing(PyRefType::Borrowed, obj);
142 assert(thing.IsValid());
158class NullTerminated {
160 llvm::SmallString<32> storage;
163 NullTerminated(
const llvm::Twine &twine) {
164 llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
167 operator const char *() {
return str; }
170inline llvm::Error nullDeref() {
171 return llvm::createStringError(llvm::inconvertibleErrorCode(),
172 "A NULL PyObject* was dereferenced");
175inline llvm::Error exception(
const char *s =
nullptr) {
176 return llvm::make_error<PythonException>(s);
179inline llvm::Error keyError() {
180 return llvm::createStringError(llvm::inconvertibleErrorCode(),
184inline const char *py2_const_cast(
const char *s) {
return s; }
189template <
typename T,
typename Enable =
void>
struct PythonFormat;
191template <
typename T,
char F>
struct PassthroughFormat {
192 static constexpr char format = F;
193 static constexpr T get(T t) {
return t; }
196template <>
struct PythonFormat<char *> : PassthroughFormat<
char *,
's'> {};
198struct PythonFormat<const char *> : PassthroughFormat<
const char *,
's'> {};
199template <>
struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
201struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
202template <>
struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
204struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
205template <>
struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
206template <>
struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
208struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
209template <>
struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
211struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {};
213struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {};
215struct PythonFormat<unsigned long long>
216 : PassthroughFormat<unsigned long long, 'K'> {};
218struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *,
'O'> {};
222 T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
223 static constexpr char format =
'O';
224 static auto get(
const T &value) {
return value.get(); }
229 PythonObject() =
default;
231 PythonObject(PyRefType type, PyObject *py_obj) {
237 if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
238 Py_XINCREF(m_py_obj);
241 PythonObject(
const PythonObject &rhs)
242 : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
244 PythonObject(PythonObject &&rhs) {
245 m_py_obj = rhs.m_py_obj;
246 rhs.m_py_obj =
nullptr;
249 ~PythonObject() { Reset(); }
253 void Dump(Stream &strm)
const;
255 PyObject *get()
const {
return m_py_obj; }
257 PyObject *release() {
258 PyObject *result = m_py_obj;
263 PythonObject &operator=(PythonObject other) {
265 m_py_obj = std::exchange(other.m_py_obj,
nullptr);
269 PyObjectType GetObjectType()
const;
271 PythonString Repr()
const;
273 PythonString Str()
const;
275 static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
276 const PythonDictionary &dict);
278 template <
typename T>
279 static T ResolveNameWithDictionary(llvm::StringRef name,
280 const PythonDictionary &dict) {
281 return ResolveNameWithDictionary(name, dict).AsType<T>();
284 PythonObject ResolveName(llvm::StringRef name)
const;
286 template <
typename T> T ResolveName(llvm::StringRef name)
const {
287 return ResolveName(name).AsType<T>();
290 bool HasAttribute(llvm::StringRef attribute)
const;
292 PythonObject GetAttributeValue(llvm::StringRef attribute)
const;
294 bool IsNone()
const {
return m_py_obj == Py_None; }
296 bool IsValid()
const {
return m_py_obj !=
nullptr; }
298 bool IsAllocated()
const {
return IsValid() && !IsNone(); }
300 explicit operator bool()
const {
return IsValid() && !IsNone(); }
302 template <
typename T> T AsType()
const {
303 if (!T::Check(m_py_obj))
305 return T(PyRefType::Borrowed, m_py_obj);
308 StructuredData::ObjectSP CreateStructuredObject()
const;
310 template <
typename... T>
311 llvm::Expected<PythonObject> CallMethod(
const char *name,
312 const T &... t)
const {
313 const char format[] = {
'(', PythonFormat<T>::format...,
')', 0};
315 PyObject_CallMethod(m_py_obj, py2_const_cast(name),
316 py2_const_cast(format), PythonFormat<T>::get(t)...);
319 return python::Take<PythonObject>(obj);
322 template <
typename... T>
323 llvm::Expected<PythonObject> Call(
const T &... t)
const {
324 const char format[] = {
'(', PythonFormat<T>::format...,
')', 0};
325 PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
326 PythonFormat<T>::get(t)...);
329 return python::Take<PythonObject>(obj);
332 llvm::Expected<PythonObject> GetAttribute(
const llvm::Twine &name)
const {
335 PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
338 return python::Take<PythonObject>(obj);
341 llvm::Expected<PythonObject> GetType()
const {
344 PyObject *obj = PyObject_Type(m_py_obj);
347 return python::Take<PythonObject>(obj);
350 llvm::Expected<bool> IsTrue() {
353 int r = PyObject_IsTrue(m_py_obj);
359 llvm::Expected<long long> AsLongLong()
const;
361 llvm::Expected<unsigned long long> AsUnsignedLongLong()
const;
364 llvm::Expected<unsigned long long> AsModuloUnsignedLongLong()
const;
366 llvm::Expected<bool> IsInstance(
const PythonObject &cls) {
367 if (!m_py_obj || !cls.IsValid())
369 int r = PyObject_IsInstance(m_py_obj, cls.get());
376 PyObject *m_py_obj =
nullptr;
381template <
typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
383 return obj.takeError();
384 if (!T::Check(obj.get().get()))
385 return llvm::createStringError(llvm::inconvertibleErrorCode(),
387 return T(PyRefType::Borrowed, std::move(obj.get().get()));
390template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
393llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
396llvm::Expected<unsigned long long>
397As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
400llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
403template <
class T>
class TypedPythonObject :
public PythonObject {
405 TypedPythonObject(PyRefType type, PyObject *py_obj) {
408 if (T::Check(py_obj))
409 PythonObject::operator=(PythonObject(type, py_obj));
410 else if (type == PyRefType::Owned)
414 TypedPythonObject() =
default;
417class PythonBytes :
public TypedPythonObject<PythonBytes> {
419 using TypedPythonObject::TypedPythonObject;
420 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
421 PythonBytes(
const uint8_t *bytes,
size_t length);
423 static bool Check(PyObject *py_obj);
425 llvm::ArrayRef<uint8_t>
GetBytes()
const;
427 size_t GetSize()
const;
429 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
431 StructuredData::StringSP CreateStructuredString()
const;
434class PythonByteArray :
public TypedPythonObject<PythonByteArray> {
436 using TypedPythonObject::TypedPythonObject;
437 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
438 PythonByteArray(
const uint8_t *bytes,
size_t length);
439 PythonByteArray(
const PythonBytes &
object);
441 static bool Check(PyObject *py_obj);
443 llvm::ArrayRef<uint8_t>
GetBytes()
const;
445 size_t GetSize()
const;
447 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
449 StructuredData::StringSP CreateStructuredString()
const;
452class PythonString :
public TypedPythonObject<PythonString> {
454 using TypedPythonObject::TypedPythonObject;
455 static llvm::Expected<PythonString> FromUTF8(llvm::StringRef
string);
457 PythonString() : TypedPythonObject() {}
459 explicit PythonString(llvm::StringRef
string);
461 static bool Check(PyObject *py_obj);
463 llvm::StringRef GetString()
const;
465 llvm::Expected<llvm::StringRef> AsUTF8()
const;
467 size_t GetSize()
const;
469 void SetString(llvm::StringRef
string);
471 StructuredData::StringSP CreateStructuredString()
const;
474class PythonInteger :
public TypedPythonObject<PythonInteger> {
476 using TypedPythonObject::TypedPythonObject;
478 PythonInteger() : TypedPythonObject() {}
480 explicit PythonInteger(int64_t value);
482 static bool Check(PyObject *py_obj);
486 StructuredData::IntegerSP CreateStructuredInteger()
const;
488 StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger()
const;
490 StructuredData::SignedIntegerSP CreateStructuredSignedInteger()
const;
493class PythonBoolean :
public TypedPythonObject<PythonBoolean> {
495 using TypedPythonObject::TypedPythonObject;
497 explicit PythonBoolean(
bool value);
499 static bool Check(PyObject *py_obj);
501 bool GetValue()
const;
503 void SetValue(
bool value);
505 StructuredData::BooleanSP CreateStructuredBoolean()
const;
508class PythonList :
public TypedPythonObject<PythonList> {
510 using TypedPythonObject::TypedPythonObject;
512 PythonList() : TypedPythonObject() {}
514 explicit PythonList(PyInitialValue value);
515 explicit PythonList(
int list_size);
517 static bool Check(PyObject *py_obj);
519 uint32_t GetSize()
const;
521 PythonObject GetItemAtIndex(uint32_t index)
const;
523 void SetItemAtIndex(uint32_t index,
const PythonObject &
object);
525 void AppendItem(
const PythonObject &
object);
527 StructuredData::ArraySP CreateStructuredArray()
const;
530class PythonTuple :
public TypedPythonObject<PythonTuple> {
532 using TypedPythonObject::TypedPythonObject;
534 explicit PythonTuple(PyInitialValue value);
535 explicit PythonTuple(
int tuple_size);
536 PythonTuple(std::initializer_list<PythonObject> objects);
537 PythonTuple(std::initializer_list<PyObject *> objects);
539 static bool Check(PyObject *py_obj);
541 uint32_t GetSize()
const;
543 PythonObject GetItemAtIndex(uint32_t index)
const;
545 void SetItemAtIndex(uint32_t index,
const PythonObject &
object);
547 StructuredData::ArraySP CreateStructuredArray()
const;
550class PythonDictionary :
public TypedPythonObject<PythonDictionary> {
552 using TypedPythonObject::TypedPythonObject;
554 PythonDictionary() : TypedPythonObject() {}
556 explicit PythonDictionary(PyInitialValue value);
558 static bool Check(PyObject *py_obj);
560 bool HasKey(
const llvm::Twine &key)
const;
562 uint32_t GetSize()
const;
564 PythonList GetKeys()
const;
566 PythonObject GetItemForKey(
const PythonObject &key)
const;
567 void SetItemForKey(
const PythonObject &key,
568 const PythonObject &value);
570 llvm::Expected<PythonObject> GetItem(
const PythonObject &key)
const;
571 llvm::Expected<PythonObject> GetItem(
const llvm::Twine &key)
const;
572 llvm::Error SetItem(
const PythonObject &key,
const PythonObject &value)
const;
573 llvm::Error SetItem(
const llvm::Twine &key,
const PythonObject &value)
const;
575 StructuredData::DictionarySP CreateStructuredDictionary()
const;
578class PythonModule :
public TypedPythonObject<PythonModule> {
580 using TypedPythonObject::TypedPythonObject;
582 static bool Check(PyObject *py_obj);
584 static PythonModule BuiltinsModule();
586 static PythonModule MainModule();
588 static PythonModule AddModule(llvm::StringRef module);
591 static PythonModule ImportModule(llvm::StringRef name) {
592 std::string s = std::string(name);
593 auto mod = Import(s.c_str());
595 llvm::consumeError(mod.takeError());
596 return PythonModule();
598 return std::move(mod.get());
601 static llvm::Expected<PythonModule> Import(
const llvm::Twine &name);
603 llvm::Expected<PythonObject> Get(
const llvm::Twine &name);
605 PythonDictionary GetDictionary()
const;
608class PythonCallable :
public TypedPythonObject<PythonCallable> {
610 using TypedPythonObject::TypedPythonObject;
616 unsigned max_positional_args;
617 static constexpr unsigned UNBOUNDED = UINT_MAX;
620 static bool Check(PyObject *py_obj);
622 llvm::Expected<ArgInfo> GetArgInfo()
const;
624 PythonObject operator()();
626 PythonObject operator()(std::initializer_list<PyObject *> args);
628 PythonObject operator()(std::initializer_list<PythonObject> args);
630 template <
typename Arg,
typename... Args>
631 PythonObject operator()(
const Arg &arg, Args... args) {
632 return operator()({arg, args...});
636class PythonFile :
public TypedPythonObject<PythonFile> {
638 using TypedPythonObject::TypedPythonObject;
640 PythonFile() : TypedPythonObject() {}
642 static bool Check(PyObject *py_obj);
644 static llvm::Expected<PythonFile> FromFile(File &file,
645 const char *mode =
nullptr);
647 llvm::Expected<lldb::FileSP> ConvertToFile(
bool borrowed =
false);
648 llvm::Expected<lldb::FileSP>
649 ConvertToFileForcingUseOfScriptingIOMethods(
bool borrowed =
false);
652class PythonException :
public llvm::ErrorInfo<PythonException> {
654 PyObject *m_exception_type, *m_exception, *m_traceback;
655 PyObject *m_repr_bytes;
659 const char *toCString()
const;
660 PythonException(
const char *caller =
nullptr);
662 ~PythonException()
override;
663 void log(llvm::raw_ostream &OS)
const override;
664 std::error_code convertToErrorCode()
const override;
665 bool Matches(PyObject *exc)
const;
666 std::string ReadBacktrace()
const;
690template <
typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
692 return expected.get();
693 llvm::handleAllErrors(
694 expected.takeError(), [](PythonException &E) { E.Restore(); },
695 [](
const llvm::ErrorInfoBase &E) {
696 PyErr_SetString(PyExc_Exception, E.message().c_str());
703template <
typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
705 return std::move(expected.get());
706 llvm::consumeError(expected.takeError());
710llvm::Expected<PythonObject> runStringOneLine(
const llvm::Twine &
string,
711 const PythonDictionary &globals,
712 const PythonDictionary &locals);
714llvm::Expected<PythonObject> runStringMultiLine(
const llvm::Twine &
string,
715 const PythonDictionary &globals,
716 const PythonDictionary &locals);
737 PythonCallable function;
742 PythonScript(
const char *script) : script(script), function() {}
744 template <
typename... Args>
745 llvm::Expected<PythonObject> operator()(Args &&... args) {
746 if (llvm::Error
error = Init())
747 return std::move(
error);
748 return function.Call(std::forward<Args>(args)...);
752class StructuredPythonObject :
public StructuredData::Generic {
754 StructuredPythonObject() : StructuredData::Generic() {}
757 StructuredPythonObject(PythonObject obj)
758 : StructuredData::Generic(obj.release()) {}
760 ~StructuredPythonObject()
override {
763 PythonObject(PyRefType::Owned,
static_cast<PyObject *
>(GetValue()));
766 bool IsValid()
const override {
return GetValue() && GetValue() != Py_None; }
768 void Serialize(llvm::json::OStream &s)
const override;
771 StructuredPythonObject(
const StructuredPythonObject &) =
delete;
772 const StructuredPythonObject &
773 operator=(
const StructuredPythonObject &) =
delete;
776PyObject *RunString(
const char *str,
int start, PyObject *globals,
778int RunSimpleString(
const char *str);
static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed)
static llvm::raw_ostream & error(Stream &strm)
@ Empty
If the Mangled object has neither a mangled name or demangled name we can encode the object with one ...
static uint32_t GetBytes(uint32_t bits)
A class that represents a running process on the host machine.
StructuredData::ObjectSP Serialize(llvm::ArrayRef< DiagnosticDetail > details)