Commit 524b5755 authored by Stefan Behnel's avatar Stefan Behnel

Specialise coercion from bytes to char* (and friends) to avoid going through...

Specialise coercion from bytes to char* (and friends) to avoid going through several type checks in the generic "__Pyx_PyObject_AsStringAndSize()" function.
parent dcc7b307
...@@ -12678,7 +12678,7 @@ class NoneCheckNode(CoercionNode): ...@@ -12678,7 +12678,7 @@ class NoneCheckNode(CoercionNode):
is_nonecheck = True is_nonecheck = True
def __init__(self, arg, exception_type_cname, exception_message, def __init__(self, arg, exception_type_cname, exception_message,
exception_format_args): exception_format_args=()):
CoercionNode.__init__(self, arg) CoercionNode.__init__(self, arg)
self.type = arg.type self.type = arg.type
self.result_ctype = arg.ctype() self.result_ctype = arg.ctype()
...@@ -12714,6 +12714,19 @@ class NoneCheckNode(CoercionNode): ...@@ -12714,6 +12714,19 @@ class NoneCheckNode(CoercionNode):
else: else:
raise Exception("unsupported type") raise Exception("unsupported type")
@classmethod
def generate(cls, arg, code, exception_message,
exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
node = cls(arg, exception_type_cname, exception_message, exception_format_args)
node.in_nogil_context = in_nogil_context
node.put_nonecheck(code)
@classmethod
def generate_if_needed(cls, arg, code, exception_message,
exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
if arg.may_be_none():
cls.generate(arg, code, exception_message, exception_type_cname, exception_format_args, in_nogil_context)
def put_nonecheck(self, code): def put_nonecheck(self, code):
code.putln( code.putln(
"if (unlikely(%s == Py_None)) {" % self.condition()) "if (unlikely(%s == Py_None)) {" % self.condition())
...@@ -12888,8 +12901,15 @@ class CoerceFromPyTypeNode(CoercionNode): ...@@ -12888,8 +12901,15 @@ class CoerceFromPyTypeNode(CoercionNode):
return (self.type.is_ptr and not self.type.is_array) and self.arg.is_ephemeral() return (self.type.is_ptr and not self.type.is_array) and self.arg.is_ephemeral()
def generate_result_code(self, code): def generate_result_code(self, code):
from_py_function = None
# for certain source types, we can do better than the generic coercion
if self.type.is_string and self.arg.type is bytes_type:
if self.type.from_py_function.startswith('__Pyx_PyObject_As'):
from_py_function = '__Pyx_PyBytes' + self.type.from_py_function[len('__Pyx_PyObject'):]
NoneCheckNode.generate_if_needed(self.arg, code, "expected bytes, NoneType found")
code.putln(self.type.from_py_call_code( code.putln(self.type.from_py_call_code(
self.arg.py_result(), self.result(), self.pos, code)) self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
......
...@@ -54,6 +54,12 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); ...@@ -54,6 +54,12 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
#define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
#endif #endif
#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s))
#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s))
#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s))
#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s))
#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s))
#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s))
#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s))
#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
......
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