Commit 2a299874 authored by Stefan Behnel's avatar Stefan Behnel

streamline obj.pop() code

parent f1984275
...@@ -2667,7 +2667,8 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2667,7 +2667,8 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
PyObject_PopIndex_func_type = PyrexTypes.CFuncType( PyObject_PopIndex_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [ PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None),
PyrexTypes.CFuncTypeArg("index", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("py_index", PyrexTypes.py_object_type, None),
PyrexTypes.CFuncTypeArg("c_index", PyrexTypes.c_py_ssize_t_type, None),
PyrexTypes.CFuncTypeArg("is_signed", PyrexTypes.c_int_type, None), PyrexTypes.CFuncTypeArg("is_signed", PyrexTypes.c_int_type, None),
], ],
has_varargs=True) # to fake the additional macro args that lack a proper C type has_varargs=True) # to fake the additional macro args that lack a proper C type
...@@ -2702,14 +2703,23 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2702,14 +2703,23 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
) )
elif len(args) == 2: elif len(args) == 2:
index = unwrap_coerced_node(args[1]) index = unwrap_coerced_node(args[1])
py_index = ExprNodes.NoneNode(index.pos)
orig_index_type = index.type orig_index_type = index.type
if not index.type.is_int: if not index.type.is_int:
if is_list or isinstance(index, ExprNodes.IntNode): if isinstance(index, ExprNodes.IntNode):
py_index = index.coerce_to_pyobject(self.current_env())
index = index.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env())
elif is_list:
if index.type.is_pyobject:
py_index = index.coerce_to_simple(self.current_env())
index = ExprNodes.CloneNode(py_index)
index = index.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) index = index.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env())
else: else:
return node return node
elif not PyrexTypes.numeric_type_fits(index.type, PyrexTypes.c_py_ssize_t_type): elif not PyrexTypes.numeric_type_fits(index.type, PyrexTypes.c_py_ssize_t_type):
return node return node
elif isinstance(index, ExprNodes.IntNode):
py_index = index.coerce_to_pyobject(self.current_env())
# real type might still be larger at runtime # real type might still be larger at runtime
if not orig_index_type.is_int: if not orig_index_type.is_int:
orig_index_type = index.type orig_index_type = index.type
...@@ -2721,7 +2731,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2721,7 +2731,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
return ExprNodes.PythonCapiCallNode( return ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_Py%s_PopIndex" % type_name, node.pos, "__Pyx_Py%s_PopIndex" % type_name,
self.PyObject_PopIndex_func_type, self.PyObject_PopIndex_func_type,
args=[obj, index, args=[obj, py_index, index,
ExprNodes.IntNode(index.pos, value=str(orig_index_type.signed and 1 or 0), ExprNodes.IntNode(index.pos, value=str(orig_index_type.signed and 1 or 0),
constant_result=orig_index_type.signed and 1 or 0, constant_result=orig_index_type.signed and 1 or 0,
type=PyrexTypes.c_int_type), type=PyrexTypes.c_int_type),
......
...@@ -78,11 +78,17 @@ static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { ...@@ -78,11 +78,17 @@ static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
/////////////// pop.proto /////////////// /////////////// pop.proto ///////////////
#define __Pyx_PyObject_Pop(L) (PyList_CheckExact(L) ? \ static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); /*proto*/
__Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L))
#if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); /*proto*/ static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); /*proto*/
static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); /*proto*/ #define __Pyx_PyObject_Pop(L) (likely(PyList_CheckExact(L)) ? \
__Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L))
#else
#define __Pyx_PyList_Pop(L) __Pyx__PyObject_Pop(L)
#define __Pyx_PyObject_Pop(L) __Pyx__PyObject_Pop(L)
#endif
/////////////// pop /////////////// /////////////// pop ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod0 //@requires: ObjectHandling.c::PyObjectCallMethod0
...@@ -96,44 +102,65 @@ static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) { ...@@ -96,44 +102,65 @@ static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) {
return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop")); return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
} }
static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) {
#if CYTHON_COMPILING_IN_CPYTHON #if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) {
/* Check that both the size is positive and no reallocation shrinking needs to be done. */ /* Check that both the size is positive and no reallocation shrinking needs to be done. */
if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) { if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
Py_SIZE(L) -= 1; Py_SIZE(L) -= 1;
return PyList_GET_ITEM(L, PyList_GET_SIZE(L)); return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
} }
#endif
return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop")); return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
} }
#endif
/////////////// pop_index.proto /////////////// /////////////// pop_index.proto ///////////////
#define __Pyx_PyObject_PopIndex(L, ix, is_signed, type, to_py_func) ( \ static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); /*proto*/
(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed)) ? \ static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); /*proto*/
__Pyx__PyList_PopIndex(L, ix) : __Pyx__PyObject_PopIndex(L, to_py_func(ix)))
#if CYTHON_COMPILING_IN_CPYTHON
static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix); /*proto*/
#define __Pyx_PyList_PopIndex(L, ix, is_signed, type, to_py_func) ( \ #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
(likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ? \
__Pyx__PyList_PopIndex(L, py_ix, ix) : ( \
(unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
__Pyx__PyObject_PopIndex(L, py_ix)))
#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
__Pyx_fits_Py_ssize_t(ix, type, is_signed) ? \ __Pyx_fits_Py_ssize_t(ix, type, is_signed) ? \
__Pyx__PyList_PopIndex(L, ix) : __Pyx__PyObject_PopIndex(L, to_py_func(ix))) __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \
(unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
__Pyx__PyObject_PopIndex(L, py_ix)))
static PyObject* __Pyx__PyList_PopIndex(PyObject* L, Py_ssize_t ix); /*proto*/ #else
static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); /*proto*/
#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) \
__Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func)
#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
(unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
__Pyx__PyObject_PopIndex(L, py_ix))
#endif
/////////////// pop_index /////////////// /////////////// pop_index ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod1 //@requires: ObjectHandling.c::PyObjectCallMethod1
static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) { static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) {
PyObject *r; PyObject *r;
if (unlikely(!py_ix)) return NULL; if (unlikely(!py_ix)) return NULL;
r = __Pyx_PyObject_CallMethod1(L, PYIDENT("pop"), py_ix); r = __Pyx__PyObject_PopIndex(L, py_ix);
Py_DECREF(py_ix); Py_DECREF(py_ix);
return r; return r;
} }
static PyObject* __Pyx__PyList_PopIndex(PyObject* L, Py_ssize_t ix) { static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) {
return __Pyx_PyObject_CallMethod1(L, PYIDENT("pop"), py_ix);
}
#if CYTHON_COMPILING_IN_CPYTHON #if CYTHON_COMPILING_IN_CPYTHON
static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix) {
Py_ssize_t size = PyList_GET_SIZE(L); Py_ssize_t size = PyList_GET_SIZE(L);
if (likely(size > (((PyListObject*)L)->allocated >> 1))) { if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
Py_ssize_t cix = ix; Py_ssize_t cix = ix;
...@@ -148,9 +175,13 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, Py_ssize_t ix) { ...@@ -148,9 +175,13 @@ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, Py_ssize_t ix) {
return v; return v;
} }
} }
#endif if (py_ix == Py_None) {
return __Pyx__PyObject_PopIndex(L, PyInt_FromSsize_t(ix)); return __Pyx__PyObject_PopNewIndex(L, PyInt_FromSsize_t(ix));
} else {
return __Pyx__PyObject_PopIndex(L, py_ix);
}
} }
#endif
/////////////// dict_getitem_default.proto /////////////// /////////////// dict_getitem_default.proto ///////////////
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment