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
a0654d24
Commit
a0654d24
authored
Dec 01, 2008
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More fixes for new temps
parent
98d56995
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
21 deletions
+117
-21
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+2
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+86
-18
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+23
-0
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+6
-2
No files found.
Cython/Compiler/Code.py
View file @
a0654d24
...
@@ -150,8 +150,9 @@ class FunctionState(object):
...
@@ -150,8 +150,9 @@ class FunctionState(object):
freelist
=
self
.
temps_free
.
get
((
type
,
manage_ref
))
freelist
=
self
.
temps_free
.
get
((
type
,
manage_ref
))
if
freelist
is
None
:
if
freelist
is
None
:
freelist
=
[]
freelist
=
[]
self
.
temps_free
[(
type
,
manage_ref
)]
=
freelist
self
.
temps_free
[(
type
,
manage_ref
)]
=
freelist
if
name
in
freelist
:
raise
RuntimeError
(
"Temp %s freed twice!"
%
name
)
freelist
.
append
(
name
)
freelist
.
append
(
name
)
if
DebugFlags
.
debug_temp_code_comments
:
if
DebugFlags
.
debug_temp_code_comments
:
self
.
owner
.
putln
(
"/* %s released */"
%
name
)
self
.
owner
.
putln
(
"/* %s released */"
%
name
)
...
...
Cython/Compiler/ExprNodes.py
View file @
a0654d24
...
@@ -439,6 +439,7 @@ class ExprNode(Node):
...
@@ -439,6 +439,7 @@ class ExprNode(Node):
self
.
generate_result_code
(
code
)
self
.
generate_result_code
(
code
)
if
self
.
is_temp
:
if
self
.
is_temp
:
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
self
.
free_subexpr_temps
(
code
)
def
generate_subexpr_evaluation_code
(
self
,
code
):
def
generate_subexpr_evaluation_code
(
self
,
code
):
for
node
in
self
.
subexpr_nodes
():
for
node
in
self
.
subexpr_nodes
():
...
@@ -487,6 +488,10 @@ class ExprNode(Node):
...
@@ -487,6 +488,10 @@ class ExprNode(Node):
def
free_temps
(
self
,
code
):
def
free_temps
(
self
,
code
):
pass
pass
def
free_subexpr_temps
(
self
,
code
):
for
sub
in
self
.
subexpr_nodes
():
sub
.
free_temps
(
code
)
# ---------------- Annotation ---------------------
# ---------------- Annotation ---------------------
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
...
@@ -582,6 +587,7 @@ class RemoveAllocateTemps(type):
...
@@ -582,6 +587,7 @@ class RemoveAllocateTemps(type):
class
NewTempExprNode
(
ExprNode
):
class
NewTempExprNode
(
ExprNode
):
backwards_compatible_result
=
None
backwards_compatible_result
=
None
temp_code
=
None
# Do not enable this unless you are trying to make all ExprNodes
# Do not enable this unless you are trying to make all ExprNodes
# NewTempExprNodes (child nodes reached via recursion may not have
# NewTempExprNodes (child nodes reached via recursion may not have
...
@@ -617,6 +623,8 @@ class NewTempExprNode(ExprNode):
...
@@ -617,6 +623,8 @@ class NewTempExprNode(ExprNode):
self
.
release_subexpr_temps
(
env
)
self
.
release_subexpr_temps
(
env
)
def
allocate_temp_result
(
self
,
code
):
def
allocate_temp_result
(
self
,
code
):
if
self
.
temp_code
:
raise
RuntimeError
(
"Temp allocated multiple times"
)
type
=
self
.
type
type
=
self
.
type
if
not
type
.
is_void
:
if
not
type
.
is_void
:
if
type
.
is_pyobject
:
if
type
.
is_pyobject
:
...
@@ -630,7 +638,11 @@ class NewTempExprNode(ExprNode):
...
@@ -630,7 +638,11 @@ class NewTempExprNode(ExprNode):
self
.
temp_code
=
None
self
.
temp_code
=
None
def
release_temp_result
(
self
,
code
):
def
release_temp_result
(
self
,
code
):
if
not
self
.
temp_code
:
raise
RuntimeError
(
"No temp (perhaps released multiple times? See self.old_temp)"
)
code
.
funcstate
.
release_temp
(
self
.
temp_code
)
code
.
funcstate
.
release_temp
(
self
.
temp_code
)
self
.
old_temp
=
self
.
temp_code
self
.
temp_code
=
None
def
generate_evaluation_code
(
self
,
code
):
def
generate_evaluation_code
(
self
,
code
):
code
.
mark_pos
(
self
.
pos
)
code
.
mark_pos
(
self
.
pos
)
...
@@ -648,6 +660,7 @@ class NewTempExprNode(ExprNode):
...
@@ -648,6 +660,7 @@ class NewTempExprNode(ExprNode):
# If we are temp we do not need to wait until this node is disposed
# If we are temp we do not need to wait until this node is disposed
# before disposing children.
# before disposing children.
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
self
.
free_subexpr_temps
(
code
)
def
generate_disposal_code
(
self
,
code
):
def
generate_disposal_code
(
self
,
code
):
if
self
.
is_temp
:
if
self
.
is_temp
:
...
@@ -658,15 +671,17 @@ class NewTempExprNode(ExprNode):
...
@@ -658,15 +671,17 @@ class NewTempExprNode(ExprNode):
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
def
generate_post_assignment_code
(
self
,
code
):
def
generate_post_assignment_code
(
self
,
code
):
if
self
.
is_temp
and
self
.
type
.
is_pyobject
:
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
putln
(
"%s = 0;"
%
self
.
result
())
code
.
putln
(
"%s = 0;"
%
self
.
result
())
else
:
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
def
free_temps
(
self
,
code
):
def
free_temps
(
self
,
code
):
if
self
.
is_temp
:
if
self
.
is_temp
:
self
.
release_temp_result
()
self
.
release_temp_result
(
code
)
for
sub
in
self
.
subexpr_nodes
()
:
else
:
s
ub
.
free
_temps
(
code
)
s
elf
.
free_subexpr
_temps
(
code
)
# ExprNode = NewTempExprNode
# ExprNode = NewTempExprNode
...
@@ -1238,7 +1253,7 @@ class NameNode(AtomicExprNode):
...
@@ -1238,7 +1253,7 @@ class NameNode(AtomicExprNode):
print
(
"NameNode.generate_assignment_code:"
)
print
(
"NameNode.generate_assignment_code:"
)
print
(
"...generating disposal code for %s"
%
rhs
)
print
(
"...generating disposal code for %s"
%
rhs
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
free_temps
(
code
)
else
:
else
:
if
self
.
type
.
is_buffer
:
if
self
.
type
.
is_buffer
:
# Generate code for doing the buffer release/acquisition.
# Generate code for doing the buffer release/acquisition.
...
@@ -1270,6 +1285,7 @@ class NameNode(AtomicExprNode):
...
@@ -1270,6 +1285,7 @@ class NameNode(AtomicExprNode):
print
(
"NameNode.generate_assignment_code:"
)
print
(
"NameNode.generate_assignment_code:"
)
print
(
"...generating post-assignment code for %s"
%
rhs
)
print
(
"...generating post-assignment code for %s"
%
rhs
)
rhs
.
generate_post_assignment_code
(
code
)
rhs
.
generate_post_assignment_code
(
code
)
rhs
.
free_temps
(
code
)
def
generate_acquire_buffer
(
self
,
rhs
,
code
):
def
generate_acquire_buffer
(
self
,
rhs
,
code
):
# rhstmp is only used in case the rhs is a complicated expression leading to
# rhstmp is only used in case the rhs is a complicated expression leading to
...
@@ -1708,6 +1724,14 @@ class IndexNode(ExprNode):
...
@@ -1708,6 +1724,14 @@ class IndexNode(ExprNode):
for
i
in
self
.
indices
:
for
i
in
self
.
indices
:
i
.
generate_disposal_code
(
code
)
i
.
generate_disposal_code
(
code
)
def
free_subexpr_temps
(
self
,
code
):
self
.
base
.
free_temps
(
code
)
if
not
self
.
indices
:
self
.
index
.
free_temps
(
code
)
else
:
for
i
in
self
.
indices
:
i
.
free_temps
(
code
)
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
if
self
.
is_buffer_access
:
if
self
.
is_buffer_access
:
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
...
@@ -1795,7 +1819,9 @@ class IndexNode(ExprNode):
...
@@ -1795,7 +1819,9 @@ class IndexNode(ExprNode):
"%s = %s;"
%
(
"%s = %s;"
%
(
self
.
result
(),
rhs
.
result
()))
self
.
result
(),
rhs
.
result
()))
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
self
.
free_subexpr_temps
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
free_temps
(
code
)
def
generate_deletion_code
(
self
,
code
):
def
generate_deletion_code
(
self
,
code
):
self
.
generate_subexpr_evaluation_code
(
code
)
self
.
generate_subexpr_evaluation_code
(
code
)
...
@@ -1935,6 +1961,7 @@ class SliceIndexNode(ExprNode):
...
@@ -1935,6 +1961,7 @@ class SliceIndexNode(ExprNode):
rhs
.
result
(),
i
))
rhs
.
result
(),
i
))
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
free_temps
(
code
)
def
generate_deletion_code
(
self
,
code
):
def
generate_deletion_code
(
self
,
code
):
if
not
self
.
type
.
is_pyobject
:
if
not
self
.
type
.
is_pyobject
:
...
@@ -2722,6 +2749,7 @@ class AttributeNode(ExprNode):
...
@@ -2722,6 +2749,7 @@ class AttributeNode(ExprNode):
self
.
interned_attr_cname
,
self
.
interned_attr_cname
,
rhs
.
py_result
()))
rhs
.
py_result
()))
rhs
.
generate_disposal_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
free_temps
(
code
)
else
:
else
:
if
(
self
.
obj
.
type
.
is_extension_type
if
(
self
.
obj
.
type
.
is_extension_type
and
self
.
needs_none_check
and
self
.
needs_none_check
...
@@ -2738,7 +2766,9 @@ class AttributeNode(ExprNode):
...
@@ -2738,7 +2766,9 @@ class AttributeNode(ExprNode):
rhs
.
result_as
(
self
.
ctype
())))
rhs
.
result_as
(
self
.
ctype
())))
#rhs.result()))
#rhs.result()))
rhs
.
generate_post_assignment_code
(
code
)
rhs
.
generate_post_assignment_code
(
code
)
rhs
.
free_temps
(
code
)
self
.
obj
.
generate_disposal_code
(
code
)
self
.
obj
.
generate_disposal_code
(
code
)
self
.
obj
.
free_temps
(
code
)
def
generate_deletion_code
(
self
,
code
):
def
generate_deletion_code
(
self
,
code
):
self
.
obj
.
generate_evaluation_code
(
code
)
self
.
obj
.
generate_evaluation_code
(
code
)
...
@@ -2750,6 +2780,7 @@ class AttributeNode(ExprNode):
...
@@ -2750,6 +2780,7 @@ class AttributeNode(ExprNode):
else
:
else
:
error
(
self
.
pos
,
"Cannot delete C attribute of extension type"
)
error
(
self
.
pos
,
"Cannot delete C attribute of extension type"
)
self
.
obj
.
generate_disposal_code
(
code
)
self
.
obj
.
generate_disposal_code
(
code
)
self
.
obj
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
if
self
.
is_py_attr
:
if
self
.
is_py_attr
:
...
@@ -2838,6 +2869,10 @@ class SequenceNode(NewTempExprNode):
...
@@ -2838,6 +2869,10 @@ class SequenceNode(NewTempExprNode):
self
.
generate_operation_code
(
code
)
self
.
generate_operation_code
(
code
)
def
generate_assignment_code
(
self
,
rhs
,
code
):
def
generate_assignment_code
(
self
,
rhs
,
code
):
# Need to work around the fact that generate_evaluation_code
# allocates the temps in a rather hacky way -- the assignment
# is evaluated twice, within each if-block.
code
.
putln
(
code
.
putln
(
"if (PyTuple_CheckExact(%s) && PyTuple_GET_SIZE(%s) == %s) {"
%
(
"if (PyTuple_CheckExact(%s) && PyTuple_GET_SIZE(%s) == %s) {"
%
(
rhs
.
py_result
(),
rhs
.
py_result
(),
...
@@ -2855,6 +2890,10 @@ class SequenceNode(NewTempExprNode):
...
@@ -2855,6 +2890,10 @@ class SequenceNode(NewTempExprNode):
value_node
.
generate_evaluation_code
(
code
)
value_node
.
generate_evaluation_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
rhs
.
generate_disposal_code
(
code
)
for
i
in
range
(
len
(
self
.
args
)):
self
.
args
[
i
].
generate_assignment_code
(
self
.
coerced_unpacked_items
[
i
],
code
)
code
.
putln
(
"} else {"
)
code
.
putln
(
"} else {"
)
code
.
putln
(
code
.
putln
(
...
@@ -2881,12 +2920,13 @@ class SequenceNode(NewTempExprNode):
...
@@ -2881,12 +2920,13 @@ class SequenceNode(NewTempExprNode):
print
(
"UnpackNode.generate_assignment_code:"
)
print
(
"UnpackNode.generate_assignment_code:"
)
print
(
"...generating disposal code for %s"
%
self
.
iterator
)
print
(
"...generating disposal code for %s"
%
self
.
iterator
)
self
.
iterator
.
generate_disposal_code
(
code
)
self
.
iterator
.
generate_disposal_code
(
code
)
self
.
iterator
.
free_temps
(
code
)
code
.
putln
(
"}"
)
rhs
.
free_temps
()
for
i
in
range
(
len
(
self
.
args
)):
for
i
in
range
(
len
(
self
.
args
)):
self
.
args
[
i
].
generate_assignment_code
(
self
.
args
[
i
].
generate_assignment_code
(
self
.
coerced_unpacked_items
[
i
],
code
)
self
.
coerced_unpacked_items
[
i
],
code
)
code
.
putln
(
"}"
)
rhs
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
...
@@ -2949,6 +2989,8 @@ class TupleNode(SequenceNode):
...
@@ -2949,6 +2989,8 @@ class TupleNode(SequenceNode):
# in the tuple using a reference-stealing operation.
# in the tuple using a reference-stealing operation.
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
arg
.
generate_post_assignment_code
(
code
)
arg
.
generate_post_assignment_code
(
code
)
# Should NOT call free_temps -- this is invoked by the default
# generate_evaluation_code which will do that.
class
ListNode
(
SequenceNode
):
class
ListNode
(
SequenceNode
):
...
@@ -3051,6 +3093,8 @@ class ListNode(SequenceNode):
...
@@ -3051,6 +3093,8 @@ class ListNode(SequenceNode):
# in the list using a reference-stealing operation.
# in the list using a reference-stealing operation.
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
arg
.
generate_post_assignment_code
(
code
)
arg
.
generate_post_assignment_code
(
code
)
# Should NOT call free_temps -- this is invoked by the default
# generate_evaluation_code which will do that.
class
ListComprehensionNode
(
SequenceNode
):
class
ListComprehensionNode
(
SequenceNode
):
...
@@ -3202,6 +3246,7 @@ class DictNode(ExprNode):
...
@@ -3202,6 +3246,7 @@ class DictNode(ExprNode):
item
.
key
.
value
,
item
.
key
.
value
,
item
.
value
.
result
()))
item
.
value
.
result
()))
item
.
generate_disposal_code
(
code
)
item
.
generate_disposal_code
(
code
)
item
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
for
item
in
self
.
key_value_pairs
:
for
item
in
self
.
key_value_pairs
:
...
@@ -3228,6 +3273,10 @@ class DictItemNode(ExprNode):
...
@@ -3228,6 +3273,10 @@ class DictItemNode(ExprNode):
self
.
key
.
generate_disposal_code
(
code
)
self
.
key
.
generate_disposal_code
(
code
)
self
.
value
.
generate_disposal_code
(
code
)
self
.
value
.
generate_disposal_code
(
code
)
def
free_temps
(
self
,
code
):
self
.
key
.
free_temps
(
code
)
self
.
value
.
free_temps
(
code
)
def
__iter__
(
self
):
def
__iter__
(
self
):
return
iter
([
self
.
key
,
self
.
value
])
return
iter
([
self
.
key
,
self
.
value
])
...
@@ -4068,10 +4117,12 @@ class BoolBinopNode(NewTempExprNode):
...
@@ -4068,10 +4117,12 @@ class BoolBinopNode(NewTempExprNode):
self
.
operand2
.
generate_evaluation_code
(
code
)
self
.
operand2
.
generate_evaluation_code
(
code
)
self
.
allocate_temp_result
(
code
)
self
.
allocate_temp_result
(
code
)
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
self
.
operand2
.
result
()))
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
self
.
operand2
.
result
()))
self
.
operand2
.
free_temps
()
self
.
operand2
.
generate_post_assignment_code
(
code
)
self
.
operand2
.
free_temps
(
code
)
code
.
putln
(
"} else {"
)
code
.
putln
(
"} else {"
)
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
self
.
operand1
.
result
()))
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
self
.
operand1
.
result
()))
self
.
operand1
.
free_temps
()
self
.
operand1
.
generate_post_assignment_code
(
code
)
self
.
operand1
.
free_temps
(
code
)
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
def
generate_operand1_test
(
self
,
code
):
def
generate_operand1_test
(
self
,
code
):
...
@@ -4174,6 +4225,7 @@ class CondExprNode(ExprNode):
...
@@ -4174,6 +4225,7 @@ class CondExprNode(ExprNode):
self
.
false_val
.
generate_evaluation_code
(
code
)
self
.
false_val
.
generate_evaluation_code
(
code
)
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
self
.
test
.
generate_disposal_code
(
code
)
self
.
test
.
generate_disposal_code
(
code
)
self
.
test
.
free_temps
(
code
)
richcmp_constants
=
{
richcmp_constants
=
{
"<"
:
"Py_LT"
,
"<"
:
"Py_LT"
,
...
@@ -4401,6 +4453,8 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode):
...
@@ -4401,6 +4453,8 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode):
self
.
result
(),
self
.
operand2
)
self
.
result
(),
self
.
operand2
)
self
.
operand1
.
generate_disposal_code
(
code
)
self
.
operand1
.
generate_disposal_code
(
code
)
self
.
operand2
.
generate_disposal_code
(
code
)
self
.
operand2
.
generate_disposal_code
(
code
)
self
.
operand1
.
free_temps
(
code
)
self
.
operand2
.
free_temps
(
code
)
def
generate_subexpr_disposal_code
(
self
,
code
):
def
generate_subexpr_disposal_code
(
self
,
code
):
# If this is called, it is a non-cascaded cmp,
# If this is called, it is a non-cascaded cmp,
...
@@ -4408,6 +4462,12 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode):
...
@@ -4408,6 +4462,12 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode):
self
.
operand1
.
generate_disposal_code
(
code
)
self
.
operand1
.
generate_disposal_code
(
code
)
self
.
operand2
.
generate_disposal_code
(
code
)
self
.
operand2
.
generate_disposal_code
(
code
)
def
free_subexpr_temps
(
self
,
code
):
# If this is called, it is a non-cascaded cmp,
# so only need to dispose of the two main operands.
self
.
operand1
.
free_temps
(
code
)
self
.
operand2
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
self
.
operand1
.
annotate
(
code
)
self
.
operand1
.
annotate
(
code
)
self
.
operand2
.
annotate
(
code
)
self
.
operand2
.
annotate
(
code
)
...
@@ -4484,6 +4544,7 @@ class CascadedCmpNode(Node, CmpNode):
...
@@ -4484,6 +4544,7 @@ class CascadedCmpNode(Node, CmpNode):
code
,
result
,
self
.
operand2
)
code
,
result
,
self
.
operand2
)
# Cascaded cmp result is always temp
# Cascaded cmp result is always temp
self
.
operand2
.
generate_disposal_code
(
code
)
self
.
operand2
.
generate_disposal_code
(
code
)
self
.
operand2
.
free_temps
(
code
)
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
...
@@ -4605,6 +4666,9 @@ class PyTypeTestNode(CoercionNode):
...
@@ -4605,6 +4666,9 @@ class PyTypeTestNode(CoercionNode):
def
generate_post_assignment_code
(
self
,
code
):
def
generate_post_assignment_code
(
self
,
code
):
self
.
arg
.
generate_post_assignment_code
(
code
)
self
.
arg
.
generate_post_assignment_code
(
code
)
def
free_temps
(
self
,
code
):
self
.
arg
.
free_temps
(
code
)
class
CoerceToPyTypeNode
(
CoercionNode
):
class
CoerceToPyTypeNode
(
CoercionNode
):
# This node is used to convert a C data type
# This node is used to convert a C data type
...
@@ -4776,7 +4840,11 @@ class CloneNode(CoercionNode):
...
@@ -4776,7 +4840,11 @@ class CloneNode(CoercionNode):
def
release_temp
(
self
,
env
):
def
release_temp
(
self
,
env
):
pass
pass
class
PersistentNode
(
ExprNode
):
def
free_temps
(
self
,
code
):
pass
class
DISABLED_PersistentNode
(
ExprNode
):
# A PersistentNode is like a CloneNode except it handles the temporary
# A PersistentNode is like a CloneNode except it handles the temporary
# allocation itself by keeping track of the number of times it has been
# allocation itself by keeping track of the number of times it has been
# used.
# used.
...
...
Cython/Compiler/Nodes.py
View file @
a0654d24
...
@@ -2444,6 +2444,7 @@ class PyClassDefNode(ClassDefNode):
...
@@ -2444,6 +2444,7 @@ class PyClassDefNode(ClassDefNode):
self
.
body
.
generate_execution_code
(
code
)
self
.
body
.
generate_execution_code
(
code
)
self
.
target
.
generate_assignment_code
(
self
.
classobj
,
code
)
self
.
target
.
generate_assignment_code
(
self
.
classobj
,
code
)
self
.
dict
.
generate_disposal_code
(
code
)
self
.
dict
.
generate_disposal_code
(
code
)
self
.
dict
.
free_temps
(
code
)
class
CClassDefNode
(
ClassDefNode
):
class
CClassDefNode
(
ClassDefNode
):
...
@@ -2659,6 +2660,7 @@ class ExprStatNode(StatNode):
...
@@ -2659,6 +2660,7 @@ class ExprStatNode(StatNode):
if
not
self
.
expr
.
is_temp
and
self
.
expr
.
result
():
if
not
self
.
expr
.
is_temp
and
self
.
expr
.
result
():
code
.
putln
(
"%s;"
%
self
.
expr
.
result
())
code
.
putln
(
"%s;"
%
self
.
expr
.
result
())
self
.
expr
.
generate_disposal_code
(
code
)
self
.
expr
.
generate_disposal_code
(
code
)
self
.
expr
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
self
.
expr
.
annotate
(
code
)
self
.
expr
.
annotate
(
code
)
...
@@ -2884,6 +2886,7 @@ class CascadedAssignmentNode(AssignmentNode):
...
@@ -2884,6 +2886,7 @@ class CascadedAssignmentNode(AssignmentNode):
lhs
.
generate_assignment_code
(
rhs
,
code
)
lhs
.
generate_assignment_code
(
rhs
,
code
)
# Assignment has disposed of the cloned RHS
# Assignment has disposed of the cloned RHS
self
.
rhs
.
generate_disposal_code
(
code
)
self
.
rhs
.
generate_disposal_code
(
code
)
self
.
rhs
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
for
i
in
range
(
len
(
self
.
lhs_list
)):
for
i
in
range
(
len
(
self
.
lhs_list
)):
...
@@ -3016,7 +3019,9 @@ class InPlaceAssignmentNode(AssignmentNode):
...
@@ -3016,7 +3019,9 @@ class InPlaceAssignmentNode(AssignmentNode):
code
.
error_goto_if_null
(
self
.
result_value
.
py_result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result_value
.
py_result
(),
self
.
pos
)))
self
.
result_value
.
generate_evaluation_code
(
code
)
# May be a type check...
self
.
result_value
.
generate_evaluation_code
(
code
)
# May be a type check...
self
.
rhs
.
generate_disposal_code
(
code
)
self
.
rhs
.
generate_disposal_code
(
code
)
self
.
rhs
.
free_temps
(
code
)
self
.
dup
.
generate_disposal_code
(
code
)
self
.
dup
.
generate_disposal_code
(
code
)
self
.
dup
.
free_temps
(
code
)
self
.
lhs
.
generate_assignment_code
(
self
.
result_value
,
code
)
self
.
lhs
.
generate_assignment_code
(
self
.
result_value
,
code
)
else
:
else
:
c_op
=
self
.
operator
c_op
=
self
.
operator
...
@@ -3034,8 +3039,10 @@ class InPlaceAssignmentNode(AssignmentNode):
...
@@ -3034,8 +3039,10 @@ class InPlaceAssignmentNode(AssignmentNode):
self
.
dup
.
generate_result_code
(
code
)
self
.
dup
.
generate_result_code
(
code
)
code
.
putln
(
"%s %s= %s;"
%
(
self
.
lhs
.
result
(),
c_op
,
self
.
rhs
.
result
())
)
code
.
putln
(
"%s %s= %s;"
%
(
self
.
lhs
.
result
(),
c_op
,
self
.
rhs
.
result
())
)
self
.
rhs
.
generate_disposal_code
(
code
)
self
.
rhs
.
generate_disposal_code
(
code
)
self
.
rhs
.
free_temps
(
code
)
if
self
.
dup
.
is_temp
:
if
self
.
dup
.
is_temp
:
self
.
dup
.
generate_subexpr_disposal_code
(
code
)
self
.
dup
.
generate_subexpr_disposal_code
(
code
)
self
.
dup
.
free_subexpr_temps
(
code
)
def
create_dup_node
(
self
,
env
):
def
create_dup_node
(
self
,
env
):
import
ExprNodes
import
ExprNodes
...
@@ -3065,6 +3072,8 @@ class InPlaceAssignmentNode(AssignmentNode):
...
@@ -3065,6 +3072,8 @@ class InPlaceAssignmentNode(AssignmentNode):
index
=
index
,
index
=
index
,
indices
=
indices
,
indices
=
indices
,
is_temp
=
self
.
dup
.
is_temp
)
is_temp
=
self
.
dup
.
is_temp
)
else
:
assert
False
self
.
lhs
=
target_lhs
self
.
lhs
=
target_lhs
return
self
.
dup
return
self
.
dup
...
@@ -3117,6 +3126,7 @@ class PrintStatNode(StatNode):
...
@@ -3117,6 +3126,7 @@ class PrintStatNode(StatNode):
self
.
append_newline
,
self
.
append_newline
,
code
.
error_goto
(
self
.
pos
)))
code
.
error_goto
(
self
.
pos
)))
self
.
arg_tuple
.
generate_disposal_code
(
code
)
self
.
arg_tuple
.
generate_disposal_code
(
code
)
self
.
arg_tuple
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
self
.
arg_tuple
.
annotate
(
code
)
self
.
arg_tuple
.
annotate
(
code
)
...
@@ -3152,6 +3162,7 @@ class ExecStatNode(StatNode):
...
@@ -3152,6 +3162,7 @@ class ExecStatNode(StatNode):
(
self
.
temp_result
,)
+
args
))
(
self
.
temp_result
,)
+
args
))
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
arg
.
generate_disposal_code
(
code
)
arg
.
generate_disposal_code
(
code
)
arg
.
free_temps
(
code
)
code
.
putln
(
code
.
putln
(
code
.
error_goto_if_null
(
self
.
temp_result
,
self
.
pos
))
code
.
error_goto_if_null
(
self
.
temp_result
,
self
.
pos
))
code
.
put_decref_clear
(
self
.
temp_result
,
py_object_type
)
code
.
put_decref_clear
(
self
.
temp_result
,
py_object_type
)
...
@@ -3287,6 +3298,7 @@ class ReturnStatNode(StatNode):
...
@@ -3287,6 +3298,7 @@ class ReturnStatNode(StatNode):
Naming
.
retval_cname
,
Naming
.
retval_cname
,
self
.
value
.
result_as
(
self
.
return_type
)))
self
.
value
.
result_as
(
self
.
return_type
)))
self
.
value
.
generate_post_assignment_code
(
code
)
self
.
value
.
generate_post_assignment_code
(
code
)
self
.
value
.
free_temps
(
code
)
else
:
else
:
if
self
.
return_type
.
is_pyobject
:
if
self
.
return_type
.
is_pyobject
:
code
.
put_init_to_py_none
(
Naming
.
retval_cname
,
self
.
return_type
)
code
.
put_init_to_py_none
(
Naming
.
retval_cname
,
self
.
return_type
)
...
@@ -3372,10 +3384,13 @@ class RaiseStatNode(StatNode):
...
@@ -3372,10 +3384,13 @@ class RaiseStatNode(StatNode):
"__Pyx_ReRaise();"
)
"__Pyx_ReRaise();"
)
if
self
.
exc_type
:
if
self
.
exc_type
:
self
.
exc_type
.
generate_disposal_code
(
code
)
self
.
exc_type
.
generate_disposal_code
(
code
)
self
.
exc_type
.
free_temps
(
code
)
if
self
.
exc_value
:
if
self
.
exc_value
:
self
.
exc_value
.
generate_disposal_code
(
code
)
self
.
exc_value
.
generate_disposal_code
(
code
)
self
.
exc_value
.
free_temps
(
code
)
if
self
.
exc_tb
:
if
self
.
exc_tb
:
self
.
exc_tb
.
generate_disposal_code
(
code
)
self
.
exc_tb
.
generate_disposal_code
(
code
)
self
.
exc_tb
.
free_temps
(
code
)
code
.
putln
(
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
code
.
error_goto
(
self
.
pos
))
...
@@ -3442,6 +3457,7 @@ class AssertStatNode(StatNode):
...
@@ -3442,6 +3457,7 @@ class AssertStatNode(StatNode):
"PyErr_SetObject(PyExc_AssertionError, %s);"
%
"PyErr_SetObject(PyExc_AssertionError, %s);"
%
self
.
value
.
py_result
())
self
.
value
.
py_result
())
self
.
value
.
generate_disposal_code
(
code
)
self
.
value
.
generate_disposal_code
(
code
)
self
.
value
.
free_temps
(
code
)
else
:
else
:
code
.
putln
(
code
.
putln
(
"PyErr_SetNone(PyExc_AssertionError);"
)
"PyErr_SetNone(PyExc_AssertionError);"
)
...
@@ -3450,6 +3466,7 @@ class AssertStatNode(StatNode):
...
@@ -3450,6 +3466,7 @@ class AssertStatNode(StatNode):
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
self
.
cond
.
generate_disposal_code
(
code
)
self
.
cond
.
generate_disposal_code
(
code
)
self
.
cond
.
free_temps
(
code
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
...
@@ -3756,6 +3773,7 @@ class ForInStatNode(LoopNode, StatNode):
...
@@ -3756,6 +3773,7 @@ class ForInStatNode(LoopNode, StatNode):
code
.
put_label
(
break_label
)
code
.
put_label
(
break_label
)
self
.
iterator
.
release_counter_temp
(
code
)
self
.
iterator
.
release_counter_temp
(
code
)
self
.
iterator
.
generate_disposal_code
(
code
)
self
.
iterator
.
generate_disposal_code
(
code
)
self
.
iterator
.
free_temps
(
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
self
.
target
.
annotate
(
code
)
self
.
target
.
annotate
(
code
)
...
@@ -3878,9 +3896,12 @@ class ForFromStatNode(LoopNode, StatNode):
...
@@ -3878,9 +3896,12 @@ class ForFromStatNode(LoopNode, StatNode):
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
code
.
put_label
(
break_label
)
code
.
put_label
(
break_label
)
self
.
bound1
.
generate_disposal_code
(
code
)
self
.
bound1
.
generate_disposal_code
(
code
)
self
.
bound1
.
free_temps
(
code
)
self
.
bound2
.
generate_disposal_code
(
code
)
self
.
bound2
.
generate_disposal_code
(
code
)
self
.
bound2
.
free_temps
(
code
)
if
self
.
step
is
not
None
:
if
self
.
step
is
not
None
:
self
.
step
.
generate_disposal_code
(
code
)
self
.
step
.
generate_disposal_code
(
code
)
self
.
step
.
free_temps
(
code
)
relation_table
=
{
relation_table
=
{
# {relop : (initial offset, increment op)}
# {relop : (initial offset, increment op)}
...
@@ -4103,6 +4124,7 @@ class ExceptClauseNode(Node):
...
@@ -4103,6 +4124,7 @@ class ExceptClauseNode(Node):
self
.
match_flag
,
self
.
match_flag
,
self
.
pattern
.
py_result
()))
self
.
pattern
.
py_result
()))
self
.
pattern
.
generate_disposal_code
(
code
)
self
.
pattern
.
generate_disposal_code
(
code
)
self
.
pattern
.
free_temps
(
code
)
code
.
putln
(
code
.
putln
(
"if (%s) {"
%
"if (%s) {"
%
self
.
match_flag
)
self
.
match_flag
)
...
@@ -4539,6 +4561,7 @@ class FromImportStatNode(StatNode):
...
@@ -4539,6 +4561,7 @@ class FromImportStatNode(StatNode):
code
.
error_goto_if_null
(
self
.
item
.
result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
item
.
result
(),
self
.
pos
)))
target
.
generate_assignment_code
(
self
.
item
,
code
)
target
.
generate_assignment_code
(
self
.
item
,
code
)
self
.
module
.
generate_disposal_code
(
code
)
self
.
module
.
generate_disposal_code
(
code
)
self
.
module
.
free_temps
(
code
)
...
...
Cython/Compiler/Optimize.py
View file @
a0654d24
...
@@ -8,9 +8,13 @@ import TypeSlots
...
@@ -8,9 +8,13 @@ import TypeSlots
import
Symtab
import
Symtab
from
StringEncoding
import
EncodedString
from
StringEncoding
import
EncodedString
#def unwrap_node(node):
# while isinstance(node, ExprNodes.PersistentNode):
# node = node.arg
# return node
# Temporary hack while PersistentNode is out of order
def
unwrap_node
(
node
):
def
unwrap_node
(
node
):
while
isinstance
(
node
,
ExprNodes
.
PersistentNode
):
node
=
node
.
arg
return
node
return
node
def
is_common_value
(
a
,
b
):
def
is_common_value
(
a
,
b
):
...
...
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