1.1 --- a/docs/optimisations.txt Sun Nov 22 21:21:41 2009 +0100
1.2 +++ b/docs/optimisations.txt Sun Nov 22 22:53:24 2009 +0100
1.3 @@ -228,7 +228,7 @@
1.4 result would resemble the following:
1.5
1.6 def f(x, y):
1.7 - if not isinstance(x, C):
1.8 + if not isinstance(x, C) and x is not C:
1.9 raise TypeError
1.10 x.method(y)
1.11 if x.something:
2.1 --- a/micropython/__init__.py Sun Nov 22 21:21:41 2009 +0100
2.2 +++ b/micropython/__init__.py Sun Nov 22 22:53:24 2009 +0100
2.3 @@ -447,16 +447,17 @@
2.4 self.name_references[from_name] = set()
2.5 self.name_references[from_name].add(names)
2.6
2.7 - def use_specific_name(self, specific_name, from_name):
2.8 + def use_specific_name(self, objname, attrname, from_name):
2.9
2.10 """
2.11 - Register the given 'specific_name' for an object as being used in the
2.12 - program from within an object with the specified 'from_name'.
2.13 + Register the given 'objname' (for an object) whose 'attrname' is being
2.14 + used in the program from within an object with the specified
2.15 + 'from_name'.
2.16 """
2.17
2.18 if not self.specific_name_references.has_key(from_name):
2.19 self.specific_name_references[from_name] = set()
2.20 - self.specific_name_references[from_name].add(specific_name)
2.21 + self.specific_name_references[from_name].add((objname, attrname))
2.22
2.23 # Name accounting products.
2.24
2.25 @@ -517,9 +518,9 @@
2.26
2.27 # Get specific name references and visit the referenced objects.
2.28
2.29 - for name in self.specific_name_references.get(from_name, []):
2.30 - self.use_attribute(from_name, name)
2.31 - self._collect_attributes(from_name + "." + name, objtable)
2.32 + for objname, attrname in self.specific_name_references.get(from_name, []):
2.33 + self.use_attribute(objname, attrname)
2.34 + self._collect_attributes(objname + "." + attrname, objtable)
2.35
2.36 # Constant accounting.
2.37
3.1 --- a/micropython/data.py Sun Nov 22 21:21:41 2009 +0100
3.2 +++ b/micropython/data.py Sun Nov 22 22:53:24 2009 +0100
3.3 @@ -289,14 +289,6 @@
3.4
3.5 # Attribute usage methods.
3.6
3.7 - def get_active_attributes(self):
3.8 -
3.9 - """
3.10 - Return attributes on this object that are actually used.
3.11 - """
3.12 -
3.13 - return self.attributes_used[-1].get(None, [])
3.14 -
3.15 def get_all_attribute_usage(self):
3.16
3.17 """
3.18 @@ -309,6 +301,9 @@
3.19 usage.add(tuple(names))
3.20 return usage
3.21
3.22 + def use_attribute(self, name, attrname):
3.23 + return self._use_attribute(name, attrname)
3.24 +
3.25 # These shadow various methods in the InspectedModule class, and provide
3.26 # implementations generally.
3.27
4.1 --- a/micropython/inspect.py Sun Nov 22 21:21:41 2009 +0100
4.2 +++ b/micropython/inspect.py Sun Nov 22 22:53:24 2009 +0100
4.3 @@ -186,8 +186,6 @@
4.4
4.5 for names in namespace.get_all_attribute_usage():
4.6 self.importer.use_names(names, namespace.full_name())
4.7 - for name in namespace.get_active_attributes():
4.8 - self.importer.use_specific_name(name, namespace.full_name())
4.9
4.10 def vacuum(self):
4.11
4.12 @@ -237,8 +235,7 @@
4.13 "Finalise the module."
4.14
4.15 for obj in self.all_objects:
4.16 - if isinstance(obj, (Class, Function)): # NOTE: Perhaps not required.
4.17 - obj.finalise_attributes(reset=1)
4.18 + obj.finalise_attributes(reset=1)
4.19
4.20 def add_object(self, obj, any_scope=0):
4.21
4.22 @@ -349,6 +346,14 @@
4.23 def use_attribute(self, name, attrname):
4.24 return self.get_namespace()._use_attribute(name, attrname)
4.25
4.26 + # Specific attribute usage, nominating specific attributes which can be
4.27 + # resolved during inspection.
4.28 +
4.29 + def use_specific_attribute(self, objname, attrname):
4.30 + from_name = self.get_namespace().full_name()
4.31 + objname = objname or from_name
4.32 + self.importer.use_specific_name(objname, attrname, from_name)
4.33 +
4.34 # Visitor methods.
4.35
4.36 def default(self, node, *args):
4.37 @@ -478,7 +483,7 @@
4.38 self.store_module_attr(node.attrname, expr.get_value())
4.39 print "Warning: attribute %r of module %r set outside the module." % (node.attrname, expr.get_value().name)
4.40
4.41 - # Note usage of the attribute.
4.42 + # Note usage of the attribute where a local is involved.
4.43
4.44 if expr.parent is self.get_namespace():
4.45 node._attrnames = self.use_attribute(expr.name, node.attrname)
4.46 @@ -504,7 +509,10 @@
4.47
4.48 self.store(node.name, self.expr)
4.49 self.define_attribute_user(node)
4.50 - self.use_attribute(None, node.name) # ensure the presence of the given name
4.51 +
4.52 + # Ensure the presence of the given name in this namespace.
4.53 +
4.54 + self.use_specific_attribute(None, node.name)
4.55 return None
4.56
4.57 visitAssTuple = visitAssList
4.58 @@ -681,7 +689,7 @@
4.59
4.60 for name, alias in node.names:
4.61 if name != "*":
4.62 - if module is not None and module.namespace.has_key(name):
4.63 + if module is not None and module.has_key(name):
4.64 attr = module[name]
4.65 self.store(alias or name, attr)
4.66 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
4.67 @@ -693,7 +701,7 @@
4.68 self.store(alias or name, UnresolvedName(name, node.modname, self))
4.69 else:
4.70 if module is not None:
4.71 - for n in module.namespace.keys():
4.72 + for n in module.keys():
4.73 attr = module[n]
4.74 self.store(n, attr)
4.75 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
4.76 @@ -720,27 +728,32 @@
4.77
4.78 if isinstance(expr, Attr):
4.79 value = expr.get_value()
4.80 +
4.81 + # Get the attribute and record its usage.
4.82 +
4.83 if isinstance(value, (Class, Module)):
4.84 - attr = value.namespace.get(attrname)
4.85 + attr = value.get(attrname)
4.86 + self.use_specific_attribute(value.full_name(), attrname)
4.87 +
4.88 elif isinstance(value, UnresolvedName):
4.89 attr = UnresolvedName(attrname, value.full_name(), self)
4.90 +
4.91 else:
4.92 attr = None
4.93
4.94 - # Note usage of the attribute.
4.95 + # Note usage of the attribute where a local is involved.
4.96
4.97 - if expr.parent is self.get_namespace():
4.98 - node._attrnames = self.use_attribute(expr.name, attrname)
4.99 - else:
4.100 - self.use_name(attrname)
4.101 + if expr.parent is self.get_namespace():
4.102 + node._attrnames = self.use_attribute(expr.name, attrname)
4.103 + else:
4.104 + self.use_name(attrname)
4.105
4.106 elif self.builtins is not None:
4.107 attr = self.builtins.get(attrname)
4.108 - self.use_name(attrname)
4.109 + self.use_specific_attribute(self.builtins.full_name(), attrname)
4.110
4.111 else:
4.112 attr = UnresolvedName(attrname, value.full_name(), self)
4.113 - self.use_name(attrname)
4.114
4.115 return attr
4.116
4.117 @@ -837,7 +850,7 @@
4.118
4.119 # Note usage of the local (potentially a class attribute).
4.120
4.121 - node._attrnames = self.use_attribute(None, name)
4.122 + self.use_specific_attribute(None, name)
4.123
4.124 # Globals.
4.125
4.126 @@ -846,16 +859,13 @@
4.127
4.128 # Note usage of the module attribute.
4.129
4.130 - node._attrnames = self.use_attribute(None, name)
4.131 + self.use_specific_attribute(self.full_name(), name)
4.132
4.133 # Builtins.
4.134
4.135 elif self.builtins is not None and self.builtins.has_key(name):
4.136 attr = self.builtins[name]
4.137 -
4.138 - # Note usage of the module attribute.
4.139 -
4.140 - node._attrnames = self.builtins.use_attribute(None, name)
4.141 + self.use_specific_attribute(self.builtins.full_name(), name)
4.142
4.143 # Unknown.
4.144
5.1 --- a/micropython/rsvp.py Sun Nov 22 21:21:41 2009 +0100
5.2 +++ b/micropython/rsvp.py Sun Nov 22 22:53:24 2009 +0100
5.3 @@ -433,7 +433,7 @@
5.4
5.5 class CheckContext(Instruction): "Check to see if the context is valid."
5.6 class CheckClass(Instruction): "Check the current value to determine whether it is a class."
5.7 -class CheckSelf(Instruction): "Check the first argument of an invocation against the target."
5.8 +class CheckInstance(Instruction): "Check the current value as an instance of a specific class (used with 'self' in an invocation)."
5.9
5.10 # Access to frames upon invocation.
5.11
5.12 @@ -496,7 +496,7 @@
5.13 StoreFrameIndex, # as the object being referenced
5.14 StoreAddressContext, # as the context
5.15 LoadCallable,
5.16 - TestIdentity, TestIdentityAddress, CheckSelf, # as one of the operands
5.17 + TestIdentity, TestIdentityAddress, CheckInstance, # as one of the operands
5.18 CheckException, CheckFrame, FillDefaults,
5.19 MakeInstance,
5.20 CheckContext, CheckClass,
6.1 --- a/micropython/trans.py Sun Nov 22 21:21:41 2009 +0100
6.2 +++ b/micropython/trans.py Sun Nov 22 22:53:24 2009 +0100
6.3 @@ -336,12 +336,23 @@
6.4
6.5 after_test_block = self.new_block()
6.6
6.7 + self.new_op(LoadClass(attr))
6.8 + temp_target = self.optimiser.optimise_temp_storage()
6.9 +
6.10 + # Generate name is target (for classes).
6.11 +
6.12 + self.dispatch(compiler.ast.Name(name))
6.13 + self.new_op(TestIdentity())
6.14 + self.optimiser.set_source(temp_target)
6.15 +
6.16 + # Jump to the next guard or the code if successful.
6.17 +
6.18 + self.new_op(JumpIfTrue(after_test_block))
6.19 +
6.20 # Generate isinstance(name, target).
6.21
6.22 - self.new_op(LoadClass(attr))
6.23 - temp_target = self.optimiser.optimise_temp_storage()
6.24 self.dispatch(compiler.ast.Name(name))
6.25 - self.new_op(CheckSelf()) # NOTE: Should be CheckInstance.
6.26 + self.new_op(CheckInstance())
6.27 self.optimiser.set_source(temp_target)
6.28
6.29 # Jump to the next guard or the code if successful.
6.30 @@ -922,7 +933,7 @@
6.31 # Check the current value (the argument) against the known context
6.32 # (given as the source).
6.33
6.34 - self.new_op(CheckSelf())
6.35 + self.new_op(CheckInstance())
6.36 self.optimiser.set_source(temp_context)
6.37
6.38 self.new_op(JumpIfTrue(adjust_block))
7.1 --- a/rsvp.py Sun Nov 22 21:21:41 2009 +0100
7.2 +++ b/rsvp.py Sun Nov 22 22:53:24 2009 +0100
7.3 @@ -97,6 +97,7 @@
7.4 self.pc = pc or 0
7.5 self.debug = debug
7.6 self.abort_upon_exception = abort_upon_exception
7.7 + self.counter = 0
7.8
7.9 # Stacks.
7.10
7.11 @@ -336,6 +337,7 @@
7.12
7.13 "Perform the 'instruction', returning the next PC value or None."
7.14
7.15 + self.counter += 1
7.16 self.operand = instruction.get_operand()
7.17 method = self.get_method(instruction)
7.18 return method()
7.19 @@ -651,13 +653,14 @@
7.20
7.21 self.value = DataValue(ref, ref)
7.22
7.23 - def CheckSelf(self):
7.24 + def CheckInstance(self):
7.25 value = self.value
7.26 - context_value = self.source
7.27 + target_value = self.source
7.28
7.29 - # Check the details of the proposed context and the target's context.
7.30 + # For the 'self' parameter in an invoked function, the proposed context
7.31 + # ('self') is checked against the target's context.
7.32
7.33 - self.status = self._CheckInstance(value.ref, context_value.ref)
7.34 + self.status = self._CheckInstance(value.ref, target_value.ref)
7.35
7.36 def JumpInFrame(self):
7.37 codeaddr = self.callable