1.1 --- a/micropython/ast.py Sun Apr 27 03:11:12 2008 +0200
1.2 +++ b/micropython/ast.py Sun Apr 27 21:05:55 2008 +0200
1.3 @@ -88,21 +88,17 @@
1.4 # being processed.
1.5
1.6 self.code = None
1.7 + self.temp_position = 0
1.8
1.9 def calculate_stack_usage(self):
1.10 max_stack_usage = 0
1.11 - max_stack_temp_usage = 0
1.12 stack_usage = 0
1.13 - stack_temp_usage = 0
1.14
1.15 for op in self.code:
1.16 stack_usage += op.stack_usage
1.17 - stack_temp_usage += op.stack_temp_usage
1.18 max_stack_usage = max(max_stack_usage, stack_usage)
1.19 - max_stack_temp_usage = max(max_stack_temp_usage, stack_temp_usage)
1.20
1.21 self.unit.stack_usage = max_stack_usage
1.22 - self.unit.stack_temp_usage = max_stack_temp_usage
1.23
1.24 def get_module_code(self):
1.25
1.26 @@ -110,8 +106,11 @@
1.27
1.28 self.unit = self.module
1.29 self.code = []
1.30 + self.temp_position = self.unit.stack_local_usage
1.31 +
1.32 if self.module.module is not None:
1.33 self.dispatch(self.module.module)
1.34 +
1.35 self.calculate_stack_usage()
1.36 return self.code
1.37
1.38 @@ -121,22 +120,14 @@
1.39
1.40 self.unit = unit
1.41 self.code = []
1.42 + self.temp_position = self.unit.stack_local_usage
1.43 +
1.44 if unit.node is not None:
1.45 self.dispatch(unit.node)
1.46 +
1.47 self.calculate_stack_usage()
1.48 return self.code
1.49
1.50 - def get_default_code(self, unit):
1.51 -
1.52 - "Return the code for the defaults in the given 'unit'."
1.53 -
1.54 - self.code = []
1.55 - for attr, default in zip(unit.default_attrs, unit.defaults):
1.56 - self.dispatch(default)
1.57 - self.new_op(LoadConst(unit))
1.58 - self.new_op(StoreAddress(attr))
1.59 - return self.code
1.60 -
1.61 def __repr__(self):
1.62 return "Translation(%r)" % self.module
1.63
1.64 @@ -187,6 +178,15 @@
1.65 def drop_exception_labels(self):
1.66 self.exception_labels.pop()
1.67
1.68 + def reserve_temp(self, n):
1.69 + temp_position = self.temp_position
1.70 + self.temp_position += n
1.71 + self.unit.stack_temp_usage = max(self.unit.stack_temp_usage, self.temp_position)
1.72 + return temp_position
1.73 +
1.74 + def discard_temp(self, n):
1.75 + self.temp_position -= n
1.76 +
1.77 def new_op(self, op):
1.78
1.79 "Add 'op' to the generated code."
1.80 @@ -241,7 +241,6 @@
1.81 """
1.82
1.83 AddressInstruction, AttrInstruction, AttrIndexInstruction = classes
1.84 - # NOTE: Only simple cases are used for optimisations.
1.85
1.86 last = self.last_op()
1.87
1.88 @@ -550,7 +549,7 @@
1.89
1.90 def _have_constant_input(self, n):
1.91 last = self.last_ops(n+1)
1.92 - return len(last) > n and (isinstance(last[n], LoadAttr) and last[n].attr.assignments == 1 or
1.93 + return len(last) > n and (isinstance(last[n], LoadAddress) and last[n].attr.assignments == 1 or
1.94 isinstance(last[n], LoadConst))
1.95
1.96 def _have_known_target(self):
1.97 @@ -650,18 +649,20 @@
1.98
1.99 # NOTE: Decide on temporary storage access.
1.100
1.101 + temp_position = self.reserve_temp(2)
1.102 +
1.103 self.dispatch(node.left)
1.104 - self.new_op(StoreTemp(1))
1.105 + self.new_op(StoreTemp(temp_position))
1.106 self.dispatch(node.right)
1.107 - self.new_op(StoreTemp(2))
1.108 + self.new_op(StoreTemp(temp_position + 1))
1.109
1.110 # Left method.
1.111
1.112 self._startCallFunc()
1.113 - self.new_op(LoadTemp(1))
1.114 + self.new_op(LoadTemp(temp_position))
1.115 self._generateAttr(node, left_method, (LoadAddress, LoadAttr, LoadAttrIndex))
1.116 - self.new_op(LoadTemp(1)) # Explicit context as first argument.
1.117 - self.new_op(LoadTemp(2))
1.118 + self.new_op(LoadTemp(temp_position)) # Explicit context as first argument.
1.119 + self.new_op(LoadTemp(temp_position + 1))
1.120 self._endCallFunc()
1.121
1.122 self.dispatch(compiler.ast.Name("AttributeError"))
1.123 @@ -672,14 +673,16 @@
1.124
1.125 self.set_label(right_label)
1.126 self._startCallFunc()
1.127 - self.new_op(LoadTemp(2))
1.128 + self.new_op(LoadTemp(temp_position + 1))
1.129 self._generateAttr(node, right_method, (LoadAddress, LoadAttr, LoadAttrIndex))
1.130 - self.new_op(LoadTemp(2)) # Explicit context as first argument.
1.131 - self.new_op(LoadTemp(1))
1.132 + self.new_op(LoadTemp(temp_position + 1)) # Explicit context as first argument.
1.133 + self.new_op(LoadTemp(temp_position))
1.134 self._endCallFunc()
1.135
1.136 self.set_label(end_label)
1.137
1.138 + self.discard_temp(2)
1.139 +
1.140 def visitAdd(self, node):
1.141 self._visitBinary(node, "__add__", "__radd__")
1.142
1.143 @@ -848,6 +851,12 @@
1.144 self.new_op(LoadConst(node.unit))
1.145 self._visitName(node, (StoreName, StoreAddress))
1.146
1.147 + # Generate the default initialisation code.
1.148 +
1.149 + for attr, default in zip(node.unit.default_attrs, node.unit.defaults):
1.150 + self.dispatch(default)
1.151 + self.new_op(StoreAddress(attr))
1.152 +
1.153 # Visiting of the code occurs when get_code is invoked on this node.
1.154
1.155 else: