1.1 --- a/micropython/__init__.py Mon Aug 25 02:04:10 2008 +0200
1.2 +++ b/micropython/__init__.py Wed Aug 27 00:43:33 2008 +0200
1.3 @@ -232,9 +232,16 @@
1.4 t = self.objtable = micropython.table.ObjectTable()
1.5 for module in self.get_modules():
1.6 t.add(module.full_name(), module.module_attributes())
1.7 +
1.8 + # Add class and instance attributes for all classes, together
1.9 + # with descendant information.
1.10 +
1.11 for obj in module.all_objects:
1.12 if isinstance(obj, micropython.inspect.Class):
1.13 - t.add(obj.full_name(), obj.all_attributes())
1.14 + attributes = {obj.full_name() : obj}
1.15 + attributes.update(obj.all_attributes())
1.16 + attributes.update(obj.all_descendants())
1.17 + t.add(obj.full_name(), attributes)
1.18
1.19 return self.objtable
1.20
2.1 --- a/micropython/data.py Mon Aug 25 02:04:10 2008 +0200
2.2 +++ b/micropython/data.py Wed Aug 27 00:43:33 2008 +0200
2.3 @@ -457,6 +457,12 @@
2.4 def has_subclass(self, other):
2.5 return other in self.descendants
2.6
2.7 + def all_descendants(self):
2.8 + d = {}
2.9 + for cls in self.descendants:
2.10 + d[cls.full_name()] = cls
2.11 + return d
2.12 +
2.13 "Return the attribute names provided by this class only."
2.14
2.15 class_attribute_names = NamespaceDict.keys
3.1 --- a/micropython/table.py Mon Aug 25 02:04:10 2008 +0200
3.2 +++ b/micropython/table.py Wed Aug 27 00:43:33 2008 +0200
3.3 @@ -20,6 +20,7 @@
3.4 """
3.5
3.6 from micropython.common import *
3.7 +from micropython.data import *
3.8
3.9 class List:
3.10
3.11 @@ -55,8 +56,8 @@
3.12
3.13 element = self.displaced[obj_offset + attr_index]
3.14 if element is not None:
3.15 - offset, details = element
3.16 - if offset == obj_offset:
3.17 + index, details = element
3.18 + if index == attr_index:
3.19 return details
3.20
3.21 return None
3.22 @@ -126,11 +127,14 @@
3.23 for i in xrange(0, offset + len(attributes) - len_displaced):
3.24 self.displaced.append(None)
3.25
3.26 - # Record the offset and attribute details in the list.
3.27 + # Record the attribute details in the list.
3.28
3.29 for i, attr in enumerate(attributes):
3.30 if attr is not None:
3.31 - self.displaced[offset+i] = offset, attr
3.32 +
3.33 + # Each entry is of the form (attribute number, attribute).
3.34 +
3.35 + self.displaced[offset+i] = i, attr
3.36
3.37 # Image production.
3.38
3.39 @@ -152,7 +156,12 @@
3.40 "An object list."
3.41
3.42 def entry_as_raw(self, entry):
3.43 - offset, attr = entry
3.44 + attr_index, attr = entry
3.45 +
3.46 + # Support descendants.
3.47 +
3.48 + if isinstance(attr, Class):
3.49 + return attr_index
3.50
3.51 if attr.parent is not None:
3.52 location = attr.parent.location or 0
3.53 @@ -163,9 +172,9 @@
3.54 else:
3.55 position = None # NOTE: Should fix unpositioned attributes.
3.56
3.57 - # Class offset/code, attribute type, context instance override flag, location/position.
3.58 + # Attribute index/code, attribute type, context instance override flag, location/position.
3.59
3.60 - return (offset, attr.is_class_attribute(), attr.defined_within_hierarchy(), position)
3.61 + return (attr_index, attr.is_class_attribute(), attr.defined_within_hierarchy(), position)
3.62
3.63 class ParameterList(List):
3.64
3.65 @@ -295,7 +304,18 @@
3.66
3.67 # Visit each row of the matrix.
3.68
3.69 + matrix_by_usage = []
3.70 + size = len(self.attributes)
3.71 +
3.72 + # Add rows in descending order of utilisation.
3.73 +
3.74 for objname, attributes in self.as_matrix().items():
3.75 + matrix_by_usage.append((size - attributes.count(None), objname, attributes))
3.76 +
3.77 + matrix_by_usage.sort()
3.78 + matrix_by_usage.reverse()
3.79 +
3.80 + for usage, objname, attributes in matrix_by_usage:
3.81 self.displaced_list.add(objname, attributes)
3.82
3.83 return self.displaced_list
4.1 --- a/rsvp.py Mon Aug 25 02:04:10 2008 +0200
4.2 +++ b/rsvp.py Wed Aug 27 00:43:33 2008 +0200
4.3 @@ -253,8 +253,8 @@
4.4 context, ref = self.value
4.5 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.6 element = self.objtable[classcode + self.operand]
4.7 - found_code, class_attr, replace_context, offset = element
4.8 - if found_code == classcode:
4.9 + attr_index, class_attr, replace_context, offset = element
4.10 + if attr_index == self.operand:
4.11 if class_attr:
4.12 loaded_context, loaded_ref = self.load(offset) # offset is address of class attribute
4.13 if replace_context:
4.14 @@ -271,8 +271,8 @@
4.15 context, ref = self.value
4.16 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.17 element = self.objtable[classcode + self.operand]
4.18 - found_code, class_attr, replace_context, offset = element
4.19 - if found_code == classcode:
4.20 + attr_index, class_attr, replace_context, offset = element
4.21 + if attr_index == self.operand:
4.22 if class_attr:
4.23 # NOTE: This should cause an attribute or type error.
4.24 # Class attributes cannot be changed at run-time.
4.25 @@ -302,8 +302,8 @@
4.26 frame = self.invocation_sp_stack[-1] # different from the current frame after MakeFrame
4.27 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.28 element = self.objtable[classcode + self.operand]
4.29 - found_code, offset = element
4.30 - if found_code == classcode:
4.31 + attr_index, offset = element
4.32 + if attr_index == self.operand:
4.33 self.frame_stack[frame + offset] = self.value
4.34 else:
4.35 # NOTE: This should cause an argument error.
4.36 @@ -349,11 +349,17 @@
4.37 def CheckSelf(self):
4.38 context, ref = self.value
4.39 target_context, target_ref = self.source
4.40 +
4.41 + # Load the details of the proposed context and the target's context.
4.42 +
4.43 classcode, attrcode, codeaddr, codedetails = self.load(ref)
4.44 target_classcode, target_attrcode, target_codeaddr, target_codedetails = self.load(target_context)
4.45 +
4.46 + # Find the table entry for the descendant.
4.47 +
4.48 element = self.objtable[target_classcode + attrcode]
4.49 - found_code, class_attr, replace_context, offset = element
4.50 - if found_code == target_classcode:
4.51 + attr_index, class_attr, replace_context, offset = element
4.52 + if attr_index == attrcode:
4.53 self.status = 1
4.54 else:
4.55 self.status = 0
5.1 --- a/test.py Mon Aug 25 02:04:10 2008 +0200
5.2 +++ b/test.py Wed Aug 27 00:43:33 2008 +0200
5.3 @@ -21,6 +21,12 @@
5.4 for i, x in enumerate(code):
5.5 print i, x
5.6
5.7 +def show_table_usage(raw_table, slice_size=100):
5.8 + for x in xrange(0, len(raw_table), slice_size):
5.9 + table_slice = raw_table[x:x+slice_size]
5.10 + print "%6d" % (len(table_slice) - table_slice.count(None)), \
5.11 + "".join(entry and "#" or "_" for entry in table_slice)
5.12 +
5.13 def machine(importer):
5.14 rc = raw(importer.code)
5.15 rm = rsvp.RSVPMachine(rc)