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
b9c2853f
Commit
b9c2853f
authored
Mar 30, 2009
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
All exprnodes over; NewTempExprNode folded into ExprNode
parent
a1f3d113
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
92 additions
and
202 deletions
+92
-202
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+89
-197
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+2
-4
Cython/Compiler/UtilNodes.py
Cython/Compiler/UtilNodes.py
+1
-1
No files found.
Cython/Compiler/ExprNodes.py
View file @
b9c2853f
...
...
@@ -46,6 +46,8 @@ class ExprNode(Node):
result_ctype
=
None
type
=
None
temp_code
=
None
old_temp
=
None
# error checker for multiple frees etc.
# The Analyse Expressions phase for expressions is split
# into two sub-phases:
...
...
@@ -222,10 +224,10 @@ class ExprNode(Node):
return
nodes
def
result
(
self
):
if
not
self
.
is_temp
or
self
.
is_target
:
if
self
.
is_temp
:
return
self
.
temp_code
else
:
return
self
.
calculate_result_code
()
else
:
# i.e. self.is_temp:
return
self
.
result_code
def
result_as
(
self
,
type
=
None
):
# Return the result code cast to the specified C type.
...
...
@@ -370,15 +372,18 @@ class ExprNode(Node):
return
self
.
is_temp
def
allocate_target_temps
(
self
,
env
,
rhs
):
# Perform temp allocation for the LHS of an assignment.
if
debug_temp_alloc
:
print
(
"%s Allocating target temps"
%
self
)
self
.
allocate_subexpr_temps
(
env
)
self
.
is_target
=
True
if
rhs
:
rhs
.
release_temp
(
env
)
self
.
release_subexpr_temps
(
env
)
def
allocate_temps
(
self
,
env
,
result
=
None
):
assert
result
is
None
,
"deprecated, contact dagss if this triggers"
self
.
allocate_subexpr_temps
(
env
)
if
self
.
is_temp
:
self
.
release_subexpr_temps
(
env
)
def
allocate_temps
(
self
,
env
,
result
=
None
):
# Allocate temporary variables for this node and
# all its sub-expressions. If a result is specified,
...
...
@@ -405,28 +410,7 @@ class ExprNode(Node):
node
.
allocate_temps
(
env
)
def
allocate_temp
(
self
,
env
,
result
=
None
):
# If this node requires a temporary variable for its
# result, allocate one, otherwise set the result to
# a C code fragment. If a result is specified,
# this must be a temp node and the specified variable
# is used as the result instead of allocating a new
# one.
if
debug_temp_alloc
:
print
(
"%s Allocating temp"
%
self
)
if
result
:
if
not
self
.
is_temp
:
raise
InternalError
(
"Result forced on non-temp node"
)
self
.
result_code
=
result
elif
self
.
is_temp
:
type
=
self
.
type
if
not
type
.
is_void
:
if
type
.
is_pyobject
:
type
=
PyrexTypes
.
py_object_type
self
.
result_code
=
env
.
allocate_temp
(
type
)
else
:
self
.
result_code
=
None
if
debug_temp_alloc
:
print
(
"%s Allocated result %s"
%
(
self
,
self
.
result_code
))
assert
result
is
None
def
target_code
(
self
):
# Return code fragment for use as LHS of a C assignment.
...
...
@@ -439,13 +423,10 @@ class ExprNode(Node):
# # Release temporaries used by LHS of an assignment.
# self.release_subexpr_temps(env)
def
release_temp
(
self
,
env
):
# If this node owns a temporary result, release it,
# otherwise release results of its sub-expressions.
if
self
.
is_temp
:
if
debug_temp_alloc
:
print
(
"%s Releasing result %s"
%
(
self
,
self
.
result_code
))
env
.
release_temp
(
self
.
result_code
)
pass
else
:
self
.
release_subexpr_temps
(
env
)
...
...
@@ -456,6 +437,30 @@ class ExprNode(Node):
if
node
:
node
.
release_temp
(
env
)
def
allocate_temp_result
(
self
,
code
):
if
self
.
temp_code
:
raise
RuntimeError
(
"Temp allocated multiple times"
)
type
=
self
.
type
if
not
type
.
is_void
:
if
type
.
is_pyobject
:
type
=
PyrexTypes
.
py_object_type
self
.
temp_code
=
code
.
funcstate
.
allocate_temp
(
type
,
manage_ref
=
True
)
else
:
self
.
temp_code
=
None
def
release_temp_result
(
self
,
code
):
if
not
self
.
temp_code
:
if
self
.
old_temp
:
raise
RuntimeError
(
"temp %s released multiple times in %s"
%
(
self
.
old_temp
,
self
.
__class__
.
__name__
))
else
:
raise
RuntimeError
(
"no temp, but release requested in %s"
%
(
self
.
__class__
.
__name__
))
code
.
funcstate
.
release_temp
(
self
.
temp_code
)
self
.
old_temp
=
self
.
temp_code
self
.
temp_code
=
None
# ---------------- Code Generation -----------------
def
make_owned_reference
(
self
,
code
):
...
...
@@ -466,12 +471,19 @@ class ExprNode(Node):
def
generate_evaluation_code
(
self
,
code
):
code
.
mark_pos
(
self
.
pos
)
# Generate code to evaluate this node and
# its sub-expressions, and dispose of any
# temporary results of its sub-expressions.
self
.
generate_subexpr_evaluation_code
(
code
)
if
self
.
is_temp
:
self
.
allocate_temp_result
(
code
)
self
.
generate_result_code
(
code
)
if
self
.
is_temp
:
# If we are temp we do not need to wait until this node is disposed
# before disposing children.
self
.
generate_subexpr_disposal_code
(
code
)
self
.
free_subexpr_temps
(
code
)
...
...
@@ -483,14 +495,13 @@ class ExprNode(Node):
self
.
not_implemented
(
"generate_result_code"
)
def
generate_disposal_code
(
self
,
code
):
# If necessary, generate code to dispose of
# temporary Python reference.
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
())
else
:
# Already done if self.is_temp
self
.
generate_subexpr_disposal_code
(
code
)
def
generate_subexpr_disposal_code
(
self
,
code
):
# Generate code to dispose of temporary results
# of all sub-expressions.
...
...
@@ -498,15 +509,12 @@ class ExprNode(Node):
node
.
generate_disposal_code
(
code
)
def
generate_post_assignment_code
(
self
,
code
):
# Same as generate_disposal_code except that
# assignment will have absorbed a reference to
# the result if it is a Python object.
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
putln
(
"%s = 0;"
%
self
.
result
())
else
:
self
.
generate_subexpr_disposal_code
(
code
)
def
generate_assignment_code
(
self
,
rhs
,
code
):
# Stub method for nodes which are not legal as
# the LHS of an assignment. An error will have
...
...
@@ -520,9 +528,11 @@ class ExprNode(Node):
pass
def
free_temps
(
self
,
code
):
if
not
self
.
is_temp
:
if
self
.
is_temp
:
if
not
self
.
type
.
is_void
:
self
.
release_temp_result
(
code
)
else
:
self
.
free_subexpr_temps
(
code
)
# otherwise, already freed in generate_evaluation_code
def
free_subexpr_temps
(
self
,
code
):
for
sub
in
self
.
subexpr_nodes
():
...
...
@@ -612,125 +622,7 @@ class ExprNode(Node):
def
as_cython_attribute
(
self
):
return
None
class
RemoveAllocateTemps
(
type
):
def
__init__
(
cls
,
name
,
bases
,
dct
):
super
(
RemoveAllocateTemps
,
cls
).
__init__
(
name
,
bases
,
dct
)
def
noop
(
self
,
env
):
pass
setattr
(
cls
,
'allocate_temps'
,
noop
)
setattr
(
cls
,
'allocate_temp'
,
noop
)
setattr
(
cls
,
'release_temp'
,
noop
)
class
NewTempExprNode
(
ExprNode
):
temp_code
=
None
old_temp
=
None
# error checker for multiple frees etc.
# Do not enable this unless you are trying to make all ExprNodes
# NewTempExprNodes (child nodes reached via recursion may not have
# transferred).
# __metaclass__ = RemoveAllocateTemps
def
result
(
self
):
if
self
.
is_temp
:
return
self
.
temp_code
else
:
return
self
.
calculate_result_code
()
def
allocate_target_temps
(
self
,
env
,
rhs
):
self
.
allocate_subexpr_temps
(
env
)
self
.
is_target
=
True
if
rhs
:
rhs
.
release_temp
(
env
)
self
.
release_subexpr_temps
(
env
)
def
allocate_temps
(
self
,
env
,
result
=
None
):
assert
result
is
None
,
"deprecated, contact dagss if this triggers"
self
.
allocate_subexpr_temps
(
env
)
if
self
.
is_temp
:
self
.
release_subexpr_temps
(
env
)
def
allocate_temp
(
self
,
env
,
result
=
None
):
assert
result
is
None
def
release_temp
(
self
,
env
):
if
self
.
is_temp
:
pass
else
:
self
.
release_subexpr_temps
(
env
)
def
allocate_temp_result
(
self
,
code
):
if
self
.
temp_code
:
raise
RuntimeError
(
"Temp allocated multiple times"
)
type
=
self
.
type
if
not
type
.
is_void
:
if
type
.
is_pyobject
:
type
=
PyrexTypes
.
py_object_type
self
.
temp_code
=
code
.
funcstate
.
allocate_temp
(
type
,
manage_ref
=
True
)
else
:
self
.
temp_code
=
None
def
release_temp_result
(
self
,
code
):
if
not
self
.
temp_code
:
if
self
.
old_temp
:
raise
RuntimeError
(
"temp %s released multiple times in %s"
%
(
self
.
old_temp
,
self
.
__class__
.
__name__
))
else
:
raise
RuntimeError
(
"no temp, but release requested in %s"
%
(
self
.
__class__
.
__name__
))
code
.
funcstate
.
release_temp
(
self
.
temp_code
)
self
.
old_temp
=
self
.
temp_code
self
.
temp_code
=
None
def
generate_evaluation_code
(
self
,
code
):
code
.
mark_pos
(
self
.
pos
)
# Generate code to evaluate this node and
# its sub-expressions, and dispose of any
# temporary results of its sub-expressions.
self
.
generate_subexpr_evaluation_code
(
code
)
if
self
.
is_temp
:
self
.
allocate_temp_result
(
code
)
self
.
generate_result_code
(
code
)
if
self
.
is_temp
:
# If we are temp we do not need to wait until this node is disposed
# before disposing children.
self
.
generate_subexpr_disposal_code
(
code
)
self
.
free_subexpr_temps
(
code
)
def
generate_disposal_code
(
self
,
code
):
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
())
else
:
# Already done if self.is_temp
self
.
generate_subexpr_disposal_code
(
code
)
def
generate_post_assignment_code
(
self
,
code
):
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
putln
(
"%s = 0;"
%
self
.
result
())
else
:
self
.
generate_subexpr_disposal_code
(
code
)
def
free_temps
(
self
,
code
):
if
self
.
is_temp
:
if
not
self
.
type
.
is_void
:
self
.
release_temp_result
(
code
)
else
:
self
.
free_subexpr_temps
(
code
)
# ExprNode = NewTempExprNode
class
AtomicExprNode
(
ExprNode
):
# Abstract base class for expression nodes which have
# no sub-expressions.
subexprs
=
[]
class
AtomicNewTempExprNode
(
NewTempExprNode
):
# I do not dare to convert NameNode yet. This is now
# ancestor of all former AtomicExprNode except
# NameNode. Should be renamed to AtomicExprNode
...
...
@@ -747,7 +639,7 @@ class AtomicNewTempExprNode(NewTempExprNode):
def
generate_subexpr_disposal_code
(
self
,
code
):
pass
class
PyConstNode
(
Atomic
NewTemp
ExprNode
):
class
PyConstNode
(
AtomicExprNode
):
# Abstract base class for constant Python values.
is_literal
=
1
...
...
@@ -787,7 +679,7 @@ class EllipsisNode(PyConstNode):
return
Ellipsis
class
ConstNode
(
Atomic
NewTemp
ExprNode
):
class
ConstNode
(
AtomicExprNode
):
# Abstract base type for literal constant nodes.
#
# value string C code fragment
...
...
@@ -1017,7 +909,7 @@ class IdentifierStringNode(ConstNode):
return
self
.
result_code
class
LongNode
(
Atomic
NewTemp
ExprNode
):
class
LongNode
(
AtomicExprNode
):
# Python long integer literal
#
# value string
...
...
@@ -1043,7 +935,7 @@ class LongNode(AtomicNewTempExprNode):
code
.
put_gotref
(
self
.
py_result
())
class
ImagNode
(
Atomic
NewTemp
ExprNode
):
class
ImagNode
(
AtomicExprNode
):
# Imaginary number literal
#
# value float imaginary part
...
...
@@ -1070,7 +962,7 @@ class ImagNode(AtomicNewTempExprNode):
class
NameNode
(
Atomic
NewTemp
ExprNode
):
class
NameNode
(
AtomicExprNode
):
# Reference to a local or global variable name.
#
# name string Python name of the variable
...
...
@@ -1425,7 +1317,7 @@ class NameNode(AtomicNewTempExprNode):
else
:
code
.
annotate
(
pos
,
AnnotationItem
(
'c_call'
,
'c function'
,
size
=
len
(
self
.
name
)))
class
BackquoteNode
(
NewTemp
ExprNode
):
class
BackquoteNode
(
ExprNode
):
# `expr`
#
# arg ExprNode
...
...
@@ -1453,7 +1345,7 @@ class BackquoteNode(NewTempExprNode):
class
ImportNode
(
NewTemp
ExprNode
):
class
ImportNode
(
ExprNode
):
# Used as part of import statement implementation.
# Implements result =
# __import__(module_name, globals(), None, name_list)
...
...
@@ -1489,7 +1381,7 @@ class ImportNode(NewTempExprNode):
code
.
put_gotref
(
self
.
py_result
())
class
IteratorNode
(
NewTemp
ExprNode
):
class
IteratorNode
(
ExprNode
):
# Used as part of for statement implementation.
#
# allocate_counter_temp/release_counter_temp needs to be called
...
...
@@ -1548,7 +1440,7 @@ class IteratorNode(NewTempExprNode):
code
.
putln
(
"}"
)
class
NextNode
(
Atomic
NewTemp
ExprNode
):
class
NextNode
(
AtomicExprNode
):
# Used as part of for statement implementation.
# Implements result = iterator.next()
# Created during analyse_types phase.
...
...
@@ -1607,7 +1499,7 @@ class NextNode(AtomicNewTempExprNode):
code
.
putln
(
"}"
)
class
ExcValueNode
(
Atomic
NewTemp
ExprNode
):
class
ExcValueNode
(
AtomicExprNode
):
# Node created during analyse_types phase
# of an ExceptClauseNode to fetch the current
# exception value.
...
...
@@ -1627,7 +1519,7 @@ class ExcValueNode(AtomicNewTempExprNode):
pass
class
TempNode
(
NewTemp
ExprNode
):
class
TempNode
(
ExprNode
):
# Node created during analyse_types phase
# of some nodes to hold a temporary value.
#
...
...
@@ -1685,7 +1577,7 @@ class PyTempNode(TempNode):
#
#-------------------------------------------------------------------
class
IndexNode
(
NewTemp
ExprNode
):
class
IndexNode
(
ExprNode
):
# Sequence indexing.
#
# base ExprNode
...
...
@@ -2012,7 +1904,7 @@ class IndexNode(NewTempExprNode):
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
code
.
putln
(
"}"
)
class
SliceIndexNode
(
NewTemp
ExprNode
):
class
SliceIndexNode
(
ExprNode
):
# 2-element slice indexing
#
# base ExprNode
...
...
@@ -2214,7 +2106,7 @@ class SliceIndexNode(NewTempExprNode):
return
"<unused>"
class
SliceNode
(
NewTemp
ExprNode
):
class
SliceNode
(
ExprNode
):
# start:stop:step in subscript list
#
# start ExprNode
...
...
@@ -2267,7 +2159,7 @@ class SliceNode(NewTempExprNode):
code
.
put_gotref
(
self
.
py_result
())
class
CallNode
(
NewTemp
ExprNode
):
class
CallNode
(
ExprNode
):
def
analyse_as_type_constructor
(
self
,
env
):
type
=
self
.
function
.
analyse_as_type
(
env
)
if
type
and
type
.
is_struct_or_union
:
...
...
@@ -2661,7 +2553,7 @@ class GeneralCallNode(CallNode):
code
.
put_gotref
(
self
.
py_result
())
class
AsTupleNode
(
NewTemp
ExprNode
):
class
AsTupleNode
(
ExprNode
):
# Convert argument to tuple. Used for normalising
# the * argument of a function call.
#
...
...
@@ -2697,7 +2589,7 @@ class AsTupleNode(NewTempExprNode):
code
.
put_gotref
(
self
.
py_result
())
class
AttributeNode
(
NewTemp
ExprNode
):
class
AttributeNode
(
ExprNode
):
# obj.attribute
#
# obj ExprNode
...
...
@@ -3041,7 +2933,7 @@ class AttributeNode(NewTempExprNode):
#
#-------------------------------------------------------------------
class
SequenceNode
(
NewTemp
ExprNode
):
class
SequenceNode
(
ExprNode
):
# Base class for list and tuple constructor nodes.
# Contains common code for performing sequence unpacking.
#
...
...
@@ -3366,7 +3258,7 @@ class ListNode(SequenceNode):
# generate_evaluation_code which will do that.
class
ComprehensionNode
(
NewTemp
ExprNode
):
class
ComprehensionNode
(
ExprNode
):
subexprs
=
[
"target"
]
child_attrs
=
[
"loop"
,
"append"
]
...
...
@@ -3397,7 +3289,7 @@ class ComprehensionNode(NewTempExprNode):
self
.
loop
.
annotate
(
code
)
class
ComprehensionAppendNode
(
NewTemp
ExprNode
):
class
ComprehensionAppendNode
(
ExprNode
):
# Need to be careful to avoid infinite recursion:
# target must not be in child_attrs/subexprs
subexprs
=
[
'expr'
]
...
...
@@ -3447,7 +3339,7 @@ class DictComprehensionAppendNode(ComprehensionAppendNode):
code
.
error_goto_if
(
self
.
result
(),
self
.
pos
)))
class
SetNode
(
NewTemp
ExprNode
):
class
SetNode
(
ExprNode
):
# Set constructor.
subexprs
=
[
'args'
]
...
...
@@ -3491,7 +3383,7 @@ class SetNode(NewTempExprNode):
arg
.
free_temps
(
code
)
class
DictNode
(
NewTemp
ExprNode
):
class
DictNode
(
ExprNode
):
# Dictionary constructor.
#
# key_value_pairs [DictItemNode]
...
...
@@ -3591,7 +3483,7 @@ class DictNode(NewTempExprNode):
for
item
in
self
.
key_value_pairs
:
item
.
annotate
(
code
)
class
DictItemNode
(
NewTemp
ExprNode
):
class
DictItemNode
(
ExprNode
):
# Represents a single item in a DictNode
#
# key ExprNode
...
...
@@ -3626,7 +3518,7 @@ class DictItemNode(NewTempExprNode):
return
iter
([
self
.
key
,
self
.
value
])
class
ClassNode
(
NewTemp
ExprNode
):
class
ClassNode
(
ExprNode
):
# Helper class used in the implementation of Python
# class definitions. Constructs a class object given
# a name, tuple of bases and class dictionary.
...
...
@@ -3669,7 +3561,7 @@ class ClassNode(NewTempExprNode):
code
.
put_gotref
(
self
.
py_result
())
class
UnboundMethodNode
(
NewTemp
ExprNode
):
class
UnboundMethodNode
(
ExprNode
):
# Helper class used in the implementation of Python
# class definitions. Constructs an unbound method
# object from a class and a function.
...
...
@@ -3695,7 +3587,7 @@ class UnboundMethodNode(NewTempExprNode):
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
class
PyCFunctionNode
(
Atomic
NewTemp
ExprNode
):
class
PyCFunctionNode
(
AtomicExprNode
):
# Helper class used in the implementation of Python
# class definitions. Constructs a PyCFunction object
# from a PyMethodDef struct.
...
...
@@ -3729,7 +3621,7 @@ compile_time_unary_operators = {
'+'
:
operator
.
pos
,
}
class
UnopNode
(
NewTemp
ExprNode
):
class
UnopNode
(
ExprNode
):
# operator string
# operand ExprNode
#
...
...
@@ -3805,7 +3697,7 @@ class UnopNode(NewTempExprNode):
self
.
type
=
PyrexTypes
.
error_type
class
NotNode
(
NewTemp
ExprNode
):
class
NotNode
(
ExprNode
):
# 'not' operator
#
# operand ExprNode
...
...
@@ -3883,7 +3775,7 @@ class TildeNode(UnopNode):
return
"(~%s)"
%
self
.
operand
.
result
()
class
AmpersandNode
(
NewTemp
ExprNode
):
class
AmpersandNode
(
ExprNode
):
# The C address-of operator.
#
# operand ExprNode
...
...
@@ -3934,7 +3826,7 @@ def unop_node(pos, operator, operand):
operand
=
operand
)
class
TypecastNode
(
NewTemp
ExprNode
):
class
TypecastNode
(
ExprNode
):
# C type cast
#
# operand ExprNode
...
...
@@ -4009,7 +3901,7 @@ class TypecastNode(NewTempExprNode):
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
class
SizeofNode
(
NewTemp
ExprNode
):
class
SizeofNode
(
ExprNode
):
# Abstract base class for sizeof(x) expression nodes.
type
=
PyrexTypes
.
c_size_t_type
...
...
@@ -4138,7 +4030,7 @@ def get_compile_time_binop(node):
%
node
.
operator
)
return
func
class
BinopNode
(
NewTemp
ExprNode
):
class
BinopNode
(
ExprNode
):
# operator string
# operand1 ExprNode
# operand2 ExprNode
...
...
@@ -4444,7 +4336,7 @@ class PowNode(NumBinopNode):
# one could have a look at adding this again after /all/ classes
# are converted to the new temp scheme. (The temp juggling cannot work
# otherwise).
class
BoolBinopNode
(
NewTemp
ExprNode
):
class
BoolBinopNode
(
ExprNode
):
# Short-circuiting boolean operation.
#
# operator string
...
...
@@ -4574,7 +4466,7 @@ class BoolBinopNode(NewTempExprNode):
return
(
test_result
,
self
.
type
.
is_pyobject
)
class
CondExprNode
(
NewTemp
ExprNode
):
class
CondExprNode
(
ExprNode
):
# Short-circuiting conditional expression.
#
# test ExprNode
...
...
@@ -4781,7 +4673,7 @@ class CmpNode(object):
return
op
class
PrimaryCmpNode
(
NewTemp
ExprNode
,
CmpNode
):
class
PrimaryCmpNode
(
ExprNode
,
CmpNode
):
# Non-cascaded comparison or first comparison of
# a cascaded sequence.
#
...
...
@@ -5035,7 +4927,7 @@ def binop_node(pos, operator, operand1, operand2):
#
#-------------------------------------------------------------------
class
CoercionNode
(
NewTemp
ExprNode
):
class
CoercionNode
(
ExprNode
):
# Abstract base class for coercion nodes.
#
# arg ExprNode node being coerced
...
...
Cython/Compiler/Nodes.py
View file @
b9c2853f
...
...
@@ -3084,10 +3084,8 @@ class InPlaceAssignmentNode(AssignmentNode):
import
ExprNodes
self
.
rhs
.
generate_evaluation_code
(
code
)
self
.
dup
.
generate_subexpr_evaluation_code
(
code
)
if
isinstance
(
self
.
dup
,
ExprNodes
.
NewTempExprNode
):
# This is because we're manually messing with subexpr nodes
if
self
.
dup
.
is_temp
:
self
.
dup
.
allocate_temp_result
(
code
)
if
self
.
dup
.
is_temp
:
self
.
dup
.
allocate_temp_result
(
code
)
# self.dup.generate_result_code is run only if it is not buffer access
if
self
.
operator
==
"**"
:
extra
=
", Py_None"
...
...
Cython/Compiler/UtilNodes.py
View file @
b9c2853f
...
...
@@ -142,7 +142,7 @@ class ResultRefNode(AtomicExprNode):
pass
class
EvalWithTempExprNode
(
ExprNodes
.
NewTemp
ExprNode
):
class
EvalWithTempExprNode
(
ExprNodes
.
ExprNode
):
# A wrapper around a subexpression that moves an expression into a
# temp variable and provides it to the subexpression.
...
...
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