From 5e4da6a9e0a0bf91ce23edef7b582cb59a3c6d5f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 20 Nov 2000 03:28:00 +0000 Subject: [PATCH] Expend less energy on fancy error messages for internal errors which might as well be asserts() because they can never happen. [SVN r8263] --- extclass.cpp | 21 ++-- newtypes.cpp | 279 +++++++++++++++++++++++++-------------------------- subclass.cpp | 2 +- 3 files changed, 152 insertions(+), 150 deletions(-) diff --git a/extclass.cpp b/extclass.cpp index 786bc321..9566d6f8 100644 --- a/extclass.cpp +++ b/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 DPtr; DPtr lwrapper(static_cast(left), DPtr::new_ref); DPtr rwrapper(static_cast(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; } diff --git a/newtypes.cpp b/newtypes.cpp index e0efddfc..df9b0078 100644 --- a/newtypes.cpp +++ b/newtypes.cpp @@ -16,6 +16,7 @@ #include #include #include "objects.h" +#include 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::value; + return (size + alignment - 1) / alignment * alignment; + } -int* counted_pod_refcount(char* pod) -{ - if(pod == 0) - return 0; - return reinterpret_cast(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 + 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& x1, + const std::pair& 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& x1, - const std::pair& 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& x) const - { - return pod == x.first; - } - - char* pod; -}; + bool operator()(const std::pair& 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(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(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(::operator new(total_size)); -#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - ++pod_instance_counter; -#endif - memset(buffer, 0, total_size); + const Holder element(static_cast(pod), size); - int* ref_count = reinterpret_cast(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(pod)) <= 1) - { - const Storage::iterator found = - std::find_if(m_storage.begin(), m_storage.end(), - identical(static_cast(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(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(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(::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(pod), size) <= 1) + { + const Storage::iterator found = + std::find_if(m_storage.begin(), m_storage.end(), + identical(static_cast(pod))); + + if(found != m_storage.end()) + { + m_storage.erase(found); + } + } + counted_pod_decref(static_cast(pod), size); + } } // namespace detail namespace { diff --git a/subclass.cpp b/subclass.cpp index d590e17e..c65a052f 100644 --- a/subclass.cpp +++ b/subclass.cpp @@ -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); }