micropython

Changeset

470:138fa7678c43
2011-09-12 Paul Boddie raw files shortlog changelog graph Filtered out unused classes from the descendants stored for each class in the object table. Especially for the 'object' class, this makes it possible to reduce the table substantially.
lib/builtins.py (file) micropython/__init__.py (file)
     1.1 --- a/lib/builtins.py	Sat Sep 10 20:33:52 2011 +0200
     1.2 +++ b/lib/builtins.py	Mon Sep 12 23:08:54 2011 +0200
     1.3 @@ -789,7 +789,7 @@
     1.4  function
     1.5  AttributeError
     1.6  #IndexError
     1.7 -#NoneType
     1.8 +NoneType
     1.9  NotImplementedType
    1.10  #StopIteration
    1.11  TypeError
     2.1 --- a/micropython/__init__.py	Sat Sep 10 20:33:52 2011 +0200
     2.2 +++ b/micropython/__init__.py	Mon Sep 12 23:08:54 2011 +0200
     2.3 @@ -38,8 +38,8 @@
     2.4  """
     2.5  
     2.6  from micropython.common import *
     2.7 +from micropython.data import *
     2.8  import micropython.ast
     2.9 -import micropython.data
    2.10  import micropython.opt
    2.11  import micropython.inspect
    2.12  import micropython.table
    2.13 @@ -143,7 +143,7 @@
    2.14              # Append classes and functions to the image.
    2.15  
    2.16              for obj in module.all_objects:
    2.17 -                if isinstance(obj, micropython.data.Class):
    2.18 +                if isinstance(obj, Class):
    2.19  
    2.20                      # Add header details.
    2.21  
    2.22 @@ -169,7 +169,7 @@
    2.23                      # level, and the code location is set within the code
    2.24                      # generation process for the module.
    2.25  
    2.26 -                elif isinstance(obj, micropython.data.Function):
    2.27 +                elif isinstance(obj, Function):
    2.28  
    2.29                      # Add header details.
    2.30  
    2.31 @@ -264,35 +264,53 @@
    2.32          if self.objtable is None or reset:
    2.33  
    2.34              t = self.objtable = micropython.table.ObjectTable()
    2.35 +
    2.36 +            # First, get all active modules and classes.
    2.37 +
    2.38 +            all_objects = set()
    2.39 +
    2.40              for module in self.importer.get_modules():
    2.41 +                all_objects.add(module)
    2.42 +                for obj in module.all_objects:
    2.43 +                    if isinstance(obj, Class):
    2.44 +                        all_objects.add(obj)
    2.45 +
    2.46 +            # Then, visit the modules and classes.
    2.47 +
    2.48 +            for obj in all_objects:
    2.49  
    2.50                  # Add module attributes and module identity information.
    2.51  
    2.52 -                full_name = module.full_name()
    2.53 -                attributes = {full_name : module}
    2.54 -                attributes.update(module.module_attributes())
    2.55 -                t.add(full_name, attributes)
    2.56 +                if isinstance(obj, Module):
    2.57 +                    full_name = obj.full_name()
    2.58 +                    attributes = {full_name : obj}
    2.59 +                    attributes.update(obj.module_attributes())
    2.60 +                    t.add(full_name, attributes)
    2.61  
    2.62                  # Add class and instance attributes for all classes, together
    2.63                  # with descendant information.
    2.64  
    2.65 -                for obj in module.all_objects:
    2.66 -                    if isinstance(obj, micropython.data.Class):
    2.67 +                elif isinstance(obj, Class):
    2.68 +
    2.69 +                    # Prevent ambiguous classes.
    2.70  
    2.71 -                        # Prevent ambiguous classes.
    2.72 +                    full_name = obj.full_name()
    2.73  
    2.74 -                        full_name = obj.full_name()
    2.75 +                    #if obj.module.has_key(name) and obj.module[name].defines_ambiguous_class():
    2.76 +                    #    raise TableGenerationError, "Class %r in module %r is ambiguously defined." % (name, obj.module.full_name())
    2.77 +
    2.78 +                    # Define a table entry for the class.
    2.79  
    2.80 -                        #name = obj.name
    2.81 -                        #if module.has_key(name) and module[name].defines_ambiguous_class():
    2.82 -                        #    raise TableGenerationError, "Class %r in module %r is ambiguously defined." % (name, module.full_name())
    2.83 +                    attributes = {full_name : obj}
    2.84 +                    attributes.update(obj.all_attributes())
    2.85 +
    2.86 +                    # Filter out unused classes.
    2.87  
    2.88 -                        # Define a table entry for the class.
    2.89 +                    for name, descendant in obj.all_descendants().items():
    2.90 +                        if descendant in all_objects:
    2.91 +                            attributes[name] = descendant
    2.92  
    2.93 -                        attributes = {full_name : obj}
    2.94 -                        attributes.update(obj.all_attributes())
    2.95 -                        attributes.update(obj.all_descendants())
    2.96 -                        t.add(full_name, attributes)
    2.97 +                    t.add(full_name, attributes)
    2.98  
    2.99          return self.objtable
   2.100  
   2.101 @@ -309,14 +327,14 @@
   2.102  
   2.103              for module in self.importer.get_modules():
   2.104                  for obj in module.all_objects:
   2.105 -                    if isinstance(obj, micropython.data.Function):
   2.106 +                    if isinstance(obj, Function):
   2.107                          t.add(obj.full_name(), obj.parameters())
   2.108  
   2.109                      # Classes are callable, too.
   2.110                      # Take details of the appropriate __init__ method to make an
   2.111                      # entry for an instantiation function for the class.
   2.112  
   2.113 -                    elif isinstance(obj, micropython.data.Class):
   2.114 +                    elif isinstance(obj, Class):
   2.115                          t.add(obj.get_instantiator().full_name(), obj.get_instantiator().parameters())
   2.116  
   2.117              # Filter out all parameter table entries not referenced by keyword
   2.118 @@ -692,7 +710,7 @@
   2.119                      parent = attr.parent
   2.120                      if parent is None:
   2.121                          continue
   2.122 -                    elif isinstance(parent, micropython.data.Instance):
   2.123 +                    elif isinstance(parent, Instance):
   2.124                          parentname = objname
   2.125                      else:
   2.126                          parentname = parent.full_name()
   2.127 @@ -706,11 +724,11 @@
   2.128                          # NOTE: Here, an instance actually represents any kind
   2.129                          # NOTE: of object.
   2.130  
   2.131 -                        if isinstance(parent, micropython.data.Instance):
   2.132 +                        if isinstance(parent, Instance):
   2.133                              for attrvalue in attrvalues:
   2.134                                  for name in objtable.any_possible_objects([attrname]):
   2.135                                      parent = objtable.access(name, name)
   2.136 -                                    if not isinstance(parent, micropython.data.Class) or \
   2.137 +                                    if not isinstance(parent, Class) or \
   2.138                                          not parent.instance_attributes().has_key(attrname):
   2.139                                          parent.set(attrname, attrvalue, 0)
   2.140                          else:
   2.141 @@ -759,7 +777,7 @@
   2.142  
   2.143          "Return a constant for the given 'value'."
   2.144  
   2.145 -        const = micropython.data.Const(value)
   2.146 +        const = Const(value)
   2.147          return self.constant_values[const]
   2.148  
   2.149      def get_constant_type_name(self, value):
   2.150 @@ -774,7 +792,7 @@
   2.151  
   2.152          # Make a constant object and return it.
   2.153  
   2.154 -        const = micropython.data.Const(value)
   2.155 +        const = Const(value)
   2.156          if not self.constant_values.has_key(const):
   2.157              self.constant_values[const] = const
   2.158          return self.constant_values[const]