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
e2ad82d7
Commit
e2ad82d7
authored
Sep 27, 2014
by
Charles Blake
Browse files
Options
Browse Files
Download
Plain Diff
Merge /home/cb/pkg/cy/cython
Conflicts: CHANGES.rst
parents
77b4c4ba
68a5d5d7
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
118 additions
and
22 deletions
+118
-22
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+26
-13
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+14
-7
tests/compile/posix_pxds.pyx
tests/compile/posix_pxds.pyx
+8
-0
tests/run/boolop.pyx
tests/run/boolop.pyx
+29
-2
tests/run/boolop_py.py
tests/run/boolop_py.py
+25
-0
tests/run/isinstance.pyx
tests/run/isinstance.pyx
+16
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
e2ad82d7
...
...
@@ -9921,7 +9921,7 @@ class BoolBinopNode(ExprNode):
operator
=
self
.
operator
,
operand1
=
operand1
,
operand2
=
operand2
)
def
generate_bool_evaluation_code
(
self
,
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
):
def
generate_bool_evaluation_code
(
self
,
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
,
fall_through
):
code
.
mark_pos
(
self
.
pos
)
outer_labels
=
(
and_label
,
or_label
)
...
...
@@ -9929,20 +9929,21 @@ class BoolBinopNode(ExprNode):
my_label
=
and_label
=
code
.
new_label
(
'next_and'
)
else
:
my_label
=
or_label
=
code
.
new_label
(
'next_or'
)
self
.
operand1
.
generate_bool_evaluation_code
(
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
)
self
.
operand1
.
generate_bool_evaluation_code
(
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
,
my_label
)
and_label
,
or_label
=
outer_labels
code
.
put_label
(
my_label
)
self
.
operand2
.
generate_bool_evaluation_code
(
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
)
self
.
operand2
.
generate_bool_evaluation_code
(
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
,
fall_through
)
def
generate_evaluation_code
(
self
,
code
):
self
.
allocate_temp_result
(
code
)
or_label
=
and_label
=
None
end_label
=
code
.
new_label
(
'bool_binop_done'
)
self
.
generate_bool_evaluation_code
(
code
,
self
.
result
(),
and_label
,
or_label
,
end_label
)
if
code
.
label_used
(
end_label
):
code
.
put_label
(
end_label
)
self
.
generate_bool_evaluation_code
(
code
,
self
.
result
(),
and_label
,
or_label
,
end_label
,
end_label
)
code
.
put_label
(
end_label
)
gil_message
=
"Truth-testing Python object"
...
...
@@ -10026,7 +10027,7 @@ class BoolBinopResultNode(ExprNode):
test_result
=
self
.
arg
.
result
()
return
(
test_result
,
self
.
arg
.
type
.
is_pyobject
)
def
generate_bool_evaluation_code
(
self
,
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
):
def
generate_bool_evaluation_code
(
self
,
code
,
final_result_temp
,
and_label
,
or_label
,
end_label
,
fall_through
):
code
.
mark_pos
(
self
.
pos
)
# x => x
...
...
@@ -10038,31 +10039,43 @@ class BoolBinopResultNode(ExprNode):
self
.
arg
.
generate_evaluation_code
(
code
)
if
and_label
or
or_label
:
test_result
,
uses_temp
=
self
.
generate_operand_test
(
code
)
if
uses_temp
and
(
and_label
and
or_label
):
# cannot become final result => free early
# disposal: uses_temp and (and_label and or_label)
self
.
arg
.
generate_disposal_code
(
code
)
sense
=
'!'
if
or_label
else
''
code
.
putln
(
"if (%s%s) {"
%
(
sense
,
test_result
))
if
uses_temp
:
code
.
funcstate
.
release_temp
(
test_result
)
self
.
arg
.
generate_disposal_code
(
code
)
if
not
uses_temp
or
not
(
and_label
and
or_label
):
# disposal: (not uses_temp) or {not (and_label and or_label) [if]}
self
.
arg
.
generate_disposal_code
(
code
)
if
or_label
:
if
or_label
and
or_label
!=
fall_through
:
# value is false => short-circuit to next 'or'
code
.
put_goto
(
or_label
)
code
.
putln
(
"} else {"
)
if
and_label
:
# value is true => go to next 'and'
code
.
put_goto
(
and_label
)
if
not
or_label
:
if
or_label
:
code
.
putln
(
"} else {"
)
if
not
uses_temp
:
# disposal: (not uses_temp) and {(and_label and or_label) [else]}
self
.
arg
.
generate_disposal_code
(
code
)
if
and_label
!=
fall_through
:
code
.
put_goto
(
and_label
)
if
not
and_label
or
not
or_label
:
# if no next 'and' or 'or', we provide the result
if
and_label
or
or_label
:
code
.
putln
(
"} else {"
)
self
.
value
.
generate_evaluation_code
(
code
)
self
.
value
.
make_owned_reference
(
code
)
code
.
putln
(
"%s = %s;"
%
(
final_result_temp
,
self
.
value
.
result
()))
self
.
value
.
generate_post_assignment_code
(
code
)
# disposal: {not (and_label and or_label) [else]}
self
.
arg
.
generate_disposal_code
(
code
)
self
.
value
.
free_temps
(
code
)
if
and_label
or
or_label
:
if
end_label
!=
fall_through
:
code
.
put_goto
(
end_label
)
if
and_label
or
or_label
:
...
...
Cython/Compiler/Optimize.py
View file @
e2ad82d7
...
...
@@ -2276,11 +2276,14 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
if
len
(
pos_args
)
!=
2
:
return
node
arg
,
types
=
pos_args
temp
=
None
temp
s
=
[]
if
isinstance
(
types
,
ExprNodes
.
TupleNode
):
types
=
types
.
args
if
len
(
types
)
==
1
and
not
types
[
0
].
type
is
Builtin
.
type_type
:
return
node
# nothing to improve here
if
arg
.
is_attribute
or
not
arg
.
is_simple
():
arg
=
temp
=
UtilNodes
.
ResultRefNode
(
arg
)
arg
=
UtilNodes
.
ResultRefNode
(
arg
)
temps
.
append
(
arg
)
elif
types
.
type
is
Builtin
.
type_type
:
types
=
[
types
]
else
:
...
...
@@ -2311,13 +2314,17 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
type_check_function
=
'__Pyx_TypeCheck'
type_check_args
=
[
arg
,
test_type_node
]
else
:
return
node
if
not
test_type_node
.
is_literal
:
test_type_node
=
UtilNodes
.
ResultRefNode
(
test_type_node
)
temps
.
append
(
test_type_node
)
type_check_function
=
'PyObject_IsInstance'
type_check_args
=
[
arg
,
test_type_node
]
test_nodes
.
append
(
ExprNodes
.
PythonCapiCallNode
(
test_type_node
.
pos
,
type_check_function
,
self
.
Py_type_check_func_type
,
args
=
type_check_args
,
is_temp
=
True
,
))
args
=
type_check_args
,
is_temp
=
True
,
))
def
join_with_or
(
a
,
b
,
make_binop_node
=
ExprNodes
.
binop_node
):
or_node
=
make_binop_node
(
node
.
pos
,
'or'
,
a
,
b
)
...
...
@@ -2326,7 +2333,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
return
or_node
test_node
=
reduce
(
join_with_or
,
test_nodes
).
coerce_to
(
node
.
type
,
env
)
if
temp
is
not
None
:
for
temp
in
temps
[::
-
1
]
:
test_node
=
UtilNodes
.
EvalWithTempExprNode
(
temp
,
test_node
)
return
test_node
...
...
tests/compile/posix_pxds.pyx
View file @
e2ad82d7
...
...
@@ -34,3 +34,11 @@ from posix.time cimport *
cimport
posix.resource
from
posix
cimport
resource
from
posix.resource
cimport
*
cimport
posix.wait
from
posix
cimport
wait
from
posix.wait
cimport
*
cimport
posix.mman
from
posix
cimport
mman
from
posix.mman
cimport
*
tests/run/boolop.pyx
View file @
e2ad82d7
def
foo
(
obj1
,
obj2
,
obj3
,
obj4
,
obj5
):
def
simple_values
(
obj1
,
obj2
,
obj3
,
obj4
):
"""
>>>
foo(True, False, 23, 'test', 1
)
>>>
simple_values(True, False, 23, 'test'
)
(0.0, 1.0, False, False)
"""
cdef
int
bool1
,
bool2
...
...
@@ -22,3 +23,29 @@ def foo(obj1, obj2, obj3, obj4, obj5):
obj4
=
obj1
and
obj2
and
obj3
obj5
=
(
obj1
+
obj2
+
obj3
)
and
obj4
return
bool3
,
bool4
,
obj4
,
obj5
def
non_simple_values
(
obj1
,
obj2
,
obj3
,
obj4
):
"""
>>> non_simple_values(1, 2, 3, 4)
(7, 3, 7, 3, 7, 7, 5, 5)
>>> non_simple_values(0, 0, 3, 4)
(0, 7, 4, 4, 4, 4, 4, 4)
>>> non_simple_values(0, 0, 1, -1)
(0, 0, -1, 0, -1, -1, 0, 0)
>>> non_simple_values(1, -1, 1, -1)
(0, 0, 0, 0, 0, 0, 0, 0)
>>> non_simple_values(1, 2, 1, -1)
(0, 3, 0, 3, 0, 0, 1, 1)
>>> non_simple_values(2, 1, 1, -1)
(0, 3, 1, 3, 0, 0, 1, 1)
"""
and1
=
obj1
+
obj2
and
obj3
+
obj4
or1
=
obj1
+
obj2
or
obj3
+
obj4
and_or
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
or_and
=
obj1
+
obj2
or
obj3
+
obj4
and
obj1
+
obj4
and_or_and
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
and
obj2
+
obj4
and1_or_and
=
(
and1
or
(
obj1
+
obj4
and
obj2
+
obj4
))
or_and_or
=
(
obj1
+
obj2
or
obj3
+
obj4
)
and
(
obj1
+
obj4
or
obj2
+
obj4
)
or1_and_or
=
(
or1
and
(
obj1
+
obj4
or
obj2
+
obj4
))
return
(
and1
,
or1
,
and_or
,
or_and
,
and_or_and
,
and1_or_and
,
or_and_or
,
or1_and_or
)
tests/run/boolop_py.py
0 → 100644
View file @
e2ad82d7
def
non_simple_values
(
obj1
,
obj2
,
obj3
,
obj4
):
"""
>>> non_simple_values(1, 2, 3, 4)
(7, 3, 7, 3, 7, 7, 5, 5)
>>> non_simple_values(0, 0, 3, 4)
(0, 7, 4, 4, 4, 4, 4, 4)
>>> non_simple_values(0, 0, 1, -1)
(0, 0, -1, 0, -1, -1, 0, 0)
>>> non_simple_values(1, -1, 1, -1)
(0, 0, 0, 0, 0, 0, 0, 0)
>>> non_simple_values(1, 2, 1, -1)
(0, 3, 0, 3, 0, 0, 1, 1)
>>> non_simple_values(2, 1, 1, -1)
(0, 3, 1, 3, 0, 0, 1, 1)
"""
and1
=
obj1
+
obj2
and
obj3
+
obj4
or1
=
obj1
+
obj2
or
obj3
+
obj4
and_or
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
or_and
=
obj1
+
obj2
or
obj3
+
obj4
and
obj1
+
obj4
and_or_and
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
and
obj2
+
obj4
and1_or_and
=
(
and1
or
(
obj1
+
obj4
and
obj2
+
obj4
))
or_and_or
=
(
obj1
+
obj2
or
obj3
+
obj4
)
and
(
obj1
+
obj4
or
obj2
+
obj4
)
or1_and_or
=
(
or1
and
(
obj1
+
obj4
or
obj2
+
obj4
))
return
(
and1
,
or1
,
and_or
,
or_and
,
and_or_and
,
and1_or_and
,
or_and_or
,
or1_and_or
)
tests/run/isinstance.pyx
View file @
e2ad82d7
...
...
@@ -5,6 +5,10 @@ from cpython.bool cimport bool
cdef
class
A
:
pass
a_as_obj
=
A
@
cython
.
test_assert_path_exists
(
'//SimpleCallNode//SimpleCallNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode//PythonCapiCallNode'
,
'//PythonCapiCallNode//SimpleCallNode'
)
...
...
@@ -18,6 +22,7 @@ def test_non_optimised():
assert
isinstance
(
A
(),
foo
)
return
True
@
cython
.
test_assert_path_exists
(
'//PythonCapiCallNode'
,
'//PythonCapiCallNode//SimpleCallNode'
,
'//PythonCapiFunctionNode[@cname = "PyType_Check"]'
,
...
...
@@ -104,6 +109,7 @@ def test_optimised():
assert
isinstance
(
A
(),
<
type
>
untyped_type
)
return
True
@
cython
.
test_assert_path_exists
(
'//PythonCapiCallNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode//SimpleCallNode'
,
'//SimpleCallNode//PythonCapiCallNode'
,
...
...
@@ -116,10 +122,14 @@ def test_optimised_tuple():
assert
isinstance
(
int
(),
(
int
,
long
,
float
,
bytes
,
str
,
unicode
,
tuple
,
list
,
dict
,
set
,
slice
,
type
,
A
))
assert
isinstance
(
list
(),
(
int
,
long
,
float
,
bytes
,
str
,
unicode
,
tuple
,
list
,
dict
,
set
,
slice
,
type
,
A
))
assert
isinstance
(
A
(),
(
int
,
long
,
float
,
bytes
,
str
,
unicode
,
tuple
,
list
,
dict
,
set
,
slice
,
type
,
A
))
assert
isinstance
(
A
(),
(
int
,
long
,
float
,
bytes
,
str
,
unicode
,
tuple
,
list
,
dict
,
set
,
slice
,
type
,
A
,
a_as_obj
))
assert
isinstance
(
A
(),
(
int
,
long
,
float
,
bytes
,
str
,
unicode
,
tuple
,
list
,
dict
,
set
,
slice
,
type
,
a_as_obj
,
A
))
assert
isinstance
(
A
(),
(
int
,
long
,
float
,
bytes
,
str
,
unicode
,
a_as_obj
,
tuple
,
list
,
dict
,
set
,
slice
,
type
,
A
))
assert
isinstance
(
0
,
(
int
,
long
))
assert
not
isinstance
(
u"xyz"
,
(
int
,
long
))
return
True
def
test_custom
():
"""
>>> test_custom()
...
...
@@ -134,6 +144,11 @@ cdef class B:
cdef
class
C
:
pass
@
cython
.
test_assert_path_exists
(
'//PythonCapiCallNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode//SimpleCallNode'
,
'//SimpleCallNode//PythonCapiCallNode'
,
'//TupleNode//NameNode'
)
def
test_custom_tuple
(
obj
):
"""
>>> test_custom_tuple(A())
...
...
@@ -145,6 +160,7 @@ def test_custom_tuple(obj):
"""
return
isinstance
(
obj
,
(
A
,
B
))
def
test_nested
(
x
):
"""
>>> test_nested(1)
...
...
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