Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
327e0209
Commit
327e0209
authored
Dec 05, 2007
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pyrex type conversion with overflow check for all int types.
parent
19ecd0df
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
130 additions
and
35 deletions
+130
-35
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+4
-2
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+0
-16
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+126
-17
No files found.
Cython/Compiler/ModuleNode.py
View file @
327e0209
...
...
@@ -279,6 +279,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
code
.
putln
(
''
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
code
.
put
(
PyrexTypes
.
type_conversion_predeclarations
)
code
.
put
(
Nodes
.
branch_prediction_macros
)
code
.
putln
(
''
)
code
.
putln
(
'static PyObject *%s;'
%
env
.
module_cname
)
...
...
@@ -1598,6 +1599,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
utility_code
in
env
.
utility_code_used
:
code
.
h
.
put
(
utility_code
[
0
])
code
.
put
(
utility_code
[
1
])
code
.
put
(
PyrexTypes
.
type_conversion_functions
)
#------------------------------------------------------------------------------------
#
...
...
@@ -1745,11 +1747,11 @@ bad:
register_cleanup_utility_code
=
[
"""
static int __Pyx_RegisterCleanup(); /*proto*/
static int __Pyx_RegisterCleanup(
void
); /*proto*/
static PyObject* cleanup(PyObject *self, PyObject *unused); /*proto*/
static PyMethodDef cleanup_def = {"__cleanup", (PyCFunction)&cleanup, METH_NOARGS, 0};
"""
,
"""
static int __Pyx_RegisterCleanup() {
static int __Pyx_RegisterCleanup(
void
) {
/* Don't use Py_AtExit because that has a 32-call limit
* and is called after python finalization.
*/
...
...
Cython/Compiler/Nodes.py
View file @
327e0209
...
...
@@ -3068,22 +3068,6 @@ utility_function_predeclarations = \
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n; int is_unicode;} __Pyx_StringTabEntry; /*proto*/
static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
PyObject* x = PyNumber_Index(b);
if (!x) return -1;
ival = PyInt_AsSsize_t(x);
Py_DECREF(x);
return ival;
}
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
if (x == Py_True) return 1;
else if (x == Py_False) return 0;
else return PyObject_IsTrue(x);
}
"""
+
"""
static int %(skip_dispatch_cname)s = 0;
...
...
Cython/Compiler/PyrexTypes.py
View file @
327e0209
...
...
@@ -359,19 +359,59 @@ class CNumericType(CType):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
base
=
public_decl
(
self
.
sign_and_name
(),
dll_linkage
)
return
self
.
base_declaration_code
(
base
,
entity_code
)
int_conversion_list
=
{}
type_conversion_functions
=
""
type_conversion_predeclarations
=
""
class
CIntType
(
CNumericType
):
is_int
=
1
typedef_flag
=
0
to_py_function
=
"PyInt_FromLong"
from_py_function
=
"PyInt_AsLong"
from_py_function
=
"
__pyx_
PyInt_AsLong"
exception_value
=
-
1
def
__init__
(
self
,
rank
,
signed
,
pymemberdef_typecode
=
None
,
is_returncode
=
0
):
CNumericType
.
__init__
(
self
,
rank
,
signed
,
pymemberdef_typecode
)
self
.
is_returncode
=
is_returncode
if
self
.
from_py_function
==
'__pyx_PyInt_AsLong'
:
self
.
from_py_function
=
self
.
get_type_conversion
()
def
get_type_conversion
(
self
):
# error on overflow
c_type
=
self
.
sign_and_name
()
c_name
=
c_type
.
replace
(
' '
,
'_'
);
func_name
=
"__pyx_PyInt_%s"
%
c_name
;
c_mask
=
"__pyx_%s_MASK"
%
c_name
if
not
int_conversion_list
.
has_key
(
func_name
):
# no env to add utility code to
global
type_conversion_predeclarations
,
type_conversion_functions
if
self
.
signed
:
neg_test
=
" && ((-val) & %s)"
%
c_mask
else
:
neg_test
=
""
type_conversion_predeclarations
+=
"""
static INLINE %(c_type)s %(func_name)s(PyObject* x);"""
%
{
'c_type'
:
c_type
,
'c_name'
:
c_name
,
'func_name'
:
func_name
}
type_conversion_functions
+=
"""
#define %(c_mask)s ((long)(~((1LL << (8*sizeof(%(c_type)s))) - 1LL)))
static INLINE %(c_type)s %(func_name)s(PyObject* x) {
if (sizeof(%(c_type)s) < sizeof(long)) {
long val = __pyx_PyInt_AsLong(x);
if (unlikely((val & %(c_mask)s) %(neg_test)s)) {
PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s");
return (%(c_type)s)-1;
}
return (%(c_type)s)val;
}
else {
return __pyx_PyInt_AsLong(x);
}
}
"""
%
{
'c_type'
:
c_type
,
'c_name'
:
c_name
,
'func_name'
:
func_name
,
'c_mask'
:
c_mask
,
'neg_test'
:
neg_test
}
int_conversion_list
[
func_name
]
=
True
return
func_name
def
assignable_from_resolved_type
(
self
,
src_type
):
return
src_type
.
is_int
or
src_type
.
is_enum
or
src_type
is
error_type
...
...
@@ -405,13 +445,13 @@ class CULongType(CUIntType):
class
CLongLongType
(
CUIntType
):
to_py_function
=
"PyLong_FromLongLong"
from_py_function
=
"
PyInt_AsUnsignedLongLongMask
"
from_py_function
=
"
__pyx_PyInt_AsLongLong
"
class
CULongLongType
(
CUIntType
):
to_py_function
=
"PyLong_FromUnsignedLongLong"
from_py_function
=
"
PyInt_AsUnsignedLongLongMask
"
from_py_function
=
"
__pyx_PyInt_AsUnsignedLongLong
"
class
CPySSizeTType
(
CIntType
):
...
...
@@ -424,7 +464,7 @@ class CFloatType(CNumericType):
is_float
=
1
to_py_function
=
"PyFloat_FromDouble"
from_py_function
=
"PyFloat_AsDouble"
from_py_function
=
"
__pyx_
PyFloat_AsDouble"
def
__init__
(
self
,
rank
,
pymemberdef_typecode
=
None
):
CNumericType
.
__init__
(
self
,
rank
,
1
,
pymemberdef_typecode
)
...
...
@@ -828,6 +868,18 @@ class ErrorType(PyrexType):
return
1
rank_to_type_name
=
(
"char"
,
# 0
"short"
,
# 1
"int"
,
# 2
"long"
,
# 3
"PY_LONG_LONG"
,
# 4
"Py_ssize_t"
,
# 5
"float"
,
# 6
"double"
,
# 7
"long double"
,
# 8
)
py_object_type
=
PyObjectType
()
c_void_type
=
CVoidType
()
...
...
@@ -872,18 +924,6 @@ error_type = ErrorType()
lowest_float_rank
=
6
rank_to_type_name
=
(
"char"
,
# 0
"short"
,
# 1
"int"
,
# 2
"long"
,
# 3
"PY_LONG_LONG"
,
# 4
"Py_ssize_t"
,
# 5
"float"
,
# 6
"double"
,
# 7
"long double"
,
# 8
)
sign_and_rank_to_type
=
{
#(signed, rank)
(
0
,
0
,
):
c_uchar_type
,
...
...
@@ -988,3 +1028,72 @@ def typecast(to_type, from_type, expr_code):
else
:
#print "typecast: to", to_type, "from", from_type ###
return
to_type
.
cast_code
(
expr_code
)
type_conversion_predeclarations
=
"""
/* Type Conversion Predeclarations */
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x);
static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x);
static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x);
static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b);
#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x))
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
"""
+
type_conversion_predeclarations
type_conversion_functions
=
"""
/* Type Conversion Functions */
static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
PyObject* x = PyNumber_Index(b);
if (!x) return -1;
ival = PyInt_AsSsize_t(x);
Py_DECREF(x);
return ival;
}
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
if (x == Py_True) return 1;
else if (x == Py_False) return 0;
else return PyObject_IsTrue(x);
}
static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
if (PyInt_CheckExact(x)) {
return PyInt_AS_LONG(x);
}
else if (PyLong_CheckExact(x)) {
return PyLong_AsLongLong(x);
}
else {
PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
PY_LONG_LONG val = __pyx_PyInt_AsLongLong(tmp);
Py_DECREF(tmp);
return val;
}
}
static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
if (PyInt_CheckExact(x)) {
long val = PyInt_AS_LONG(x);
if (unlikely(val < 0)) {
PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type.");
return (unsigned PY_LONG_LONG)-1;
}
return val;
}
else if (PyLong_CheckExact(x)) {
return PyLong_AsUnsignedLongLong(x);
}
else {
PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
PY_LONG_LONG val = __pyx_PyInt_AsUnsignedLongLong(tmp);
Py_DECREF(tmp);
return val;
}
}
"""
+
type_conversion_functions
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment