Commit 581c8e7f authored by Stefan Behnel's avatar Stefan Behnel

undo redundant Py->C->Py coercions that originate from "optimisations"

parent 8e1e2932
...@@ -1968,6 +1968,36 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -1968,6 +1968,36 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
return arg.arg.coerce_to_boolean(self.current_env()) return arg.arg.coerce_to_boolean(self.current_env())
return node return node
PyNumber_Float_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("o", PyrexTypes.py_object_type, None)
])
def visit_CoerceToPyTypeNode(self, node):
"""Drop redundant conversion nodes after tree changes."""
self.visitchildren(node)
arg = node.arg
if isinstance(arg, ExprNodes.CoerceFromPyTypeNode):
arg = arg.arg
if arg.type.is_pyobject:
if node.type in (arg.type, PyrexTypes.py_object_type):
return arg
if isinstance(arg, ExprNodes.PythonCapiCallNode):
if arg.function.name == 'float' and len(arg.args) == 1:
# undo redundant Py->C->Py coercion
func_arg = arg.args[0]
if func_arg.type is Builtin.float_type:
return func_arg.as_none_safe_node("float() argument must be a string or a number, not 'NoneType'")
elif func_arg.type.is_pyobject:
return ExprNodes.PythonCapiCallNode(
node.pos, '__Pyx_PyNumber_Float', self.PyNumber_Float_func_type,
args=[func_arg],
py_name='float',
is_temp=node.is_temp,
result_is_used=node.result_is_used,
).coerce_to(node.type, self.current_env())
return node
def visit_CoerceFromPyTypeNode(self, node): def visit_CoerceFromPyTypeNode(self, node):
"""Drop redundant conversion nodes after tree changes. """Drop redundant conversion nodes after tree changes.
...@@ -2337,7 +2367,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2337,7 +2367,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
return node # handled in visit_CoerceFromPyTypeNode() return node # handled in visit_CoerceFromPyTypeNode()
if func_arg.type.is_pyobject and node.type.is_pyobject: if func_arg.type.is_pyobject and node.type.is_pyobject:
return ExprNodes.PythonCapiCallNode( return ExprNodes.PythonCapiCallNode(
node.pos, "PyNumber_Int", self.PyNumber_Int_func_type, node.pos, "__Pyx_PyNumber_Int", self.PyNumber_Int_func_type,
args=pos_args, is_temp=True, py_name='int') args=pos_args, is_temp=True, py_name='int')
return node return node
......
...@@ -81,7 +81,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) ...@@ -81,7 +81,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None)
#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) #define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False))
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x);
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
...@@ -93,6 +93,13 @@ static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); ...@@ -93,6 +93,13 @@ static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
#endif #endif
#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x))
#else
#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x))
#endif
#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x))
#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
static int __Pyx_sys_getdefaultencoding_not_ascii; static int __Pyx_sys_getdefaultencoding_not_ascii;
static int __Pyx_init_sys_getdefaultencoding_params(void) { static int __Pyx_init_sys_getdefaultencoding_params(void) {
...@@ -258,7 +265,7 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { ...@@ -258,7 +265,7 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
else return PyObject_IsTrue(x); else return PyObject_IsTrue(x);
} }
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) {
PyNumberMethods *m; PyNumberMethods *m;
const char *name = NULL; const char *name = NULL;
PyObject *res = NULL; PyObject *res = NULL;
...@@ -707,7 +714,7 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) { ...@@ -707,7 +714,7 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
"_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
#else #else
{{TYPE}} val; {{TYPE}} val;
PyObject *v = __Pyx_PyNumber_Int(x); PyObject *v = __Pyx_PyNumber_IntOrLong(x);
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
if (likely(v) && !PyLong_Check(v)) { if (likely(v) && !PyLong_Check(v)) {
PyObject *tmp = v; PyObject *tmp = v;
...@@ -730,7 +737,7 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) { ...@@ -730,7 +737,7 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
} }
} else { } else {
{{TYPE}} val; {{TYPE}} val;
PyObject *tmp = __Pyx_PyNumber_Int(x); PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
if (!tmp) return ({{TYPE}}) -1; if (!tmp) return ({{TYPE}}) -1;
val = {{FROM_PY_FUNCTION}}(tmp); val = {{FROM_PY_FUNCTION}}(tmp);
Py_DECREF(tmp); Py_DECREF(tmp);
......
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