2015-10-24 01:08:35 +00:00
|
|
|
//===-- PythonDataObjects.h--------------------------------------*- C++ -*-===//
|
2012-08-23 22:02:23 +00:00
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2012-08-23 22:02:23 +00:00
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2015-07-30 20:28:07 +00:00
|
|
|
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
|
|
|
|
|
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
|
2012-08-23 22:02:23 +00:00
|
|
|
|
2018-06-21 17:36:32 +00:00
|
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
|
|
|
|
2016-08-19 20:44:07 +00:00
|
|
|
// LLDB Python header must be included first
|
|
|
|
|
#include "lldb-python.h"
|
|
|
|
|
|
2017-02-14 19:06:07 +00:00
|
|
|
#include "lldb/Utility/Flags.h"
|
|
|
|
|
|
2015-10-15 19:35:48 +00:00
|
|
|
#include "lldb/Host/File.h"
|
2012-08-23 22:02:23 +00:00
|
|
|
#include "lldb/Interpreter/OptionValue.h"
|
2017-02-02 21:39:50 +00:00
|
|
|
#include "lldb/Utility/ConstString.h"
|
2017-06-27 10:45:31 +00:00
|
|
|
#include "lldb/Utility/StructuredData.h"
|
2016-08-11 14:12:10 +00:00
|
|
|
#include "lldb/lldb-defines.h"
|
2012-08-23 22:02:23 +00:00
|
|
|
|
2016-01-11 22:16:12 +00:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
|
|
|
|
2012-08-23 22:02:23 +00:00
|
|
|
namespace lldb_private {
|
2015-10-24 01:08:35 +00:00
|
|
|
|
2016-01-11 22:16:12 +00:00
|
|
|
class PythonBytes;
|
2015-03-17 20:04:04 +00:00
|
|
|
class PythonString;
|
|
|
|
|
class PythonList;
|
|
|
|
|
class PythonDictionary;
|
|
|
|
|
class PythonInteger;
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class StructuredPythonObject : public StructuredData::Generic {
|
2015-10-24 01:08:35 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredPythonObject() : StructuredData::Generic() {}
|
|
|
|
|
|
|
|
|
|
StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
|
|
|
|
|
Py_XINCREF(GetValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~StructuredPythonObject() override {
|
|
|
|
|
if (Py_IsInitialized())
|
|
|
|
|
Py_XDECREF(GetValue());
|
|
|
|
|
SetValue(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
|
|
|
|
|
|
|
|
|
|
void Dump(Stream &s, bool pretty_print = true) const override;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2015-10-24 01:08:35 +00:00
|
|
|
private:
|
2016-09-06 20:57:50 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
|
2015-03-17 20:04:04 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
enum class PyObjectType {
|
|
|
|
|
Unknown,
|
|
|
|
|
None,
|
|
|
|
|
Integer,
|
|
|
|
|
Dictionary,
|
|
|
|
|
List,
|
|
|
|
|
String,
|
|
|
|
|
Bytes,
|
|
|
|
|
ByteArray,
|
|
|
|
|
Module,
|
|
|
|
|
Callable,
|
|
|
|
|
Tuple,
|
|
|
|
|
File
|
2015-03-17 20:04:04 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
enum class PyRefType {
|
|
|
|
|
Borrowed, // We are not given ownership of the incoming PyObject.
|
|
|
|
|
// We cannot safely hold it without calling Py_INCREF.
|
|
|
|
|
Owned // We have ownership of the incoming PyObject. We should
|
|
|
|
|
// not call Py_INCREF.
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
enum class PyInitialValue { Invalid, Empty };
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonObject {
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject() : m_py_obj(nullptr) {}
|
|
|
|
|
|
|
|
|
|
PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
|
|
|
|
|
Reset(type, py_obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); }
|
|
|
|
|
|
|
|
|
|
virtual ~PythonObject() { Reset(); }
|
|
|
|
|
|
|
|
|
|
void Reset() {
|
|
|
|
|
// Avoid calling the virtual method since it's not necessary
|
|
|
|
|
// to actually validate the type of the PyObject if we're
|
|
|
|
|
// just setting to null.
|
|
|
|
|
if (Py_IsInitialized())
|
|
|
|
|
Py_XDECREF(m_py_obj);
|
|
|
|
|
m_py_obj = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Reset(const PythonObject &rhs) {
|
|
|
|
|
// Avoid calling the virtual method if it's not necessary
|
|
|
|
|
// to actually validate the type of the PyObject.
|
|
|
|
|
if (!rhs.IsValid())
|
|
|
|
|
Reset();
|
|
|
|
|
else
|
|
|
|
|
Reset(PyRefType::Borrowed, rhs.m_py_obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PythonObject is implicitly convertible to PyObject *, which will call the
|
|
|
|
|
// wrong overload. We want to explicitly disallow this, since a PyObject
|
|
|
|
|
// *always* owns its reference. Therefore the overload which takes a
|
|
|
|
|
// PyRefType doesn't make sense, and the copy constructor should be used.
|
|
|
|
|
void Reset(PyRefType type, const PythonObject &ref) = delete;
|
|
|
|
|
|
|
|
|
|
virtual void Reset(PyRefType type, PyObject *py_obj) {
|
|
|
|
|
if (py_obj == m_py_obj)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (Py_IsInitialized())
|
|
|
|
|
Py_XDECREF(m_py_obj);
|
|
|
|
|
|
|
|
|
|
m_py_obj = py_obj;
|
|
|
|
|
|
|
|
|
|
// If this is a borrowed reference, we need to convert it to
|
|
|
|
|
// an owned reference by incrementing it. If it is an owned
|
|
|
|
|
// reference (for example the caller allocated it with PyDict_New()
|
|
|
|
|
// then we must *not* increment it.
|
|
|
|
|
if (Py_IsInitialized() && type == PyRefType::Borrowed)
|
|
|
|
|
Py_XINCREF(m_py_obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Dump() const {
|
|
|
|
|
if (m_py_obj)
|
|
|
|
|
_PyObject_Dump(m_py_obj);
|
|
|
|
|
else
|
|
|
|
|
puts("NULL");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Dump(Stream &strm) const;
|
|
|
|
|
|
|
|
|
|
PyObject *get() const { return m_py_obj; }
|
|
|
|
|
|
|
|
|
|
PyObject *release() {
|
|
|
|
|
PyObject *result = m_py_obj;
|
|
|
|
|
m_py_obj = nullptr;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PythonObject &operator=(const PythonObject &other) {
|
|
|
|
|
Reset(PyRefType::Borrowed, other.get());
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PyObjectType GetObjectType() const;
|
|
|
|
|
|
|
|
|
|
PythonString Repr() const;
|
|
|
|
|
|
|
|
|
|
PythonString Str() const;
|
|
|
|
|
|
|
|
|
|
static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
|
|
|
|
|
const PythonDictionary &dict);
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
static T ResolveNameWithDictionary(llvm::StringRef name,
|
|
|
|
|
const PythonDictionary &dict) {
|
|
|
|
|
return ResolveNameWithDictionary(name, dict).AsType<T>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PythonObject ResolveName(llvm::StringRef name) const;
|
|
|
|
|
|
|
|
|
|
template <typename T> T ResolveName(llvm::StringRef name) const {
|
|
|
|
|
return ResolveName(name).AsType<T>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HasAttribute(llvm::StringRef attribute) const;
|
|
|
|
|
|
|
|
|
|
PythonObject GetAttributeValue(llvm::StringRef attribute) const;
|
|
|
|
|
|
|
|
|
|
bool IsValid() const;
|
|
|
|
|
|
|
|
|
|
bool IsAllocated() const;
|
|
|
|
|
|
|
|
|
|
bool IsNone() const;
|
|
|
|
|
|
|
|
|
|
template <typename T> T AsType() const {
|
|
|
|
|
if (!T::Check(m_py_obj))
|
|
|
|
|
return T();
|
|
|
|
|
return T(PyRefType::Borrowed, m_py_obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StructuredData::ObjectSP CreateStructuredObject() const;
|
2012-08-24 05:45:15 +00:00
|
|
|
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
protected:
|
2016-09-06 20:57:50 +00:00
|
|
|
PyObject *m_py_obj;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
};
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonBytes : public PythonObject {
|
2016-01-11 22:16:12 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonBytes();
|
|
|
|
|
explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
|
|
|
|
|
PythonBytes(const uint8_t *bytes, size_t length);
|
|
|
|
|
PythonBytes(PyRefType type, PyObject *o);
|
|
|
|
|
PythonBytes(const PythonBytes &object);
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonBytes() override;
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
llvm::ArrayRef<uint8_t> GetBytes() const;
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
size_t GetSize() const;
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
|
2016-01-11 22:16:12 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::StringSP CreateStructuredString() const;
|
2016-01-11 22:16:12 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonByteArray : public PythonObject {
|
2016-01-25 23:21:09 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonByteArray();
|
|
|
|
|
explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
|
|
|
|
|
PythonByteArray(const uint8_t *bytes, size_t length);
|
|
|
|
|
PythonByteArray(PyRefType type, PyObject *o);
|
|
|
|
|
PythonByteArray(const PythonBytes &object);
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonByteArray() override;
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
llvm::ArrayRef<uint8_t> GetBytes() const;
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
size_t GetSize() const;
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
|
2016-01-25 23:21:09 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::StringSP CreateStructuredString() const;
|
2016-01-25 23:21:09 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonString : public PythonObject {
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonString();
|
|
|
|
|
explicit PythonString(llvm::StringRef string);
|
|
|
|
|
explicit PythonString(const char *string);
|
|
|
|
|
PythonString(PyRefType type, PyObject *o);
|
|
|
|
|
PythonString(const PythonString &object);
|
2015-10-24 01:08:35 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonString() override;
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
llvm::StringRef GetString() const;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
size_t GetSize() const;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void SetString(llvm::StringRef string);
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::StringSP CreateStructuredString() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
};
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonInteger : public PythonObject {
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonInteger();
|
|
|
|
|
explicit PythonInteger(int64_t value);
|
|
|
|
|
PythonInteger(PyRefType type, PyObject *o);
|
|
|
|
|
PythonInteger(const PythonInteger &object);
|
2015-10-24 01:08:35 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonInteger() override;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
int64_t GetInteger() const;
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void SetInteger(int64_t value);
|
Port native Python-API to 3.x
With this change, liblldb is 95% of the way towards being able
to work under both Python 2.x and Python 3.x. This should
introduce no functional change for Python 2.x, but for Python
3.x there are some important changes. Primarily, these are:
1) PyString doesn't exist in Python 3. Everything is a PyUnicode.
To account for this, PythonString now stores a PyBytes instead
of a PyString. In Python 2, this is equivalent to a PyUnicode,
and in Python 3, we do a conversion from PyUnicode to PyBytes
and store the PyBytes.
2) PyInt doesn't exist in Python 3. Everything is a PyLong. To
account for this, PythonInteger stores a PyLong instead of a
PyInt. In Python 2.x, this requires doing a conversion to
PyLong when creating a PythonInteger from a PyInt. In 3.x,
there is no PyInt anyway, so we can assume everything is a
PyLong.
3) PyFile_FromFile doesn't exist in Python 3. Instead there is a
PyFile_FromFd. This is not addressed in this patch because it
will require quite a large change to plumb fd's all the way
through the system into the ScriptInterpreter. This is the only
remaining piece of the puzzle to get LLDB supporting Python 3.x.
Being able to run the test suite is not addressed in this patch.
After the extension module can compile and you can enter an embedded
3.x interpreter, the test suite will be addressed in a followup.
llvm-svn: 249886
2015-10-09 19:45:41 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::IntegerSP CreateStructuredInteger() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
};
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonList : public PythonObject {
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonList() {}
|
|
|
|
|
explicit PythonList(PyInitialValue value);
|
|
|
|
|
explicit PythonList(int list_size);
|
|
|
|
|
PythonList(PyRefType type, PyObject *o);
|
|
|
|
|
PythonList(const PythonList &list);
|
2015-10-24 01:08:35 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonList() override;
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2012-08-24 01:42:50 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2012-08-23 23:49:47 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2012-08-23 23:49:47 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
uint32_t GetSize() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject GetItemAtIndex(uint32_t index) const;
|
2014-01-27 23:43:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void SetItemAtIndex(uint32_t index, const PythonObject &object);
|
2015-03-17 20:04:04 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void AppendItem(const PythonObject &object);
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::ArraySP CreateStructuredArray() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonTuple : public PythonObject {
|
2015-11-11 19:42:27 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonTuple() {}
|
|
|
|
|
explicit PythonTuple(PyInitialValue value);
|
|
|
|
|
explicit PythonTuple(int tuple_size);
|
|
|
|
|
PythonTuple(PyRefType type, PyObject *o);
|
|
|
|
|
PythonTuple(const PythonTuple &tuple);
|
|
|
|
|
PythonTuple(std::initializer_list<PythonObject> objects);
|
|
|
|
|
PythonTuple(std::initializer_list<PyObject *> objects);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonTuple() override;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
uint32_t GetSize() const;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject GetItemAtIndex(uint32_t index) const;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void SetItemAtIndex(uint32_t index, const PythonObject &object);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::ArraySP CreateStructuredArray() const;
|
2015-11-11 19:42:27 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonDictionary : public PythonObject {
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonDictionary() {}
|
|
|
|
|
explicit PythonDictionary(PyInitialValue value);
|
|
|
|
|
PythonDictionary(PyRefType type, PyObject *o);
|
|
|
|
|
PythonDictionary(const PythonDictionary &dict);
|
2015-10-24 01:08:35 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonDictionary() override;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
uint32_t GetSize() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonList GetKeys() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject GetItemForKey(const PythonObject &key) const;
|
|
|
|
|
void SetItemForKey(const PythonObject &key, const PythonObject &value);
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
StructuredData::DictionarySP CreateStructuredDictionary() const;
|
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
2015-10-13 18:16:15 +00:00
|
|
|
};
|
2015-10-14 16:59:44 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonModule : public PythonObject {
|
|
|
|
|
public:
|
|
|
|
|
PythonModule();
|
|
|
|
|
PythonModule(PyRefType type, PyObject *o);
|
|
|
|
|
PythonModule(const PythonModule &dict);
|
2015-11-11 17:59:49 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonModule() override;
|
2015-11-11 17:59:49 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2015-11-11 17:59:49 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static PythonModule BuiltinsModule();
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static PythonModule MainModule();
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static PythonModule AddModule(llvm::StringRef module);
|
2015-11-11 17:59:49 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static PythonModule ImportModule(llvm::StringRef module);
|
2015-11-13 21:28:45 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2015-11-11 17:59:49 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2015-11-11 17:59:49 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonDictionary GetDictionary() const;
|
2015-11-11 17:59:49 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonCallable : public PythonObject {
|
2015-11-11 19:42:27 +00:00
|
|
|
public:
|
2016-09-06 20:57:50 +00:00
|
|
|
struct ArgInfo {
|
|
|
|
|
size_t count;
|
|
|
|
|
bool is_bound_method : 1;
|
|
|
|
|
bool has_varargs : 1;
|
|
|
|
|
bool has_kwargs : 1;
|
|
|
|
|
};
|
2015-11-12 16:23:16 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonCallable();
|
|
|
|
|
PythonCallable(PyRefType type, PyObject *o);
|
|
|
|
|
PythonCallable(const PythonCallable &dict);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonCallable() override;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
// Bring in the no-argument base class version
|
|
|
|
|
using PythonObject::Reset;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ArgInfo GetNumArguments() const;
|
2015-11-12 16:23:16 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject operator()();
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject operator()(std::initializer_list<PyObject *> args);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
PythonObject operator()(std::initializer_list<PythonObject> args);
|
2015-11-12 16:23:16 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
template <typename Arg, typename... Args>
|
|
|
|
|
PythonObject operator()(const Arg &arg, Args... args) {
|
|
|
|
|
return operator()({arg, args...});
|
|
|
|
|
}
|
2015-11-11 19:42:27 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
class PythonFile : public PythonObject {
|
|
|
|
|
public:
|
|
|
|
|
PythonFile();
|
|
|
|
|
PythonFile(File &file, const char *mode);
|
|
|
|
|
PythonFile(const char *path, const char *mode);
|
|
|
|
|
PythonFile(PyRefType type, PyObject *o);
|
2015-11-11 19:42:27 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
~PythonFile() override;
|
2015-10-24 01:08:35 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static bool Check(PyObject *py_obj);
|
2015-10-15 19:35:48 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
using PythonObject::Reset;
|
2015-10-15 19:35:48 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void Reset(PyRefType type, PyObject *py_obj) override;
|
|
|
|
|
void Reset(File &file, const char *mode);
|
2015-10-15 19:35:48 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
static uint32_t GetOptionsFromMode(llvm::StringRef mode);
|
2015-10-16 16:39:18 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
bool GetUnderlyingFile(File &file) const;
|
2015-10-15 19:35:48 +00:00
|
|
|
};
|
|
|
|
|
|
2012-08-23 22:02:23 +00:00
|
|
|
} // namespace lldb_private
|
|
|
|
|
|
2015-11-13 17:27:20 +00:00
|
|
|
#endif
|
2018-06-21 17:36:32 +00:00
|
|
|
|
|
|
|
|
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
|