mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
use RAII in dispatcher to avoid refcount leaks in certain circumstances when handling exceptions
This commit is contained in:
parent
66c9a40213
commit
f4671f6a04
@ -227,20 +227,20 @@ private:
|
||||
*result = (PyObject *) 1;
|
||||
try {
|
||||
for (; it != nullptr; it = it->next) {
|
||||
PyObject *args_ = args;
|
||||
object args_(args, true);
|
||||
int kwargs_consumed = 0;
|
||||
|
||||
if (nargs < (int) it->args.size()) {
|
||||
args_ = PyTuple_New(it->args.size());
|
||||
args_ = object(PyTuple_New(it->args.size()), false);
|
||||
for (int i = 0; i < nargs; ++i) {
|
||||
PyObject *item = PyTuple_GET_ITEM(args, i);
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(args_, i, item);
|
||||
PyTuple_SET_ITEM(args_.ptr(), i, item);
|
||||
}
|
||||
int arg_ctr = 0;
|
||||
for (auto const &it2 : it->args) {
|
||||
int index = arg_ctr++;
|
||||
if (PyTuple_GET_ITEM(args_, index))
|
||||
if (PyTuple_GET_ITEM(args_.ptr(), index))
|
||||
continue;
|
||||
PyObject *value = nullptr;
|
||||
if (kwargs)
|
||||
@ -251,7 +251,7 @@ private:
|
||||
value = it2.value;
|
||||
if (value) {
|
||||
Py_INCREF(value);
|
||||
PyTuple_SET_ITEM(args_, index, value);
|
||||
PyTuple_SET_ITEM(args_.ptr(), index, value);
|
||||
} else {
|
||||
kwargs_consumed = -1; /* definite failure */
|
||||
break;
|
||||
@ -260,11 +260,7 @@ private:
|
||||
}
|
||||
|
||||
if (kwargs_consumed == nkwargs)
|
||||
result = it->impl(it, args_, parent);
|
||||
|
||||
if (args_ != args) {
|
||||
Py_DECREF(args_);
|
||||
}
|
||||
result = it->impl(it, args_.ptr(), parent);
|
||||
|
||||
if (result != (PyObject *) 1)
|
||||
break;
|
||||
@ -868,15 +864,13 @@ private:
|
||||
instance_type *inst = (instance_type *) inst_;
|
||||
try {
|
||||
new (&inst->holder) holder_type(
|
||||
inst->value->shared_from_this()
|
||||
);
|
||||
inst->value->shared_from_this());
|
||||
} catch (const std::bad_weak_ptr &) {
|
||||
new (&inst->holder) holder_type(inst->value);
|
||||
}
|
||||
inst->constructed = true;
|
||||
}
|
||||
|
||||
|
||||
static void dealloc(PyObject *inst_) {
|
||||
instance_type *inst = (instance_type *) inst_;
|
||||
if (inst->owned) {
|
||||
|
Loading…
Reference in New Issue
Block a user