# HG changeset patch # User Paul Boddie # Date 1243039564 -7200 # Node ID 1ecd4a4b2a0599292201a8b2a48fa725ad460a4d # Parent 2fb8b284aba302f570328c8bf1195f5e17db49cd Fixed exception raising by actually instantiating exceptions properly in both the generated code and in the RSVP instructions. Simplified predefined internal class and instance template location initialisation in RSVPMachine. Added exception reporting in the RSVPMachine.run method. diff -r 2fb8b284aba3 -r 1ecd4a4b2a05 micropython/trans.py --- a/micropython/trans.py Sat May 23 01:46:46 2009 +0200 +++ b/micropython/trans.py Sat May 23 02:46:04 2009 +0200 @@ -44,6 +44,14 @@ self.new_op(MakeObject(n + 1)) + def make_exception(self, name, node): + + "Make an exception of the given 'name' using 'node'." + + # NOTE: Reserving only one attribute. + + self.make_object(self.get_builtin_class(name, node), 1) + # Name-related methods. def get_scope(self, name): @@ -676,7 +684,7 @@ self.new_op(DropFrame()) self.new_op(LoadResult()) - self.load_builtin("TypeError", node) + self.make_exception("TypeError", node) self.new_op(StoreException()) self.new_op(RaiseException()) @@ -933,7 +941,7 @@ # Raise a TypeError. self.set_block(type_error_block) - self.load_builtin("TypeError", node) + self.make_exception("TypeError", node) self.new_op(StoreException()) self.new_op(RaiseException()) @@ -1018,7 +1026,7 @@ # Raise a TypeError. self.set_block(type_error_block) - self.load_builtin("TypeError", node) + self.make_exception("TypeError", node) self.new_op(StoreException()) self.new_op(RaiseException()) diff -r 2fb8b284aba3 -r 1ecd4a4b2a05 rsvp.py --- a/rsvp.py Sat May 23 01:46:46 2009 +0200 +++ b/rsvp.py Sat May 23 02:46:04 2009 +0200 @@ -121,22 +121,31 @@ # Constants. - self.attr_error = objlist.access("__builtins__", "AttributeError").get_value().location - self.type_error = objlist.access("__builtins__", "TypeError").get_value().location - self.index_error = objlist.access("__builtins__", "IndexError").get_value().location + cls = self._get_class("__builtins__", "AttributeError") + self.attr_error = cls.location + self.attr_error_instance = cls.instance_template_location + cls = self._get_class("__builtins__", "TypeError") + self.type_error = cls.location + self.type_error_instance = cls.instance_template_location + cls = self._get_class("__builtins__", "IndexError") + self.index_error = cls.location + self.index_error_instance = cls.instance_template_location # Native class constants. - cls = objlist.access("__builtins__", "int") - self.int_class_location = cls and cls.get_value() and cls.get_value().location - self.int_instance_location = cls and cls.get_value() and cls.get_value().instance_template_location - cls = objlist.access("__builtins__", "list") - self.list_instance_location = cls and cls.get_value() and cls.get_value().instance_template_location + cls = self._get_class("__builtins__", "int") + self.int_class = cls.location + self.int_instance = cls.instance_template_location + cls = self._get_class("__builtins__", "list") + self.list_instance = cls.instance_template_location # Debugging attributes. self.breakpoints = set() + def _get_class(self, module, name): + return self._objlist.access(module, name).get_value() + # Debugging methods. def dump(self): @@ -245,6 +254,14 @@ except EmptyPCStack: pass + print "Execution terminated", + if self.exception is not None: + context, ref = self.exception + print "with exception:", self.load(ref) + print "at address:", self.load(ref + 1) + else: + print "successfully." + def execute(self): "Execute code in the memory at the current PC address." @@ -395,7 +412,8 @@ else: self.value = self.load(ref + offset) else: - self.exception = self.attr_error + exc = self._MakeObject(2, self.attr_error_instance) + self.exception = exc, exc return self.RaiseException() def LoadAttrIndexContext(self): @@ -407,7 +425,8 @@ loaded_context, loaded_ref = self.load(offset) # offset is address of class attribute self.value = ref, loaded_ref else: - self.exception = self.attr_error + exc = self._MakeObject(2, self.attr_error_instance) + self.exception = exc, exc return self.RaiseException() def LoadAttrIndexContextCond(self): @@ -422,7 +441,8 @@ else: self.value = self.load(ref + offset) else: - self.exception = self.attr_error + exc = self._MakeObject(2, self.attr_error_instance) + self.exception = exc, exc return self.RaiseException() def StoreAttrIndex(self): @@ -432,12 +452,14 @@ attr_index, class_attr, offset = element if attr_index == self.operand: if class_attr: - self.exception = self.type_error + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc return self.RaiseException() else: self.save(ref + offset, self.source) else: - self.exception = self.attr_error + exc = self._MakeObject(2, self.attr_error_instance) + self.exception = exc, exc return self.RaiseException() # NOTE: LoadAttrIndexContext is a possibility if a particular attribute can always be overridden. @@ -468,7 +490,8 @@ if param_index == self.operand: self.frame_stack[frame + offset + 1] = self.source # add 1 to skip the context always generated else: - self.exception = self.type_error + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc return self.RaiseException() def LoadCallable(self): @@ -527,21 +550,24 @@ if nlocals > 0: self_context, self_ref = self.frame_stack[frame + 1] if not self._CheckInstance(self_ref, context_context): - raise Exception, "CheckFrame %r (%r vs. %r)" % (self.operand, self.load(self_ref), self.load(context_context)) - #self.exception = self.type_error - #return self.RaiseException() + #raise Exception, "CheckFrame %r (%r vs. %r)" % (self.operand, self.load(self_ref), self.load(context_context)) + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc + return self.RaiseException() else: - raise Exception, "CheckFrame %r (no self argument)" % self.operand - #self.exception = self.type_error - #return self.RaiseException() + #raise Exception, "CheckFrame %r (no self argument)" % self.operand + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc + return self.RaiseException() # Test the frame size. # NOTE: Raise a proper exception here. if not ((nargs - ndefaults) <= nlocals and (nlocals <= nargs or has_star)): - raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (self.operand, nargs - ndefaults, nlocals, nargs) - #self.exception = self.type_error - #return self.RaiseException() + #raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (self.operand, nargs - ndefaults, nlocals, nargs) + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc + return self.RaiseException() def FillDefaults(self): # NOTE: Make the get_operand method of the instruction provide the @@ -617,6 +643,9 @@ self.exception = self.value[1] def RaiseException(self): + # NOTE: Adding the program counter as the first attribute. + self.save(self.exception[1] + 1, self.pc) + # Jumping to the current handler. return self.handler_stack[-1] def PushHandler(self): @@ -696,8 +725,9 @@ # Test operand suitability. - if not self._CheckInstance(left, self.int_class_location) and self._CheckInstance(right, self.int_class_location): - self.exception = self.type_error + if not self._CheckInstance(left, self.int_class) and self._CheckInstance(right, self.int_class): + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc return self.RaiseException() # NOTE: Assume single location for data. @@ -707,7 +737,7 @@ # Make a new object. - addr = self._MakeObject(2, self.int_instance_location) + addr = self._MakeObject(2, self.int_instance) # Store the result. # NOTE: The data is considered ready to use. @@ -728,8 +758,9 @@ # Test operand suitability. - if not self._CheckInstance(left, self.int_class_location): - self.exception = self.type_error + if not self._CheckInstance(left, self.int_class): + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc return self.RaiseException() # NOTE: Assume single location for data. @@ -753,8 +784,9 @@ # Test operand suitability. - if not self._CheckInstance(left, self.int_class_location): - self.exception = self.type_error + if not self._CheckInstance(left, self.int_class): + exc = self._MakeObject(2, self.type_error_instance) + self.exception = exc, exc return self.RaiseException() # NOTE: Assume single location for data. @@ -763,7 +795,7 @@ # Make a new object. - addr = self._MakeObject(2, self.int_instance_location) + addr = self._MakeObject(2, self.int_instance) # Store the result. # NOTE: The data is considered ready to use. @@ -791,7 +823,7 @@ args_context, args = self.frame_stack[frame] header = self.load(args) - list = self._MakeObject(header.size, self.list_instance_location) + list = self._MakeObject(header.size, self.list_instance) for i in range(1, header.size): self.save(list + i, self.load(args + i)) @@ -816,7 +848,8 @@ elif item_pos < 0 and item_pos >= -nelements: item_pos = nelements + item_pos else: - self.exception = self.index_error + exc = self._MakeObject(2, self.index_error_instance) + self.exception = exc, exc return self.RaiseException() self.result = self.load(obj + 1 + item_pos)