Commit 912d05a2 authored by Stefan Behnel's avatar Stefan Behnel

Split 2-tuple unpacking helper function into a (still) inlineable fast-path...

Split 2-tuple unpacking helper function into a (still) inlineable fast-path and a slow fallback function that does not need inlining.
parent 195b23c9
...@@ -80,49 +80,70 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { ...@@ -80,49 +80,70 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
/////////////// UnpackTuple2.proto /////////////// /////////////// UnpackTuple2.proto ///////////////
static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** value1, PyObject** value2, #define __Pyx_unpack_tuple2(tuple, value1, value2, is_tuple, has_known_size, decref_tuple) \
int is_tuple, int has_known_size, int decref_tuple); (likely(is_tuple || PyTuple_Check(tuple)) ? \
(likely(has_known_size || PyTuple_GET_SIZE(tuple) == 2) ? \
__Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple) : \
(__Pyx_UnpackTupleError(tuple, 2), -1)) : \
__Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple))
static CYTHON_INLINE int __Pyx_unpack_tuple2_exact(
PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple);
static int __Pyx_unpack_tuple2_generic(
PyObject* tuple, PyObject** value1, PyObject** value2, int has_known_size, int decref_tuple);
/////////////// UnpackTuple2 /////////////// /////////////// UnpackTuple2 ///////////////
//@requires: UnpackItemEndCheck //@requires: UnpackItemEndCheck
//@requires: UnpackTupleError //@requires: UnpackTupleError
//@requires: RaiseNeedMoreValuesToUnpack //@requires: RaiseNeedMoreValuesToUnpack
static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, static CYTHON_INLINE int __Pyx_unpack_tuple2_exact(
int is_tuple, int has_known_size, int decref_tuple) { PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) {
Py_ssize_t index; PyObject *value1 = NULL, *value2 = NULL;
PyObject *value1 = NULL, *value2 = NULL, *iter = NULL;
if (!is_tuple && unlikely(!PyTuple_Check(tuple))) {
iternextfunc iternext;
iter = PyObject_GetIter(tuple);
if (unlikely(!iter)) goto bad;
if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; }
iternext = Py_TYPE(iter)->tp_iternext;
value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; }
value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; }
if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad;
Py_DECREF(iter);
} else {
if (!has_known_size && unlikely(PyTuple_GET_SIZE(tuple) != 2)) {
__Pyx_UnpackTupleError(tuple, 2);
goto bad;
}
#if CYTHON_COMPILING_IN_PYPY #if CYTHON_COMPILING_IN_PYPY
value1 = PySequence_ITEM(tuple, 0); value1 = PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad;
if (unlikely(!value1)) goto bad; value2 = PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad;
value2 = PySequence_ITEM(tuple, 1);
if (unlikely(!value2)) goto bad;
#else #else
value1 = PyTuple_GET_ITEM(tuple, 0); value1 = PyTuple_GET_ITEM(tuple, 0); Py_INCREF(value1);
value2 = PyTuple_GET_ITEM(tuple, 1); value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value2);
Py_INCREF(value1);
Py_INCREF(value2);
#endif #endif
if (decref_tuple) { Py_DECREF(tuple); } if (decref_tuple) {
Py_DECREF(tuple);
} }
*pvalue1 = value1; *pvalue1 = value1;
*pvalue2 = value2; *pvalue2 = value2;
return 0; return 0;
#if CYTHON_COMPILING_IN_PYPY
bad:
Py_XDECREF(iter);
Py_XDECREF(value1);
Py_XDECREF(value2);
if (decref_tuple) { Py_XDECREF(tuple); }
return -1;
#endif
}
static int __Pyx_unpack_tuple2_generic(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2,
int has_known_size, int decref_tuple) {
Py_ssize_t index;
PyObject *value1 = NULL, *value2 = NULL, *iter = NULL;
iternextfunc iternext;
iter = PyObject_GetIter(tuple);
if (unlikely(!iter)) goto bad;
if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; }
iternext = Py_TYPE(iter)->tp_iternext;
value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; }
value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; }
if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad;
Py_DECREF(iter);
*pvalue1 = value1;
*pvalue2 = value2;
return 0;
unpacking_failed: unpacking_failed:
if (!has_known_size && __Pyx_IterFinish() == 0) if (!has_known_size && __Pyx_IterFinish() == 0)
__Pyx_RaiseNeedMoreValuesError(index); __Pyx_RaiseNeedMoreValuesError(index);
...@@ -134,6 +155,7 @@ bad: ...@@ -134,6 +155,7 @@ bad:
return -1; return -1;
} }
/////////////// IterNext.proto /////////////// /////////////// IterNext.proto ///////////////
#define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL) #define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL)
......
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