Commit 321b3d1e authored by Xavier Thompson's avatar Xavier Thompson

Use temporaries to prevent nested cypclass lock acquisition

parent af8dcdb3
...@@ -445,10 +445,12 @@ class CypclassLockTransform(Visitor.EnvTransform): ...@@ -445,10 +445,12 @@ class CypclassLockTransform(Visitor.EnvTransform):
error(lock.pos, "A writelock is required, but a readlock is manually acquired") error(lock.pos, "A writelock is required, but a readlock is manually acquired")
return obj return obj
except: except:
self.autolocks += 1
return ExprNodes.CoerceToLockedNode(obj, self.current_env(), rlock_only = not exclusive) return ExprNodes.CoerceToLockedNode(obj, self.current_env(), rlock_only = not exclusive)
def __call__(self, root): def __call__(self, root):
self.locked = {} self.locked = {}
self.autolocks = 0
return super(CypclassLockTransform, self).__call__(root) return super(CypclassLockTransform, self).__call__(root)
def visit_Node(self, node): def visit_Node(self, node):
...@@ -495,6 +497,21 @@ class CypclassLockTransform(Visitor.EnvTransform): ...@@ -495,6 +497,21 @@ class CypclassLockTransform(Visitor.EnvTransform):
node.obj = self.lock(node.obj, exclusive=node.is_target) node.obj = self.lock(node.obj, exclusive=node.is_target)
return node return node
def visit_value(self, node):
if node is None:
return None
autolocks = self.autolocks
node = self.visit(node)
if self.autolocks > autolocks:
self.autolocks = 0
return node.coerce_to_temp(self.current_env())
return node
def visit_IndexNode(self, node):
node.index = self.visit_value(node.index)
node.base = self.visit(node.base)
return node
def visit_DelStatNode(self, node): def visit_DelStatNode(self, node):
for arg in node.args: for arg in node.args:
arg_entry = self.id(arg) arg_entry = self.id(arg)
...@@ -511,7 +528,8 @@ class CypclassLockTransform(Visitor.EnvTransform): ...@@ -511,7 +528,8 @@ class CypclassLockTransform(Visitor.EnvTransform):
# Disallow re-binding a locked name # Disallow re-binding a locked name
error(lhs.pos, "Assigning to a locked cypclass reference") error(lhs.pos, "Assigning to a locked cypclass reference")
return node return node
self.visitchildren(node) node.rhs = self.visit_value(node.rhs)
self.visitchildren(node, exclude=['rhs'])
return node return node
def visit_CascadedAssignmentNode(self, node): def visit_CascadedAssignmentNode(self, node):
...@@ -520,7 +538,8 @@ class CypclassLockTransform(Visitor.EnvTransform): ...@@ -520,7 +538,8 @@ class CypclassLockTransform(Visitor.EnvTransform):
# Disallow re-binding a locked name # Disallow re-binding a locked name
error(lhs.pos, "Assigning to a locked cypclass reference") error(lhs.pos, "Assigning to a locked cypclass reference")
return node return node
self.visitchildren(node) node.rhs = self.visit_value(node.rhs)
self.visitchildren(node, exclude=['rhs'])
return node return node
def visit_WithTargetAssignmentStatNode(self, node): def visit_WithTargetAssignmentStatNode(self, node):
......
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