# HG changeset patch # User Paul Boddie # Date 1481392374 -3600 # Node ID 22cf1ce6cfa74975b16025dfef57d84025846f70 # Parent 853edfa770e31cfb5880c0f3e3d7597719bab967 Introduced a separate variable for assignment accessors, preventing conflicts between assignment targets and assignment expressions. diff -r 853edfa770e3 -r 22cf1ce6cfa7 optimiser.py --- a/optimiser.py Sat Dec 10 17:35:58 2016 +0100 +++ b/optimiser.py Sat Dec 10 18:52:54 2016 +0100 @@ -375,6 +375,8 @@ # Determine whether the first access involves assignment. assigning = not traversed and not attrnames and final_method == "assign" + set_accessor = assigning and "__set_target_accessor" or "__set_accessor" + stored_accessor = assigning and "" or "" # Set the context if already available. @@ -385,8 +387,8 @@ # Prevent re-evaluation of any dynamic expression by storing it. if original_accessor == "": - emit(("__set_accessor", original_accessor)) - accessor = context_var = ("",) + emit((set_accessor, original_accessor)) + accessor = context_var = (stored_accessor,) else: accessor = context_var = (original_accessor,) @@ -397,8 +399,8 @@ # Prevent re-evaluation of any dynamic expression by storing it. if original_accessor == "": - emit(("__set_accessor", original_accessor)) - accessor = ("",) + emit((set_accessor, original_accessor)) + accessor = (stored_accessor,) else: accessor = (original_accessor,) diff -r 853edfa770e3 -r 22cf1ce6cfa7 templates/ops.h --- a/templates/ops.h Sat Dec 10 17:35:58 2016 +0100 +++ b/templates/ops.h Sat Dec 10 18:52:54 2016 +0100 @@ -73,6 +73,7 @@ #define __set_context(__ATTR) (__tmp_context = (__ATTR).value) #define __set_accessor(__ATTR) (__tmp_value = (__ATTR).value) +#define __set_target_accessor(__ATTR) (__tmp_target_value = (__ATTR).value) /* Basic structure tests. */ diff -r 853edfa770e3 -r 22cf1ce6cfa7 translator.py --- a/translator.py Sat Dec 10 17:35:58 2016 +0100 +++ b/translator.py Sat Dec 10 18:52:54 2016 +0100 @@ -647,20 +647,7 @@ def process_attribute_access(self, n): - """ - Process the given attribute access node 'n'. - - Where a name is provided, a single access should be recorded - involving potentially many attributes, thus providing a path to an - object. The remaining attributes are then accessed dynamically. - The remaining accesses could be deduced and computed, but they would - also need to be tested. - - Where no name is provided, potentially many accesses should be - recorded, one per attribute name. These could be used to provide - computed accesses, but the accessors would need to be tested in each - case. - """ + "Process the given attribute access node 'n'." # Obtain any completed chain and return the reference to it. @@ -684,6 +671,7 @@ "" : str(self.in_assignment), "" : "__tmp_context", "" : "__tmp_value", + "" : "__tmp_target_value", } output = [] @@ -1687,7 +1675,7 @@ targets = targets is not None and "__tmp_targets[%d], " % targets or "" - self.writeline("__ref __tmp_context, __tmp_value;") + self.writeline("__ref __tmp_context, __tmp_value, __tmp_target_value;") self.writeline("__attr %s__tmp_result;" % targets) self.writeline("__exc __tmp_exc;")