mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 09:13:06 +00:00
libdrgn: python: add _cleanup_pydecref_ scope guard
We have tons of cleanup code just for calling Py_DECREF(); this is a perfect use case for a scope guard. Add it and use it everywhere that it is straightforward to. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
ee51244dc1
commit
91b26e2338
@ -11,6 +11,7 @@
|
||||
#include "structmember.h"
|
||||
|
||||
#include "docstrings.h"
|
||||
#include "../cleanup.h"
|
||||
#include "../drgn.h"
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
@ -73,6 +74,14 @@
|
||||
Py_RETURN_FALSE; \
|
||||
} while (0)
|
||||
|
||||
static inline void pydecrefp(void *p)
|
||||
{
|
||||
Py_XDECREF(*(PyObject **)p);
|
||||
}
|
||||
|
||||
/** Call @c Py_XDECREF() when the variable goes out of scope. */
|
||||
#define _cleanup_pydecref_ _cleanup_(pydecrefp)
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
struct drgn_object obj;
|
||||
|
@ -21,34 +21,26 @@ static int FaultError_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
static PyObject *FaultError_str(PyObject *self)
|
||||
{
|
||||
PyObject *message, *address, *args, *fmt, *ret = NULL;
|
||||
|
||||
message = PyObject_GetAttrString(self, "message");
|
||||
_cleanup_pydecref_ PyObject *message =
|
||||
PyObject_GetAttrString(self, "message");
|
||||
if (!message)
|
||||
return NULL;
|
||||
|
||||
address = PyObject_GetAttrString(self, "address");
|
||||
_cleanup_pydecref_ PyObject *address =
|
||||
PyObject_GetAttrString(self, "address");
|
||||
if (!address)
|
||||
goto out_message;
|
||||
return NULL;
|
||||
|
||||
args = Py_BuildValue("OO", message, address);
|
||||
_cleanup_pydecref_ PyObject *args =
|
||||
Py_BuildValue("OO", message, address);
|
||||
if (!args)
|
||||
goto out_address;
|
||||
return NULL;
|
||||
|
||||
fmt = PyUnicode_FromString("%s: %#x");
|
||||
_cleanup_pydecref_ PyObject *fmt = PyUnicode_FromString("%s: %#x");
|
||||
if (!fmt)
|
||||
goto out_args;
|
||||
return NULL;
|
||||
|
||||
ret = PyUnicode_Format(fmt, args);
|
||||
|
||||
Py_DECREF(fmt);
|
||||
out_args:
|
||||
Py_DECREF(args);
|
||||
out_address:
|
||||
Py_DECREF(address);
|
||||
out_message:
|
||||
Py_DECREF(message);
|
||||
return ret;
|
||||
return PyUnicode_Format(fmt, args);
|
||||
}
|
||||
|
||||
PyTypeObject FaultError_type = {
|
||||
@ -157,14 +149,11 @@ DRGNPY_PUBLIC void *set_drgn_error(struct drgn_error *err)
|
||||
PyErr_SetString(PyExc_LookupError, err->message);
|
||||
break;
|
||||
case DRGN_ERROR_FAULT: {
|
||||
PyObject *exc;
|
||||
|
||||
exc = PyObject_CallFunction((PyObject *)&FaultError_type, "sK",
|
||||
err->message, err->address);
|
||||
if (exc) {
|
||||
_cleanup_pydecref_ PyObject *exc =
|
||||
PyObject_CallFunction((PyObject *)&FaultError_type,
|
||||
"sK", err->message, err->address);
|
||||
if (exc)
|
||||
PyErr_SetObject((PyObject *)&FaultError_type, exc);
|
||||
Py_DECREF(exc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRGN_ERROR_TYPE:
|
||||
|
@ -28,8 +28,6 @@ PyObject *drgnpy_linux_helper_read_vm(PyObject *self, PyObject *args,
|
||||
struct index_arg pgtable = {};
|
||||
struct index_arg address = {};
|
||||
Py_ssize_t size;
|
||||
PyObject *buf;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O&O&n:read_vm",
|
||||
keywords, &Program_type, &prog,
|
||||
index_converter, &pgtable,
|
||||
@ -40,16 +38,14 @@ PyObject *drgnpy_linux_helper_read_vm(PyObject *self, PyObject *args,
|
||||
PyErr_SetString(PyExc_ValueError, "negative size");
|
||||
return NULL;
|
||||
}
|
||||
buf = PyBytes_FromStringAndSize(NULL, size);
|
||||
_cleanup_pydecref_ PyObject *buf = PyBytes_FromStringAndSize(NULL, size);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
err = linux_helper_read_vm(&prog->prog, pgtable.uvalue, address.uvalue,
|
||||
PyBytes_AS_STRING(buf), size);
|
||||
if (err) {
|
||||
Py_DECREF(buf);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return buf;
|
||||
return_ptr(buf);
|
||||
}
|
||||
|
||||
PyObject *drgnpy_linux_helper_follow_phys(PyObject *self, PyObject *args,
|
||||
@ -81,21 +77,18 @@ DrgnObject *drgnpy_linux_helper_per_cpu_ptr(PyObject *self, PyObject *args,
|
||||
struct drgn_error *err;
|
||||
DrgnObject *ptr;
|
||||
struct index_arg cpu = {};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O&:per_cpu_ptr",
|
||||
keywords, &DrgnObject_type, &ptr,
|
||||
index_converter, &cpu))
|
||||
return NULL;
|
||||
|
||||
DrgnObject *res = DrgnObject_alloc(DrgnObject_prog(ptr));
|
||||
_cleanup_pydecref_ DrgnObject *res = DrgnObject_alloc(DrgnObject_prog(ptr));
|
||||
if (!res)
|
||||
return NULL;
|
||||
err = linux_helper_per_cpu_ptr(&res->obj, &ptr->obj, cpu.uvalue);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
DrgnObject *drgnpy_linux_helper_cpu_curr(PyObject *self, PyObject *args,
|
||||
@ -105,21 +98,18 @@ DrgnObject *drgnpy_linux_helper_cpu_curr(PyObject *self, PyObject *args,
|
||||
struct drgn_error *err;
|
||||
Program *prog;
|
||||
struct index_arg cpu = {};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O&:cpu_curr", keywords,
|
||||
&Program_type, &prog, index_converter,
|
||||
&cpu))
|
||||
return NULL;
|
||||
|
||||
DrgnObject *res = DrgnObject_alloc(prog);
|
||||
_cleanup_pydecref_ DrgnObject *res = DrgnObject_alloc(prog);
|
||||
if (!res)
|
||||
return NULL;
|
||||
err = linux_helper_cpu_curr(&res->obj, cpu.uvalue);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
DrgnObject *drgnpy_linux_helper_idle_task(PyObject *self, PyObject *args,
|
||||
@ -129,21 +119,18 @@ DrgnObject *drgnpy_linux_helper_idle_task(PyObject *self, PyObject *args,
|
||||
struct drgn_error *err;
|
||||
Program *prog;
|
||||
struct index_arg cpu = {};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O&:idle_task", keywords,
|
||||
&Program_type, &prog, index_converter,
|
||||
&cpu))
|
||||
return NULL;
|
||||
|
||||
DrgnObject *res = DrgnObject_alloc(prog);
|
||||
_cleanup_pydecref_ DrgnObject *res = DrgnObject_alloc(prog);
|
||||
if (!res)
|
||||
return NULL;
|
||||
err = linux_helper_idle_task(&res->obj, cpu.uvalue);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
PyObject *drgnpy_linux_helper_task_cpu(PyObject *self, PyObject *args,
|
||||
@ -175,15 +162,13 @@ DrgnObject *drgnpy_linux_helper_xa_load(PyObject *self, PyObject *args,
|
||||
&index))
|
||||
return NULL;
|
||||
|
||||
DrgnObject *res = DrgnObject_alloc(DrgnObject_prog(xa));
|
||||
_cleanup_pydecref_ DrgnObject *res = DrgnObject_alloc(DrgnObject_prog(xa));
|
||||
if (!res)
|
||||
return NULL;
|
||||
err = linux_helper_xa_load(&res->obj, &xa->obj, index.uvalue);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
DrgnObject *drgnpy_linux_helper_idr_find(PyObject *self, PyObject *args,
|
||||
@ -193,22 +178,19 @@ DrgnObject *drgnpy_linux_helper_idr_find(PyObject *self, PyObject *args,
|
||||
struct drgn_error *err;
|
||||
DrgnObject *idr;
|
||||
struct index_arg id = {};
|
||||
DrgnObject *res;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O&:idr_find", keywords,
|
||||
&DrgnObject_type, &idr,
|
||||
index_converter, &id))
|
||||
return NULL;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(idr));
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(idr));
|
||||
if (!res)
|
||||
return NULL;
|
||||
err = linux_helper_idr_find(&res->obj, &idr->obj, id.uvalue);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
struct prog_or_ns_arg {
|
||||
@ -295,22 +277,18 @@ DrgnObject *drgnpy_linux_helper_pid_task(PyObject *self, PyObject *args,
|
||||
struct drgn_error *err;
|
||||
DrgnObject *pid;
|
||||
struct index_arg pid_type = {};
|
||||
DrgnObject *res;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O&:pid_task", keywords,
|
||||
&DrgnObject_type, &pid,
|
||||
index_converter, &pid_type))
|
||||
return NULL;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(pid));
|
||||
_cleanup_pydecref_ DrgnObject *res = DrgnObject_alloc(DrgnObject_prog(pid));
|
||||
if (!res)
|
||||
return NULL;
|
||||
err = linux_helper_pid_task(&res->obj, &pid->obj, pid_type.uvalue);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
DrgnObject *drgnpy_linux_helper_find_task(PyObject *self, PyObject *args,
|
||||
|
@ -188,34 +188,29 @@ static int add_type_aliases(PyObject *m)
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *os_module = PyImport_ImportModule("os");
|
||||
_cleanup_pydecref_ PyObject *os_module = PyImport_ImportModule("os");
|
||||
if (!os_module)
|
||||
return -1;
|
||||
PyObject *os_PathLike = PyObject_GetAttrString(os_module, "PathLike");
|
||||
Py_DECREF(os_module);
|
||||
_cleanup_pydecref_ PyObject *os_PathLike =
|
||||
PyObject_GetAttrString(os_module, "PathLike");
|
||||
if (!os_PathLike)
|
||||
return -1;
|
||||
PyObject *item = Py_BuildValue("OOO", &PyUnicode_Type, &PyBytes_Type,
|
||||
os_PathLike);
|
||||
Py_DECREF(os_PathLike);
|
||||
_cleanup_pydecref_ PyObject *item =
|
||||
Py_BuildValue("OOO", &PyUnicode_Type, &PyBytes_Type,
|
||||
os_PathLike);
|
||||
if (!item)
|
||||
return -1;
|
||||
|
||||
PyObject *typing_module = PyImport_ImportModule("typing");
|
||||
if (!typing_module) {
|
||||
Py_DECREF(item);
|
||||
_cleanup_pydecref_ PyObject *typing_module =
|
||||
PyImport_ImportModule("typing");
|
||||
if (!typing_module)
|
||||
return -1;
|
||||
}
|
||||
PyObject *typing_Union = PyObject_GetAttrString(typing_module, "Union");
|
||||
Py_DECREF(typing_module);
|
||||
if (!typing_Union) {
|
||||
Py_DECREF(item);
|
||||
_cleanup_pydecref_ PyObject *typing_Union =
|
||||
PyObject_GetAttrString(typing_module, "Union");
|
||||
if (!typing_Union)
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *Path = PyObject_GetItem(typing_Union, item);
|
||||
Py_DECREF(typing_Union);
|
||||
Py_DECREF(item);
|
||||
if (!Path)
|
||||
return -1;
|
||||
if (PyModule_AddObject(m, "Path", Path) == -1) {
|
||||
|
@ -26,11 +26,11 @@ static int DrgnObject_literal(struct drgn_object *res, PyObject *literal)
|
||||
PyErr_ExceptionMatches(PyExc_OverflowError)) {
|
||||
is_negative = true;
|
||||
PyErr_Clear();
|
||||
literal = PyNumber_Negative(literal);
|
||||
if (!literal)
|
||||
_cleanup_pydecref_ PyObject *negated =
|
||||
PyNumber_Negative(literal);
|
||||
if (!negated)
|
||||
return -1;
|
||||
uvalue = PyLong_AsUint64(literal);
|
||||
Py_DECREF(literal);
|
||||
uvalue = PyLong_AsUint64(negated);
|
||||
}
|
||||
if (uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
return -1;
|
||||
@ -61,7 +61,6 @@ static int serialize_compound_value(struct drgn_program *prog, char *buf,
|
||||
const struct drgn_object_type *type)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
int ret = -1;
|
||||
|
||||
if (!PyMapping_Check(value_obj)) {
|
||||
set_error_type_name("'%s' value must be dictionary or mapping",
|
||||
@ -69,16 +68,13 @@ static int serialize_compound_value(struct drgn_program *prog, char *buf,
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *tmp = PyMapping_Items(value_obj);
|
||||
_cleanup_pydecref_ PyObject *tmp = PyMapping_Items(value_obj);
|
||||
if (!tmp)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Since Python 3.7, PyMapping_Items() always returns a list. However,
|
||||
* before that, it could also return a tuple.
|
||||
*/
|
||||
PyObject *items = PySequence_Fast(tmp, "items must be sequence");
|
||||
Py_DECREF(tmp);
|
||||
// Since Python 3.7, PyMapping_Items() always returns a list. However,
|
||||
// before that, it could also return a tuple.
|
||||
_cleanup_pydecref_ PyObject *items =
|
||||
PySequence_Fast(tmp, "items must be sequence");
|
||||
if (!items)
|
||||
return -1;
|
||||
|
||||
@ -87,17 +83,17 @@ static int serialize_compound_value(struct drgn_program *prog, char *buf,
|
||||
PyObject *item = PySequence_Fast_GET_ITEM(items, i);
|
||||
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid item");
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
PyObject *key = PyTuple_GET_ITEM(item, 0);
|
||||
if (!PyUnicode_Check(key)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"member key must be string");
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
const char *member_name = PyUnicode_AsUTF8(key);
|
||||
if (!member_name)
|
||||
goto out;
|
||||
return -1;
|
||||
|
||||
struct drgn_type_member *member;
|
||||
uint64_t member_bit_offset;
|
||||
@ -105,7 +101,7 @@ static int serialize_compound_value(struct drgn_program *prog, char *buf,
|
||||
&member, &member_bit_offset);
|
||||
if (err) {
|
||||
set_drgn_error(err);
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
struct drgn_qualified_type member_qualified_type;
|
||||
uint64_t member_bit_field_size;
|
||||
@ -113,25 +109,22 @@ static int serialize_compound_value(struct drgn_program *prog, char *buf,
|
||||
&member_bit_field_size);
|
||||
if (err) {
|
||||
set_drgn_error(err);
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct drgn_object_type member_type;
|
||||
err = drgn_object_type(member_qualified_type,
|
||||
member_bit_field_size, &member_type);
|
||||
if (err)
|
||||
goto out;
|
||||
return -1;
|
||||
if (serialize_py_object(prog, buf, buf_bit_size,
|
||||
bit_offset + member_bit_offset,
|
||||
PyTuple_GET_ITEM(item, 1),
|
||||
&member_type) == -1)
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
Py_DECREF(items);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serialize_array_value(struct drgn_program *prog, char *buf,
|
||||
@ -155,7 +148,7 @@ static int serialize_array_value(struct drgn_program *prog, char *buf,
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *seq = PySequence_Fast(value_obj, "");
|
||||
_cleanup_pydecref_ PyObject *seq = PySequence_Fast(value_obj, "");
|
||||
if (!seq) {
|
||||
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
|
||||
set_error_type_name("'%s' value must be iterable",
|
||||
@ -165,7 +158,6 @@ static int serialize_array_value(struct drgn_program *prog, char *buf,
|
||||
}
|
||||
size_t seq_length = PySequence_Fast_GET_SIZE(seq);
|
||||
if (seq_length > length) {
|
||||
Py_DECREF(seq);
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"too many items in array value");
|
||||
return -1;
|
||||
@ -175,13 +167,10 @@ static int serialize_array_value(struct drgn_program *prog, char *buf,
|
||||
if (serialize_py_object(prog, buf, buf_bit_size,
|
||||
bit_offset + i * element_type.bit_size,
|
||||
PySequence_Fast_GET_ITEM(seq, i),
|
||||
&element_type) == -1) {
|
||||
Py_DECREF(seq);
|
||||
&element_type) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -209,7 +198,8 @@ static int serialize_py_object(struct drgn_program *prog, char *buf,
|
||||
drgn_object_type_qualified(type));
|
||||
return -1;
|
||||
}
|
||||
PyObject *long_obj = PyNumber_Long(value_obj);
|
||||
_cleanup_pydecref_ PyObject *long_obj =
|
||||
PyNumber_Long(value_obj);
|
||||
if (!long_obj)
|
||||
return -1;
|
||||
union {
|
||||
@ -217,7 +207,6 @@ static int serialize_py_object(struct drgn_program *prog, char *buf,
|
||||
uint64_t uvalue;
|
||||
} tmp;
|
||||
tmp.uvalue = PyLong_AsUint64Mask(long_obj);
|
||||
Py_DECREF(long_obj);
|
||||
if (tmp.uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
return -1;
|
||||
if (type->encoding == DRGN_OBJECT_ENCODING_SIGNED) {
|
||||
@ -338,8 +327,6 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
struct index_arg bit_offset = { .allow_none = true, .is_none = true };
|
||||
struct index_arg bit_field_size = { .allow_none = true, .is_none = true };
|
||||
struct drgn_qualified_type qualified_type;
|
||||
DrgnObject *obj;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|OO$O&O&O&:Object",
|
||||
keywords, &Program_type, &prog,
|
||||
&type_obj, &value_obj, index_converter,
|
||||
@ -356,18 +343,18 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = DrgnObject_alloc(prog);
|
||||
_cleanup_pydecref_ DrgnObject *obj = DrgnObject_alloc(prog);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
if (!address.is_none && value_obj != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"object cannot have address and value");
|
||||
goto err;
|
||||
return NULL;
|
||||
} else if (!address.is_none) {
|
||||
if (!qualified_type.type) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"reference must have type");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = drgn_object_set_reference(&obj->obj, qualified_type,
|
||||
@ -380,29 +367,29 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
if (!bit_offset.is_none) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"literal cannot have bit offset");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
if (!bit_field_size.is_none) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"literal cannot be bit field");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = DrgnObject_literal(&obj->obj, value_obj);
|
||||
if (ret == -1) {
|
||||
goto err;
|
||||
return NULL;
|
||||
} else if (ret) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"cannot create %s literal",
|
||||
Py_TYPE(value_obj)->tp_name);
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
err = NULL;
|
||||
} else if (value_obj != Py_None) {
|
||||
if (!bit_offset.is_none) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"value cannot have bit offset");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum drgn_object_encoding encoding =
|
||||
@ -410,8 +397,7 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
if (!drgn_object_encoding_is_complete(encoding)) {
|
||||
err = drgn_error_incomplete_type("cannot create value with %s type",
|
||||
qualified_type.type);
|
||||
set_drgn_error(err);
|
||||
goto err;
|
||||
return set_drgn_error(err);
|
||||
|
||||
}
|
||||
if (!bit_field_size.is_none &&
|
||||
@ -419,36 +405,34 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
encoding != DRGN_OBJECT_ENCODING_UNSIGNED) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bit field must be integer");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (encoding) {
|
||||
case DRGN_OBJECT_ENCODING_BUFFER:
|
||||
if (buffer_object_from_value(&obj->obj, qualified_type,
|
||||
value_obj) == -1)
|
||||
goto err;
|
||||
return NULL;
|
||||
err = NULL;
|
||||
break;
|
||||
case DRGN_OBJECT_ENCODING_SIGNED:
|
||||
case DRGN_OBJECT_ENCODING_UNSIGNED: {
|
||||
PyObject *long_obj;
|
||||
if (!PyNumber_Check(value_obj)) {
|
||||
return set_error_type_name("'%s' value must be number",
|
||||
qualified_type);
|
||||
}
|
||||
_cleanup_pydecref_ PyObject *long_obj =
|
||||
PyNumber_Long(value_obj);
|
||||
if (!long_obj)
|
||||
return NULL;
|
||||
union {
|
||||
int64_t svalue;
|
||||
uint64_t uvalue;
|
||||
} tmp;
|
||||
|
||||
if (!PyNumber_Check(value_obj)) {
|
||||
set_error_type_name("'%s' value must be number",
|
||||
qualified_type);
|
||||
goto err;
|
||||
}
|
||||
long_obj = PyNumber_Long(value_obj);
|
||||
if (!long_obj)
|
||||
goto err;
|
||||
tmp.uvalue = PyLong_AsUint64Mask(long_obj);
|
||||
Py_DECREF(long_obj);
|
||||
} tmp = {
|
||||
.uvalue = PyLong_AsUint64Mask(long_obj)
|
||||
};
|
||||
if (tmp.uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
goto err;
|
||||
return NULL;
|
||||
if (encoding == DRGN_OBJECT_ENCODING_SIGNED) {
|
||||
err = drgn_object_set_signed(&obj->obj,
|
||||
qualified_type,
|
||||
@ -463,16 +447,13 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
break;
|
||||
}
|
||||
case DRGN_OBJECT_ENCODING_FLOAT: {
|
||||
double fvalue;
|
||||
|
||||
if (!PyNumber_Check(value_obj)) {
|
||||
set_error_type_name("'%s' value must be number",
|
||||
qualified_type);
|
||||
goto err;
|
||||
return set_error_type_name("'%s' value must be number",
|
||||
qualified_type);
|
||||
}
|
||||
fvalue = PyFloat_AsDouble(value_obj);
|
||||
double fvalue = PyFloat_AsDouble(value_obj);
|
||||
if (fvalue == -1.0 && PyErr_Occurred())
|
||||
goto err;
|
||||
return NULL;
|
||||
err = drgn_object_set_float(&obj->obj, qualified_type,
|
||||
fvalue);
|
||||
break;
|
||||
@ -484,25 +465,19 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
if (!qualified_type.type) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"absent object must have type");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
if (!bit_offset.is_none) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"absent object cannot have bit offset");
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
err = drgn_object_set_absent(&obj->obj, qualified_type,
|
||||
bit_field_size.uvalue);
|
||||
}
|
||||
if (err) {
|
||||
set_drgn_error(err);
|
||||
goto err;
|
||||
}
|
||||
return obj;
|
||||
|
||||
err:
|
||||
Py_DECREF(obj);
|
||||
return NULL;
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
return_ptr(obj);
|
||||
}
|
||||
|
||||
static void DrgnObject_dealloc(DrgnObject *self)
|
||||
@ -557,7 +532,8 @@ static PyObject *DrgnObject_compound_value(struct drgn_object *obj,
|
||||
goto out;
|
||||
}
|
||||
|
||||
PyObject *member_value = DrgnObject_value_impl(&member);
|
||||
_cleanup_pydecref_ PyObject *member_value =
|
||||
DrgnObject_value_impl(&member);
|
||||
if (!member_value) {
|
||||
Py_CLEAR(dict);
|
||||
goto out;
|
||||
@ -570,7 +546,6 @@ static PyObject *DrgnObject_compound_value(struct drgn_object *obj,
|
||||
} else {
|
||||
ret = PyDict_Update(dict, member_value);
|
||||
}
|
||||
Py_DECREF(member_value);
|
||||
if (ret) {
|
||||
Py_CLEAR(dict);
|
||||
goto out;
|
||||
@ -711,40 +686,33 @@ static PyObject *DrgnObject_string(DrgnObject *self)
|
||||
static DrgnObject *DrgnObject_address_of(DrgnObject *self)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
DrgnObject *res;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(self));
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(self));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
err = drgn_object_address_of(&res->obj, &self->obj);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
static DrgnObject *DrgnObject_read(DrgnObject *self)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
DrgnObject *res;
|
||||
|
||||
SWITCH_ENUM(self->obj.kind,
|
||||
case DRGN_OBJECT_VALUE:
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
case DRGN_OBJECT_REFERENCE:
|
||||
res = DrgnObject_alloc(DrgnObject_prog(self));
|
||||
case DRGN_OBJECT_REFERENCE: {
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(self));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
err = drgn_object_read(&res->obj, &self->obj);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
case DRGN_OBJECT_ABSENT:
|
||||
return set_drgn_error(&drgn_error_object_absent);
|
||||
)
|
||||
@ -753,16 +721,14 @@ static DrgnObject *DrgnObject_read(DrgnObject *self)
|
||||
static PyObject *DrgnObject_to_bytes(DrgnObject *self)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
PyObject *buf = PyBytes_FromStringAndSize(NULL,
|
||||
drgn_object_size(&self->obj));
|
||||
_cleanup_pydecref_ PyObject *buf =
|
||||
PyBytes_FromStringAndSize(NULL, drgn_object_size(&self->obj));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
err = drgn_object_read_bytes(&self->obj, PyBytes_AS_STRING(buf));
|
||||
if (err) {
|
||||
Py_DECREF(buf);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return buf;
|
||||
return_ptr(buf);
|
||||
}
|
||||
|
||||
static DrgnObject *DrgnObject_from_bytes(PyTypeObject *type, PyObject *args,
|
||||
@ -824,50 +790,40 @@ static int append_bit_offset(PyObject *parts, uint8_t bit_offset)
|
||||
static PyObject *DrgnObject_repr(DrgnObject *self)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
PyObject *parts, *tmp, *ret = NULL;
|
||||
char *type_name;
|
||||
|
||||
parts = PyList_New(0);
|
||||
_cleanup_pydecref_ PyObject *parts = PyList_New(0);
|
||||
if (!parts)
|
||||
return NULL;
|
||||
|
||||
char *type_name;
|
||||
err = drgn_format_type_name(drgn_object_qualified_type(&self->obj),
|
||||
&type_name);
|
||||
if (err) {
|
||||
set_drgn_error(err);
|
||||
goto out;
|
||||
}
|
||||
tmp = PyUnicode_FromString(type_name);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
_cleanup_pydecref_ PyObject *tmp = PyUnicode_FromString(type_name);
|
||||
free(type_name);
|
||||
if (!tmp)
|
||||
goto out;
|
||||
return NULL;
|
||||
|
||||
if (append_format(parts, "Object(prog, %R", tmp) == -1) {
|
||||
Py_DECREF(tmp);
|
||||
goto out;
|
||||
}
|
||||
Py_DECREF(tmp);
|
||||
if (append_format(parts, "Object(prog, %R", tmp) == -1)
|
||||
return NULL;
|
||||
|
||||
SWITCH_ENUM(self->obj.kind,
|
||||
case DRGN_OBJECT_VALUE: {
|
||||
if (append_string(parts, ", value=") == -1)
|
||||
goto out;
|
||||
PyObject *value_obj = DrgnObject_value(self);
|
||||
return NULL;
|
||||
_cleanup_pydecref_ PyObject *value_obj = DrgnObject_value(self);
|
||||
if (!value_obj)
|
||||
goto out;
|
||||
if (drgn_type_kind(drgn_underlying_type(self->obj.type)) ==
|
||||
DRGN_TYPE_POINTER)
|
||||
tmp = PyNumber_ToBase(value_obj, 16);
|
||||
return NULL;
|
||||
_cleanup_pydecref_ PyObject *part;
|
||||
if (drgn_type_kind(drgn_underlying_type(self->obj.type))
|
||||
== DRGN_TYPE_POINTER)
|
||||
part = PyNumber_ToBase(value_obj, 16);
|
||||
else
|
||||
tmp = PyObject_Repr(value_obj);
|
||||
Py_DECREF(value_obj);
|
||||
if (!tmp)
|
||||
goto out;
|
||||
if (PyList_Append(parts, tmp) == -1) {
|
||||
Py_DECREF(tmp);
|
||||
goto out;
|
||||
}
|
||||
Py_DECREF(tmp);
|
||||
part = PyObject_Repr(value_obj);
|
||||
if (!part)
|
||||
return NULL;
|
||||
if (PyList_Append(parts, part) == -1)
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
case DRGN_OBJECT_REFERENCE: {
|
||||
@ -875,7 +831,7 @@ static PyObject *DrgnObject_repr(DrgnObject *self)
|
||||
snprintf(buf, sizeof(buf), "%" PRIx64, self->obj.address);
|
||||
if (append_format(parts, ", address=0x%s", buf) == -1 ||
|
||||
append_bit_offset(parts, self->obj.bit_offset) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
case DRGN_OBJECT_ABSENT:
|
||||
@ -885,15 +841,12 @@ static PyObject *DrgnObject_repr(DrgnObject *self)
|
||||
if (self->obj.is_bit_field &&
|
||||
append_format(parts, ", bit_field_size=%llu",
|
||||
(unsigned long long)self->obj.bit_size) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
|
||||
if (append_string(parts, ")") == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
|
||||
ret = join_strings(parts);
|
||||
out:
|
||||
Py_DECREF(parts);
|
||||
return ret;
|
||||
return join_strings(parts);
|
||||
}
|
||||
|
||||
static PyObject *DrgnObject_str(DrgnObject *self)
|
||||
@ -1117,22 +1070,18 @@ DrgnObject_BINARY_OP(or)
|
||||
DrgnObject_BINARY_OP(xor)
|
||||
#undef DrgnObject_BINARY_OP
|
||||
|
||||
#define DrgnObject_UNARY_OP(op) \
|
||||
static DrgnObject *DrgnObject_##op(DrgnObject *self) \
|
||||
{ \
|
||||
struct drgn_error *err; \
|
||||
DrgnObject *res; \
|
||||
\
|
||||
res = DrgnObject_alloc(DrgnObject_prog(self)); \
|
||||
if (!res) \
|
||||
return NULL; \
|
||||
\
|
||||
err = drgn_object_##op(&res->obj, &self->obj); \
|
||||
if (err) { \
|
||||
Py_DECREF(res); \
|
||||
return set_drgn_error(err); \
|
||||
} \
|
||||
return res; \
|
||||
#define DrgnObject_UNARY_OP(op) \
|
||||
static DrgnObject *DrgnObject_##op(DrgnObject *self) \
|
||||
{ \
|
||||
struct drgn_error *err; \
|
||||
_cleanup_pydecref_ DrgnObject *res = \
|
||||
DrgnObject_alloc(DrgnObject_prog(self)); \
|
||||
if (!res) \
|
||||
return NULL; \
|
||||
err = drgn_object_##op(&res->obj, &self->obj); \
|
||||
if (err) \
|
||||
return set_drgn_error(err); \
|
||||
return_ptr(res); \
|
||||
}
|
||||
DrgnObject_UNARY_OP(pos)
|
||||
DrgnObject_UNARY_OP(neg)
|
||||
@ -1255,8 +1204,7 @@ static PyObject *DrgnObject_round(DrgnObject *self, PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"ndigits", NULL};
|
||||
PyObject *ndigits = Py_None, *value, *ret;
|
||||
|
||||
PyObject *ndigits = Py_None;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:round", keywords,
|
||||
&ndigits))
|
||||
return NULL;
|
||||
@ -1266,51 +1214,24 @@ static PyObject *DrgnObject_round(DrgnObject *self, PyObject *args,
|
||||
drgn_object_qualified_type(&self->obj));
|
||||
}
|
||||
|
||||
value = DrgnObject_value(self);
|
||||
_cleanup_pydecref_ PyObject *value = DrgnObject_value(self);
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
if (ndigits == Py_None) {
|
||||
ret = PyObject_CallMethod(value, "__round__", NULL);
|
||||
Py_DECREF(value);
|
||||
} else {
|
||||
PyObject *args, *kwds, *tmp, *type;
|
||||
if (ndigits == Py_None)
|
||||
return PyObject_CallMethod(value, "__round__", NULL);
|
||||
|
||||
tmp = PyObject_CallMethod(value, "__round__", "O", ndigits);
|
||||
Py_DECREF(value);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
value = tmp;
|
||||
_cleanup_pydecref_ PyObject *rounded_value =
|
||||
PyObject_CallMethod(value, "__round__", "O", ndigits);
|
||||
if (!rounded_value)
|
||||
return NULL;
|
||||
|
||||
kwds = PyDict_New();
|
||||
if (!kwds) {
|
||||
Py_DECREF(value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(kwds, "value", value) == -1) {
|
||||
Py_DECREF(value);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(value);
|
||||
|
||||
type = DrgnObject_get_type(self, NULL);
|
||||
if (!type) {
|
||||
Py_DECREF(kwds);
|
||||
return NULL;
|
||||
}
|
||||
args = Py_BuildValue("OO", DrgnObject_prog(self), type);
|
||||
Py_DECREF(type);
|
||||
if (!args) {
|
||||
Py_DECREF(kwds);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = PyObject_Call((PyObject *)&DrgnObject_type, args, kwds);
|
||||
Py_DECREF(args);
|
||||
Py_DECREF(kwds);
|
||||
}
|
||||
return ret;
|
||||
_cleanup_pydecref_ PyObject *type = DrgnObject_get_type(self, NULL);
|
||||
if (!type)
|
||||
return NULL;
|
||||
return PyObject_CallFunctionObjArgs((PyObject *)&DrgnObject_type,
|
||||
DrgnObject_prog(self), type,
|
||||
rounded_value, NULL);
|
||||
}
|
||||
|
||||
#define DrgnObject_round_method(func) \
|
||||
@ -1389,13 +1310,12 @@ static DrgnObject *DrgnObject_member(DrgnObject *self, PyObject *args,
|
||||
static char *keywords[] = {"name", NULL};
|
||||
struct drgn_error *err;
|
||||
const char *name;
|
||||
DrgnObject *res;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:member_", keywords,
|
||||
&name))
|
||||
return NULL;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(self));
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(self));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@ -1405,11 +1325,9 @@ static DrgnObject *DrgnObject_member(DrgnObject *self, PyObject *args,
|
||||
} else {
|
||||
err = drgn_object_member(&res->obj, &self->obj, name);
|
||||
}
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
static PyObject *DrgnObject_getattro(DrgnObject *self, PyObject *attr_name)
|
||||
@ -1513,18 +1431,14 @@ static DrgnObject *DrgnObject_subscript_impl(DrgnObject *self,
|
||||
int64_t index)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
DrgnObject *res;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(self));
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(self));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
err = drgn_object_subscript(&res->obj, &self->obj, index);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
static DrgnObject *DrgnObject_subscript(DrgnObject *self, PyObject *key)
|
||||
@ -1571,14 +1485,12 @@ static int add_to_dir(PyObject *dir, struct drgn_type *type)
|
||||
|
||||
member = &members[i];
|
||||
if (member->name) {
|
||||
PyObject *str = PyUnicode_FromString(member->name);
|
||||
_cleanup_pydecref_ PyObject *str =
|
||||
PyUnicode_FromString(member->name);
|
||||
if (!str)
|
||||
return -1;
|
||||
if (PyList_Append(dir, str) == -1) {
|
||||
Py_DECREF(str);
|
||||
if (PyList_Append(dir, str) == -1)
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(str);
|
||||
} else {
|
||||
struct drgn_qualified_type member_type;
|
||||
err = drgn_member_type(member, &member_type, NULL);
|
||||
@ -1596,28 +1508,23 @@ static int add_to_dir(PyObject *dir, struct drgn_type *type)
|
||||
static PyObject *DrgnObject_dir(DrgnObject *self)
|
||||
{
|
||||
_Py_IDENTIFIER(__dir__);
|
||||
PyObject *method, *dir;
|
||||
struct drgn_type *type;
|
||||
|
||||
method = _PyObject_GetAttrId((PyObject *)Py_TYPE(self)->tp_base,
|
||||
&PyId___dir__);
|
||||
_cleanup_pydecref_ PyObject *method =
|
||||
_PyObject_GetAttrId((PyObject *)Py_TYPE(self)->tp_base,
|
||||
&PyId___dir__);
|
||||
if (!method)
|
||||
return NULL;
|
||||
|
||||
dir = PyObject_CallFunctionObjArgs(method, self, NULL);
|
||||
Py_DECREF(method);
|
||||
_cleanup_pydecref_ PyObject *dir =
|
||||
PyObject_CallFunctionObjArgs(method, self, NULL);
|
||||
if (!dir)
|
||||
return NULL;
|
||||
|
||||
type = drgn_underlying_type(self->obj.type);
|
||||
struct drgn_type *type = drgn_underlying_type(self->obj.type);
|
||||
if (drgn_type_kind(type) == DRGN_TYPE_POINTER)
|
||||
type = drgn_type_type(type).type;
|
||||
if (add_to_dir(dir, type) == -1) {
|
||||
Py_DECREF(dir);
|
||||
if (add_to_dir(dir, type) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dir;
|
||||
return_ptr(dir);
|
||||
}
|
||||
|
||||
static PyGetSetDef DrgnObject_getset[] = {
|
||||
@ -1714,24 +1621,11 @@ PyObject *DrgnObject_NULL(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"prog", "type", NULL};
|
||||
PyObject *prog_obj, *type_obj;
|
||||
PyObject *a, *k, *ret;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:NULL", keywords,
|
||||
&prog_obj, &type_obj))
|
||||
return NULL;
|
||||
|
||||
a = Py_BuildValue("OO", prog_obj, type_obj);
|
||||
if (!a)
|
||||
return NULL;
|
||||
k = Py_BuildValue("{s:i}", "value", 0);
|
||||
if (!k) {
|
||||
Py_DECREF(a);
|
||||
return NULL;
|
||||
}
|
||||
ret = PyObject_Call((PyObject *)&DrgnObject_type, a, k);
|
||||
Py_DECREF(k);
|
||||
Py_DECREF(a);
|
||||
return ret;
|
||||
return PyObject_CallFunction((PyObject *)&DrgnObject_type, "OOi",
|
||||
prog_obj, type_obj, 0);
|
||||
}
|
||||
|
||||
DrgnObject *cast(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
@ -1740,8 +1634,7 @@ DrgnObject *cast(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
struct drgn_error *err;
|
||||
struct drgn_qualified_type qualified_type;
|
||||
PyObject *type_obj;
|
||||
DrgnObject *obj, *res;
|
||||
|
||||
DrgnObject *obj;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO!:cast", keywords,
|
||||
&type_obj, &DrgnObject_type, &obj))
|
||||
return NULL;
|
||||
@ -1750,16 +1643,15 @@ DrgnObject *cast(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
&qualified_type) == -1)
|
||||
return NULL;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(obj));
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(obj));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
err = drgn_object_cast(&res->obj, qualified_type, &obj->obj);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
DrgnObject *reinterpret(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
@ -1768,8 +1660,7 @@ DrgnObject *reinterpret(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
struct drgn_error *err;
|
||||
PyObject *type_obj;
|
||||
struct drgn_qualified_type qualified_type;
|
||||
DrgnObject *obj, *res;
|
||||
|
||||
DrgnObject *obj;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO!:reinterpret",
|
||||
keywords, &type_obj, &DrgnObject_type,
|
||||
&obj))
|
||||
@ -1779,16 +1670,15 @@ DrgnObject *reinterpret(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
&qualified_type) == -1)
|
||||
return NULL;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(obj));
|
||||
_cleanup_pydecref_ DrgnObject *res =
|
||||
DrgnObject_alloc(DrgnObject_prog(obj));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
err = drgn_object_reinterpret(&res->obj, qualified_type, &obj->obj);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
DrgnObject *DrgnObject_container_of(PyObject *self, PyObject *args,
|
||||
@ -1796,11 +1686,10 @@ DrgnObject *DrgnObject_container_of(PyObject *self, PyObject *args,
|
||||
{
|
||||
static char *keywords[] = {"ptr", "type", "member", NULL};
|
||||
struct drgn_error *err;
|
||||
DrgnObject *obj, *res;
|
||||
DrgnObject *obj;
|
||||
PyObject *type_obj;
|
||||
struct drgn_qualified_type qualified_type;
|
||||
const char *member_designator;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!Os:container_of",
|
||||
keywords, &DrgnObject_type, &obj,
|
||||
&type_obj, &member_designator))
|
||||
@ -1810,17 +1699,15 @@ DrgnObject *DrgnObject_container_of(PyObject *self, PyObject *args,
|
||||
&qualified_type) == -1)
|
||||
return NULL;
|
||||
|
||||
res = DrgnObject_alloc(DrgnObject_prog(obj));
|
||||
_cleanup_pydecref_ DrgnObject *res = DrgnObject_alloc(DrgnObject_prog(obj));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
err = drgn_object_container_of(&res->obj, &obj->obj, qualified_type,
|
||||
member_designator);
|
||||
if (err) {
|
||||
Py_DECREF(res);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return res;
|
||||
return_ptr(res);
|
||||
}
|
||||
|
||||
static void ObjectIterator_dealloc(ObjectIterator *self)
|
||||
|
@ -83,39 +83,30 @@ static PyObject *Platform_get_flags(Platform *self, void *arg)
|
||||
static PyObject *Platform_get_registers(Platform *self, void *arg)
|
||||
{
|
||||
size_t num_registers = drgn_platform_num_registers(self->platform);
|
||||
PyObject *tuple = PyTuple_New(num_registers);
|
||||
_cleanup_pydecref_ PyObject *tuple = PyTuple_New(num_registers);
|
||||
if (!tuple)
|
||||
return NULL;
|
||||
for (size_t i = 0; i < num_registers; i++) {
|
||||
const struct drgn_register *reg =
|
||||
drgn_platform_register(self->platform, i);
|
||||
Register *item = call_tp_alloc(Register);
|
||||
if (!item) {
|
||||
Py_DECREF(tuple);
|
||||
if (!item)
|
||||
return NULL;
|
||||
}
|
||||
item->reg = reg;
|
||||
PyTuple_SET_ITEM(tuple, i, (PyObject *)item);
|
||||
}
|
||||
return tuple;
|
||||
return_ptr(tuple);
|
||||
}
|
||||
|
||||
static PyObject *Platform_repr(Platform *self)
|
||||
{
|
||||
PyObject *arch_obj, *flags_obj, *ret;
|
||||
|
||||
arch_obj = Platform_get_arch(self, NULL);
|
||||
_cleanup_pydecref_ PyObject *arch_obj = Platform_get_arch(self, NULL);
|
||||
if (!arch_obj)
|
||||
return NULL;
|
||||
flags_obj = Platform_get_flags(self, NULL);
|
||||
if (!flags_obj) {
|
||||
Py_DECREF(arch_obj);
|
||||
_cleanup_pydecref_ PyObject *flags_obj = Platform_get_flags(self, NULL);
|
||||
if (!flags_obj)
|
||||
return NULL;
|
||||
}
|
||||
ret = PyUnicode_FromFormat("Platform(%R, %R)", arch_obj, flags_obj);
|
||||
Py_XDECREF(flags_obj);
|
||||
Py_XDECREF(arch_obj);
|
||||
return ret;
|
||||
return PyUnicode_FromFormat("Platform(%R, %R)", arch_obj, flags_obj);
|
||||
}
|
||||
|
||||
static PyGetSetDef Platform_getset[] = {
|
||||
@ -154,26 +145,22 @@ static PyObject *Register_get_names(Register *self, void *arg)
|
||||
{
|
||||
size_t num_names;
|
||||
const char * const *names = drgn_register_names(self->reg, &num_names);
|
||||
PyObject *ret = PyTuple_New(num_names);
|
||||
_cleanup_pydecref_ PyObject *ret = PyTuple_New(num_names);
|
||||
for (size_t i = 0; i < num_names; i++) {
|
||||
PyObject *item = PyUnicode_FromString(names[i]);
|
||||
if (!item) {
|
||||
Py_DECREF(ret);
|
||||
if (!item)
|
||||
return NULL;
|
||||
}
|
||||
PyTuple_SET_ITEM(ret, i, item);
|
||||
}
|
||||
return ret;
|
||||
return_ptr(ret);
|
||||
}
|
||||
|
||||
static PyObject *Register_repr(Register *self)
|
||||
{
|
||||
PyObject *names_obj = Register_get_names(self, NULL);
|
||||
_cleanup_pydecref_ PyObject *names_obj = Register_get_names(self, NULL);
|
||||
if (!names_obj)
|
||||
return NULL;
|
||||
PyObject *ret = PyUnicode_FromFormat("Register(%R)", names_obj);
|
||||
Py_DECREF(names_obj);
|
||||
return ret;
|
||||
return PyUnicode_FromFormat("Register(%R)", names_obj);
|
||||
}
|
||||
|
||||
static PyGetSetDef Register_getset[] = {
|
||||
|
@ -47,12 +47,12 @@ static int get_log_level(void)
|
||||
// logging.disable() into account.
|
||||
int level;
|
||||
for (level = 0; level < DRGN_LOG_NONE; level++) {
|
||||
PyObject *enabled = PyObject_CallMethod(logger, "isEnabledFor",
|
||||
"i", (level + 1) * 10);
|
||||
_cleanup_pydecref_ PyObject *enabled =
|
||||
PyObject_CallMethod(logger, "isEnabledFor", "i",
|
||||
(level + 1) * 10);
|
||||
if (!enabled)
|
||||
return -1;
|
||||
int ret = PyObject_IsTrue(enabled);
|
||||
Py_DECREF(enabled);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
if (ret)
|
||||
@ -110,15 +110,13 @@ static int init_logger_cache_wrapper(void)
|
||||
LoggerCacheWrapper_type.tp_base = &PyDict_Type;
|
||||
if (PyType_Ready(&LoggerCacheWrapper_type))
|
||||
return -1;
|
||||
PyObject *cache_wrapper =
|
||||
_cleanup_pydecref_ PyObject *cache_wrapper =
|
||||
PyObject_CallFunction((PyObject *)&LoggerCacheWrapper_type,
|
||||
NULL);
|
||||
if (!cache_wrapper)
|
||||
return -1;
|
||||
int r = PyObject_SetAttrString(logger, "_cache", cache_wrapper);
|
||||
Py_DECREF(cache_wrapper);
|
||||
if (r)
|
||||
return r;
|
||||
if (PyObject_SetAttrString(logger, "_cache", cache_wrapper))
|
||||
return -1;
|
||||
|
||||
return cache_log_level();
|
||||
}
|
||||
@ -160,11 +158,10 @@ int init_logging(void)
|
||||
if (!percent_s)
|
||||
return -1;
|
||||
|
||||
PyObject *logging = PyImport_ImportModule("logging");
|
||||
_cleanup_pydecref_ PyObject *logging = PyImport_ImportModule("logging");
|
||||
if (!logging)
|
||||
return -1;
|
||||
logger = PyObject_CallMethod(logging, "getLogger", "s", "drgn");
|
||||
Py_DECREF(logging);
|
||||
if (!logger)
|
||||
return -1;
|
||||
logger_log = PyObject_GetAttrString(logger, "log");
|
||||
@ -257,25 +254,21 @@ static Program *Program_new(PyTypeObject *subtype, PyObject *args,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *cache = PyDict_New();
|
||||
_cleanup_pydecref_ PyObject *cache = PyDict_New();
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
Program *prog = call_tp_alloc(Program);
|
||||
if (!prog) {
|
||||
Py_DECREF(cache);
|
||||
_cleanup_pydecref_ Program *prog = call_tp_alloc(Program);
|
||||
if (!prog)
|
||||
return NULL;
|
||||
}
|
||||
prog->cache = cache;
|
||||
prog->cache = no_cleanup_ptr(cache);
|
||||
pyobjectp_set_init(&prog->objects);
|
||||
drgn_program_init(&prog->prog, platform);
|
||||
drgn_program_set_blocking_callback(&prog->prog, drgnpy_begin_blocking,
|
||||
drgnpy_end_blocking, NULL);
|
||||
if (Program_init_logging(prog)) {
|
||||
Py_DECREF(prog);
|
||||
if (Program_init_logging(prog))
|
||||
return NULL;
|
||||
}
|
||||
return prog;
|
||||
return_ptr(prog);
|
||||
}
|
||||
|
||||
static void Program_dealloc(Program *self)
|
||||
@ -456,11 +449,10 @@ out_gstate:
|
||||
static PyObject *Program_add_type_finder(Program *self, PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"fn", NULL};
|
||||
struct drgn_error *err;
|
||||
PyObject *fn, *arg;
|
||||
int ret;
|
||||
|
||||
static char *keywords[] = {"fn", NULL};
|
||||
PyObject *fn;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:add_type_finder",
|
||||
keywords, &fn))
|
||||
return NULL;
|
||||
@ -470,12 +462,10 @@ static PyObject *Program_add_type_finder(Program *self, PyObject *args,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arg = Py_BuildValue("OO", self, fn);
|
||||
_cleanup_pydecref_ PyObject *arg = Py_BuildValue("OO", self, fn);
|
||||
if (!arg)
|
||||
return NULL;
|
||||
ret = Program_hold_object(self, arg);
|
||||
Py_DECREF(arg);
|
||||
if (ret == -1)
|
||||
if (Program_hold_object(self, arg))
|
||||
return NULL;
|
||||
|
||||
err = drgn_program_add_type_finder(&self->prog, py_type_find_fn, arg);
|
||||
@ -539,11 +529,10 @@ out_gstate:
|
||||
static PyObject *Program_add_object_finder(Program *self, PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"fn", NULL};
|
||||
struct drgn_error *err;
|
||||
PyObject *fn, *arg;
|
||||
int ret;
|
||||
|
||||
static char *keywords[] = {"fn", NULL};
|
||||
PyObject *fn;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:add_object_finder",
|
||||
keywords, &fn))
|
||||
return NULL;
|
||||
@ -553,12 +542,10 @@ static PyObject *Program_add_object_finder(Program *self, PyObject *args,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arg = Py_BuildValue("OO", self, fn);
|
||||
_cleanup_pydecref_ PyObject *arg = Py_BuildValue("OO", self, fn);
|
||||
if (!arg)
|
||||
return NULL;
|
||||
ret = Program_hold_object(self, arg);
|
||||
Py_DECREF(arg);
|
||||
if (ret == -1)
|
||||
if (Program_hold_object(self, arg))
|
||||
return NULL;
|
||||
|
||||
err = drgn_program_add_object_finder(&self->prog, py_object_find_fn,
|
||||
@ -630,43 +617,35 @@ static PyObject *Program_load_debug_info(Program *self, PyObject *args,
|
||||
struct path_arg_vector path_args = VECTOR_INIT;
|
||||
const char **paths = NULL;
|
||||
if (paths_obj != Py_None) {
|
||||
Py_ssize_t length_hint;
|
||||
PyObject *it, *item;
|
||||
|
||||
it = PyObject_GetIter(paths_obj);
|
||||
_cleanup_pydecref_ PyObject *it = PyObject_GetIter(paths_obj);
|
||||
if (!it)
|
||||
goto out;
|
||||
|
||||
length_hint = PyObject_LengthHint(paths_obj, 1);
|
||||
if (length_hint == -1) {
|
||||
Py_DECREF(it);
|
||||
Py_ssize_t length_hint = PyObject_LengthHint(paths_obj, 1);
|
||||
if (length_hint == -1)
|
||||
goto out;
|
||||
}
|
||||
if (!path_arg_vector_reserve(&path_args, length_hint)) {
|
||||
PyErr_NoMemory();
|
||||
Py_DECREF(it);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((item = PyIter_Next(it))) {
|
||||
struct path_arg *path_arg;
|
||||
int ret;
|
||||
for (;;) {
|
||||
_cleanup_pydecref_ PyObject *item = PyIter_Next(it);
|
||||
if (!item)
|
||||
break;
|
||||
|
||||
path_arg = path_arg_vector_append_entry(&path_args);
|
||||
struct path_arg *path_arg =
|
||||
path_arg_vector_append_entry(&path_args);
|
||||
if (!path_arg) {
|
||||
PyErr_NoMemory();
|
||||
Py_DECREF(item);
|
||||
break;
|
||||
}
|
||||
memset(path_arg, 0, sizeof(*path_arg));
|
||||
ret = path_converter(item, path_arg);
|
||||
Py_DECREF(item);
|
||||
if (!ret) {
|
||||
if (!path_converter(item, path_arg)) {
|
||||
path_args.size--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Py_DECREF(it);
|
||||
if (PyErr_Occurred())
|
||||
goto out;
|
||||
|
||||
@ -710,9 +689,7 @@ static PyObject *Program_read(Program *self, PyObject *args, PyObject *kwds)
|
||||
struct index_arg address = {};
|
||||
Py_ssize_t size;
|
||||
int physical = 0;
|
||||
PyObject *buf;
|
||||
bool clear;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&n|p:read", keywords,
|
||||
index_converter, &address, &size,
|
||||
&physical))
|
||||
@ -722,7 +699,8 @@ static PyObject *Program_read(Program *self, PyObject *args, PyObject *kwds)
|
||||
PyErr_SetString(PyExc_ValueError, "negative size");
|
||||
return NULL;
|
||||
}
|
||||
buf = PyBytes_FromStringAndSize(NULL, size);
|
||||
_cleanup_pydecref_ PyObject *buf =
|
||||
PyBytes_FromStringAndSize(NULL, size);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
clear = set_drgn_in_python();
|
||||
@ -730,11 +708,9 @@ static PyObject *Program_read(Program *self, PyObject *args, PyObject *kwds)
|
||||
address.uvalue, size, physical);
|
||||
if (clear)
|
||||
clear_drgn_in_python();
|
||||
if (err) {
|
||||
Py_DECREF(buf);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return buf;
|
||||
return_ptr(buf);
|
||||
}
|
||||
|
||||
#define METHOD_READ(x, type) \
|
||||
@ -962,7 +938,7 @@ static PyObject *Program_symbols(Program *self, PyObject *args)
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
|
||||
PyObject *list = PyList_New(count);
|
||||
_cleanup_pydecref_ PyObject *list = PyList_New(count);
|
||||
if (!list) {
|
||||
drgn_symbols_destroy(symbols, count);
|
||||
return NULL;
|
||||
@ -972,15 +948,13 @@ static PyObject *Program_symbols(Program *self, PyObject *args)
|
||||
if (!pysym) {
|
||||
/* Free symbols which aren't yet added to list. */
|
||||
drgn_symbols_destroy(symbols, count);
|
||||
/* Free list and all symbols already added. */
|
||||
Py_DECREF(list);
|
||||
return NULL;
|
||||
}
|
||||
symbols[i] = NULL;
|
||||
PyList_SET_ITEM(list, i, pysym);
|
||||
}
|
||||
free(symbols);
|
||||
return list;
|
||||
return_ptr(list);
|
||||
}
|
||||
|
||||
static PyObject *Program_symbol(Program *self, PyObject *arg)
|
||||
@ -1089,24 +1063,21 @@ static PyObject *Program__log(Program *self, PyObject *args, PyObject *kwds)
|
||||
static DrgnObject *Program_subscript(Program *self, PyObject *key)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
const char *name;
|
||||
DrgnObject *ret;
|
||||
bool clear;
|
||||
|
||||
if (!PyUnicode_Check(key)) {
|
||||
PyErr_SetObject(PyExc_KeyError, key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = PyUnicode_AsUTF8(key);
|
||||
const char *name = PyUnicode_AsUTF8(key);
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
ret = DrgnObject_alloc(self);
|
||||
_cleanup_pydecref_ DrgnObject *ret = DrgnObject_alloc(self);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
clear = set_drgn_in_python();
|
||||
bool clear = set_drgn_in_python();
|
||||
err = drgn_program_find_object(&self->prog, name, NULL,
|
||||
DRGN_FIND_OBJECT_ANY, &ret->obj);
|
||||
if (clear)
|
||||
@ -1118,10 +1089,9 @@ static DrgnObject *Program_subscript(Program *self, PyObject *key)
|
||||
} else {
|
||||
set_drgn_error(err);
|
||||
}
|
||||
Py_DECREF(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
return_ptr(ret);
|
||||
}
|
||||
|
||||
static int Program_contains(Program *self, PyObject *key)
|
||||
@ -1321,14 +1291,13 @@ Program *program_from_core_dump(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
static char *keywords[] = {"path", NULL};
|
||||
struct drgn_error *err;
|
||||
struct path_arg path = {};
|
||||
Program *prog;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||
"O&:program_from_core_dump", keywords,
|
||||
path_converter, &path))
|
||||
return NULL;
|
||||
|
||||
prog = (Program *)PyObject_CallObject((PyObject *)&Program_type, NULL);
|
||||
_cleanup_pydecref_ Program *prog =
|
||||
(Program *)PyObject_CallObject((PyObject *)&Program_type, NULL);
|
||||
if (!prog) {
|
||||
path_cleanup(&path);
|
||||
return NULL;
|
||||
@ -1336,49 +1305,39 @@ Program *program_from_core_dump(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
err = drgn_program_init_core_dump(&prog->prog, path.path);
|
||||
path_cleanup(&path);
|
||||
if (err) {
|
||||
Py_DECREF(prog);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return prog;
|
||||
return_ptr(prog);
|
||||
}
|
||||
|
||||
Program *program_from_kernel(PyObject *self)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
Program *prog;
|
||||
|
||||
prog = (Program *)PyObject_CallObject((PyObject *)&Program_type, NULL);
|
||||
_cleanup_pydecref_ Program *prog =
|
||||
(Program *)PyObject_CallObject((PyObject *)&Program_type, NULL);
|
||||
if (!prog)
|
||||
return NULL;
|
||||
|
||||
err = drgn_program_init_kernel(&prog->prog);
|
||||
if (err) {
|
||||
Py_DECREF(prog);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return prog;
|
||||
return_ptr(prog);
|
||||
}
|
||||
|
||||
Program *program_from_pid(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *keywords[] = {"pid", NULL};
|
||||
struct drgn_error *err;
|
||||
static char *keywords[] = {"pid", NULL};
|
||||
int pid;
|
||||
Program *prog;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:program_from_pid",
|
||||
keywords, &pid))
|
||||
return NULL;
|
||||
|
||||
prog = (Program *)PyObject_CallObject((PyObject *)&Program_type, NULL);
|
||||
_cleanup_pydecref_ Program *prog =
|
||||
(Program *)PyObject_CallObject((PyObject *)&Program_type, NULL);
|
||||
if (!prog)
|
||||
return NULL;
|
||||
|
||||
err = drgn_program_init_pid(&prog->prog, pid);
|
||||
if (err) {
|
||||
Py_DECREF(prog);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return prog;
|
||||
return_ptr(prog);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ static PyObject *StackFrame_locals(StackFrame *self)
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
|
||||
PyObject *list = PyList_New(count);
|
||||
_cleanup_pydecref_ PyObject *list = PyList_New(count);
|
||||
if (!list) {
|
||||
drgn_stack_frame_locals_destroy(names, count);
|
||||
return NULL;
|
||||
@ -132,13 +132,12 @@ static PyObject *StackFrame_locals(StackFrame *self)
|
||||
PyObject *string = PyUnicode_FromString(names[i]);
|
||||
if (!string) {
|
||||
drgn_stack_frame_locals_destroy(names, count);
|
||||
Py_DECREF(list);
|
||||
return NULL;
|
||||
}
|
||||
PyList_SET_ITEM(list, i, string);
|
||||
}
|
||||
drgn_stack_frame_locals_destroy(names, count);
|
||||
return list;
|
||||
return_ptr(list);
|
||||
}
|
||||
|
||||
static DrgnObject *StackFrame_subscript(StackFrame *self, PyObject *key)
|
||||
@ -152,7 +151,7 @@ static DrgnObject *StackFrame_subscript(StackFrame *self, PyObject *key)
|
||||
const char *name = PyUnicode_AsUTF8(key);
|
||||
if (!name)
|
||||
return NULL;
|
||||
DrgnObject *ret = DrgnObject_alloc(prog);
|
||||
_cleanup_pydecref_ DrgnObject *ret = DrgnObject_alloc(prog);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
bool clear = set_drgn_in_python();
|
||||
@ -167,10 +166,9 @@ static DrgnObject *StackFrame_subscript(StackFrame *self, PyObject *key)
|
||||
} else {
|
||||
set_drgn_error(err);
|
||||
}
|
||||
Py_DECREF(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
return_ptr(ret);
|
||||
}
|
||||
|
||||
static int StackFrame_contains(StackFrame *self, PyObject *key)
|
||||
@ -253,7 +251,7 @@ static PyObject *StackFrame_register(StackFrame *self, PyObject *arg)
|
||||
|
||||
static PyObject *StackFrame_registers(StackFrame *self)
|
||||
{
|
||||
PyObject *dict = PyDict_New();
|
||||
_cleanup_pydecref_ PyObject *dict = PyDict_New();
|
||||
if (!dict)
|
||||
return NULL;
|
||||
const struct drgn_platform *platform =
|
||||
@ -266,26 +264,19 @@ static PyObject *StackFrame_registers(StackFrame *self)
|
||||
if (!drgn_stack_frame_register(self->trace->trace, self->i, reg,
|
||||
&value))
|
||||
continue;
|
||||
PyObject *value_obj = PyLong_FromUint64(value);
|
||||
if (!value_obj) {
|
||||
Py_DECREF(dict);
|
||||
_cleanup_pydecref_ PyObject *value_obj =
|
||||
PyLong_FromUint64(value);
|
||||
if (!value_obj)
|
||||
return NULL;
|
||||
}
|
||||
size_t num_names;
|
||||
const char * const *names = drgn_register_names(reg,
|
||||
&num_names);
|
||||
for (size_t j = 0; j < num_names; j++) {
|
||||
int ret = PyDict_SetItemString(dict, names[j],
|
||||
value_obj);
|
||||
if (ret == -1) {
|
||||
Py_DECREF(value_obj);
|
||||
Py_DECREF(dict);
|
||||
if (PyDict_SetItemString(dict, names[j], value_obj))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_DECREF(value_obj);
|
||||
}
|
||||
return dict;
|
||||
return_ptr(dict);
|
||||
}
|
||||
|
||||
static PyObject *StackFrame_get_name(StackFrame *self, void *arg)
|
||||
|
@ -63,32 +63,22 @@ static PyObject *Symbol_get_kind(Symbol *self, void *arg)
|
||||
|
||||
static PyObject *Symbol_repr(Symbol *self)
|
||||
{
|
||||
PyObject *ret = NULL;
|
||||
PyObject *tmp = PyUnicode_FromString(drgn_symbol_name(self->sym));
|
||||
if (!tmp)
|
||||
_cleanup_pydecref_ PyObject *name =
|
||||
PyUnicode_FromString(drgn_symbol_name(self->sym));
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
PyObject *binding = Symbol_get_binding(self, NULL);
|
||||
_cleanup_pydecref_ PyObject *binding = Symbol_get_binding(self, NULL);
|
||||
if (!binding)
|
||||
goto out_tmp;
|
||||
|
||||
PyObject *kind = Symbol_get_kind(self, NULL);
|
||||
return NULL;
|
||||
_cleanup_pydecref_ PyObject *kind = Symbol_get_kind(self, NULL);
|
||||
if (!kind)
|
||||
goto out_binding;
|
||||
return NULL;
|
||||
|
||||
char address[19], size[19];
|
||||
sprintf(address, "0x%" PRIx64, drgn_symbol_address(self->sym));
|
||||
sprintf(size, "0x%" PRIx64, drgn_symbol_size(self->sym));
|
||||
ret = PyUnicode_FromFormat("Symbol(name=%R, address=%s, size=%s, binding=%R, kind=%R)",
|
||||
tmp, address, size, binding, kind);
|
||||
|
||||
Py_DECREF(kind);
|
||||
out_binding:
|
||||
Py_DECREF(binding);
|
||||
out_tmp:
|
||||
Py_DECREF(tmp);
|
||||
return ret;
|
||||
|
||||
return PyUnicode_FromFormat("Symbol(name=%R, address=%s, size=%s, binding=%R, kind=%R)",
|
||||
name, address, size, binding, kind);
|
||||
}
|
||||
|
||||
static PyGetSetDef Symbol_getset[] = {
|
||||
|
@ -12,18 +12,17 @@ static Program *Thread_prog(Thread *self)
|
||||
|
||||
PyObject *Thread_wrap(struct drgn_thread *thread)
|
||||
{
|
||||
Thread *ret = call_tp_alloc(Thread);
|
||||
_cleanup_pydecref_ Thread *ret = call_tp_alloc(Thread);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
struct drgn_error *err =
|
||||
drgn_thread_dup_internal(thread, &ret->thread);
|
||||
if (err) {
|
||||
ret->thread.prog = NULL;
|
||||
Py_DECREF(ret);
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
Py_INCREF(container_of(thread->prog, Program, prog));
|
||||
return (PyObject *)ret;
|
||||
return (PyObject *)no_cleanup_ptr(ret);
|
||||
}
|
||||
|
||||
static void Thread_dealloc(Thread *self)
|
||||
@ -47,15 +46,14 @@ static DrgnObject *Thread_get_object(Thread *self)
|
||||
struct drgn_error *err = drgn_thread_object(&self->thread, &object);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
DrgnObject *ret = DrgnObject_alloc(Thread_prog(self));
|
||||
_cleanup_pydecref_ DrgnObject *ret =
|
||||
DrgnObject_alloc(Thread_prog(self));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
err = drgn_object_copy(&ret->obj, object);
|
||||
if (err) {
|
||||
Py_DECREF(ret);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return ret;
|
||||
return_ptr(ret);
|
||||
}
|
||||
|
||||
static PyObject *Thread_stack_trace(Thread *self)
|
||||
|
@ -23,18 +23,16 @@ static const char *drgn_type_kind_str(struct drgn_type *type)
|
||||
|
||||
DRGNPY_PUBLIC PyObject *DrgnType_wrap(struct drgn_qualified_type qualified_type)
|
||||
{
|
||||
DrgnType *type_obj = call_tp_alloc(DrgnType);
|
||||
_cleanup_pydecref_ DrgnType *type_obj = call_tp_alloc(DrgnType);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
type_obj->type = qualified_type.type;
|
||||
type_obj->qualifiers = qualified_type.qualifiers;
|
||||
Py_INCREF(DrgnType_prog(type_obj));
|
||||
type_obj->attr_cache = PyDict_New();
|
||||
if (!type_obj->attr_cache) {
|
||||
Py_DECREF(type_obj);
|
||||
if (!type_obj->attr_cache)
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject *)type_obj;
|
||||
return (PyObject *)no_cleanup_ptr(type_obj);
|
||||
}
|
||||
|
||||
static inline struct drgn_qualified_type DrgnType_unwrap(DrgnType *type)
|
||||
@ -181,7 +179,7 @@ static TypeMember *TypeMember_wrap(PyObject *parent,
|
||||
struct drgn_type_member *member,
|
||||
uint64_t bit_offset)
|
||||
{
|
||||
TypeMember *py_member = call_tp_alloc(TypeMember);
|
||||
_cleanup_pydecref_ TypeMember *py_member = call_tp_alloc(TypeMember);
|
||||
if (!py_member)
|
||||
return NULL;
|
||||
|
||||
@ -191,27 +189,19 @@ static TypeMember *TypeMember_wrap(PyObject *parent,
|
||||
if (member->name) {
|
||||
py_member->name = PyUnicode_FromString(member->name);
|
||||
if (!py_member->name)
|
||||
goto err;
|
||||
return NULL;
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
py_member->name = Py_None;
|
||||
}
|
||||
py_member->bit_offset = PyLong_FromUint64(bit_offset);
|
||||
if (!py_member->bit_offset)
|
||||
goto err;
|
||||
return py_member;
|
||||
|
||||
err:
|
||||
Py_DECREF(py_member);
|
||||
return NULL;
|
||||
return NULL;
|
||||
return_ptr(py_member);
|
||||
}
|
||||
|
||||
static PyObject *DrgnType_get_members(DrgnType *self)
|
||||
{
|
||||
PyObject *members_obj;
|
||||
struct drgn_type_member *members;
|
||||
size_t num_members, i;
|
||||
|
||||
if (!drgn_type_has_members(self->type)) {
|
||||
return PyErr_Format(PyExc_AttributeError,
|
||||
"%s type does not have members",
|
||||
@ -221,34 +211,26 @@ static PyObject *DrgnType_get_members(DrgnType *self)
|
||||
if (!drgn_type_is_complete(self->type))
|
||||
Py_RETURN_NONE;
|
||||
|
||||
members = drgn_type_members(self->type);
|
||||
num_members = drgn_type_num_members(self->type);
|
||||
members_obj = PyTuple_New(num_members);
|
||||
struct drgn_type_member *members = drgn_type_members(self->type);
|
||||
size_t num_members = drgn_type_num_members(self->type);
|
||||
|
||||
_cleanup_pydecref_ PyObject *members_obj = PyTuple_New(num_members);
|
||||
if (!members_obj)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < num_members; i++) {
|
||||
for (size_t i = 0; i < num_members; i++) {
|
||||
TypeMember *item = TypeMember_wrap((PyObject *)self,
|
||||
&members[i],
|
||||
members[i].bit_offset);
|
||||
if (!item)
|
||||
goto err;
|
||||
return NULL;
|
||||
PyTuple_SET_ITEM(members_obj, i, (PyObject *)item);
|
||||
}
|
||||
return members_obj;
|
||||
|
||||
err:
|
||||
Py_DECREF(members_obj);
|
||||
return NULL;
|
||||
return_ptr(members_obj);
|
||||
}
|
||||
|
||||
static PyObject *DrgnType_get_enumerators(DrgnType *self)
|
||||
{
|
||||
PyObject *enumerators_obj;
|
||||
const struct drgn_type_enumerator *enumerators;
|
||||
bool is_signed;
|
||||
size_t num_enumerators, i;
|
||||
|
||||
if (!drgn_type_has_enumerators(self->type)) {
|
||||
return PyErr_Format(PyExc_AttributeError,
|
||||
"%s type does not have enumerators",
|
||||
@ -258,15 +240,16 @@ static PyObject *DrgnType_get_enumerators(DrgnType *self)
|
||||
if (!drgn_type_is_complete(self->type))
|
||||
Py_RETURN_NONE;
|
||||
|
||||
enumerators = drgn_type_enumerators(self->type);
|
||||
num_enumerators = drgn_type_num_enumerators(self->type);
|
||||
is_signed = drgn_enum_type_is_signed(self->type);
|
||||
const struct drgn_type_enumerator *enumerators =
|
||||
drgn_type_enumerators(self->type);
|
||||
size_t num_enumerators = drgn_type_num_enumerators(self->type);
|
||||
bool is_signed = drgn_enum_type_is_signed(self->type);
|
||||
|
||||
enumerators_obj = PyTuple_New(num_enumerators);
|
||||
_cleanup_pydecref_ PyObject *enumerators_obj = PyTuple_New(num_enumerators);
|
||||
if (!enumerators_obj)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < num_enumerators; i++) {
|
||||
for (size_t i = 0; i < num_enumerators; i++) {
|
||||
PyObject *item;
|
||||
|
||||
if (is_signed) {
|
||||
@ -278,39 +261,36 @@ static PyObject *DrgnType_get_enumerators(DrgnType *self)
|
||||
"sK", enumerators[i].name,
|
||||
(unsigned long long)enumerators[i].uvalue);
|
||||
}
|
||||
if (!item) {
|
||||
Py_DECREF(enumerators_obj);
|
||||
if (!item)
|
||||
return NULL;
|
||||
}
|
||||
PyTuple_SET_ITEM(enumerators_obj, i, item);
|
||||
}
|
||||
|
||||
return enumerators_obj;
|
||||
return_ptr(enumerators_obj);
|
||||
}
|
||||
|
||||
static PyObject *DrgnType_get_parameters(DrgnType *self)
|
||||
{
|
||||
PyObject *parameters_obj;
|
||||
struct drgn_type_parameter *parameters;
|
||||
size_t num_parameters, i;
|
||||
|
||||
if (!drgn_type_has_parameters(self->type)) {
|
||||
return PyErr_Format(PyExc_AttributeError,
|
||||
"%s type does not have parameters",
|
||||
drgn_type_kind_str(self->type));
|
||||
}
|
||||
|
||||
parameters = drgn_type_parameters(self->type);
|
||||
num_parameters = drgn_type_num_parameters(self->type);
|
||||
parameters_obj = PyTuple_New(num_parameters);
|
||||
struct drgn_type_parameter *parameters =
|
||||
drgn_type_parameters(self->type);
|
||||
size_t num_parameters = drgn_type_num_parameters(self->type);
|
||||
|
||||
_cleanup_pydecref_ PyObject *parameters_obj =
|
||||
PyTuple_New(num_parameters);
|
||||
if (!parameters_obj)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < num_parameters; i++) {
|
||||
for (size_t i = 0; i < num_parameters; i++) {
|
||||
struct drgn_type_parameter *parameter = ¶meters[i];
|
||||
TypeParameter *item = call_tp_alloc(TypeParameter);
|
||||
if (!item)
|
||||
goto err;
|
||||
return NULL;
|
||||
PyTuple_SET_ITEM(parameters_obj, i, (PyObject *)item);
|
||||
Py_INCREF(self);
|
||||
item->lazy_obj.obj = (PyObject *)self;
|
||||
@ -318,17 +298,13 @@ static PyObject *DrgnType_get_parameters(DrgnType *self)
|
||||
if (parameter->name) {
|
||||
item->name = PyUnicode_FromString(parameter->name);
|
||||
if (!item->name)
|
||||
goto err;
|
||||
return NULL;
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
item->name = Py_None;
|
||||
}
|
||||
}
|
||||
return parameters_obj;
|
||||
|
||||
err:
|
||||
Py_DECREF(parameters_obj);
|
||||
return NULL;
|
||||
return_ptr(parameters_obj);
|
||||
}
|
||||
|
||||
static PyObject *DrgnType_get_is_variadic(DrgnType *self)
|
||||
@ -353,7 +329,9 @@ static PyObject *DrgnType_get_template_parameters(DrgnType *self)
|
||||
drgn_type_template_parameters(self->type);
|
||||
size_t num_template_parameters =
|
||||
drgn_type_num_template_parameters(self->type);
|
||||
PyObject *template_parameters_obj = PyTuple_New(num_template_parameters);
|
||||
|
||||
_cleanup_pydecref_ PyObject *template_parameters_obj =
|
||||
PyTuple_New(num_template_parameters);
|
||||
if (!template_parameters_obj)
|
||||
return NULL;
|
||||
|
||||
@ -364,7 +342,7 @@ static PyObject *DrgnType_get_template_parameters(DrgnType *self)
|
||||
TypeTemplateParameter *item =
|
||||
call_tp_alloc(TypeTemplateParameter);
|
||||
if (!item)
|
||||
goto err;
|
||||
return NULL;
|
||||
PyTuple_SET_ITEM(template_parameters_obj, i, (PyObject *)item);
|
||||
Py_INCREF(self);
|
||||
item->lazy_obj.obj = (PyObject *)self;
|
||||
@ -372,7 +350,7 @@ static PyObject *DrgnType_get_template_parameters(DrgnType *self)
|
||||
if (template_parameter->name) {
|
||||
item->name = PyUnicode_FromString(template_parameter->name);
|
||||
if (!item->name)
|
||||
goto err;
|
||||
return NULL;
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
item->name = Py_None;
|
||||
@ -380,11 +358,7 @@ static PyObject *DrgnType_get_template_parameters(DrgnType *self)
|
||||
item->is_default =
|
||||
PyBool_FromLong(template_parameter->is_default);
|
||||
}
|
||||
return template_parameters_obj;
|
||||
|
||||
err:
|
||||
Py_DECREF(template_parameters_obj);
|
||||
return NULL;
|
||||
return_ptr(template_parameters_obj);
|
||||
}
|
||||
|
||||
struct DrgnType_Attr {
|
||||
@ -506,35 +480,27 @@ static int DrgnType_clear(DrgnType *self)
|
||||
|
||||
static int append_field(PyObject *parts, bool *first, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
PyObject *str;
|
||||
int ret;
|
||||
|
||||
if (!*first && append_string(parts, ", ") == -1)
|
||||
return -1;
|
||||
*first = false;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
str = PyUnicode_FromFormatV(format, ap);
|
||||
_cleanup_pydecref_ PyObject *str = PyUnicode_FromFormatV(format, ap);
|
||||
va_end(ap);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
ret = PyList_Append(parts, str);
|
||||
Py_DECREF(str);
|
||||
return ret;
|
||||
return PyList_Append(parts, str);
|
||||
}
|
||||
|
||||
#define append_member(parts, type_obj, first, member) ({ \
|
||||
int _ret = 0; \
|
||||
PyObject *_obj; \
|
||||
\
|
||||
if (drgn_type_has_##member((type_obj)->type)) { \
|
||||
_obj = DrgnType_getter((type_obj), &DrgnType_attr_##member); \
|
||||
_cleanup_pydecref_ PyObject *_obj = \
|
||||
DrgnType_getter((type_obj), &DrgnType_attr_##member); \
|
||||
if (_obj) { \
|
||||
_ret = append_field((parts), (first), #member"=%R", \
|
||||
_obj); \
|
||||
Py_DECREF(_obj); \
|
||||
} else { \
|
||||
_ret = -1; \
|
||||
} \
|
||||
@ -544,87 +510,74 @@ static int append_field(PyObject *parts, bool *first, const char *format, ...)
|
||||
|
||||
static PyObject *DrgnType_repr(DrgnType *self)
|
||||
{
|
||||
PyObject *parts = PyList_New(0);
|
||||
_cleanup_pydecref_ PyObject *parts = PyList_New(0);
|
||||
if (!parts)
|
||||
return NULL;
|
||||
|
||||
PyObject *ret = NULL;
|
||||
bool first = true;
|
||||
if (append_format(parts, "prog.%s_type(",
|
||||
drgn_type_kind_str(self->type)) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, name) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, tag) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
|
||||
if (drgn_type_kind(self->type) != DRGN_TYPE_POINTER &&
|
||||
append_member(parts, self, &first, size) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, is_signed) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, type) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (drgn_type_kind(self->type) == DRGN_TYPE_POINTER &&
|
||||
(!drgn_type_program(self->type)->has_platform ||
|
||||
drgn_type_size(self->type) !=
|
||||
drgn_platform_address_size(&drgn_type_program(self->type)->platform)) &&
|
||||
append_member(parts, self, &first, size) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (drgn_type_has_little_endian(self->type) &&
|
||||
(!drgn_type_program(self->type)->has_platform ||
|
||||
drgn_type_little_endian(self->type) !=
|
||||
drgn_platform_is_little_endian(&drgn_type_program(self->type)->platform))) {
|
||||
PyObject *obj = DrgnType_get_byteorder(self, NULL);
|
||||
if (!obj)
|
||||
goto out;
|
||||
if (append_field(parts, &first, "byteorder=%R", obj) == -1) {
|
||||
Py_DECREF(obj);
|
||||
goto out;
|
||||
}
|
||||
Py_DECREF(obj);
|
||||
_cleanup_pydecref_ PyObject *obj =
|
||||
DrgnType_get_byteorder(self, NULL);
|
||||
if (!obj
|
||||
|| append_field(parts, &first, "byteorder=%R", obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
if (append_member(parts, self, &first, length) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, members) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, enumerators) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, parameters) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_member(parts, self, &first, is_variadic) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (drgn_type_has_template_parameters(self->type) &&
|
||||
drgn_type_num_template_parameters(self->type) > 0 &&
|
||||
append_member(parts, self, &first, template_parameters) == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (self->qualifiers) {
|
||||
PyObject *obj = DrgnType_getter(self,
|
||||
&DrgnType_attr_qualifiers);
|
||||
if (!obj)
|
||||
goto out;
|
||||
if (append_field(parts, &first, "qualifiers=%R", obj) == -1) {
|
||||
Py_DECREF(obj);
|
||||
goto out;
|
||||
}
|
||||
Py_DECREF(obj);
|
||||
_cleanup_pydecref_ PyObject *obj =
|
||||
DrgnType_getter(self, &DrgnType_attr_qualifiers);
|
||||
if (!obj
|
||||
|| append_field(parts, &first, "qualifiers=%R", obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
if (drgn_type_language(self->type) !=
|
||||
drgn_program_language(drgn_type_program(self->type))) {
|
||||
PyObject *obj = DrgnType_get_language(self, NULL);
|
||||
if (append_field(parts, &first, "language=%R", obj) == -1) {
|
||||
Py_DECREF(obj);
|
||||
goto out;
|
||||
}
|
||||
Py_DECREF(obj);
|
||||
_cleanup_pydecref_ PyObject *obj = DrgnType_get_language(self, NULL);
|
||||
if (!obj
|
||||
|| append_field(parts, &first, "language=%R", obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
if (append_string(parts, ")") == -1)
|
||||
goto out;
|
||||
return NULL;
|
||||
|
||||
ret = join_strings(parts);
|
||||
out:
|
||||
Py_DECREF(parts);
|
||||
return ret;
|
||||
return join_strings(parts);
|
||||
}
|
||||
|
||||
static PyObject *DrgnType_str(DrgnType *self)
|
||||
@ -867,16 +820,14 @@ PyTypeObject TypeEnumerator_type = {
|
||||
|
||||
static DrgnObject *DrgnType_to_absent_DrgnObject(DrgnType *type)
|
||||
{
|
||||
DrgnObject *obj = DrgnObject_alloc(DrgnType_prog(type));
|
||||
_cleanup_pydecref_ DrgnObject *obj = DrgnObject_alloc(DrgnType_prog(type));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
struct drgn_error *err =
|
||||
drgn_object_set_absent(&obj->obj, DrgnType_unwrap(type), 0);
|
||||
if (err) {
|
||||
Py_DECREF(obj);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
}
|
||||
return obj;
|
||||
return_ptr(obj);
|
||||
}
|
||||
|
||||
static const char *PyType_name(PyTypeObject *type)
|
||||
@ -982,11 +933,11 @@ static int append_lazy_object_repr(PyObject *parts, LazyObject *self)
|
||||
set_drgn_error(err);
|
||||
return -1;
|
||||
}
|
||||
PyObject *tmp = PyUnicode_FromString(type_name);
|
||||
_cleanup_pydecref_ PyObject *tmp = PyUnicode_FromString(type_name);
|
||||
free(type_name);
|
||||
int ret = append_format(parts, "prog.type(%R)", tmp);
|
||||
Py_DECREF(tmp);
|
||||
return ret;
|
||||
if (!tmp)
|
||||
return -1;
|
||||
return append_format(parts, "prog.type(%R)", tmp);
|
||||
} else {
|
||||
return append_format(parts, "%R", object);
|
||||
}
|
||||
@ -1048,7 +999,8 @@ static TypeMember *TypeMember_new(PyTypeObject *subtype, PyObject *args,
|
||||
if (LazyObject_arg(object, "TypeMember", true, &obj, &state))
|
||||
return NULL;
|
||||
|
||||
TypeMember *member = (TypeMember *)subtype->tp_alloc(subtype, 0);
|
||||
_cleanup_pydecref_ TypeMember *member =
|
||||
(TypeMember *)subtype->tp_alloc(subtype, 0);
|
||||
if (!member) {
|
||||
Py_DECREF(obj);
|
||||
return NULL;
|
||||
@ -1062,14 +1014,10 @@ static TypeMember *TypeMember_new(PyTypeObject *subtype, PyObject *args,
|
||||
} else {
|
||||
bit_offset = PyLong_FromLong(0);
|
||||
if (!bit_offset)
|
||||
goto err;
|
||||
return NULL;
|
||||
}
|
||||
member->bit_offset = bit_offset;
|
||||
return member;
|
||||
|
||||
err:
|
||||
Py_DECREF(member);
|
||||
return NULL;
|
||||
return_ptr(member);
|
||||
}
|
||||
|
||||
static void TypeMember_dealloc(TypeMember *self)
|
||||
@ -1105,22 +1053,19 @@ static PyObject *TypeMember_get_bit_field_size(TypeMember *self, void *arg)
|
||||
|
||||
static PyObject *TypeMember_repr(TypeMember *self)
|
||||
{
|
||||
PyObject *parts = PyList_New(0), *ret = NULL;
|
||||
_cleanup_pydecref_ PyObject *parts = PyList_New(0);
|
||||
if (!parts)
|
||||
return NULL;
|
||||
if (append_format(parts, "TypeMember(") < 0 ||
|
||||
append_lazy_object_repr(parts, (LazyObject *)self) < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (self->name != Py_None &&
|
||||
append_format(parts, ", name=%R", self->name) < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
/* Include the bit offset even if it is the default of 0 for clarity. */
|
||||
if (append_format(parts, ", bit_offset=%R)", self->bit_offset) < 0)
|
||||
goto out;
|
||||
ret = join_strings(parts);
|
||||
out:
|
||||
Py_DECREF(parts);
|
||||
return ret;
|
||||
return NULL;
|
||||
return join_strings(parts);
|
||||
}
|
||||
|
||||
static PyMemberDef TypeMember_members[] = {
|
||||
@ -1198,21 +1143,18 @@ static void TypeParameter_dealloc(TypeParameter *self)
|
||||
|
||||
static PyObject *TypeParameter_repr(TypeParameter *self)
|
||||
{
|
||||
PyObject *parts = PyList_New(0), *ret = NULL;
|
||||
_cleanup_pydecref_ PyObject *parts = PyList_New(0);
|
||||
if (!parts)
|
||||
return NULL;
|
||||
if (append_format(parts, "TypeParameter(") < 0 ||
|
||||
append_lazy_object_repr(parts, (LazyObject *)self) < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (self->name != Py_None &&
|
||||
append_format(parts, ", name=%R", self->name) < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_string(parts, ")") < 0)
|
||||
goto out;
|
||||
ret = join_strings(parts);
|
||||
out:
|
||||
Py_DECREF(parts);
|
||||
return ret;
|
||||
return NULL;
|
||||
return join_strings(parts);
|
||||
}
|
||||
|
||||
static PyMemberDef TypeParameter_members[] = {
|
||||
@ -1290,24 +1232,21 @@ static void TypeTemplateParameter_dealloc(TypeTemplateParameter *self)
|
||||
|
||||
static PyObject *TypeTemplateParameter_repr(TypeTemplateParameter *self)
|
||||
{
|
||||
PyObject *parts = PyList_New(0), *ret = NULL;
|
||||
_cleanup_pydecref_ PyObject *parts = PyList_New(0);
|
||||
if (!parts)
|
||||
return NULL;
|
||||
if (append_format(parts, "TypeTemplateParameter(") < 0 ||
|
||||
append_lazy_object_repr(parts, (LazyObject *)self) < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (self->name != Py_None &&
|
||||
append_format(parts, ", name=%R", self->name) < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (self->is_default == Py_True &&
|
||||
append_string(parts, ", is_default=True") < 0)
|
||||
goto out;
|
||||
return NULL;
|
||||
if (append_string(parts, ")") < 0)
|
||||
goto out;
|
||||
ret = join_strings(parts);
|
||||
out:
|
||||
Py_DECREF(parts);
|
||||
return ret;
|
||||
return NULL;
|
||||
return join_strings(parts);
|
||||
}
|
||||
|
||||
static PyObject *TypeTemplateParameter_get_argument(TypeTemplateParameter *self,
|
||||
@ -1443,18 +1382,17 @@ DrgnType *Program_int_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
Program_hold_object(self, name_obj);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
|
||||
if (drgn_type_name(qualified_type.type) == name &&
|
||||
_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_name.id,
|
||||
name_obj) == -1) {
|
||||
Py_DECREF(type_obj);
|
||||
name_obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return type_obj;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
DrgnType *Program_bool_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
@ -1499,18 +1437,17 @@ DrgnType *Program_bool_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
Program_hold_object(self, name_obj);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
|
||||
if (drgn_type_name(qualified_type.type) == name &&
|
||||
_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_name.id,
|
||||
name_obj) == -1) {
|
||||
Py_DECREF(type_obj);
|
||||
name_obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return type_obj;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
DrgnType *Program_float_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
@ -1556,18 +1493,17 @@ DrgnType *Program_float_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
Program_hold_object(self, name_obj);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
|
||||
if (drgn_type_name(qualified_type.type) == name &&
|
||||
_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_name.id,
|
||||
name_obj) == -1) {
|
||||
Py_DECREF(type_obj);
|
||||
name_obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return type_obj;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
static struct drgn_error *py_lazy_object_thunk_fn(struct drgn_object *res,
|
||||
@ -1726,7 +1662,7 @@ static DrgnType *Program_compound_type(Program *self, PyObject *args,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *cached_members;
|
||||
_cleanup_pydecref_ PyObject *cached_members = NULL;
|
||||
size_t num_members;
|
||||
if (members_obj == Py_None) {
|
||||
if (!size.is_none) {
|
||||
@ -1735,7 +1671,6 @@ static DrgnType *Program_compound_type(Program *self, PyObject *args,
|
||||
drgn_type_kind_spelling[kind]);
|
||||
return NULL;
|
||||
}
|
||||
cached_members = NULL;
|
||||
num_members = 0;
|
||||
} else {
|
||||
if (size.is_none) {
|
||||
@ -1755,7 +1690,7 @@ static DrgnType *Program_compound_type(Program *self, PyObject *args,
|
||||
}
|
||||
bool can_cache_members = true;
|
||||
|
||||
PyObject *cached_template_parameters;
|
||||
_cleanup_pydecref_ PyObject *cached_template_parameters;
|
||||
if (template_parameters_obj) {
|
||||
cached_template_parameters =
|
||||
PySequence_Tuple(template_parameters_obj);
|
||||
@ -1763,7 +1698,7 @@ static DrgnType *Program_compound_type(Program *self, PyObject *args,
|
||||
cached_template_parameters = PyTuple_New(0);
|
||||
}
|
||||
if (!cached_template_parameters)
|
||||
goto err_members;
|
||||
return NULL;
|
||||
size_t num_template_parameters =
|
||||
PyTuple_GET_SIZE(cached_template_parameters);
|
||||
bool can_cache_template_parameters = true;
|
||||
@ -1798,7 +1733,7 @@ static DrgnType *Program_compound_type(Program *self, PyObject *args,
|
||||
set_drgn_error(err);
|
||||
err_builder:
|
||||
drgn_compound_type_builder_deinit(&builder);
|
||||
goto err_template_parameters;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tag_obj != Py_None && drgn_type_tag(qualified_type.type) == tag)
|
||||
@ -1809,9 +1744,10 @@ err_builder:
|
||||
Program_hold_object(self, cached_template_parameters);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
goto err_template_parameters;
|
||||
return NULL;
|
||||
|
||||
if (_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_tag.id,
|
||||
tag_obj) == -1 ||
|
||||
@ -1823,19 +1759,9 @@ err_builder:
|
||||
_PyDict_SetItemId(type_obj->attr_cache,
|
||||
&DrgnType_attr_template_parameters.id,
|
||||
cached_template_parameters) == -1))
|
||||
goto err_type;
|
||||
Py_XDECREF(cached_members);
|
||||
Py_DECREF(cached_template_parameters);
|
||||
return NULL;
|
||||
|
||||
return type_obj;
|
||||
|
||||
err_type:
|
||||
Py_DECREF(type_obj);
|
||||
err_template_parameters:
|
||||
Py_DECREF(cached_template_parameters);
|
||||
err_members:
|
||||
Py_XDECREF(cached_members);
|
||||
return NULL;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
DrgnType *Program_struct_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
@ -1930,7 +1856,7 @@ DrgnType *Program_enum_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *cached_enumerators;
|
||||
_cleanup_pydecref_ PyObject *cached_enumerators = NULL;
|
||||
struct drgn_qualified_type qualified_type;
|
||||
struct drgn_error *err;
|
||||
if (enumerators_obj == Py_None) {
|
||||
@ -1948,8 +1874,6 @@ DrgnType *Program_enum_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
&qualified_type.type);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
|
||||
cached_enumerators = NULL;
|
||||
} else {
|
||||
if (compatible_type_obj == Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
@ -1986,7 +1910,7 @@ DrgnType *Program_enum_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
if (unpack_enumerator(&builder,
|
||||
PyTuple_GET_ITEM(cached_enumerators, i),
|
||||
is_signed) == -1)
|
||||
goto err_enumerators;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!Program_hold_reserve(self, 1 + (tag_obj != Py_None)))
|
||||
@ -1998,7 +1922,7 @@ DrgnType *Program_enum_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
set_drgn_error(err);
|
||||
err_builder:
|
||||
drgn_enum_type_builder_deinit(&builder);
|
||||
goto err_enumerators;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Program_hold_object(self, cached_enumerators);
|
||||
@ -2008,9 +1932,10 @@ err_builder:
|
||||
Program_hold_object(self, tag_obj);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
goto err_enumerators;
|
||||
return NULL;
|
||||
|
||||
if (_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_tag.id,
|
||||
tag_obj) == -1 ||
|
||||
@ -2020,16 +1945,9 @@ err_builder:
|
||||
&DrgnType_attr_enumerators.id,
|
||||
cached_enumerators ?
|
||||
cached_enumerators : Py_None) == -1)
|
||||
goto err_type;
|
||||
Py_XDECREF(cached_enumerators);
|
||||
return NULL;
|
||||
|
||||
return type_obj;
|
||||
|
||||
err_type:
|
||||
Py_DECREF(type_obj);
|
||||
err_enumerators:
|
||||
Py_XDECREF(cached_enumerators);
|
||||
return NULL;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
DrgnType *Program_typedef_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
@ -2068,19 +1986,18 @@ DrgnType *Program_typedef_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
Program_hold_object(self, name_obj);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
|
||||
if (_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_type.id,
|
||||
(PyObject *)aliased_type_obj) == -1 ||
|
||||
_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_name.id,
|
||||
name_obj) == -1) {
|
||||
Py_DECREF(type_obj);
|
||||
name_obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return type_obj;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
DrgnType *Program_pointer_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
@ -2124,17 +2041,16 @@ DrgnType *Program_pointer_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
|
||||
if (_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_type.id,
|
||||
(PyObject *)referenced_type_obj) == -1) {
|
||||
Py_DECREF(type_obj);
|
||||
(PyObject *)referenced_type_obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return type_obj;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
DrgnType *Program_array_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
@ -2170,17 +2086,16 @@ DrgnType *Program_array_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
return NULL;
|
||||
|
||||
if (_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_type.id,
|
||||
(PyObject *)element_type_obj) == -1) {
|
||||
Py_DECREF(type_obj);
|
||||
(PyObject *)element_type_obj) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return type_obj;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
||||
static int unpack_parameter(struct drgn_function_type_builder *builder,
|
||||
@ -2245,13 +2160,14 @@ DrgnType *Program_function_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *cached_parameters = PySequence_Tuple(parameters_obj);
|
||||
_cleanup_pydecref_ PyObject *cached_parameters =
|
||||
PySequence_Tuple(parameters_obj);
|
||||
if (!cached_parameters)
|
||||
return NULL;
|
||||
size_t num_parameters = PyTuple_GET_SIZE(cached_parameters);
|
||||
bool can_cache_parameters = true;
|
||||
|
||||
PyObject *cached_template_parameters;
|
||||
_cleanup_pydecref_ PyObject *cached_template_parameters;
|
||||
if (template_parameters_obj) {
|
||||
cached_template_parameters =
|
||||
PySequence_Tuple(template_parameters_obj);
|
||||
@ -2259,7 +2175,7 @@ DrgnType *Program_function_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
cached_template_parameters = PyTuple_New(0);
|
||||
}
|
||||
if (!cached_template_parameters)
|
||||
goto err_parameters;
|
||||
return NULL;
|
||||
size_t num_template_parameters =
|
||||
PyTuple_GET_SIZE(cached_template_parameters);
|
||||
bool can_cache_template_parameters = true;
|
||||
@ -2294,7 +2210,7 @@ DrgnType *Program_function_type(Program *self, PyObject *args, PyObject *kwds)
|
||||
set_drgn_error(err);
|
||||
err_builder:
|
||||
drgn_function_type_builder_deinit(&builder);
|
||||
goto err_template_parameters;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (num_parameters > 0)
|
||||
@ -2303,9 +2219,10 @@ err_builder:
|
||||
Program_hold_object(self, cached_template_parameters);
|
||||
|
||||
qualified_type.qualifiers = qualifiers;
|
||||
DrgnType *type_obj = (DrgnType *)DrgnType_wrap(qualified_type);
|
||||
_cleanup_pydecref_ DrgnType *type_obj =
|
||||
(DrgnType *)DrgnType_wrap(qualified_type);
|
||||
if (!type_obj)
|
||||
goto err_template_parameters;
|
||||
return NULL;
|
||||
|
||||
if (_PyDict_SetItemId(type_obj->attr_cache, &DrgnType_attr_type.id,
|
||||
(PyObject *)return_type_obj) == -1 ||
|
||||
@ -2317,17 +2234,7 @@ err_builder:
|
||||
_PyDict_SetItemId(type_obj->attr_cache,
|
||||
&DrgnType_attr_template_parameters.id,
|
||||
cached_template_parameters) == -1))
|
||||
goto err_type;
|
||||
Py_DECREF(cached_parameters);
|
||||
Py_DECREF(cached_template_parameters);
|
||||
return NULL;
|
||||
|
||||
return type_obj;
|
||||
|
||||
err_type:
|
||||
Py_DECREF(type_obj);
|
||||
err_template_parameters:
|
||||
Py_DECREF(cached_template_parameters);
|
||||
err_parameters:
|
||||
Py_DECREF(cached_parameters);
|
||||
return NULL;
|
||||
return_ptr(type_obj);
|
||||
}
|
||||
|
@ -7,30 +7,18 @@
|
||||
|
||||
int append_string(PyObject *parts, const char *s)
|
||||
{
|
||||
PyObject *str;
|
||||
int ret;
|
||||
|
||||
str = PyUnicode_FromString(s);
|
||||
_cleanup_pydecref_ PyObject *str = PyUnicode_FromString(s);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
ret = PyList_Append(parts, str);
|
||||
Py_DECREF(str);
|
||||
return ret;
|
||||
return PyList_Append(parts, str);
|
||||
}
|
||||
|
||||
static int append_formatv(PyObject *parts, const char *format, va_list ap)
|
||||
{
|
||||
PyObject *str;
|
||||
int ret;
|
||||
|
||||
str = PyUnicode_FromFormatV(format, ap);
|
||||
_cleanup_pydecref_ PyObject *str = PyUnicode_FromFormatV(format, ap);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
ret = PyList_Append(parts, str);
|
||||
Py_DECREF(str);
|
||||
return ret;
|
||||
return PyList_Append(parts, str);
|
||||
}
|
||||
|
||||
int append_format(PyObject *parts, const char *format, ...)
|
||||
@ -46,12 +34,10 @@ int append_format(PyObject *parts, const char *format, ...)
|
||||
|
||||
PyObject *join_strings(PyObject *parts)
|
||||
{
|
||||
PyObject *sep = PyUnicode_New(0, 0);
|
||||
_cleanup_pydecref_ PyObject *sep = PyUnicode_New(0, 0);
|
||||
if (!sep)
|
||||
return NULL;
|
||||
PyObject *ret = PyUnicode_Join(sep, parts);
|
||||
Py_DECREF(sep);
|
||||
return ret;
|
||||
return PyUnicode_Join(sep, parts);
|
||||
}
|
||||
|
||||
PyObject *repr_pretty_from_str(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
@ -66,33 +52,28 @@ PyObject *repr_pretty_from_str(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
if (cycle)
|
||||
return PyObject_CallMethod(p, "text", "s", "...");
|
||||
|
||||
PyObject *str_obj = PyObject_Str(self);
|
||||
_cleanup_pydecref_ PyObject *str_obj = PyObject_Str(self);
|
||||
if (!str_obj)
|
||||
return NULL;
|
||||
PyObject *ret = PyObject_CallMethod(p, "text", "O", str_obj);
|
||||
Py_DECREF(str_obj);
|
||||
return ret;
|
||||
return PyObject_CallMethod(p, "text", "O", str_obj);
|
||||
}
|
||||
|
||||
int index_converter(PyObject *o, void *p)
|
||||
{
|
||||
struct index_arg *arg = p;
|
||||
PyObject *index_obj;
|
||||
|
||||
arg->is_none = o == Py_None;
|
||||
if (arg->allow_none && arg->is_none)
|
||||
return 1;
|
||||
|
||||
index_obj = PyNumber_Index(o);
|
||||
_cleanup_pydecref_ PyObject *index_obj = PyNumber_Index(o);
|
||||
if (!index_obj)
|
||||
return 0;
|
||||
if (arg->is_signed) {
|
||||
arg->svalue = PyLong_AsLongLong(index_obj);
|
||||
Py_DECREF(index_obj);
|
||||
return (arg->svalue != -1LL || !PyErr_Occurred());
|
||||
} else {
|
||||
arg->uvalue = PyLong_AsUnsignedLongLong(index_obj);
|
||||
Py_DECREF(index_obj);
|
||||
return (arg->uvalue != -1ULL || !PyErr_Occurred());
|
||||
}
|
||||
}
|
||||
@ -144,12 +125,10 @@ int enum_converter(PyObject *o, void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
o = PyObject_GetAttrString(o, "value");
|
||||
if (!o)
|
||||
_cleanup_pydecref_ PyObject *value = PyObject_GetAttrString(o, "value");
|
||||
if (!value)
|
||||
return 0;
|
||||
|
||||
arg->value = PyLong_AsUnsignedLong(o);
|
||||
Py_DECREF(o);
|
||||
arg->value = PyLong_AsUnsignedLong(value);
|
||||
if (arg->value == -1 && PyErr_Occurred())
|
||||
return 0;
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user