1.1 --- a/rsvp.py Thu Mar 05 00:45:42 2009 +0100
1.2 +++ b/rsvp.py Thu Mar 19 23:05:55 2009 +0100
1.3 @@ -71,6 +71,9 @@
1.4 class EmptyFrameStack(Exception):
1.5 pass
1.6
1.7 +class BreakpointReached(Exception):
1.8 + pass
1.9 +
1.10 class RSVPMachine:
1.11
1.12 "A really simple virtual processor."
1.13 @@ -119,6 +122,10 @@
1.14 cls = objlist.access("__builtins__", "int")
1.15 self.int_instance_location = cls and cls.get_value() and cls.get_value().instance_template_location
1.16
1.17 + # Debugging attributes.
1.18 +
1.19 + self.breakpoints = set()
1.20 +
1.21 # Debugging methods.
1.22
1.23 def dump(self):
1.24 @@ -164,6 +171,9 @@
1.25 if dump:
1.26 self.dump()
1.27
1.28 + def set_break(self, location):
1.29 + self.breakpoints.add(location)
1.30 +
1.31 # Internal operations.
1.32
1.33 def load(self, address):
1.34 @@ -228,6 +238,10 @@
1.35
1.36 "Execute code in the memory at the current PC address."
1.37
1.38 + if self.pc in self.breakpoints:
1.39 + self.breakpoints.remove(self.pc)
1.40 + raise BreakpointReached
1.41 +
1.42 self.instruction = self.load(self.pc)
1.43
1.44 # Process any inputs of the instruction.
1.45 @@ -322,7 +336,12 @@
1.46 def LoadAddressContext(self):
1.47 context, ref = self.load(self.operand)
1.48 inst_context, inst_ref = self.value
1.49 - self.value = self._LoadAddressContext(context, ref, inst_context, inst_ref)
1.50 + self.value = inst_ref, ref
1.51 +
1.52 + def LoadAddressContextCond(self):
1.53 + context, ref = self.load(self.operand)
1.54 + inst_context, inst_ref = self.value
1.55 + self.value = self._LoadAddressContextCond(context, ref, inst_context, inst_ref)
1.56
1.57 def StoreAddress(self):
1.58 # Preserve context.
1.59 @@ -352,22 +371,50 @@
1.60 context, ref = self.value
1.61 data = self.load(ref)
1.62 element = self.objlist[data.classcode + self.operand]
1.63 - attr_index, class_attr, replace_context, offset = element
1.64 + attr_index, class_attr, offset = element
1.65 if attr_index == self.operand:
1.66 if class_attr:
1.67 - loaded_context, loaded_ref = self.load(offset) # offset is address of class attribute
1.68 - self.value = self._LoadAddressContext(loaded_context, loaded_ref, context, ref)
1.69 + self.value = self.load(offset) # offset is address of class attribute
1.70 else:
1.71 self.value = self.load(ref + offset)
1.72 else:
1.73 self.exception = self.attr_error
1.74 return self.RaiseException()
1.75
1.76 + def LoadAttrIndexContext(self):
1.77 + context, ref = self.value
1.78 + data = self.load(ref)
1.79 + element = self.objlist[data.classcode + self.operand]
1.80 + attr_index, class_attr, offset = element
1.81 + if attr_index == self.operand:
1.82 + loaded_context, loaded_ref = self.load(offset) # offset is address of class attribute
1.83 + self.value = ref, loaded_ref
1.84 + else:
1.85 + self.exception = self.attr_error
1.86 + return self.RaiseException()
1.87 +
1.88 + def LoadAttrIndexContextCond(self):
1.89 + context, ref = self.value
1.90 + data = self.load(ref)
1.91 + element = self.objlist[data.classcode + self.operand]
1.92 + attr_index, class_attr, offset = element
1.93 + if attr_index == self.operand:
1.94 + if class_attr:
1.95 + loaded_context, loaded_ref = self.load(offset) # offset is address of class attribute
1.96 + self.value = self._LoadAddressContextCond(loaded_context, loaded_ref, context, ref)
1.97 + else:
1.98 + self.value = self.load(ref + offset)
1.99 + else:
1.100 + self.exception = self.attr_error
1.101 + return self.RaiseException()
1.102 +
1.103 + # NOTE: LoadAttrIndexContextCond will test context compatibility.
1.104 +
1.105 def StoreAttrIndex(self):
1.106 context, ref = self.value
1.107 data = self.load(ref)
1.108 element = self.objlist[data.classcode + self.operand]
1.109 - attr_index, class_attr, replace_context, offset = element
1.110 + attr_index, class_attr, offset = element
1.111 if attr_index == self.operand:
1.112 if class_attr:
1.113 self.exception = self.type_error
1.114 @@ -554,7 +601,7 @@
1.115 # Find the table entry for the descendant.
1.116
1.117 element = self.objlist[target_data.classcode + data.attrcode]
1.118 - attr_index, class_attr, replace_context, offset = element
1.119 + attr_index, class_attr, offset = element
1.120 return attr_index == data.attrcode
1.121
1.122 def _MakeObject(self, size, ref):
1.123 @@ -564,7 +611,7 @@
1.124 self.save(addr, data)
1.125 return addr
1.126
1.127 - def _LoadAddressContext(self, context, ref, inst_context, inst_ref):
1.128 + def _LoadAddressContextCond(self, context, ref, inst_context, inst_ref):
1.129
1.130 # Check the instance context against the target's context.
1.131