1.1 --- a/micropython/ast.py Mon May 12 23:54:16 2008 +0200
1.2 +++ b/micropython/ast.py Sun May 18 01:08:03 2008 +0200
1.3 @@ -252,6 +252,7 @@
1.4 if self._have_constant_input(0):
1.5
1.6 # Optimise away the constant storage if appropriate.
1.7 + # The target and value loading operations are removed.
1.8
1.9 if self._optimise_constant_storage(AddressInstruction, 1):
1.10 return
1.11 @@ -353,13 +354,11 @@
1.12
1.13 temp = self._optimise_temp_storage()
1.14
1.15 - # Where a target is known and has a known context, avoid generating any
1.16 - # first argument. Instance methods do not have a known target since they
1.17 - # are accessed via an instance whose identity cannot generally be known
1.18 - # at compile-time.
1.19 + # Where a target or context are not known, load the target and context.
1.20
1.21 if context is None:
1.22 continue_label = self.new_label()
1.23 + self.new_ops(temp)
1.24 self.new_op(LoadContext())
1.25 self.new_op(CheckContext())
1.26 self.new_op(JumpIfTrue(continue_label))
1.27 @@ -371,6 +370,15 @@
1.28 self.dispatch(compiler.ast.Name("TypeError"))
1.29 self.new_op(RaiseException())
1.30 self.set_label(continue_label)
1.31 +
1.32 + # Where an instance is known to be the context, load the context.
1.33 +
1.34 + elif isinstance(context, Instance):
1.35 + self.new_ops(temp)
1.36 + self.new_op(LoadContext())
1.37 +
1.38 + # Otherwise omit the context.
1.39 +
1.40 else:
1.41 pass # NOTE: Class methods should be supported.
1.42
1.43 @@ -391,7 +399,7 @@
1.44
1.45 # NOTE: Fix context for self-accessed methods.
1.46
1.47 - if context is not None and isinstance(context, Instance):
1.48 + if context is not None:
1.49 ncontext = 1
1.50 else:
1.51 ncontext = 0
1.52 @@ -565,6 +573,9 @@
1.53
1.54 NameInstruction, AddressInstruction = classes
1.55
1.56 + # Optimise away the constant storage if appropriate.
1.57 + # The target and value loading operations are removed.
1.58 +
1.59 if self._optimise_constant_storage(NameInstruction, 0):
1.60 return
1.61
1.62 @@ -618,7 +629,7 @@
1.63 def _have_constant_input(self, n):
1.64 last = self.last_ops(n+1)
1.65 return len(last) > n and (isinstance(last[n], LoadAddress) and last[n].attr.assignments == 1 or
1.66 - isinstance(last[n], LoadConst)) # and not isinstance(last[n].attr, Instance)
1.67 + isinstance(last[n], LoadConst))
1.68
1.69 def _have_known_target(self):
1.70 return self._have_constant_input(0)
1.71 @@ -708,7 +719,7 @@
1.72 if self._should_optimise_known_target() and self._have_known_target():
1.73 last = self.last_op()
1.74 target = last.attr.value
1.75 - context = last.context
1.76 + context = last.attr.context
1.77
1.78 # Handle calls to classes.
1.79
1.80 @@ -737,11 +748,19 @@
1.81 if self._should_optimise_self_access() and self._have_self_input() and \
1.82 not self.unit.is_relocated(attrname):
1.83
1.84 - attr = self.unit.parent.all_attributes()[attrname]
1.85 - if isinstance(attr.parent, Instance):
1.86 + # Either generate an instruction operating on an instance attribute.
1.87 +
1.88 + try:
1.89 + attr = self.unit.parent.instance_attributes()[attrname]
1.90 self.new_op(AttrInstruction(attr))
1.91 - else:
1.92 - self.new_op(AddressInstruction(attr, Instance()))
1.93 +
1.94 + # Or generate an instruction operating on a class attribute.
1.95 +
1.96 + except KeyError:
1.97 + attr = self.unit.parent.all_attributes()[attrname]
1.98 + new_attr = attr.via_instance()
1.99 + self.replace_op(AddressInstruction(new_attr))
1.100 +
1.101 return 1
1.102 else:
1.103 return 0