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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
64908ab7
Commit
64908ab7
authored
Mar 29, 2009
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NoneCheckNode to enforce runtime None checks for object references
parent
aaeee9d0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
11 deletions
+67
-11
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+38
-1
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+29
-10
No files found.
Cython/Compiler/ExprNodes.py
View file @
64908ab7
...
...
@@ -5091,7 +5091,44 @@ class PyTypeTestNode(CoercionNode):
def
free_temps
(
self
,
code
):
self
.
arg
.
free_temps
(
code
)
class
NoneCheckNode
(
CoercionNode
):
# This node is used to check that a Python object is not None and
# raises an appropriate exception (as specified by the creating
# transform).
def
__init__
(
self
,
arg
,
exception_type_cname
,
exception_message
):
CoercionNode
.
__init__
(
self
,
arg
)
self
.
type
=
arg
.
type
self
.
result_ctype
=
arg
.
ctype
()
self
.
exception_type_cname
=
exception_type_cname
self
.
exception_message
=
exception_message
def
analyse_types
(
self
,
env
):
pass
def
result_in_temp
(
self
):
return
self
.
arg
.
result_in_temp
()
def
calculate_result_code
(
self
):
return
self
.
arg
.
result
()
def
generate_result_code
(
self
,
code
):
code
.
putln
(
"if (unlikely(%s == Py_None)) {"
%
self
.
arg
.
result
())
code
.
putln
(
'PyErr_SetString(%s, "%s"); %s '
%
(
self
.
exception_type_cname
,
StringEncoding
.
escape_byte_string
(
self
.
exception_message
),
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
"}"
)
def
generate_post_assignment_code
(
self
,
code
):
self
.
arg
.
generate_post_assignment_code
(
code
)
def
free_temps
(
self
,
code
):
self
.
arg
.
free_temps
(
code
)
class
CoerceToPyTypeNode
(
CoercionNode
):
# This node is used to convert a C data type
...
...
Cython/Compiler/Optimize.py
View file @
64908ab7
...
...
@@ -476,6 +476,7 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
arg_list
=
arg_tuple
.
args
self_arg
=
function
.
obj
obj_type
=
self_arg
.
type
is_unbound_method
=
False
if
obj_type
.
is_builtin_type
:
if
obj_type
is
Builtin
.
type_type
and
arg_list
and
\
arg_list
[
0
].
type
.
is_pyobject
:
...
...
@@ -483,6 +484,7 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
# (ignoring 'type.mro()' here ...)
type_name
=
function
.
obj
.
name
self_arg
=
None
is_unbound_method
=
True
else
:
type_name
=
obj_type
.
name
else
:
...
...
@@ -494,9 +496,9 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
if
self_arg
is
not
None
:
arg_list
=
[
self_arg
]
+
list
(
arg_list
)
if
kwargs
:
return
method_handler
(
node
,
arg_list
,
kwargs
)
return
method_handler
(
node
,
arg_list
,
kwargs
,
is_unbound_method
)
else
:
return
method_handler
(
node
,
arg_list
)
return
method_handler
(
node
,
arg_list
,
is_unbound_method
)
else
:
return
node
...
...
@@ -625,7 +627,7 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
PyrexTypes
.
CFuncTypeArg
(
"item"
,
PyrexTypes
.
py_object_type
,
None
),
])
def
_handle_simple_method_object_append
(
self
,
node
,
args
):
def
_handle_simple_method_object_append
(
self
,
node
,
args
,
is_unbound_method
):
# X.append() is almost always referring to a list
if
len
(
args
)
!=
2
:
return
node
...
...
@@ -644,13 +646,14 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
],
exception_value
=
"-1"
)
def
_handle_simple_method_list_append
(
self
,
node
,
args
):
def
_handle_simple_method_list_append
(
self
,
node
,
args
,
is_unbound_method
):
if
len
(
args
)
!=
2
:
error
(
node
.
pos
,
"list.append(x) called with wrong number of args, found %d"
%
len
(
args
))
return
node
return
self
.
_substitute_method_call
(
node
,
"PyList_Append"
,
self
.
PyList_Append_func_type
,
args
)
node
,
"PyList_Append"
,
self
.
PyList_Append_func_type
,
'append'
,
is_unbound_method
,
args
)
single_param_func_type
=
PyrexTypes
.
CFuncType
(
PyrexTypes
.
c_int_type
,
[
...
...
@@ -658,21 +661,37 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
],
exception_value
=
"-1"
)
def
_handle_simple_method_list_sort
(
self
,
node
,
args
):
def
_handle_simple_method_list_sort
(
self
,
node
,
args
,
is_unbound_method
):
if
len
(
args
)
!=
1
:
return
node
return
self
.
_substitute_method_call
(
node
,
"PyList_Sort"
,
self
.
single_param_func_type
,
args
)
node
,
"PyList_Sort"
,
self
.
single_param_func_type
,
'sort'
,
is_unbound_method
,
args
)
def
_handle_simple_method_list_reverse
(
self
,
node
,
args
):
def
_handle_simple_method_list_reverse
(
self
,
node
,
args
,
is_unbound_method
):
if
len
(
args
)
!=
1
:
error
(
node
.
pos
,
"list.reverse(x) called with wrong number of args, found %d"
%
len
(
args
))
return
node
return
self
.
_substitute_method_call
(
node
,
"PyList_Reverse"
,
self
.
single_param_func_type
,
args
)
node
,
"PyList_Reverse"
,
self
.
single_param_func_type
,
'reverse'
,
is_unbound_method
,
args
)
def
_substitute_method_call
(
self
,
node
,
name
,
func_type
,
args
=
()):
def
_substitute_method_call
(
self
,
node
,
name
,
func_type
,
attr_name
,
is_unbound_method
,
args
=
()):
args
=
list
(
args
)
if
args
:
self_arg
=
args
[
0
]
if
is_unbound_method
:
self_arg
=
ExprNodes
.
NoneCheckNode
(
self_arg
,
"PyExc_TypeError"
,
"descriptor '%s' requires a '%s' object but received a 'NoneType'"
%
(
attr_name
,
node
.
function
.
obj
.
name
))
else
:
self_arg
=
ExprNodes
.
NoneCheckNode
(
self_arg
,
"PyExc_AttributeError"
,
"'NoneType' object has no attribute '%s'"
%
attr_name
)
args
[
0
]
=
self_arg
# FIXME: args[0] may need a runtime None check (ticket #166)
return
ExprNodes
.
PythonCapiCallNode
(
node
.
pos
,
name
,
func_type
,
...
...
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