# HG changeset patch # User Paul Boddie # Date 1693913607 -7200 # Node ID 06335a0e411366319ffbf4115086b8161d0cc28b # Parent 4e68e347740990566bbbb76eff27f559fda20df7 Prevent inadvertent object copying during __data__ attribute assignment. diff -r 4e68e3477409 -r 06335a0e4113 access_plan.py --- a/access_plan.py Tue Sep 05 01:32:12 2023 +0200 +++ b/access_plan.py Tue Sep 05 13:33:27 2023 +0200 @@ -241,12 +241,14 @@ attrname = self.get_first_attribute_name() assigning = self.assigning_first_attribute() + store = attrname != "__data__" and "__store_via_attr_ref" or "__store_via_attr_ref__" + # Access via the accessor's class. if self.first_method == "relative-class": if assigning: emit(("", ("__get_class_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__load_via_class", accessor, attrname) @@ -255,7 +257,7 @@ elif self.first_method == "relative-object": if assigning: emit(("", ("__get_object_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__load_via_object", accessor, attrname) @@ -280,7 +282,7 @@ elif self.first_method == "check-object": if assigning: emit(("", ("__check_and_get_object_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__check_and_load_via_object", accessor, attrname) @@ -290,7 +292,7 @@ elif self.first_method == "check-object-class": if assigning: emit(("", ("__check_and_get_object_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__check_and_load_via_any", accessor, attrname) @@ -334,16 +336,18 @@ if num_remaining > 1 or self.final_method in ("access", "access-invoke", "assign"): + store = attrname != "__data__" and "__store_via_attr_ref" or "__store_via_attr_ref__" + if traversal_mode == "class": if assigning: emit(("", ("__get_class_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__load_via_class", accessor, attrname) else: if assigning: emit(("", ("__get_object_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__load_via_object", accessor, attrname) @@ -392,11 +396,12 @@ # Constrain instructions involving certain special # attribute names. + store = attrname != "__data__" and "__store_via_attr_ref" or "__store_via_attr_ref__" to_search = attrname != "__data__" and "any" or "object" if assigning: emit(("", ("__check_and_get_object_attr_ref", accessor, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) else: accessor = ("__check_and_load_via_%s" % to_search, accessor, attrname) @@ -423,8 +428,9 @@ if self.final_method == "static-assign": parent, attrname = self.origin.rsplit(".", 1) + store = attrname != "__data__" and "__store_via_attr_ref" or "__store_via_attr_ref__" emit(("", ("__get_object_attr_ref", parent, attrname))) - emit(("__store_via_attr_ref", "", "")) + emit((store, "", "")) # Invoked attributes employ a separate context. diff -r 4e68e3477409 -r 06335a0e4113 transresults.py --- a/transresults.py Tue Sep 05 01:32:12 2023 +0200 +++ b/transresults.py Tue Sep 05 13:33:27 2023 +0200 @@ -101,6 +101,8 @@ if self.expr: + store = self.attrname != "__data__" and "__store_via_attr_ref" or "__store_via_attr_ref__" + # Eliminate assignments between constants. if self.static_ref and self.expr.static(): @@ -109,14 +111,14 @@ # Qualified names must be converted into parent-relative assignments. elif self.parent: - return "__store_via_attr_ref(__get_object_attr_ref(&%s, %s), %s)" % ( - encode_path(self.parent), self.attrname, self.expr) + return "%s(__get_object_attr_ref(&%s, %s), %s)" % ( + store, encode_path(self.parent), self.attrname, self.expr) # All other assignments involve the names as they were given. # To support value replacement, a special operation is used. else: - return "__set_attr(&%s, %s)" % (self.attrname, self.expr) + return "%s(&%s, %s)" % (store, self.attrname, self.expr) # Expressions.