1.1 --- a/lib/builtins.py Sat Mar 19 22:46:02 2011 +0100
1.2 +++ b/lib/builtins.py Sun Mar 20 23:00:45 2011 +0100
1.3 @@ -367,6 +367,7 @@
1.4 "Implementation of BaseException."
1.5
1.6 def __init__(self, *args):
1.7 + self._pc = None # remember where the exception occurred
1.8 self.args = args
1.9
1.10 class Exception(BaseException): pass
2.1 --- a/micropython/ast.py Sat Mar 19 22:46:02 2011 +0100
2.2 +++ b/micropython/ast.py Sun Mar 20 23:00:45 2011 +0100
2.3 @@ -38,10 +38,7 @@
2.4 LoadAddress, LoadAddressContext, LoadAddressContextCond,
2.5 LoadAttr, LoadAttrIndex, LoadAttrIndexContextCond
2.6 )
2.7 - attribute_store_instructions = (
2.8 - None, None, None,
2.9 - StoreAttr, StoreAttrIndex, None
2.10 - )
2.11 + # attribute_store_instructions are defined by the optimiser
2.12
2.13 # Name access instructions, for use with the appropriate handlers.
2.14
2.15 @@ -484,7 +481,7 @@
2.16
2.17 "Assign the assignment expression to the recipient 'node'."
2.18
2.19 - self._visitAttr(node, self.attribute_store_instructions)
2.20 + self._visitAttr(node, self.optimiser.get_attribute_store_instructions())
2.21 self.set_source()
2.22
2.23 def visitAssList(self, node):
3.1 --- a/micropython/data.py Sat Mar 19 22:46:02 2011 +0100
3.2 +++ b/micropython/data.py Sun Mar 20 23:00:45 2011 +0100
3.3 @@ -1226,12 +1226,23 @@
3.4 # Administrative methods.
3.5
3.6 def items_for_vacuum(self):
3.7 +
3.8 + "Consider both class and instance attributes for vacuuming."
3.9 +
3.10 items = []
3.11 for name in self.instattr:
3.12 items.append((name, None))
3.13 return NamespaceDict.items_for_vacuum(self) + items
3.14
3.15 def vacuum_item(self, name):
3.16 +
3.17 + "Vacuum 'name' from the class or instance attribute collections."
3.18 +
3.19 + # NOTE: Hack to prevent damage to exceptions.
3.20 +
3.21 + if name == "_pc":
3.22 + return 0
3.23 +
3.24 if not NamespaceDict.vacuum_item(self, name):
3.25 self.instattr.remove(name)
3.26 return 1
4.1 --- a/micropython/inspect.py Sat Mar 19 22:46:02 2011 +0100
4.2 +++ b/micropython/inspect.py Sun Mar 20 23:00:45 2011 +0100
4.3 @@ -296,6 +296,7 @@
4.4 """
4.5
4.6 module.set(name, self.expr, 0)
4.7 + self.use_specific_attribute(module.full_name(), name)
4.8
4.9 def store_class_attr(self, name, cls):
4.10
4.11 @@ -305,6 +306,7 @@
4.12 """
4.13
4.14 cls.set(name, self.expr, 0)
4.15 + self.use_specific_attribute(cls.full_name(), name)
4.16
4.17 def store_instance_attr(self, name):
4.18
4.19 @@ -315,7 +317,9 @@
4.20 # Current namespace is the function.
4.21 # Previous namespace is the class.
4.22
4.23 - self.namespaces[-2].add_instance_attribute(name)
4.24 + cls = self.namespaces[-2]
4.25 + cls.add_instance_attribute(name)
4.26 + self.use_specific_attribute(cls.full_name(), name)
4.27
4.28 def get_namespace(self):
4.29
4.30 @@ -609,12 +613,10 @@
4.31
4.32 elif isinstance(value, Module):
4.33 self.store_module_attr(attrname, value)
4.34 - self.use_specific_attribute(value.full_name(), attrname)
4.35 print "Warning: attribute %r of module %r set outside the module." % (node.attrname, expr.get_value().name)
4.36
4.37 elif isinstance(value, Class):
4.38 self.store_class_attr(attrname, value)
4.39 - self.use_specific_attribute(value.full_name(), attrname)
4.40
4.41 # Note usage of the attribute where a local is involved.
4.42
5.1 --- a/micropython/opt.py Sat Mar 19 22:46:02 2011 +0100
5.2 +++ b/micropython/opt.py Sun Mar 20 23:00:45 2011 +0100
5.3 @@ -57,6 +57,24 @@
5.4
5.5 self.active_value = None
5.6
5.7 + def get_attribute_store_instructions(self):
5.8 +
5.9 + """
5.10 + Return an appropriate set of instructions available when storing
5.11 + attributes.
5.12 + """
5.13 +
5.14 + ca = self.should_optimise_accesses_by_attribute_usage()
5.15 +
5.16 + return (
5.17 + ca and StoreAddress or None, # plain assignment
5.18 + ca and StoreAddressContext or None, # assignment via class
5.19 + ca and StoreAddressContext or None, # assignment via class (never via instance)
5.20 + StoreAttr, # assignment via instance
5.21 + StoreAttrIndex, # special assignment via instance
5.22 + None
5.23 + )
5.24 +
5.25 def reset(self):
5.26
5.27 "Reset the optimiser, clearing the active instructions."
6.1 --- a/micropython/trans.py Sat Mar 19 22:46:02 2011 +0100
6.2 +++ b/micropython/trans.py Sun Mar 20 23:00:45 2011 +0100
6.3 @@ -431,8 +431,11 @@
6.4
6.5 if attrname == "__class__":
6.6 if isinstance(target, Class):
6.7 - self.replace_active_value(LoadAddress(self.get_builtin("type", node)))
6.8 - return
6.9 + if AddressInstruction is LoadAddress:
6.10 + self.replace_active_value(LoadAddress(self.get_builtin("type", node)))
6.11 + return
6.12 + else:
6.13 + raise TranslateError("Assigning to __class__ is not permitted.")
6.14
6.15 # Access the object table to get the attribute.
6.16
7.1 --- a/rsvp.py Sat Mar 19 22:46:02 2011 +0100
7.2 +++ b/rsvp.py Sun Mar 20 23:00:45 2011 +0100
7.3 @@ -463,11 +463,7 @@
7.4 # Overwrite context if null.
7.5 context_value = self.value
7.6 source_value = self.source
7.7 - if source_value.context is ReplaceableContext:
7.8 - context = context_value.ref
7.9 - else:
7.10 - context = source_value.context
7.11 - self.save(self.operand, DataValue(context, source_value.ref))
7.12 + self._StoreAddressContext(self.operand, context_value, source_value)
7.13
7.14 def MakeInstance(self):
7.15 size = self.operand
7.16 @@ -545,8 +541,8 @@
7.17 attr_index, static_attr, offset = element
7.18 if attr_index == self.operand:
7.19 if static_attr:
7.20 - self.exception = self._MakeObject(Library.instance_size, self.type_error_instance)
7.21 - return self.RaiseException()
7.22 + self._StoreAddressContext(offset, value, self.source)
7.23 + return
7.24 else:
7.25 self.save(value.ref + offset, self.source)
7.26 return
7.27 @@ -864,6 +860,13 @@
7.28 else:
7.29 return DataValue(context, ref)
7.30
7.31 + def _StoreAddressContext(self, location, context_value, source_value):
7.32 + if source_value.context is ReplaceableContext:
7.33 + context = context_value.ref
7.34 + else:
7.35 + context = source_value.context
7.36 + self.save(location, DataValue(context, source_value.ref))
7.37 +
7.38 # Convenience functions.
7.39
7.40 def machine(program, with_builtins=0, debug=0, abort_upon_exception=0):
8.1 --- a/tests/attributes_class_assignment_unknown_alternatives.py Sat Mar 19 22:46:02 2011 +0100
8.2 +++ b/tests/attributes_class_assignment_unknown_alternatives.py Sun Mar 20 23:00:45 2011 +0100
8.3 @@ -7,16 +7,16 @@
8.4 class D:
8.5 clsattr = 321
8.6
8.7 -def f(cls):
8.8 +def f(cls, x):
8.9 cls.clsattr = 789
8.10 - if cls.clsattr:
8.11 + if x:
8.12 cls.clsattr2 = 234
8.13
8.14 -f(C)
8.15 -f(D)
8.16 +f(C, 1)
8.17 +f(D, 0) # prevent AttributeError
8.18
8.19 -result_789 = C.clsattr
8.20 -result_234 = C.clsattr2
8.21 -result_789 = D.clsattr
8.22 +result1_789 = C.clsattr
8.23 +result1_234 = C.clsattr2
8.24 +result2_789 = D.clsattr
8.25
8.26 # vim: tabstop=4 expandtab shiftwidth=4