mirror of
https://github.com/boostorg/python.git
synced 2026-01-26 18:52:26 +00:00
Expend less energy on fancy error messages for internal errors which might as
well be asserts() because they can never happen. [SVN r8263]
This commit is contained in:
21
extclass.cpp
21
extclass.cpp
@@ -72,9 +72,7 @@ namespace detail {
|
||||
if (left->ob_type != &operator_dispatcher::type_object ||
|
||||
right->ob_type != &operator_dispatcher::type_object)
|
||||
{
|
||||
String format("operator_dispatcher::unwrap_args(): internal error (%d, %d)");
|
||||
String message(format % Tuple(__FILE__, __LINE__));
|
||||
PyErr_SetObject(PyExc_RuntimeError, message.get());
|
||||
PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_args(): expecting operator_dispatcher arguments only!");
|
||||
return unwrap_exception_code;
|
||||
}
|
||||
|
||||
@@ -103,13 +101,10 @@ namespace detail {
|
||||
right->ob_type != &operator_dispatcher::type_object ||
|
||||
m->ob_type != &operator_dispatcher::type_object)
|
||||
{
|
||||
String format("operator_dispatcher::unwrap_pow_args(): internal error (%d, %d)");
|
||||
String message(format % Tuple(__FILE__, __LINE__));
|
||||
PyErr_SetObject(PyExc_RuntimeError, message.get());
|
||||
PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_pow_args(): expecting operator_dispatcher arguments only!");
|
||||
return unwrap_exception_code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef PyPtr<operator_dispatcher> DPtr;
|
||||
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::new_ref);
|
||||
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::new_ref);
|
||||
@@ -493,7 +488,15 @@ void operator_dispatcher_dealloc(PyObject* self)
|
||||
int operator_dispatcher_coerce(PyObject** l, PyObject** r)
|
||||
{
|
||||
Py_INCREF(*l);
|
||||
*r = operator_dispatcher::create(Ptr(*r, Ptr::new_ref), Ptr());
|
||||
try
|
||||
{
|
||||
*r = operator_dispatcher::create(Ptr(*r, Ptr::new_ref), Ptr());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
handle_exception();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
279
newtypes.cpp
279
newtypes.cpp
@@ -16,6 +16,7 @@
|
||||
#include <stdexcept>
|
||||
#include <boost/smart_ptr.hpp>
|
||||
#include "objects.h"
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
namespace py {
|
||||
|
||||
@@ -584,169 +585,167 @@ TypeObjectBase::TypeObjectBase(PyTypeObject* t)
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef long pod_refcount;
|
||||
|
||||
inline pod_refcount pod_refcount_offset(std::size_t size)
|
||||
{
|
||||
const std::size_t alignment = boost::alignment_of<pod_refcount>::value;
|
||||
return (size + alignment - 1) / alignment * alignment;
|
||||
}
|
||||
|
||||
int* counted_pod_refcount(char* pod)
|
||||
{
|
||||
if(pod == 0)
|
||||
return 0;
|
||||
return reinterpret_cast<int*>(pod - detail::shared_pod_manager::offset);
|
||||
}
|
||||
inline pod_refcount* counted_pod_refcount(char* pod, std::size_t size)
|
||||
{
|
||||
if(pod == 0)
|
||||
return 0;
|
||||
|
||||
return reinterpret_cast<pod_refcount*>(pod + pod_refcount_offset(size));
|
||||
}
|
||||
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
int pod_instance_counter = 0;
|
||||
#endif
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
int pod_instance_counter = 0;
|
||||
#endif
|
||||
|
||||
int counted_pod_getref(char* pod)
|
||||
{
|
||||
int* ref_count = counted_pod_refcount(pod);
|
||||
if(ref_count == 0)
|
||||
return -1;
|
||||
return *ref_count;
|
||||
}
|
||||
inline pod_refcount counted_pod_getref(char* pod, std::size_t size)
|
||||
{
|
||||
pod_refcount* ref_count = counted_pod_refcount(pod, size);
|
||||
return ref_count == 0 ? -1 : *ref_count;
|
||||
}
|
||||
|
||||
int counted_pod_decref(char* pod)
|
||||
{
|
||||
int* ref_count = counted_pod_refcount(pod);
|
||||
if(ref_count == 0)
|
||||
return -1;
|
||||
--(*ref_count);
|
||||
if(*ref_count <= 0)
|
||||
{
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
--pod_instance_counter;
|
||||
#endif
|
||||
::operator delete(ref_count);
|
||||
return 0;
|
||||
}
|
||||
return *ref_count;
|
||||
}
|
||||
inline pod_refcount counted_pod_decref(char* pod, std::size_t size)
|
||||
{
|
||||
pod_refcount* const ref_count = counted_pod_refcount(pod, size);
|
||||
if (ref_count == 0)
|
||||
return -1;
|
||||
--(*ref_count);
|
||||
if (*ref_count <= 0)
|
||||
{
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
--pod_instance_counter;
|
||||
#endif
|
||||
::operator delete(pod);
|
||||
return 0;
|
||||
}
|
||||
return *ref_count;
|
||||
}
|
||||
|
||||
int counted_pod_incref(char* pod)
|
||||
{
|
||||
int* ref_count = counted_pod_refcount(pod);
|
||||
if(ref_count == 0)
|
||||
return -1;
|
||||
return ++(*ref_count);
|
||||
}
|
||||
pod_refcount counted_pod_incref(char* pod, std::size_t size)
|
||||
{
|
||||
pod_refcount* ref_count = counted_pod_refcount(pod, size);
|
||||
return ref_count == 0 ? -1 : ++(*ref_count);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct shared_pod_manager::Compare
|
||||
{
|
||||
bool operator()(const std::pair<char*, std::size_t>& x1,
|
||||
const std::pair<char*, std::size_t>& x2) const
|
||||
{
|
||||
const std::size_t n1 = x1.second;
|
||||
const std::size_t n2 = x2.second;
|
||||
return n1 < n2 || n1 == n2 && PY_CSTD_::memcmp(x1.first, x2.first, n1) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct shared_pod_manager::Compare
|
||||
{
|
||||
bool operator()(const std::pair<char*, std::size_t>& x1,
|
||||
const std::pair<char*, std::size_t>& x2) const
|
||||
{
|
||||
const std::size_t n1 = x1.second;
|
||||
const std::size_t n2 = x2.second;
|
||||
return n1 < n2 || n1 == n2 && PY_CSTD_::memcmp(x1.first, x2.first, n1) < 0;
|
||||
}
|
||||
};
|
||||
struct shared_pod_manager::identical
|
||||
{
|
||||
identical(char* p) : pod(p) {}
|
||||
|
||||
struct shared_pod_manager::identical
|
||||
{
|
||||
identical(char* p) : pod(p) {}
|
||||
|
||||
bool operator()(const std::pair<char*, std::size_t>& x) const
|
||||
{
|
||||
return pod == x.first;
|
||||
}
|
||||
|
||||
char* pod;
|
||||
};
|
||||
bool operator()(const std::pair<char*, std::size_t>& x) const
|
||||
{
|
||||
return pod == x.first;
|
||||
}
|
||||
|
||||
shared_pod_manager& shared_pod_manager::instance()
|
||||
{
|
||||
static shared_pod_manager spm;
|
||||
return spm;
|
||||
}
|
||||
char* pod;
|
||||
};
|
||||
|
||||
shared_pod_manager::~shared_pod_manager()
|
||||
{
|
||||
}
|
||||
shared_pod_manager& shared_pod_manager::instance()
|
||||
{
|
||||
static shared_pod_manager spm;
|
||||
return spm;
|
||||
}
|
||||
|
||||
void* shared_pod_manager::replace_if_equal(void* pod, std::size_t size)
|
||||
{
|
||||
if(pod == 0)
|
||||
return 0;
|
||||
|
||||
const Holder element(static_cast<char*>(pod), size);
|
||||
|
||||
const Storage::iterator found
|
||||
= std::lower_bound(m_storage.begin(), m_storage.end(), element, Compare());
|
||||
|
||||
if (found != m_storage.end() && pod == found->first)
|
||||
{
|
||||
// pod already in list => do nothing
|
||||
return pod;
|
||||
}
|
||||
else if (found != m_storage.end() && !Compare()(element, *found))
|
||||
{
|
||||
// equal element in list => replace
|
||||
void* replacement = found->first;
|
||||
counted_pod_incref(found->first);
|
||||
dec_ref(element.first); // invalidates iterator 'found'
|
||||
return replacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
// new element => insert
|
||||
m_storage.insert(found, element);
|
||||
return pod;
|
||||
}
|
||||
}
|
||||
shared_pod_manager::~shared_pod_manager()
|
||||
{
|
||||
}
|
||||
|
||||
void* shared_pod_manager::make_unique_copy(void* pod, std::size_t size)
|
||||
{
|
||||
if(pod == 0)
|
||||
return 0;
|
||||
if(counted_pod_getref(static_cast<char*>(pod)) == 1)
|
||||
return pod;
|
||||
void* copy = create(size);
|
||||
memmove(copy, pod, size);
|
||||
dec_ref(pod);
|
||||
return copy;
|
||||
}
|
||||
void* shared_pod_manager::replace_if_equal(void* pod, std::size_t size)
|
||||
{
|
||||
if(pod == 0)
|
||||
return 0;
|
||||
|
||||
void* shared_pod_manager::create(std::size_t size)
|
||||
{
|
||||
std::size_t total_size = offset + size;
|
||||
char* buffer = static_cast<char*>(::operator new(total_size));
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
++pod_instance_counter;
|
||||
#endif
|
||||
memset(buffer, 0, total_size);
|
||||
const Holder element(static_cast<char*>(pod), size);
|
||||
|
||||
int* ref_count = reinterpret_cast<int*>(buffer);
|
||||
*ref_count = 1;
|
||||
|
||||
char* pod = buffer + offset;
|
||||
const Storage::iterator found
|
||||
= std::lower_bound(m_storage.begin(), m_storage.end(), element, Compare());
|
||||
|
||||
return pod;
|
||||
}
|
||||
if (found != m_storage.end() && pod == found->first)
|
||||
{
|
||||
// pod already in list => do nothing
|
||||
return pod;
|
||||
}
|
||||
else if (found != m_storage.end() && !Compare()(element, *found))
|
||||
{
|
||||
// equal element in list => replace
|
||||
void* replacement = found->first;
|
||||
counted_pod_incref(found->first, size);
|
||||
dec_ref(element.first, size); // invalidates iterator 'found'
|
||||
return replacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
// new element => insert
|
||||
m_storage.insert(found, element);
|
||||
return pod;
|
||||
}
|
||||
}
|
||||
|
||||
void shared_pod_manager::dec_ref(void* pod)
|
||||
{
|
||||
if(pod == 0)
|
||||
return;
|
||||
|
||||
if(counted_pod_getref(static_cast<char*>(pod)) <= 1)
|
||||
{
|
||||
const Storage::iterator found =
|
||||
std::find_if(m_storage.begin(), m_storage.end(),
|
||||
identical(static_cast<char*>(pod)));
|
||||
void* shared_pod_manager::make_unique_copy(void* pod, std::size_t size)
|
||||
{
|
||||
if(pod == 0)
|
||||
return 0;
|
||||
if(counted_pod_getref(static_cast<char*>(pod), size) == 1)
|
||||
return pod;
|
||||
void* copy = create(size);
|
||||
memmove(copy, pod, size);
|
||||
dec_ref(pod, size);
|
||||
return copy;
|
||||
}
|
||||
|
||||
if(found != m_storage.end())
|
||||
{
|
||||
m_storage.erase(found);
|
||||
}
|
||||
}
|
||||
counted_pod_decref(static_cast<char*>(pod));
|
||||
}
|
||||
void* shared_pod_manager::create(std::size_t size)
|
||||
{
|
||||
std::size_t total_size = pod_refcount_offset(size) + sizeof(pod_refcount);
|
||||
char* pod = static_cast<char*>(::operator new(total_size));
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
++pod_instance_counter;
|
||||
#endif
|
||||
memset(pod, 0, total_size);
|
||||
|
||||
*counted_pod_refcount(pod, size) = 1;
|
||||
|
||||
return pod;
|
||||
}
|
||||
|
||||
void shared_pod_manager::dec_ref(void* pod, std::size_t size)
|
||||
{
|
||||
if(pod == 0)
|
||||
return;
|
||||
|
||||
if(counted_pod_getref(static_cast<char*>(pod), size) <= 1)
|
||||
{
|
||||
const Storage::iterator found =
|
||||
std::find_if(m_storage.begin(), m_storage.end(),
|
||||
identical(static_cast<char*>(pod)));
|
||||
|
||||
if(found != m_storage.end())
|
||||
{
|
||||
m_storage.erase(found);
|
||||
}
|
||||
}
|
||||
counted_pod_decref(static_cast<char*>(pod), size);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace {
|
||||
|
||||
Ptr state(PyObject_GetAttrString(instance, "__dict__"), Ptr::null_ok);
|
||||
PyErr_Clear();
|
||||
if (state.get() != 0)
|
||||
if (state.get() != 0 && Dict(state).size() > 0)
|
||||
{
|
||||
return Tuple(instance_class, initargs, state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user