mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-08 01:41:59 +00:00
TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_STACK (pointee)
This commit is contained in:
parent
4f8447d707
commit
76e7770134
@ -2037,7 +2037,7 @@ public:
|
|||||||
|
|
||||||
template <typename Return, typename Guard, typename Func>
|
template <typename Return, typename Guard, typename Func>
|
||||||
enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) && {
|
enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) && {
|
||||||
return std::move(*this).template call_impl<Return>(std::forward<Func>(f), indices{}, Guard{});
|
return std::move(*this).template call_impl<Return>(std::forward<Func>(f), indices{}, Guard{}); // GET_INT_STACK -3
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Return, typename Guard, typename Func>
|
template <typename Return, typename Guard, typename Func>
|
||||||
@ -2065,7 +2065,7 @@ private:
|
|||||||
|
|
||||||
template <typename Return, typename Func, size_t... Is, typename Guard>
|
template <typename Return, typename Func, size_t... Is, typename Guard>
|
||||||
Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {
|
Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {
|
||||||
return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...);
|
return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...); // GET_INT_STACK -2
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<make_caster<Args>...> argcasters;
|
std::tuple<make_caster<Args>...> argcasters;
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
# include <cxxabi.h>
|
# include <cxxabi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TRIGGER_SEGSEV { unsigned long *bad = nullptr; *bad = -1; }
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object
|
/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object
|
||||||
@ -97,7 +99,7 @@ public:
|
|||||||
/// Construct a cpp_function from a class method (const, no ref-qualifier)
|
/// Construct a cpp_function from a class method (const, no ref-qualifier)
|
||||||
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
||||||
cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
|
cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
|
||||||
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
|
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); }, // GET_INT_STACK -1
|
||||||
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
|
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +169,7 @@ protected:
|
|||||||
"The number of argument annotations does not match the number of function arguments");
|
"The number of argument annotations does not match the number of function arguments");
|
||||||
|
|
||||||
/* Dispatch code which converts function arguments and performs the actual function call */
|
/* Dispatch code which converts function arguments and performs the actual function call */
|
||||||
rec->impl = [](function_call &call) -> handle {
|
rec->impl = [](function_call &call) -> handle { // GET_INT_STACK -5
|
||||||
cast_in args_converter;
|
cast_in args_converter;
|
||||||
|
|
||||||
/* Try to cast the function arguments into the C++ domain */
|
/* Try to cast the function arguments into the C++ domain */
|
||||||
@ -190,7 +192,7 @@ protected:
|
|||||||
|
|
||||||
/* Perform the function call */
|
/* Perform the function call */
|
||||||
handle result = cast_out::cast(
|
handle result = cast_out::cast(
|
||||||
std::move(args_converter).template call<Return, Guard>(cap->f), policy, call.parent);
|
std::move(args_converter).template call<Return, Guard>(cap->f), policy, call.parent); // GET_INT_STACK -4
|
||||||
|
|
||||||
/* Invoke call policy post-call hook */
|
/* Invoke call policy post-call hook */
|
||||||
process_attributes<Extra...>::postcall(call, result);
|
process_attributes<Extra...>::postcall(call, result);
|
||||||
@ -552,7 +554,7 @@ protected:
|
|||||||
handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,
|
handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,
|
||||||
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
||||||
|
|
||||||
auto self_value_and_holder = value_and_holder();
|
auto self_value_and_holder = value_and_holder(); // cast.h
|
||||||
if (overloads->is_constructor) {
|
if (overloads->is_constructor) {
|
||||||
if (!PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) {
|
if (!PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) {
|
||||||
PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument");
|
PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument");
|
||||||
@ -764,7 +766,7 @@ protected:
|
|||||||
// 6. Call the function.
|
// 6. Call the function.
|
||||||
try {
|
try {
|
||||||
loader_life_support guard{};
|
loader_life_support guard{};
|
||||||
result = func.impl(call);
|
result = func.impl(call); // GET_INT_STACK -6
|
||||||
} catch (reference_cast_error &) {
|
} catch (reference_cast_error &) {
|
||||||
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
||||||
}
|
}
|
||||||
@ -930,7 +932,7 @@ protected:
|
|||||||
} else {
|
} else {
|
||||||
if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {
|
if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {
|
||||||
auto *pi = reinterpret_cast<instance *>(parent.ptr());
|
auto *pi = reinterpret_cast<instance *>(parent.ptr());
|
||||||
self_value_and_holder.type->init_instance(pi, nullptr);
|
self_value_and_holder.type->init_instance(pi, nullptr); // GET_STACK -4
|
||||||
}
|
}
|
||||||
return result.ptr();
|
return result.ptr();
|
||||||
}
|
}
|
||||||
@ -1536,7 +1538,7 @@ private:
|
|||||||
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
} else if (inst->owned || detail::always_construct_holder<holder_type>::value) {
|
} else if (inst->owned || detail::always_construct_holder<holder_type>::value) {
|
||||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>()); // GET_STACK -2
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1551,7 +1553,7 @@ private:
|
|||||||
register_instance(inst, v_h.value_ptr(), v_h.type);
|
register_instance(inst, v_h.value_ptr(), v_h.type);
|
||||||
v_h.set_instance_registered();
|
v_h.set_instance_registered();
|
||||||
}
|
}
|
||||||
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
|
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>()); // GET_STACK -3
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
@ -11,9 +12,12 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|||||||
// To enable passing of unique_ptr as in pure C++.
|
// To enable passing of unique_ptr as in pure C++.
|
||||||
template <typename T> class vptr {
|
template <typename T> class vptr {
|
||||||
public:
|
public:
|
||||||
explicit vptr(T *ptr = nullptr) : vptr_{std::unique_ptr<T>(ptr)} {}
|
explicit vptr(T *ptr = nullptr) : vptr_{std::unique_ptr<T>(ptr)} {
|
||||||
explicit vptr(std::unique_ptr<T> u) : vptr_{std::move(u)} {}
|
std::cout << std::endl << "explicit vptr(T *ptr = nullptr)" << std::endl;
|
||||||
explicit vptr(std::shared_ptr<T> s) : vptr_{s} {}
|
//TRIGGER_SEGSEV
|
||||||
|
}
|
||||||
|
explicit vptr(std::unique_ptr<T> u) : vptr_{std::move(u)} { std::cout << std::endl << "explicit vptr(std::unique_ptr<T> u)" << std::endl; }
|
||||||
|
explicit vptr(std::shared_ptr<T> s) : vptr_{s} { std::cout << std::endl << "explicit vptr(std::shared_ptr<T> s)" << std::endl; }
|
||||||
|
|
||||||
int ownership_type() const {
|
int ownership_type() const {
|
||||||
if (std::get_if<0>(&vptr_)) {
|
if (std::get_if<0>(&vptr_)) {
|
||||||
@ -26,6 +30,7 @@ template <typename T> class vptr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
T *get() {
|
T *get() {
|
||||||
|
std::cout << std::endl << "vptr::get" << std::endl;
|
||||||
auto u = std::get_if<0>(&vptr_);
|
auto u = std::get_if<0>(&vptr_);
|
||||||
if (u) {
|
if (u) {
|
||||||
return u->get();
|
return u->get();
|
||||||
@ -64,7 +69,7 @@ template <typename T> class vptr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> class vptr_holder : public vptr<T> {
|
template <typename T> class vptr_holder : public vptr<T> {
|
||||||
using vptr<T>::vptr;
|
using vptr<T>::vptr; // GET_STACK -1
|
||||||
};
|
};
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
@ -16,6 +16,7 @@ class pointee { // NOT copyable.
|
|||||||
|
|
||||||
int get_int() const {
|
int get_int() const {
|
||||||
to_cout("pointee::get_int()");
|
to_cout("pointee::get_int()");
|
||||||
|
//TRIGGER_SEGSEV
|
||||||
return 213;
|
return 213;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
tests/work.py
Normal file
12
tests/work.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from pybind11_tests import unique_ptr_member as m
|
||||||
|
|
||||||
|
|
||||||
|
def test_pointee_and_ptr_owner():
|
||||||
|
m.to_cout("")
|
||||||
|
obj = m.pointee()
|
||||||
|
assert obj.get_int() == 213
|
||||||
|
del obj
|
||||||
|
print("DONE.", flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
test_pointee_and_ptr_owner()
|
Loading…
Reference in New Issue
Block a user