Commit 03d7c50c authored by Xavier Thompson's avatar Xavier Thompson

Refactor coercion to locked cypclass nodes

parent f72728e7
......@@ -502,7 +502,7 @@ class CypclassLockTransform(Visitor.EnvTransform):
return super(CypclassLockTransform, self).__call__(root)
def reference_identifier(self, node):
while isinstance(node, ExprNodes.CoerceToTempNode): # works for CoerceToLockedTempNode as well
while isinstance(node, ExprNodes.CoerceToTempNode):
node = node.arg
if node.is_name:
return node.entry
......@@ -531,13 +531,13 @@ class CypclassLockTransform(Visitor.EnvTransform):
) % self.id_to_name(ref_id) )
elif lock_mode == "autolock":
# for now, lock a temporary for each expression
return ExprNodes.CoerceToLockedTempNode(read_node, self.current_env(), rlock_only=True)
return ExprNodes.CoerceToLockedNode(read_node, self.current_env(), rlock_only=True)
else:
if lock_mode == "checklock":
error(read_node.pos, "This expression is not correctly locked (read lock required)")
elif lock_mode == "autolock":
if not isinstance(read_node, ExprNodes.CoerceToLockedTempNode):
return ExprNodes.CoerceToLockedTempNode(read_node, self.current_env(), rlock_only=True)
if not isinstance(read_node, ExprNodes.CoerceToLockedNode):
return ExprNodes.CoerceToLockedNode(read_node, self.current_env(), rlock_only=True)
return read_node
def lockcheck_written(self, written_node):
......@@ -553,15 +553,15 @@ class CypclassLockTransform(Visitor.EnvTransform):
) % self.id_to_name(ref_id) )
elif lock_mode == "autolock":
# for now, lock a temporary for each expression
return ExprNodes.CoerceToLockedTempNode(written_node, self.current_env(), rlock_only=False)
return ExprNodes.CoerceToLockedNode(written_node, self.current_env(), rlock_only=False)
else:
if lock_mode == "checklock":
error(written_node.pos, "This expression is not correctly locked (write lock required)")
elif lock_mode == "autolock":
if isinstance(written_node, ExprNodes.CoerceToLockedTempNode):
if isinstance(written_node, ExprNodes.CoerceToLockedNode):
written_node.rlock_only = False
else:
return ExprNodes.CoerceToLockedTempNode(written_node, self.current_env())
return ExprNodes.CoerceToLockedNode(written_node, self.current_env())
return written_node
def lockcheck_written_or_read(self, node, reading=False):
......
......@@ -14158,24 +14158,29 @@ class CoerceToTempNode(CoercionNode):
code.put_incref_memoryviewslice(self.result(), self.type,
have_gil=not self.in_nogil_context)
class CoerceToLockedTempNode(CoerceToTempNode):
class CoerceToLockedNode(CoercionNode):
# This node is used to lock a node of cypclass type around the evaluation of its subexpressions.
# rlock_only boolean
# guard_code used internally
def __init__(self, arg, env=None, rlock_only=False):
self.rlock_only = rlock_only
if isinstance(arg, IndexNode):
# reuse reference count management logic
self.use_managed_ref = arg.coerce_to_temp(env).use_managed_ref
elif isinstance(arg, CoerceToTempNode):
self.use_managed_ref = arg.use_managed_ref
arg = arg.arg
super(CoerceToLockedTempNode, self).__init__(arg, env)
self.type = arg.type
arg = arg.coerce_to_temp(env)
arg.postpone_subexpr_disposal = True
super(CoerceToLockedNode,self).__init__(arg)
def generate_result_code(self, code):
super(CoerceToLockedTempNode, self).generate_result_code(code)
def result(self):
return self.arg.result()
def is_simple(self):
return False
#XXX Code duplicated from Nodes.LockCypclassNode
def may_be_none(self):
return self.arg.may_be_none()
def generate_result_code(self, code):
#XXX Code duplicated from Nodes.LockCypclassNode.
if self.arg.pos:
source_descr, lineno, colno = self.arg.pos
source_str = source_descr.get_description()
......@@ -14190,31 +14195,19 @@ class CoerceToLockedTempNode(CoerceToTempNode):
# Create a scope to use scope bound resource management (RAII).
code.putln("{")
# Each lock guard has its onw scope, so a prefix is enough to prevent name collisions
# Since each lock guard has its onw scope,
# a prefix is enough to prevent name collisions.
guard_code = "%sguard" % Naming.cypclass_lock_guard_prefix
if self.rlock_only:
code.putln("Cy_rlock_guard %s(%s, %s);" % (guard_code, self.result(), context))
else:
code.putln("Cy_wlock_guard %s(%s, %s);" % (guard_code, self.result(), context))
def generate_subexpr_disposal_code(self, code):
# Postponed until this node is disposed of.
# See ExprNode.generate_evaluation_code.
return
def free_subexpr_temps(self, code):
# Postponed until this node is disposed of.
# See ExprNode.generate_evaluation_code.
return
def generate_disposal_code(self, code):
# Close the scope to release the lock.
code.putln("}")
# Dispose of and release postponed subexpressions.
ExprNode.generate_subexpr_disposal_code(self, code)
ExprNode.free_subexpr_temps(self, code)
# Dispose of and release this temporary.
ExprNode.generate_disposal_code(self, code)
# Dispose of subexpressions.
super(CoerceToLockedNode,self).generate_disposal_code(code)
class ProxyNode(CoercionNode):
......
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