# HG changeset patch # User Paul Boddie # Date 1217715591 -7200 # Node ID c3eaefd1e52041aa302a9788f5716debf3fab687 # Parent 8d60e97e7e34a9a0fba2f683d8462b6fc65fac1e Changed the treatment of boolean status (for tests and conditional jumps) such that a special status register would be involved and that the current value would be preserved. Added a LoadBoolean instruction, which loads the boolean status into the current value (using the appropriate object). Changed temporary storage usage for lambda definitions with default values, removing the ensure_temp method. Re-introduced and cleaned up temporary storage usage (and local usage) attributes for program units. diff -r 8d60e97e7e34 -r c3eaefd1e520 micropython/ast.py --- a/micropython/ast.py Sat Aug 02 02:02:04 2008 +0200 +++ b/micropython/ast.py Sun Aug 03 00:19:51 2008 +0200 @@ -89,6 +89,7 @@ self.code = None self.temp_positions = set() + self.max_temp_position = -1 def __repr__(self): return "Translation(%r)" % self.module @@ -104,6 +105,7 @@ if self.module.module is not None: self.dispatch(self.module.module) + self.unit.temp_usage = self.max_temp_position + 1 return self.code def get_code(self, unit): @@ -117,6 +119,7 @@ if unit.astnode is not None: self.dispatch(unit.astnode) + self.unit.temp_usage = self.max_temp_position + 1 return self.code # Name-related methods. @@ -222,16 +225,13 @@ self.new_op(StoreTemp(temp_position)) return LoadTemp(temp_position) - def ensure_temp(self): - if isinstance(self.active, LoadTemp): - self.temp_positions.add(self.active.attr) - def reserve_temp(self): if not self.temp_positions: temp_position = 0 else: temp_position = max(self.temp_positions) + 1 self.temp_positions.add(temp_position) + self.max_temp_position = max(self.max_temp_position, temp_position) return temp_position def discard_temp(self, instruction=None): @@ -352,7 +352,7 @@ "Return whether 'instruction' provides an input." - return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult) + self.attribute_load_instructions) + return isinstance(instruction, (LoadConst, LoadName, LoadTemp, LoadResult, LoadBoolean) + self.attribute_load_instructions) # Convenience tests. @@ -509,11 +509,6 @@ if self._should_optimise_temp_storage() and \ self._have_temp_compatible_access(): - # Where an existing temporary storage reference will be retained, - # keep it active. - - self.ensure_temp() - last = self.last_op() self.remove_op() return last @@ -842,7 +837,6 @@ # raise an exception. self.new_op(DropFrame()) - self.new_op(LoadResult()) self.load_builtin("TypeError", node) @@ -1109,10 +1103,6 @@ self._generateBinary(node, temp1, temp2, left_method, right_method) - # Yield the result. - - self.new_op(LoadResult()) - # Compilation duties... self.discard_temp(temp1) @@ -1340,7 +1330,6 @@ """ end_label = self.new_label() - temp_result_pos = self.reserve_temp() self.dispatch(node.expr) temp2 = self._optimise_temp_storage() @@ -1355,13 +1344,16 @@ self.dispatch(next_node) temp2 = self._optimise_temp_storage() + # Use the appropriate mechanism, setting the boolean status for the + # comparison. + if methods is not None: left_method, right_method = methods # Generate method call using evaluated argument and next node. self._generateBinary(node, temp1, temp2, left_method, right_method) - self.new_op(LoadResult()) + self.new_op(TestBoolean()) else: # Deal with the special operators. @@ -1394,19 +1386,14 @@ self.new_op(StoreFrame(1)) self._doCallFunc(temp_method) self._endCallFunc(temp_method) - self.new_op(LoadResult()) + self.new_op(TestBoolean()) if op_name.find("not") != -1: self.new_op(InvertBoolean()) - # Record the result in temporary storage. - - self.new_op(StoreTemp(temp_result_pos)) - # Test the result and jump to the end label if false. if op is not last_op: - self.new_op(TestBoolean()) self.new_op(JumpIfFalse(end_label)) # Compilation duties... @@ -1416,8 +1403,9 @@ self.discard_temp(temp2) self.set_label(end_label) - self.new_op(LoadTemp(temp_result_pos)) - self.cancel_temp(temp_result_pos) + # Yield the appropriate value. + + self.new_op(LoadBoolean()) def visitConst(self, node): const = self.module.constant_values[node.value] @@ -1614,7 +1602,7 @@ self.discard_value() self.new_op(temp) - self.discard_temp(temp) + #self.discard_temp(temp) # Visiting of the code occurs when get_code is invoked on this node. @@ -1657,13 +1645,18 @@ self.dispatch(node.expr) self.new_op(TestBoolean()) - self.new_op(JumpIfTrue(true_label)) - self.load_builtin("True", node) - self.new_op(Jump(next_label)) - - self.set_label(true_label) - self.load_builtin("False", node) - self.set_label(next_label) + self.new_op(InvertBoolean()) + self.new_op(LoadBoolean()) + + # The equivalent of InvertBoolean/LoadBoolean. + + #self.new_op(JumpIfTrue(true_label)) + #self.load_builtin("True", node) + #self.new_op(Jump(next_label)) + + #self.set_label(true_label) + #self.load_builtin("False", node) + #self.set_label(next_label) # Prevent incorrect optimisation. diff -r 8d60e97e7e34 -r c3eaefd1e520 micropython/data.py --- a/micropython/data.py Sat Aug 02 02:02:04 2008 +0200 +++ b/micropython/data.py Sun Aug 03 00:19:51 2008 +0200 @@ -358,9 +358,8 @@ # Program-related details. - self.stack_usage = 0 - self.stack_temp_usage = 0 - self.stack_local_usage = 0 + self.temp_usage = 0 + self.local_usage = 0 def __repr__(self): if self.location is not None: @@ -685,9 +684,8 @@ # Program-related details. - self.stack_usage = 0 - self.stack_temp_usage = 0 - self.stack_local_usage = 0 + self.temp_usage = 0 + self.local_usage = 0 def _add_parameters(self, argnames): for name in argnames: @@ -793,7 +791,7 @@ for i, attr in enumerate(self.locals().values()): attr.position = i + j - self.stack_local_usage = i + self.local_usage = i self.finalised = 1 def function_from_method(self): @@ -860,9 +858,8 @@ # Program-related details. - self.stack_usage = 0 - self.stack_temp_usage = 0 - self.stack_local_usage = 0 + self.temp_usage = 0 + self.local_usage = 0 def full_name(self): return self.name diff -r 8d60e97e7e34 -r c3eaefd1e520 micropython/rsvp.py --- a/micropython/rsvp.py Sat Aug 02 02:02:04 2008 +0200 +++ b/micropython/rsvp.py Sun Aug 03 00:19:51 2008 +0200 @@ -205,11 +205,12 @@ class PopHandler(Instruction): "Pop an exception handler from the handler stack." class CheckException(Instruction): "Check the raised exception against another." -# General instructions. +# Test instructions, operating on the boolean status register. -class InvertBoolean(Instruction): "Invert the current value." -class TestBoolean(Instruction): "Test whether the current value is a true value." -class TestIdentity(Instruction): "Test whether the current value is identical to the source value." -class TestIdentityAddress(Address): "Test whether the current value is identical to the given address." +class TestBoolean(Instruction): "Test whether the current value is a true value, setting the boolean status." +class TestIdentity(Instruction): "Test whether the current value is identical to the source value, setting the boolean status." +class TestIdentityAddress(Address): "Test whether the current value is identical to the given address, setting the boolean status." +class InvertBoolean(Instruction): "Invert the boolean status." +class LoadBoolean(Instruction): "Load the appropriate value into the current value for the boolean status." # vim: tabstop=4 expandtab shiftwidth=4