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
Xavier Thompson
cython
Commits
d91d718f
Commit
d91d718f
authored
Jun 04, 2019
by
gsamain
Committed by
Xavier Thompson
Jun 18, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cypclass lock check/autotake refacto (ensure_[rl]hs_locked)
parent
a8d56eae
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
58 deletions
+74
-58
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+69
-49
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+5
-9
No files found.
Cython/Compiler/ExprNodes.py
View file @
d91d718f
...
@@ -721,39 +721,52 @@ class ExprNode(Node):
...
@@ -721,39 +721,52 @@ class ExprNode(Node):
def
addr_not_const
(
self
):
def
addr_not_const
(
self
):
error
(
self
.
pos
,
"Address is not constant"
)
error
(
self
.
pos
,
"Address is not constant"
)
def
is_rhs_locked
(
self
,
env
):
def
set_autorlock
(
self
,
env
):
if
hasattr
(
self
,
'entry'
)
and
self
.
entry
.
type
.
is_cyp_class
and
self
.
entry
.
is_variable
\
and
not
(
self
.
entry
.
is_rlocked
or
self
.
entry
.
is_wlocked
):
if
self
.
entry
.
type
.
lock_mode
==
"autolock"
:
print
"Request read lock autolock here"
,
self
.
entry
.
name
self
.
entry
.
is_rlocked
=
True
self
.
entry
.
is_rlocked
=
True
self
.
entry
.
needs_rlock
=
True
self
.
entry
.
needs_rlock
=
True
elif
self
.
entry
.
type
.
lock_mode
==
"checklock"
:
return
False
return
True
def
is_lhs_locked
(
self
,
env
):
def
set_autowlock
(
self
,
env
):
if
hasattr
(
self
,
'entry'
)
and
self
.
entry
.
type
.
is_cyp_class
and
self
.
entry
.
is_variable
\
print
"Setting wlock"
and
not
self
.
entry
.
is_wlocked
:
if
self
.
entry
.
type
.
lock_mode
==
"autolock"
:
print
"Request write lock autolock here"
,
self
.
entry
.
name
self
.
entry
.
is_wlocked
=
True
self
.
entry
.
is_wlocked
=
True
self
.
entry
.
needs_wlock
=
True
self
.
entry
.
needs_wlock
=
True
elif
self
.
entry
.
type
.
lock_mode
==
"checklock"
:
return
False
return
True
def
check_rhs_locked
(
self
,
env
):
def
is_autolock
(
self
,
env
):
return
self
.
type
.
is_cyp_class
and
self
.
type
.
lock_mode
==
"autolock"
def
is_checklock
(
self
,
env
):
return
self
.
type
.
is_cyp_class
and
self
.
type
.
lock_mode
==
"checklock"
def
is_rhs_locked
(
self
,
env
):
return
not
(
hasattr
(
self
,
'entry'
)
and
self
.
entry
.
type
.
is_cyp_class
and
not
(
self
.
entry
.
is_rlocked
or
self
.
entry
.
is_wlocked
))
def
is_lhs_locked
(
self
,
env
):
return
not
(
hasattr
(
self
,
'entry'
)
and
self
.
entry
.
type
.
is_cyp_class
and
not
self
.
entry
.
is_wlocked
)
def
ensure_subexpr_rhs_locked
(
self
,
env
):
for
node
in
self
.
subexpr_nodes
():
for
node
in
self
.
subexpr_nodes
():
node
.
check_rhs_locked
(
env
)
node
.
ensure_rhs_locked
(
env
)
if
not
self
.
is_rhs_locked
(
env
):
error
(
self
.
pos
,
"This rhs is not correctly locked (write lock for non-const methods, read lock is sufficient for everything else)"
)
def
check
_lhs_locked
(
self
,
env
):
def
ensure_subexpr
_lhs_locked
(
self
,
env
):
for
node
in
self
.
subexpr_nodes
():
for
node
in
self
.
subexpr_nodes
():
node
.
check_lhs_locked
(
env
)
node
.
ensure_lhs_locked
(
env
)
def
ensure_rhs_locked
(
self
,
env
,
is_dereferenced
=
False
):
self
.
ensure_subexpr_rhs_locked
(
env
)
if
is_dereferenced
:
if
not
self
.
is_rhs_locked
(
env
):
if
self
.
is_checklock
(
env
):
error
(
self
.
pos
,
"This expression is not correctly locked (read lock needed)"
)
elif
self
.
is_autolock
(
env
):
self
.
set_autorlock
(
env
)
def
ensure_lhs_locked
(
self
,
env
,
is_dereferenced
=
False
):
self
.
ensure_subexpr_lhs_locked
(
env
)
if
is_dereferenced
:
if
not
self
.
is_lhs_locked
(
env
):
if
not
self
.
is_lhs_locked
(
env
):
error
(
self
.
pos
,
"This lhs is not correctly locked (write lock needed)"
)
if
self
.
is_checklock
(
env
):
error
(
self
.
pos
,
"This expression is not correctly locked (write lock needed)"
)
elif
self
.
is_autolock
(
env
):
self
.
set_autowlock
(
env
)
# ----------------- Result Allocation -----------------
# ----------------- Result Allocation -----------------
...
@@ -5697,6 +5710,8 @@ class SimpleCallNode(CallNode):
...
@@ -5697,6 +5710,8 @@ class SimpleCallNode(CallNode):
analysed
=
False
analysed
=
False
overflowcheck
=
False
overflowcheck
=
False
explicit_cpp_self
=
None
explicit_cpp_self
=
None
rlocked
=
False
wlocked
=
False
def
compile_time_value
(
self
,
denv
):
def
compile_time_value
(
self
,
denv
):
function
=
self
.
function
.
compile_time_value
(
denv
)
function
=
self
.
function
.
compile_time_value
(
denv
)
...
@@ -5907,9 +5922,9 @@ class SimpleCallNode(CallNode):
...
@@ -5907,9 +5922,9 @@ class SimpleCallNode(CallNode):
formal_arg
=
func_type
.
args
[
i
]
formal_arg
=
func_type
.
args
[
i
]
actual_arg
=
args
[
i
]
actual_arg
=
args
[
i
]
if
formal_arg
.
type
.
is_const
:
if
formal_arg
.
type
.
is_const
:
actual_arg
.
check_rhs_locked
(
env
)
actual_arg
.
ensure_rhs_locked
(
env
,
is_dereferenced
=
True
)
else
:
else
:
actual_arg
.
check_lhs_locked
(
env
)
actual_arg
.
ensure_lhs_locked
(
env
,
is_dereferenced
=
True
)
# Coerce arguments
# Coerce arguments
some_args_in_temps
=
False
some_args_in_temps
=
False
for
i
in
range
(
min
(
max_nargs
,
actual_nargs
)):
for
i
in
range
(
min
(
max_nargs
,
actual_nargs
)):
...
@@ -6032,10 +6047,17 @@ class SimpleCallNode(CallNode):
...
@@ -6032,10 +6047,17 @@ class SimpleCallNode(CallNode):
self
.
overflowcheck
=
env
.
directives
[
'overflowcheck'
]
self
.
overflowcheck
=
env
.
directives
[
'overflowcheck'
]
def
check_rhs_locked
(
self
,
env
):
def
is_lhs_locked
(
self
,
env
):
self
.
function
.
check_rhs_locked
(
env
)
return
self
.
wlocked
#if not self.is_rhs_locked(env):
# error(self.pos, "RHS lock needed")
def
is_rhs_locked
(
self
,
env
):
return
self
.
rlocked
def
set_autorlock
(
self
,
env
):
self
.
rlocked
=
True
def
set_autowlock
(
self
,
env
):
self
.
wlocked
=
True
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
return
self
.
c_call_code
()
return
self
.
c_call_code
()
...
@@ -7335,16 +7357,14 @@ class AttributeNode(ExprNode):
...
@@ -7335,16 +7357,14 @@ class AttributeNode(ExprNode):
gil_message
=
"Accessing Python attribute"
gil_message
=
"Accessing Python attribute"
def
is_rhs_locked
(
self
,
env
):
def
ensure_subexpr_rhs_locked
(
self
,
env
):
obj
=
self
.
obj
# The subexpr mechanism will here issue check_rhs_lock on self.obj
# BUT if we are calling a non-const method, the object can be modified.
# So here we're calling directly check_lhs_lock if this is needed.
if
self
.
entry
.
is_cfunction
and
not
self
.
entry
.
type
.
is_const_method
:
if
self
.
entry
.
is_cfunction
and
not
self
.
entry
.
type
.
is_const_method
:
self
.
obj
.
check_lhs_locked
(
env
)
self
.
obj
.
ensure_lhs_locked
(
env
,
is_dereferenced
=
True
)
else
:
self
.
obj
.
ensure_rhs_locked
(
env
,
is_dereferenced
=
True
)
return
ExprNode
.
is_rhs_locked
(
self
,
env
)
def
ensure_subexpr_lhs_locked
(
self
,
env
):
self
.
obj
.
ensure_lhs_locked
(
env
,
is_dereferenced
=
True
)
def
is_cimported_module_without_shadow
(
self
,
env
):
def
is_cimported_module_without_shadow
(
self
,
env
):
return
self
.
obj
.
is_cimported_module_without_shadow
(
env
)
return
self
.
obj
.
is_cimported_module_without_shadow
(
env
)
...
@@ -12842,11 +12862,11 @@ class PrimaryCmpNode(ExprNode, CmpNode):
...
@@ -12842,11 +12862,11 @@ class PrimaryCmpNode(ExprNode, CmpNode):
operand1
=
self
.
operand1
.
compile_time_value
(
denv
)
operand1
=
self
.
operand1
.
compile_time_value
(
denv
)
return
self
.
cascaded_compile_time_value
(
operand1
,
denv
)
return
self
.
cascaded_compile_time_value
(
operand1
,
denv
)
def
check_rhs_locked
(
self
,
env
):
#
def check_rhs_locked(self, env):
self
.
operand1
.
check_rhs_locked
(
env
)
#
self.operand1.check_rhs_locked(env)
self
.
operand2
.
check_rhs_locked
(
env
)
#
self.operand2.check_rhs_locked(env)
if
self
.
cascade
:
#
if self.cascade:
self
.
cascade
.
check_rhs_locked
(
env
)
#
self.cascade.check_rhs_locked(env)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
operand1
=
self
.
operand1
.
analyse_types
(
env
)
self
.
operand1
=
self
.
operand1
.
analyse_types
(
env
)
...
@@ -13114,10 +13134,10 @@ class CascadedCmpNode(Node, CmpNode):
...
@@ -13114,10 +13134,10 @@ class CascadedCmpNode(Node, CmpNode):
return
self
.
constant_result
is
not
constant_value_not_set
and
\
return
self
.
constant_result
is
not
constant_value_not_set
and
\
self
.
constant_result
is
not
not_a_constant
self
.
constant_result
is
not
not_a_constant
def
check_rhs_locked
(
self
,
env
):
#
def check_rhs_locked(self, env):
self
.
operand2
.
check_rhs_locked
(
env
)
#
self.operand2.check_rhs_locked(env)
if
self
.
cascade
:
#
if self.cascade:
self
.
cascade
.
check_rhs_locked
(
env
)
#
self.cascade.check_rhs_locked(env)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
operand2
=
self
.
operand2
.
analyse_types
(
env
)
self
.
operand2
=
self
.
operand2
.
analyse_types
(
env
)
...
...
Cython/Compiler/Nodes.py
View file @
d91d718f
...
@@ -5596,7 +5596,7 @@ class ExprStatNode(StatNode):
...
@@ -5596,7 +5596,7 @@ class ExprStatNode(StatNode):
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
expr
.
result_is_used
=
False
# hint that .result() may safely be left empty
self
.
expr
.
result_is_used
=
False
# hint that .result() may safely be left empty
self
.
expr
=
self
.
expr
.
analyse_expressions
(
env
)
self
.
expr
=
self
.
expr
.
analyse_expressions
(
env
)
self
.
expr
.
check
_rhs_locked
(
env
)
self
.
expr
.
ensure
_rhs_locked
(
env
)
# Repeat in case of node replacement.
# Repeat in case of node replacement.
self
.
expr
.
result_is_used
=
False
# hint that .result() may safely be left empty
self
.
expr
.
result_is_used
=
False
# hint that .result() may safely be left empty
return
self
return
self
...
@@ -5772,12 +5772,8 @@ class SingleAssignmentNode(AssignmentNode):
...
@@ -5772,12 +5772,8 @@ class SingleAssignmentNode(AssignmentNode):
if
entry
.
type
.
is_cyp_class
and
entry
.
type
.
lock_mode
==
"autolock"
\
if
entry
.
type
.
is_cyp_class
and
entry
.
type
.
lock_mode
==
"autolock"
\
and
not
(
entry
.
needs_rlock
or
entry
.
needs_wlock
):
and
not
(
entry
.
needs_rlock
or
entry
.
needs_wlock
):
env
.
declare_autolocked
(
self
.
lhs
)
env
.
declare_autolocked
(
self
.
lhs
)
#self.lhs.entry.is_wlocked = False
self
.
rhs
.
ensure_rhs_locked
(
env
)
#self.lhs.entry.is_rlocked = False
self
.
lhs
.
ensure_lhs_locked
(
env
)
if
self
.
rhs
.
is_attribute
:
self
.
rhs
.
obj
.
check_rhs_locked
(
env
)
if
self
.
lhs
.
is_attribute
:
self
.
lhs
.
obj
.
check_lhs_locked
(
env
)
unrolled_assignment
=
self
.
unroll_lhs
(
env
)
unrolled_assignment
=
self
.
unroll_lhs
(
env
)
if
unrolled_assignment
:
if
unrolled_assignment
:
return
unrolled_assignment
return
unrolled_assignment
...
@@ -6001,11 +5997,11 @@ class CascadedAssignmentNode(AssignmentNode):
...
@@ -6001,11 +5997,11 @@ class CascadedAssignmentNode(AssignmentNode):
for
i
,
lhs
in
enumerate
(
self
.
lhs_list
):
for
i
,
lhs
in
enumerate
(
self
.
lhs_list
):
lhs
=
self
.
lhs_list
[
i
]
=
lhs
.
analyse_target_types
(
env
)
lhs
=
self
.
lhs_list
[
i
]
=
lhs
.
analyse_target_types
(
env
)
lhs
.
gil_assignment_check
(
env
)
lhs
.
gil_assignment_check
(
env
)
lhs
.
check
_lhs_locked
(
env
)
lhs
.
ensure
_lhs_locked
(
env
)
lhs_types
.
add
(
lhs
.
type
)
lhs_types
.
add
(
lhs
.
type
)
rhs
=
self
.
rhs
.
analyse_types
(
env
)
rhs
=
self
.
rhs
.
analyse_types
(
env
)
rhs
.
check
_rhs_locked
(
env
)
rhs
.
ensure
_rhs_locked
(
env
)
# common special case: only one type needed on the LHS => coerce only once
# common special case: only one type needed on the LHS => coerce only once
if
len
(
lhs_types
)
==
1
:
if
len
(
lhs_types
)
==
1
:
# Avoid coercion for overloaded assignment operators.
# Avoid coercion for overloaded assignment operators.
...
...
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