Commit 773293aa authored by Stefan Behnel's avatar Stefan Behnel

moved unicode iteration setup code into utility function to reduce per-loop C code overhead

parent 0862b946
...@@ -273,22 +273,6 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -273,22 +273,6 @@ class IterationTransform(Visitor.VisitorTransform):
), ),
reversed = reversed)) reversed = reversed))
PyUnicode_READY_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_int_type, [
PyrexTypes.CFuncTypeArg("s", PyrexTypes.py_object_type, None)
],
exception_value='-1')
PyUnicode_GET_LENGTH_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_py_ssize_t_type, [
PyrexTypes.CFuncTypeArg("s", PyrexTypes.py_object_type, None)
])
PyUnicode_KIND_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_int_type, [
PyrexTypes.CFuncTypeArg("s", PyrexTypes.py_object_type, None)
])
PyUnicode_READ_func_type = PyrexTypes.CFuncType( PyUnicode_READ_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_py_ucs4_type, [ PyrexTypes.c_py_ucs4_type, [
PyrexTypes.CFuncTypeArg("kind", PyrexTypes.c_int_type, None), PyrexTypes.CFuncTypeArg("kind", PyrexTypes.c_int_type, None),
...@@ -296,10 +280,14 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -296,10 +280,14 @@ class IterationTransform(Visitor.VisitorTransform):
PyrexTypes.CFuncTypeArg("index", PyrexTypes.c_py_ssize_t_type, None) PyrexTypes.CFuncTypeArg("index", PyrexTypes.c_py_ssize_t_type, None)
]) ])
PyUnicode_DATA_func_type = PyrexTypes.CFuncType( init_unicode_iteration_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_void_ptr_type, [ PyrexTypes.c_int_type, [
PyrexTypes.CFuncTypeArg("s", PyrexTypes.py_object_type, None) PyrexTypes.CFuncTypeArg("s", PyrexTypes.py_object_type, None),
]) PyrexTypes.CFuncTypeArg("length", PyrexTypes.c_py_ssize_t_ptr_type, None),
PyrexTypes.CFuncTypeArg("data", PyrexTypes.c_void_ptr_ptr_type, None),
PyrexTypes.CFuncTypeArg("kind", PyrexTypes.c_int_ptr_type, None)
],
exception_value = '-1')
def _transform_unicode_iteration(self, node, slice_node, reversed=False): def _transform_unicode_iteration(self, node, slice_node, reversed=False):
unpack_temp_node = UtilNodes.LetRefNode( unpack_temp_node = UtilNodes.LetRefNode(
...@@ -307,41 +295,24 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -307,41 +295,24 @@ class IterationTransform(Visitor.VisitorTransform):
start_node = ExprNodes.IntNode( start_node = ExprNodes.IntNode(
node.pos, value='0', constant_result=0, type=PyrexTypes.c_py_ssize_t_type) node.pos, value='0', constant_result=0, type=PyrexTypes.c_py_ssize_t_type)
end_node = ExprNodes.PythonCapiCallNode( length_temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type)
slice_node.pos, "__Pyx_PyUnicode_GET_LENGTH", end_node = length_temp.ref(node.pos)
self.PyUnicode_GET_LENGTH_func_type,
args = [unpack_temp_node],
is_temp = not reversed,
)
if reversed: if reversed:
relation1, relation2 = '>', '>=' relation1, relation2 = '>', '>='
start_node, end_node = end_node, start_node start_node, end_node = end_node, start_node
else: else:
relation1, relation2 = '<=', '<' relation1, relation2 = '<=', '<'
counter = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type) kind_temp = UtilNodes.TempHandle(PyrexTypes.c_int_type)
counter_temp = counter.ref(node.target.pos) data_temp = UtilNodes.TempHandle(PyrexTypes.c_void_ptr_type)
counter_temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type)
kind_temp = UtilNodes.LetRefNode(
ExprNodes.PythonCapiCallNode(
slice_node.pos, "__Pyx_PyUnicode_KIND",
self.PyUnicode_KIND_func_type,
args = [unpack_temp_node],
is_temp = False,
))
data_temp = UtilNodes.LetRefNode(
ExprNodes.PythonCapiCallNode(
slice_node.pos, "__Pyx_PyUnicode_DATA",
self.PyUnicode_DATA_func_type,
args = [unpack_temp_node],
is_temp = False,
))
target_value = ExprNodes.PythonCapiCallNode( target_value = ExprNodes.PythonCapiCallNode(
slice_node.pos, "__Pyx_PyUnicode_READ", slice_node.pos, "__Pyx_PyUnicode_READ",
self.PyUnicode_READ_func_type, self.PyUnicode_READ_func_type,
args = [kind_temp, data_temp, counter_temp], args = [kind_temp.ref(slice_node.pos),
data_temp.ref(slice_node.pos),
counter_temp.ref(node.target.pos)],
is_temp = False, is_temp = False,
) )
if target_value.type != node.target.type: if target_value.type != node.target.type:
...@@ -358,29 +329,34 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -358,29 +329,34 @@ class IterationTransform(Visitor.VisitorTransform):
loop_node = Nodes.ForFromStatNode( loop_node = Nodes.ForFromStatNode(
node.pos, node.pos,
bound1=start_node, relation1=relation1, bound1=start_node, relation1=relation1,
target=counter_temp, target=counter_temp.ref(node.target.pos),
relation2=relation2, bound2=end_node, relation2=relation2, bound2=end_node,
step=None, body=body, step=None, body=body,
else_clause=node.else_clause, else_clause=node.else_clause,
from_range=True) from_range=True)
loop_node = UtilNodes.TempsBlockNode(
node.pos, temps=[counter], body=loop_node)
for temp in (kind_temp, data_temp):
loop_node = UtilNodes.LetNode(temp, loop_node)
setup_node = Nodes.ExprStatNode( setup_node = Nodes.ExprStatNode(
node.pos, node.pos,
expr = ExprNodes.PythonCapiCallNode( expr = ExprNodes.PythonCapiCallNode(
slice_node.pos, "__Pyx_PyUnicode_READY", slice_node.pos, "__Pyx_init_unicode_iteration",
self.PyUnicode_READY_func_type, self.init_unicode_iteration_func_type,
args = [unpack_temp_node], args = [unpack_temp_node,
ExprNodes.AmpersandNode(slice_node.pos, operand=length_temp.ref(slice_node.pos),
type=PyrexTypes.c_py_ssize_t_ptr_type),
ExprNodes.AmpersandNode(slice_node.pos, operand=data_temp.ref(slice_node.pos),
type=PyrexTypes.c_void_ptr_ptr_type),
ExprNodes.AmpersandNode(slice_node.pos, operand=kind_temp.ref(slice_node.pos),
type=PyrexTypes.c_int_ptr_type),
],
is_temp = True, is_temp = True,
result_is_used = False, result_is_used = False,
utility_code=UtilityCode.load_cached("unicode_iter", "Optimize.c"),
)) ))
return UtilNodes.LetNode( return UtilNodes.LetNode(
unpack_temp_node, unpack_temp_node,
Nodes.StatListNode(node.pos, stats=[setup_node, loop_node])) UtilNodes.TempsBlockNode(
node.pos, temps=[counter_temp, length_temp, data_temp, kind_temp],
body=Nodes.StatListNode(node.pos, stats=[setup_node, loop_node])))
def _transform_carray_iteration(self, node, slice_node, reversed=False): def _transform_carray_iteration(self, node, slice_node, reversed=False):
neg_step = False neg_step = False
......
...@@ -119,17 +119,11 @@ ...@@ -119,17 +119,11 @@
/* new Py3.3 unicode type (PEP 393) */ /* new Py3.3 unicode type (PEP 393) */
#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
#define CYTHON_PEP393_ENABLED 1 #define CYTHON_PEP393_ENABLED 1
#define __Pyx_PyUnicode_READY(u) PyUnicode_READY(u)
#define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
#define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
#define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
#define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
#define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
#else #else
#define CYTHON_PEP393_ENABLED 0 #define CYTHON_PEP393_ENABLED 0
#define __Pyx_PyUnicode_READY(u) (0)
#define __Pyx_PyUnicode_KIND(u) (0) /* PyUnicode_WCHAR_KIND */
#define __Pyx_PyUnicode_DATA(u) PyUnicode_AS_UNICODE(u)
#define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
#define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
/* (k=k) => avoid unused variable warning due to macro: */ /* (k=k) => avoid unused variable warning due to macro: */
......
...@@ -417,6 +417,29 @@ static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* iter_obj, Py_ssize_t ori ...@@ -417,6 +417,29 @@ static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* iter_obj, Py_ssize_t ori
return 1; return 1;
} }
/////////////// unicode_iter.proto ///////////////
static CYTHON_INLINE int __Pyx_init_unicode_iteration(
PyObject* ustring, Py_ssize_t *length, void** data, int *kind); /* proto */
/////////////// unicode_iter ///////////////
static CYTHON_INLINE int __Pyx_init_unicode_iteration(
PyObject* ustring, Py_ssize_t *length, void** data, int *kind) {
#if CYTHON_PEP393_ENABLED
if (unlikely(PyUnicode_READY(ustring) < 0)) return -1;
*kind = PUnicode_KIND(ustring);
*length = PyUnicode_GET_LENGTH(ustring);
*data = PyUnicode_DATA(ustring);
#else
*kind = 0;
*length = PyUnicode_GET_SIZE(ustring);
*data = (void*)PyUnicode_AS_UNICODE(ustring);
#endif
return 0;
}
/////////////// pyobject_as_double.proto /////////////// /////////////// pyobject_as_double.proto ///////////////
static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */ static double __Pyx__PyObject_AsDouble(PyObject* obj); /* 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