1.1 --- a/docs/assignment.txt Fri Jul 05 18:03:54 2013 +0200
1.2 +++ b/docs/assignment.txt Fri Jul 05 22:35:43 2013 +0200
1.3 @@ -74,9 +74,13 @@
1.4 known not constant -> instance LoadAddressContext (attribute may always be overridden)
1.5 known not constant not known LoadAddressContextCond (perform context check)
1.6 not known not known preserved LoadAttrIndex (attribute may have preserved context in all classes)
1.7 - not known not known -> instance LoadAttrIndexContext (attribute may have overridden context in all classes)
1.8 +* not known not known -> instance LoadAttrIndexContext (attribute may have overridden context in all classes)
1.9 not known not known not known LoadAttrIndexContextCond (perform context check for class attribute access)
1.10
1.11 +* Since knowing that an instance will replace the context might also mean
1.12 + knowing the nature of the attribute, LoadAttrIndexContext is not likely to
1.13 + be useful in practice.
1.14 +
1.15 Since the object table encodes sufficient information (an instance must be
1.16 compatible to access the class attribute, and compatibility information is
1.17 stored), an explicit compatibility test may not always be required at
2.1 --- a/docs/syspython.txt Fri Jul 05 18:03:54 2013 +0200
2.2 +++ b/docs/syspython.txt Fri Jul 05 22:35:43 2013 +0200
2.3 @@ -188,18 +188,33 @@
2.4 In general, attribute access must use an explicit function indicating the
2.5 kind of access operation being performed. For example:
2.6
2.7 - # context effect
2.8 + # Instance-related operations:
2.9 +
2.10 + loadattr(obj, attrname) # preserve context
2.11 +
2.12 + # Static attribute operations:
2.13
2.14 - loadattr(obj, attrname) # preserve context
2.15 - loadattrcontext(parent, attrname, obj) # replace context with obj
2.16 - loadattrcontextcond(parent, attrname, obj) # run-time context decision
2.17 + loadaddress(obj, attrname) # preserve context
2.18 + loadaddresscontext(parent, attrname, obj) # replace context with obj
2.19 + loadaddresscontextcond(parent, attrname, obj) # run-time context decision
2.20 +
2.21 + # Unoptimised operations:
2.22
2.23 - loadattrindex(obj, attrname) # preserve context
2.24 - loadattrindexcontextcond(obj, attrname) # run-time context decision
2.25 + loadattrindex(obj, attrname) # preserve context
2.26 + loadattrindexcontextcond(obj, attrname) # run-time context decision
2.27 +
2.28 + # Instance-related operations:
2.29 +
2.30 + storeattr(obj, attrname, value) # preserve context
2.31
2.32 - storeattr(obj, attrname, value) # preserve context
2.33 - storeattrcontext(parent, attrname, value, obj) # replace context with obj
2.34 - storeattrindex(obj, attrname, value)
2.35 + # Static attribute operations:
2.36 +
2.37 + storeaddress(parent, attrname, value) # preserve context
2.38 + storeaddresscontext(parent, attrname, value, obj) # replace context with obj
2.39 +
2.40 + # Unoptimised operations:
2.41 +
2.42 + storeattrindex(obj, attrname, value) # preserve context
2.43
2.44 Recall that for loadattrindex family functions, the location of the attribute
2.45 is obtained from the object table and the nature of the attribute is
3.1 --- a/micropython/syspython.py Fri Jul 05 18:03:54 2013 +0200
3.2 +++ b/micropython/syspython.py Fri Jul 05 22:35:43 2013 +0200
3.3 @@ -34,7 +34,6 @@
3.4
3.5 # Convenience definitions.
3.6
3.7 -constant_attribute = compiler.ast.Getattr
3.8 special_name = compiler.ast.Name
3.9
3.10 def quoted_name(s):
3.11 @@ -46,14 +45,17 @@
3.12 def module_attribute(module_name, attrname):
3.13 return special_name(module_name + "." + attrname)
3.14
3.15 +def constant_attribute(parent, attrname):
3.16 + return compiler.ast.CallFunc("static", [quoted_name(parent.full_name() + "." + attrname)])
3.17 +
3.18 # Special function names.
3.19 # Some of the assignment operations cannot be supported unless attribute usage
3.20 # observations are being made.
3.21
3.22 -assattr_functions = ("storeattrcontext", "storeattrcontext", "storeattr",
3.23 - "storeattrindex", None)
3.24 -getattr_functions = ("loadattrcontext", "loadattrcontextcond", "loadattr",
3.25 - "loadattrindex", "loadattrindexcontextcond")
3.26 +assattr_functions = ("storeaddress", "storeaddresscontext", "storeaddresscontext",
3.27 + "storeattr", "storeattrindex", None)
3.28 +getattr_functions = ("loadaddress", "loadaddresscontext", "loadaddresscontextcond",
3.29 + "loadattr", "loadattrindex", "loadattrindexcontextcond")
3.30
3.31 # Source code classes.
3.32
3.33 @@ -516,8 +518,8 @@
3.34
3.35 # Choose the appropriate special functions.
3.36
3.37 - (opattrcontext, opattrcontextcond, opattr,
3.38 - opattrindex, opattrindexcontextcond) = expr and assattr_functions or getattr_functions
3.39 + (opaddress, opaddresscontext, opaddresscontextcond,
3.40 + opattr, opattrindex, opattrindexcontextcond) = expr and assattr_functions or getattr_functions
3.41
3.42 accessor = self.dispatch(node.expr)
3.43
3.44 @@ -529,12 +531,24 @@
3.45 # Generate accesses via static objects and instances.
3.46
3.47 if node._attr_deduced:
3.48 - if node._set_context == "set":
3.49 - op = opattrcontext
3.50 - elif node._set_context == "cond":
3.51 - op = opattrcontextcond
3.52 +
3.53 + # Static attributes may cause context replacement.
3.54 +
3.55 + if node._access_type == "static":
3.56 + if node._set_context == "set":
3.57 + op = opaddresscontext
3.58 + elif node._set_context == "cond":
3.59 + op = opaddresscontextcond
3.60 + else:
3.61 + op = opaddress
3.62 +
3.63 + parent = self._generateValue(node._attr_deduced.parent)
3.64 +
3.65 + # Non-static attributes.
3.66 +
3.67 else:
3.68 op = opattr
3.69 + parent = None
3.70
3.71 # Handle unsupported operations.
3.72
3.73 @@ -544,8 +558,7 @@
3.74 # Define the arguments: accessor, attribute name and optional value.
3.75
3.76 args = [
3.77 - node._access_type == "static" and \
3.78 - self._generateValue(node._attr_deduced.parent) or accessor,
3.79 + parent or accessor,
3.80 special_name(node.attrname)
3.81 ]
3.82
3.83 @@ -988,7 +1001,7 @@
3.84
3.85 elif attr is not None and not isinstance(attr, Instance):
3.86 if attr.is_constant():
3.87 - return constant_attribute(quoted_ref(attr.parent), node.name)
3.88 + return constant_attribute(attr.parent, node.name)
3.89 else:
3.90 return compiler.ast.CallFunc(
3.91 special_name("loadattr"),