# HG changeset patch # User Paul Boddie # Date 1373056543 -7200 # Node ID e429e4ff3b9899a2a56f1732f6b9dfd932fe8f36 # Parent 02feed1a9aa3022c097a6e37b565678e7789953e Reintroduced explicit address-oriented operations to syspython. (Although such operations may employ the parent of the accessed attribute and thus could support module/class-relative accesses, differentiating between such operations and instance-based accesses permits some flexibility in the syspython implementation.) Simplified the output representation of constant attributes. diff -r 02feed1a9aa3 -r e429e4ff3b98 docs/assignment.txt --- a/docs/assignment.txt Fri Jul 05 18:03:54 2013 +0200 +++ b/docs/assignment.txt Fri Jul 05 22:35:43 2013 +0200 @@ -74,9 +74,13 @@ known not constant -> instance LoadAddressContext (attribute may always be overridden) known not constant not known LoadAddressContextCond (perform context check) not known not known preserved LoadAttrIndex (attribute may have preserved context in all classes) - not known not known -> instance LoadAttrIndexContext (attribute may have overridden context in all classes) +* not known not known -> instance LoadAttrIndexContext (attribute may have overridden context in all classes) not known not known not known LoadAttrIndexContextCond (perform context check for class attribute access) +* Since knowing that an instance will replace the context might also mean + knowing the nature of the attribute, LoadAttrIndexContext is not likely to + be useful in practice. + Since the object table encodes sufficient information (an instance must be compatible to access the class attribute, and compatibility information is stored), an explicit compatibility test may not always be required at diff -r 02feed1a9aa3 -r e429e4ff3b98 docs/syspython.txt --- a/docs/syspython.txt Fri Jul 05 18:03:54 2013 +0200 +++ b/docs/syspython.txt Fri Jul 05 22:35:43 2013 +0200 @@ -188,18 +188,33 @@ In general, attribute access must use an explicit function indicating the kind of access operation being performed. For example: - # context effect + # Instance-related operations: + + loadattr(obj, attrname) # preserve context + + # Static attribute operations: - loadattr(obj, attrname) # preserve context - loadattrcontext(parent, attrname, obj) # replace context with obj - loadattrcontextcond(parent, attrname, obj) # run-time context decision + loadaddress(obj, attrname) # preserve context + loadaddresscontext(parent, attrname, obj) # replace context with obj + loadaddresscontextcond(parent, attrname, obj) # run-time context decision + + # Unoptimised operations: - loadattrindex(obj, attrname) # preserve context - loadattrindexcontextcond(obj, attrname) # run-time context decision + loadattrindex(obj, attrname) # preserve context + loadattrindexcontextcond(obj, attrname) # run-time context decision + + # Instance-related operations: + + storeattr(obj, attrname, value) # preserve context - storeattr(obj, attrname, value) # preserve context - storeattrcontext(parent, attrname, value, obj) # replace context with obj - storeattrindex(obj, attrname, value) + # Static attribute operations: + + storeaddress(parent, attrname, value) # preserve context + storeaddresscontext(parent, attrname, value, obj) # replace context with obj + + # Unoptimised operations: + + storeattrindex(obj, attrname, value) # preserve context Recall that for loadattrindex family functions, the location of the attribute is obtained from the object table and the nature of the attribute is diff -r 02feed1a9aa3 -r e429e4ff3b98 micropython/syspython.py --- a/micropython/syspython.py Fri Jul 05 18:03:54 2013 +0200 +++ b/micropython/syspython.py Fri Jul 05 22:35:43 2013 +0200 @@ -34,7 +34,6 @@ # Convenience definitions. -constant_attribute = compiler.ast.Getattr special_name = compiler.ast.Name def quoted_name(s): @@ -46,14 +45,17 @@ def module_attribute(module_name, attrname): return special_name(module_name + "." + attrname) +def constant_attribute(parent, attrname): + return compiler.ast.CallFunc("static", [quoted_name(parent.full_name() + "." + attrname)]) + # Special function names. # Some of the assignment operations cannot be supported unless attribute usage # observations are being made. -assattr_functions = ("storeattrcontext", "storeattrcontext", "storeattr", - "storeattrindex", None) -getattr_functions = ("loadattrcontext", "loadattrcontextcond", "loadattr", - "loadattrindex", "loadattrindexcontextcond") +assattr_functions = ("storeaddress", "storeaddresscontext", "storeaddresscontext", + "storeattr", "storeattrindex", None) +getattr_functions = ("loadaddress", "loadaddresscontext", "loadaddresscontextcond", + "loadattr", "loadattrindex", "loadattrindexcontextcond") # Source code classes. @@ -516,8 +518,8 @@ # Choose the appropriate special functions. - (opattrcontext, opattrcontextcond, opattr, - opattrindex, opattrindexcontextcond) = expr and assattr_functions or getattr_functions + (opaddress, opaddresscontext, opaddresscontextcond, + opattr, opattrindex, opattrindexcontextcond) = expr and assattr_functions or getattr_functions accessor = self.dispatch(node.expr) @@ -529,12 +531,24 @@ # Generate accesses via static objects and instances. if node._attr_deduced: - if node._set_context == "set": - op = opattrcontext - elif node._set_context == "cond": - op = opattrcontextcond + + # Static attributes may cause context replacement. + + if node._access_type == "static": + if node._set_context == "set": + op = opaddresscontext + elif node._set_context == "cond": + op = opaddresscontextcond + else: + op = opaddress + + parent = self._generateValue(node._attr_deduced.parent) + + # Non-static attributes. + else: op = opattr + parent = None # Handle unsupported operations. @@ -544,8 +558,7 @@ # Define the arguments: accessor, attribute name and optional value. args = [ - node._access_type == "static" and \ - self._generateValue(node._attr_deduced.parent) or accessor, + parent or accessor, special_name(node.attrname) ] @@ -988,7 +1001,7 @@ elif attr is not None and not isinstance(attr, Instance): if attr.is_constant(): - return constant_attribute(quoted_ref(attr.parent), node.name) + return constant_attribute(attr.parent, node.name) else: return compiler.ast.CallFunc( special_name("loadattr"),