Commit f1f41e51 authored by Xavier Thompson's avatar Xavier Thompson

Fix automatic lock acquisition for inplace assignments

parent 097b08db
......@@ -438,6 +438,13 @@ class CypclassLockTransform(Visitor.EnvTransform):
return obj.entry
return None
def is_locked(self, obj):
try:
lock = self.locked[self.id(obj)]
return True
except:
return False
def lock(self, obj, exclusive=True):
try:
lock = self.locked[self.id(obj)]
......@@ -511,16 +518,18 @@ class CypclassLockTransform(Visitor.EnvTransform):
autolocks = self.autolocks
node = self.visit(node)
if self.autolocks > autolocks:
self.autolocks = autolocks
return node.coerce_to_temp(self.current_env())
return node
def visit_assignment(self, node):
def visit_assignment(self, node, rhs_attr='rhs'):
autowlocks = self.autowlocks
self.visitchildren(node, exclude=['rhs'])
self.visitchildren(node, exclude=[rhs_attr])
if self.autowlocks > autowlocks:
node.rhs = self.visit_value(node.rhs)
self.autowlocks = autowlocks
setattr(node, rhs_attr, self.visit_value(getattr(node, rhs_attr)))
else:
node.rhs = self.visit(node.rhs)
setattr(node, rhs_attr, self.visit(getattr(node, rhs_attr)))
def visit_SingleAssignmentNode(self, node):
lhs = node.lhs
......@@ -544,6 +553,23 @@ class CypclassLockTransform(Visitor.EnvTransform):
self.visit_assignment(node)
return node
def visit_BinopNode(self, node):
if node.inplace:
if not node.operator.endswith('='):
# operand1 will already be evaluated as lhs of assignment node.
operand1 = node.operand1
if operand1.is_attribute and operand1.obj.type.is_cyp_class and not self.is_locked(operand1.obj):
node.operand2 = self.visit_value(node.operand2)
else:
self.visitchildren(node, exclude=["operand1"])
else:
old, node.operand1.is_target = node.operand1.is_target, True
self.visit_assignment(node, rhs_attr="operand2")
node.operand1.is_target = old
else:
self.visitchildren(node)
return node
def visit_DelStatNode(self, node):
for arg in node.args:
arg_entry = self.id(arg)
......
......@@ -11530,7 +11530,7 @@ class BinopNode(ExprNode):
# - Determine result type and result code fragment.
# - Allocate temporary for result if needed.
subexprs = ['operand1', 'operand2']
subexprs = ['operand2', 'operand1']
inplace = False
op_func_type = None
......
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