Commit da5df0d6 authored by gsamain's avatar gsamain

Make read-write info cascade through entries, not nodes (potentially less...

Make read-write info cascade through entries, not nodes (potentially less optimized, but safer and correctly handles branching)
parent 5e3bf325
...@@ -697,7 +697,7 @@ class ExprNode(Node): ...@@ -697,7 +697,7 @@ class ExprNode(Node):
if self.entry.type.lock_mode == "autolock": if self.entry.type.lock_mode == "autolock":
print "Request read lock autolock here", self.entry.name print "Request read lock autolock here", self.entry.name
self.entry.is_rlocked = True self.entry.is_rlocked = True
self.entry.locking_node.needs_rlock = True self.entry.needs_rlock = True
elif self.entry.type.lock_mode == "checklock": elif self.entry.type.lock_mode == "checklock":
return False return False
return True return True
...@@ -708,7 +708,7 @@ class ExprNode(Node): ...@@ -708,7 +708,7 @@ class ExprNode(Node):
if self.entry.type.lock_mode == "autolock": if self.entry.type.lock_mode == "autolock":
print "Request write lock autolock here", self.entry.name print "Request write lock autolock here", self.entry.name
self.entry.is_wlocked = True self.entry.is_wlocked = True
self.entry.locking_node.needs_wlock = True self.entry.needs_wlock = True
elif self.entry.type.lock_mode == "checklock": elif self.entry.type.lock_mode == "checklock":
return False return False
return True return True
...@@ -864,8 +864,7 @@ class ExprNode(Node): ...@@ -864,8 +864,7 @@ class ExprNode(Node):
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
def generate_assignment_code(self, rhs, code, overloaded_assignment=False, def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
exception_check=None, exception_value=None, needs_unlock=False, exception_check=None, exception_value=None):
needs_rlock=False, needs_wlock=False):
# Stub method for nodes which are not legal as # Stub method for nodes which are not legal as
# the LHS of an assignment. An error will have # the LHS of an assignment. An error will have
# been reported earlier. # been reported earlier.
...@@ -2318,8 +2317,7 @@ class NameNode(AtomicExprNode): ...@@ -2318,8 +2317,7 @@ class NameNode(AtomicExprNode):
code.put_error_if_unbound(self.pos, entry, self.in_nogil_context) code.put_error_if_unbound(self.pos, entry, self.in_nogil_context)
def generate_assignment_code(self, rhs, code, overloaded_assignment=False, def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
exception_check=None, exception_value=None, needs_unlock=False, exception_check=None, exception_value=None):
needs_rlock=False, needs_wlock=False):
#print "NameNode.generate_assignment_code:", self.name ### #print "NameNode.generate_assignment_code:", self.name ###
entry = self.entry entry = self.entry
if entry is None: if entry is None:
...@@ -2329,6 +2327,9 @@ class NameNode(AtomicExprNode): ...@@ -2329,6 +2327,9 @@ class NameNode(AtomicExprNode):
and not self.lhs_of_first_assignment and not rhs.in_module_scope): and not self.lhs_of_first_assignment and not rhs.in_module_scope):
error(self.pos, "Literal list must be assigned to pointer at time of declaration") error(self.pos, "Literal list must be assigned to pointer at time of declaration")
if entry.needs_wlock or entry.needs_rlock:
code.putln("Cy_UNLOCK(%s);" % self.result())
# is_pyglobal seems to be True for module level-globals only. # is_pyglobal seems to be True for module level-globals only.
# We use this to access class->tp_dict if necessary. # We use this to access class->tp_dict if necessary.
if entry.is_pyglobal: if entry.is_pyglobal:
...@@ -2414,8 +2415,6 @@ class NameNode(AtomicExprNode): ...@@ -2414,8 +2415,6 @@ class NameNode(AtomicExprNode):
code.put_cyxdecref(self.result()) code.put_cyxdecref(self.result())
if not self.type.is_memoryviewslice: if not self.type.is_memoryviewslice:
if not assigned: if not assigned:
if needs_unlock:
code.putln("Cy_UNLOCK(%s);" % self.result())
if overloaded_assignment: if overloaded_assignment:
result = rhs.result() result = rhs.result()
if exception_check == '+': if exception_check == '+':
...@@ -2433,9 +2432,9 @@ class NameNode(AtomicExprNode): ...@@ -2433,9 +2432,9 @@ class NameNode(AtomicExprNode):
code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result)) code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result))
elif result != self.result(): elif result != self.result():
code.putln('%s = %s;' % (self.result(), result)) code.putln('%s = %s;' % (self.result(), result))
if needs_wlock: if entry.needs_wlock:
code.putln("Cy_WLOCK(%s);" % self.result()) code.putln("Cy_WLOCK(%s);" % self.result())
elif needs_rlock: elif entry.needs_rlock:
code.putln("Cy_RLOCK(%s);" % self.result()) code.putln("Cy_RLOCK(%s);" % self.result())
if debug_disposal_code: if debug_disposal_code:
print("NameNode.generate_assignment_code:") print("NameNode.generate_assignment_code:")
...@@ -7362,8 +7361,7 @@ class AttributeNode(ExprNode): ...@@ -7362,8 +7361,7 @@ class AttributeNode(ExprNode):
ExprNode.generate_disposal_code(self, code) ExprNode.generate_disposal_code(self, code)
def generate_assignment_code(self, rhs, code, overloaded_assignment=False, def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
exception_check=None, exception_value=None, needs_unlock=False, exception_check=None, exception_value=None):
needs_rlock=False, needs_wlock=False):
self.obj.generate_evaluation_code(code) self.obj.generate_evaluation_code(code)
if self.is_py_attr: if self.is_py_attr:
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
...@@ -7382,6 +7380,8 @@ class AttributeNode(ExprNode): ...@@ -7382,6 +7380,8 @@ class AttributeNode(ExprNode):
rhs.result_as(self.ctype()))) rhs.result_as(self.ctype())))
else: else:
select_code = self.result() select_code = self.result()
if self.entry.needs_rlock or self.entry.needs_wlock:
code.putln("Cy_UNLOCK(%s);" % select_code)
if self.type.is_pyobject and self.use_managed_ref: if self.type.is_pyobject and self.use_managed_ref:
rhs.make_owned_reference(code) rhs.make_owned_reference(code)
code.put_giveref(rhs.py_result()) code.put_giveref(rhs.py_result())
...@@ -7397,17 +7397,15 @@ class AttributeNode(ExprNode): ...@@ -7397,17 +7397,15 @@ class AttributeNode(ExprNode):
code.put_cygotref(select_code) code.put_cygotref(select_code)
code.put_cyxdecref(select_code) code.put_cyxdecref(select_code)
if needs_unlock:
code.putln("Cy_UNLOCK(%s);" % select_code)
if not self.type.is_memoryviewslice: if not self.type.is_memoryviewslice:
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
select_code, select_code,
rhs.result_as(self.ctype()))) rhs.result_as(self.ctype())))
#rhs.result())) #rhs.result()))
if needs_wlock: if self.entry.needs_wlock:
code.putln("Cy_WLOCK(%s);" % select_code) code.putln("Cy_WLOCK(%s);" % select_code)
elif needs_rlock: elif self.entry.needs_rlock:
code.putln("Cy_RLOCK(%s);" % select_code) code.putln("Cy_RLOCK(%s);" % select_code)
rhs.generate_post_assignment_code(code) rhs.generate_post_assignment_code(code)
......
...@@ -5549,14 +5549,11 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -5549,14 +5549,11 @@ class SingleAssignmentNode(AssignmentNode):
self.lhs.gil_assignment_check(env) self.lhs.gil_assignment_check(env)
if hasattr(self.lhs, 'entry'): if hasattr(self.lhs, 'entry'):
entry = self.lhs.entry entry = self.lhs.entry
if entry.type.is_cyp_class and entry.type.lock_mode == "autolock": if entry.type.is_cyp_class and entry.type.lock_mode == "autolock"\
if entry.locking_node is None: and not (entry.needs_rlock or entry.needs_wlock):
env.declare_autolocked(self.lhs) env.declare_autolocked(self.lhs)
else: #self.lhs.entry.is_wlocked = False
self.needs_unlock = True #self.lhs.entry.is_rlocked = False
self.lhs.entry.locking_node = self
self.lhs.entry.is_wlocked = False
self.lhs.entry.is_rlocked = False
if self.rhs.is_attribute: if self.rhs.is_attribute:
self.rhs.obj.check_rhs_locked(env) self.rhs.obj.check_rhs_locked(env)
if self.lhs.is_attribute: if self.lhs.is_attribute:
...@@ -5741,17 +5738,9 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -5741,17 +5738,9 @@ class SingleAssignmentNode(AssignmentNode):
code, code,
overloaded_assignment=self.is_overloaded_assignment, overloaded_assignment=self.is_overloaded_assignment,
exception_check=self.exception_check, exception_check=self.exception_check,
exception_value=self.exception_value, exception_value=self.exception_value)
needs_unlock=self.needs_unlock,
needs_rlock=self.needs_rlock,
needs_wlock=self.needs_wlock)
else: else:
self.lhs.generate_assignment_code( self.lhs.generate_assignment_code(self.rhs, code)
self.rhs,
code,
needs_unlock=self.needs_unlock,
needs_rlock=self.needs_rlock,
needs_wlock=self.needs_wlock)
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
self.rhs.generate_function_definitions(env, code) self.rhs.generate_function_definitions(env, code)
......
...@@ -137,7 +137,8 @@ class Entry(object): ...@@ -137,7 +137,8 @@ class Entry(object):
# is_cgetter boolean Is a c-level getter function # is_cgetter boolean Is a c-level getter function
# is_wlocked boolean Is locked with a write lock (used for cypclass) # is_wlocked boolean Is locked with a write lock (used for cypclass)
# is_rlocked boolean Is locked with a read lock (used for cypclass) # is_rlocked boolean Is locked with a read lock (used for cypclass)
# locking_node Node The assignment node doing the locking # needs_rlock boolean The entry needs a read lock (used in autolock mode)
# needs_wlock boolean The entry needs a write lock (used in autolock mode)
# TODO: utility_code and utility_code_definition serves the same purpose... # TODO: utility_code and utility_code_definition serves the same purpose...
...@@ -210,7 +211,8 @@ class Entry(object): ...@@ -210,7 +211,8 @@ class Entry(object):
is_cgetter = False is_cgetter = False
is_wlocked = False is_wlocked = False
is_rlocked = False is_rlocked = False
locking_node = None needs_rlock = False
needs_wlock = False
def __init__(self, name, cname, type, pos = None, init = None): def __init__(self, name, cname, type, pos = None, init = None):
self.name = name self.name = name
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment