1.1 --- a/rsvp.py Sun Aug 07 23:01:35 2011 +0200
1.2 +++ b/rsvp.py Sun Aug 21 14:24:28 2011 +0200
1.3 @@ -44,12 +44,11 @@
1.4
1.5 * Exception handler PC stack refers to the state of the PC stack
1.6
1.7 - * Registers: current context/value,
1.8 - source context/value,
1.9 + * Registers: working context/value,
1.10 + assignment source context/value,
1.11 current result context/value,
1.12 current exception value,
1.13 - boolean status value,
1.14 - current callable
1.15 + boolean status value
1.16 """
1.17
1.18 from micropython.program import DataValue, ReplaceableContext, PlaceholderContext, FragmentObject
1.19 @@ -121,22 +120,26 @@
1.20
1.21 # Registers.
1.22
1.23 - self.value = None
1.24 - self.context = None
1.25 + self.register_names = (
1.26 + "working",
1.27 + "working_context",
1.28 + "source",
1.29 + "source_context",
1.30 + "result",
1.31 + "result_context",
1.32 + "exception",
1.33 + "status"
1.34 + )
1.35 + self.registers = {}
1.36
1.37 - self.source_value = None
1.38 - self.source_context = None
1.39 -
1.40 - self.result_value = None
1.41 - self.result_context = None
1.42 -
1.43 - self.exception = None
1.44 + for name in self.register_names:
1.45 + self.registers[name] = None
1.46
1.47 self.instruction = None
1.48 - self.status = None
1.49 - self.callable = None
1.50
1.51 # Constants.
1.52 + # NOTE: These should eventually be removed once the code using them has
1.53 + # NOTE: been migrated to the native code library.
1.54
1.55 cls = self._get_class("__builtins__", "AttributeError")
1.56 self.attr_error = cls.location
1.57 @@ -179,20 +182,12 @@
1.58 print "Handler frame stack", self.handler_local_sp_stack
1.59 print "Handler PC stack", self.handler_pc_stack
1.60 print
1.61 - print "Value", self.value
1.62 - print "Context", self.context
1.63 + print "Registers:"
1.64 print
1.65 - print "Source value", self.source_value
1.66 - print "Source context", self.source_context
1.67 - print
1.68 - print "Result value", self.result_value
1.69 - print "Result context", self.result_context
1.70 - print
1.71 - print "Exception", self.exception
1.72 + for name in self.register_names:
1.73 + print "%s: %s" % (name, self.registers[name])
1.74 print
1.75 print "Instruction", self.instruction
1.76 - print "Status", self.status
1.77 - print "Callable", self.callable
1.78
1.79 def show(self, start=None, end=None):
1.80 self.show_memory(self.memory[start:end], self.coverage[start:end], start or 0)
1.81 @@ -294,14 +289,14 @@
1.82 breakpoint = 1
1.83
1.84 print "Execution terminated",
1.85 - if self.exception is not None:
1.86 - ref = self.exception
1.87 + if breakpoint:
1.88 + print "with breakpoint."
1.89 + print "At address", self.pc
1.90 + elif self.registers["exception"] is not None:
1.91 + ref = self.registers["exception"]
1.92 addr = self.load(ref + Library.instance_data_offset)
1.93 print "with exception:", self.load(ref)
1.94 print "At address %d: %r" % (addr, self.load(addr))
1.95 - elif breakpoint:
1.96 - print "with breakpoint."
1.97 - print "At address", self.pc
1.98 else:
1.99 print "successfully."
1.100 print "After", self.counter, "instructions at cost", self.cost, "units."
1.101 @@ -316,15 +311,15 @@
1.102 self.run()
1.103 success = 1
1.104
1.105 - if self.exception is None:
1.106 + if self.registers["exception"] is None:
1.107 for name in module.keys():
1.108 if name.startswith("result"):
1.109 label, expected = name.split("_")
1.110 attr = module[name]
1.111
1.112 - # NOTE: Assumptions about headers and content made.
1.113 + # Need to skip the header to get at the members.
1.114
1.115 - attr_location = module.location + 1 + attr.position
1.116 + attr_location = module.location + Library.instance_data_offset + attr.position
1.117 value = self.load(attr_location)
1.118
1.119 if value is not None:
1.120 @@ -349,10 +344,6 @@
1.121
1.122 self.instruction = self.load(self.pc)
1.123
1.124 - # Process any inputs of the instruction.
1.125 -
1.126 - self.process_inputs()
1.127 -
1.128 # Perform the instruction itself.
1.129
1.130 next_pc = self.perform(self.instruction)
1.131 @@ -380,32 +371,15 @@
1.132 raise IllegalInstruction, (self.pc, instruction_name)
1.133 return method
1.134
1.135 - def perform(self, instruction, is_input=0):
1.136 + def perform(self, instruction):
1.137
1.138 "Perform the 'instruction', returning the next PC value or None."
1.139
1.140 - if not is_input:
1.141 - self.counter += 1
1.142 - self.cost += instruction.cost
1.143 + self.counter += 1
1.144 + self.cost += instruction.cost
1.145 operand = instruction.get_operand()
1.146 method = self.get_method(instruction)
1.147 - return method(operand)
1.148 -
1.149 - def process_inputs(self):
1.150 -
1.151 - """
1.152 - Process any inputs of the current instruction. This permits any directly
1.153 - connected sub-instructions to produce the effects that separate
1.154 - instructions would otherwise have.
1.155 - """
1.156 -
1.157 - value, context = self.value, self.context
1.158 - if self.instruction.source is not None:
1.159 - self.perform(self.instruction.source, 1)
1.160 - self.source_value, self.source_context = self.value, self.context
1.161 - self.value, self.context = value, context
1.162 - if self.instruction.input is not None:
1.163 - self.perform(self.instruction.input, 1)
1.164 + return method(operand, instruction)
1.165
1.166 def jump(self, addr, next):
1.167
1.168 @@ -428,104 +402,123 @@
1.169 self.push_pc(self.pc + 1)
1.170 return addr
1.171
1.172 + # Helper methods.
1.173 +
1.174 + def context_of(self, register):
1.175 + return "%s_context" % register
1.176 +
1.177 + def load_from_frame(self, operand):
1.178 + frame = self.local_sp_stack[-1]
1.179 + return self.frame_stack[frame + operand]
1.180 +
1.181 # Low-level instructions.
1.182
1.183 - def LoadValue(self, operand):
1.184 - self.value = operand
1.185 -
1.186 - def LoadContext(self, operand):
1.187 - self.context = operand
1.188 + def LoadImmediate(self, operand, target):
1.189 + self.registers[target] = operand
1.190
1.191 - def LoadSourceValue(self, operand):
1.192 - self.source_value = operand
1.193 -
1.194 - def LoadSourceContext(self, operand):
1.195 - self.source_context = operand
1.196 + def LoadMemory(self, operand, target, source):
1.197 + self.registers[target] = self.load(
1.198 + self.registers[source] + (operand is not None and operand or 0)
1.199 + )
1.200
1.201 # Instructions.
1.202
1.203 - def LoadConst(self, operand):
1.204 - self.LoadContext(operand)
1.205 - self.LoadValue(operand)
1.206 + def Transfer(self, operand, instruction):
1.207 + self.registers[instruction.target] = self.registers[instruction.source]
1.208
1.209 - def LoadClass(self, operand):
1.210 - self.LoadContext(PlaceholderContext)
1.211 - self.LoadValue(operand)
1.212 + def LoadConst(self, operand, instruction):
1.213 + self.LoadImmediate(operand, self.context_of(instruction.target))
1.214 + self.LoadImmediate(operand, instruction.target)
1.215 +
1.216 + def LoadClass(self, operand, instruction):
1.217 + self.LoadImmediate(PlaceholderContext, self.context_of(instruction.target))
1.218 + self.LoadImmediate(operand, instruction.target)
1.219
1.220 - def LoadFunction(self, operand):
1.221 - self.LoadContext(ReplaceableContext)
1.222 - self.LoadValue(operand)
1.223 + def LoadFunction(self, operand, instruction):
1.224 + self.LoadImmediate(ReplaceableContext, self.context_of(instruction.target))
1.225 + self.LoadImmediate(operand, instruction.target)
1.226
1.227 - def LoadName(self, operand):
1.228 + def LoadName(self, operand, instruction):
1.229 + data = self.load_from_frame(operand)
1.230 + self.LoadImmediate(data.context, self.context_of(instruction.target))
1.231 + self.LoadImmediate(data.ref, instruction.target)
1.232 +
1.233 + def StoreName(self, operand, instruction):
1.234 frame = self.local_sp_stack[-1]
1.235 - data = self.frame_stack[frame + operand]
1.236 - self.LoadContext(data.context)
1.237 - self.LoadValue(data.ref)
1.238 -
1.239 - def StoreName(self, operand):
1.240 - frame = self.local_sp_stack[-1]
1.241 - self.frame_stack[frame + operand] = DataValue(self.source_context, self.source_value)
1.242 + self.frame_stack[frame + operand] = DataValue(
1.243 + self.registers[self.context_of(instruction.source)],
1.244 + self.registers[instruction.source])
1.245
1.246 LoadTemp = LoadName
1.247
1.248 - def StoreTemp(self, operand):
1.249 + def StoreTemp(self, operand, instruction):
1.250 frame = self.local_sp_stack[-1]
1.251 - self.frame_stack[frame + operand] = DataValue(self.context, self.value)
1.252 + self.frame_stack[frame + operand] = DataValue(
1.253 + self.registers[self.context_of(instruction.working)],
1.254 + self.registers[instruction.working])
1.255
1.256 - def LoadAddress(self, operand):
1.257 + def LoadAddress(self, operand, instruction):
1.258 # Preserve context (potentially null).
1.259 data = self.load(operand)
1.260 - self.LoadContext(data.context)
1.261 - self.LoadValue(data.ref)
1.262 + self.LoadImmediate(data.context, self.context_of(instruction.target))
1.263 + self.LoadImmediate(data.ref, instruction.target)
1.264
1.265 - def LoadAddressContext(self, operand):
1.266 + def LoadAddressContext(self, operand, instruction):
1.267 # Value becomes context.
1.268 data = self.load(operand)
1.269 - self.LoadContext(self.value)
1.270 - self.LoadValue(data.ref)
1.271 + self.LoadImmediate(self.registers[instruction.working], self.context_of(instruction.target))
1.272 + self.LoadImmediate(data.ref, instruction.target)
1.273
1.274 - def LoadAddressContextCond(self, operand):
1.275 + def LoadAddressContextCond(self, operand, instruction):
1.276 data = self.load(operand)
1.277 - data = self._LoadAddressContextCond(data.context, data.ref, self.value)
1.278 - self.LoadContext(data.context)
1.279 - self.LoadValue(data.ref)
1.280 + data = self._LoadAddressContextCond(data.context, data.ref, self.registers[instruction.working])
1.281 + self.LoadImmediate(data.context, self.context_of(instruction.target))
1.282 + self.LoadImmediate(data.ref, instruction.target)
1.283
1.284 - def StoreAddress(self, operand):
1.285 + def StoreAddress(self, operand, instruction):
1.286 # Preserve context.
1.287 - self.save(operand, DataValue(self.source_context, self.source_value))
1.288 + self.save(operand, DataValue(
1.289 + self.registers[self.context_of(instruction.source)],
1.290 + self.registers[instruction.source]))
1.291
1.292 - def StoreAddressContext(self, operand):
1.293 + def StoreAddressContext(self, operand, instruction):
1.294 # Overwrite context if null.
1.295 - self._StoreAddressContext(operand, self.context, self.value, self.source_context, self.source_value)
1.296 + self._StoreAddressContext(operand,
1.297 + self.registers[self.context_of(instruction.working)],
1.298 + self.registers[instruction.working],
1.299 + self.registers[self.context_of(instruction.source)],
1.300 + self.registers[instruction.source])
1.301
1.302 - def MakeInstance(self, size):
1.303 + def MakeInstance(self, size, instruction):
1.304 # NOTE: Referencing the instance template.
1.305 - addr = self._MakeObject(size, self.value - Library.instance_template_size)
1.306 + addr = self._MakeObject(size, self.registers[instruction.working] - Library.instance_template_size)
1.307 # Introduce object as context for the new object.
1.308 - self.LoadContext(addr)
1.309 - self.LoadValue(addr)
1.310 + self.LoadImmediate(addr, self.context_of(instruction.target))
1.311 + self.LoadImmediate(addr, instruction.target)
1.312
1.313 - def MakeFragment(self, size):
1.314 + def MakeFragment(self, size, instruction):
1.315 # Reserve twice the amount of space.
1.316 addr = self._MakeFragment(size, size * 2)
1.317 # NOTE: Context is not relevant for fragments.
1.318 - self.LoadContext(None)
1.319 - self.LoadValue(addr)
1.320 + self.LoadImmediate(None, self.context_of(instruction.target))
1.321 + self.LoadImmediate(addr, instruction.target)
1.322
1.323 - def LoadAttr(self, pos):
1.324 + def LoadAttr(self, pos, instruction):
1.325 # Retrieved context should already be appropriate for the instance.
1.326 - # NOTE: Adding 1 to skip any header.
1.327 - data = self.load(self.value + pos + 1)
1.328 - self.LoadContext(data.context)
1.329 - self.LoadValue(data.ref)
1.330 + # Skip any header.
1.331 + data = self.load(self.registers[instruction.working] + Library.instance_data_offset + pos)
1.332 + self.LoadImmediate(data.context, self.context_of(instruction.target))
1.333 + self.LoadImmediate(data.ref, instruction.target)
1.334
1.335 - def StoreAttr(self, pos):
1.336 + def StoreAttr(self, pos, instruction):
1.337 # Target should already be an instance.
1.338 - # NOTE: Adding 1 to skip any header.
1.339 - self.save(self.value + pos + 1, DataValue(self.source_context, self.source_value))
1.340 + # Skip any header.
1.341 + self.save(self.registers[instruction.working] + Library.instance_data_offset + pos , DataValue(
1.342 + self.registers[self.context_of(instruction.source)],
1.343 + self.registers[instruction.source]))
1.344
1.345 - def LoadAttrIndex(self, index):
1.346 - data = self.load(self.value)
1.347 + def LoadAttrIndex(self, index, instruction):
1.348 + data = self.load(self.registers[instruction.working])
1.349 element = self.objlist[data.classcode + index]
1.350
1.351 if element is not None:
1.352 @@ -534,18 +527,18 @@
1.353 if static_attr:
1.354 data = self.load(offset) # offset is address of class/module attribute
1.355 else:
1.356 - data = self.load(self.value + offset)
1.357 - self.LoadContext(data.context)
1.358 - self.LoadValue(data.ref)
1.359 + data = self.load(self.registers[instruction.working] + offset)
1.360 + self.LoadImmediate(data.context, self.context_of(instruction.target))
1.361 + self.LoadImmediate(data.ref, instruction.target)
1.362 return
1.363
1.364 - self.exception = self._MakeObject(Library.instance_size, self.attr_error_instance)
1.365 + self.registers["exception"] = self._MakeObject(Library.instance_size, self.attr_error_instance)
1.366 return self.RaiseException()
1.367
1.368 # LoadAttrIndexContext not defined.
1.369
1.370 - def LoadAttrIndexContextCond(self, index):
1.371 - data = self.load(self.value)
1.372 + def LoadAttrIndexContextCond(self, index, instruction):
1.373 + data = self.load(self.registers[instruction.working])
1.374 element = self.objlist[data.classcode + index]
1.375
1.376 if element is not None:
1.377 @@ -555,95 +548,102 @@
1.378 loaded_data = self.load(offset) # offset is address of class/module attribute
1.379 # Absent attrcode == class/module.
1.380 if data.attrcode is not None:
1.381 - loaded_data = self._LoadAddressContextCond(loaded_data.context, loaded_data.ref, self.value)
1.382 + loaded_data = self._LoadAddressContextCond(
1.383 + loaded_data.context, loaded_data.ref,
1.384 + self.registers[instruction.working])
1.385 else:
1.386 - loaded_data = self.load(self.value + offset)
1.387 - self.LoadContext(loaded_data.context)
1.388 - self.LoadValue(loaded_data.ref)
1.389 + loaded_data = self.load(self.registers[instruction.working] + offset)
1.390 + self.LoadImmediate(loaded_data.context, self.context_of(instruction.target))
1.391 + self.LoadImmediate(loaded_data.ref, instruction.target)
1.392 return
1.393
1.394 - self.exception = self._MakeObject(Library.instance_size, self.attr_error_instance)
1.395 + self.registers["exception"] = self._MakeObject(Library.instance_size, self.attr_error_instance)
1.396 return self.RaiseException()
1.397
1.398 - def StoreAttrIndex(self, index):
1.399 - data = self.load(self.value)
1.400 + def StoreAttrIndex(self, index, instruction):
1.401 + data = self.load(self.registers[instruction.working])
1.402 element = self.objlist[data.classcode + index]
1.403
1.404 if element is not None:
1.405 attr_index, static_attr, offset = element
1.406 if attr_index == index:
1.407 if static_attr:
1.408 - self._StoreAddressContext(offset, self.context, self.value, self.source_context, self.source_value)
1.409 + self._StoreAddressContext(offset,
1.410 + self.registers[self.context_of(instruction.working)],
1.411 + self.registers[instruction.working],
1.412 + self.registers[self.context_of(instruction.source)],
1.413 + self.registers[instruction.source])
1.414 return
1.415 else:
1.416 - self.save(self.value + offset, DataValue(self.source_context, self.source_value))
1.417 + self.save(self.registers[instruction.working] + offset, DataValue(
1.418 + self.registers[self.context_of(instruction.source)],
1.419 + self.registers[instruction.source]))
1.420 return
1.421
1.422 - self.exception = self._MakeObject(Library.instance_size, self.attr_error_instance)
1.423 + self.registers["exception"] = self._MakeObject(Library.instance_size, self.attr_error_instance)
1.424 return self.RaiseException()
1.425
1.426 # NOTE: LoadAttrIndexContext is a possibility if a particular attribute can always be overridden.
1.427
1.428 - def MakeFrame(self, size):
1.429 + def MakeFrame(self, size, instruction):
1.430 self.invocation_sp_stack.append(len(self.frame_stack))
1.431 self.frame_stack.extend([None] * size)
1.432
1.433 - def DropFrame(self, operand=None):
1.434 + def DropFrame(self, operand, instruction):
1.435 self.local_sp_stack.pop()
1.436 frame = self.invocation_sp_stack.pop()
1.437 del self.frame_stack[frame:] # reset stack before call
1.438
1.439 - def StoreFrame(self, pos):
1.440 + def StoreFrame(self, pos, instruction):
1.441 frame = self.invocation_sp_stack[-1] # different from the current frame after MakeFrame
1.442 - self.frame_stack[frame + pos] = DataValue(self.context, self.value)
1.443 + self.frame_stack[frame + pos] = DataValue(
1.444 + self.registers[self.context_of(instruction.working)],
1.445 + self.registers[instruction.working])
1.446
1.447 - def StoreFrameIndex(self, index):
1.448 + def StoreFrameIndex(self, index, instruction):
1.449 frame = self.invocation_sp_stack[-1] # different from the current frame after MakeFrame
1.450 - data = self.load(self.value)
1.451 + data = self.load(self.registers[instruction.working])
1.452 element = self.paramlist[data.funccode + index]
1.453
1.454 if element is not None:
1.455 # NOTE: Need to ensure correct positioning where a context has been generated.
1.456 param_index, offset = element
1.457 if param_index == index:
1.458 - self.frame_stack[frame + offset] = DataValue(self.source_context, self.source_value)
1.459 + self.frame_stack[frame + offset] = DataValue(
1.460 + self.registers[self.context_of(instruction.source)],
1.461 + self.registers[instruction.source])
1.462 return
1.463
1.464 - self.exception = self._MakeObject(Library.instance_size, self.type_error_instance)
1.465 + self.registers["exception"] = self._MakeObject(Library.instance_size, self.type_error_instance)
1.466 return self.RaiseException()
1.467
1.468 - def LoadCallable(self, operand=None):
1.469 - data = self.load(self.value)
1.470 - self.callable = data.codeaddr
1.471 -
1.472 - def StoreCallable(self, operand=None):
1.473 - # NOTE: Should improve the representation and permit direct saving.
1.474 - data = self.load(self.value)
1.475 - self.save(self.value, data.with_callable(self.callable))
1.476 + def LoadCallable(self, operand, instruction):
1.477 + data = self.load(self.registers[instruction.working])
1.478 + self.registers[instruction.target] = data.codeaddr
1.479
1.480 - def LoadContextIntoValue(self, operand=None):
1.481 - # NOTE: Omission of the context of the context would make things like
1.482 - # NOTE: self() inside methods impossible.
1.483 - self.LoadValue(self.context)
1.484 + def StoreCallable(self, operand, instruction):
1.485 + # NOTE: Should improve the representation and permit direct saving.
1.486 + data = self.load(self.registers[instruction.working])
1.487 + self.save(self.registers[instruction.working], data.with_callable(self.registers[instruction.source]))
1.488
1.489 - def CheckContext(self, operand=None):
1.490 - self.status = self.value is not ReplaceableContext
1.491 + def CheckContext(self, operand, instruction):
1.492 + self.registers[instruction.target] = self.registers[instruction.working] is not ReplaceableContext
1.493
1.494 - def CheckClass(self, operand=None):
1.495 - if self.value in (ReplaceableContext, PlaceholderContext):
1.496 - self.status = 0
1.497 + def CheckClass(self, operand, instruction):
1.498 + if self.registers[instruction.working] in (ReplaceableContext, PlaceholderContext):
1.499 + self.registers[instruction.target] = 0
1.500 return
1.501
1.502 - data = self.load(self.value)
1.503 + data = self.load(self.registers[instruction.working])
1.504
1.505 # Classes are not themselves usable as the self argument.
1.506 # NOTE: This may change at some point.
1.507 # However, where classes appear as the context, instance
1.508 # compatibility is required in the first argument.
1.509
1.510 - self.status = data.attrcode is None # absent attrcode == class
1.511 + self.registers[instruction.target] = data.attrcode is None # absent attrcode == class
1.512
1.513 - def CheckFrame(self, operand):
1.514 + def CheckFrame(self, operand, instruction):
1.515 (nargs, ndefaults) = operand
1.516
1.517 # The frame is actually installed as the locals.
1.518 @@ -654,10 +654,10 @@
1.519
1.520 if not ((nargs - ndefaults) <= nlocals):
1.521 raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (operand, nargs - ndefaults, nlocals, nargs)
1.522 - self.exception = self._MakeObject(Library.instance_size, self.type_error_instance)
1.523 + self.registers["exception"] = self._MakeObject(Library.instance_size, self.type_error_instance)
1.524 return self.RaiseException()
1.525
1.526 - def CheckExtra(self, nargs):
1.527 + def CheckExtra(self, nargs, instruction):
1.528
1.529 # The frame is actually installed as the locals.
1.530 # Retrieve the context from the first local.
1.531 @@ -670,7 +670,7 @@
1.532 if nlocals == nargs:
1.533 self.frame_stack.extend([None]) # ExtendFrame(1)
1.534
1.535 - def FillDefaults(self, operand):
1.536 + def FillDefaults(self, operand, instruction):
1.537 (nargs, ndefaults) = operand
1.538
1.539 # The frame is actually installed as the locals.
1.540 @@ -686,11 +686,14 @@
1.541 pos = nlocals
1.542
1.543 while pos < nargs:
1.544 - self.frame_stack[frame + pos] = self.load(self.value + default + 1) # skip header
1.545 +
1.546 + # Skip any header.
1.547 +
1.548 + self.frame_stack[frame + pos] = self.load(self.registers[instruction.working] + Library.instance_data_offset + default)
1.549 default += 1
1.550 pos += 1
1.551
1.552 - def CopyExtra(self, start):
1.553 + def CopyExtra(self, start, instruction):
1.554
1.555 # The frame is the source of the extra arguments.
1.556
1.557 @@ -705,84 +708,74 @@
1.558 pos = start
1.559
1.560 while pos < nlocals:
1.561 - self.save(ref + extra + 1, self.frame_stack[frame + pos]) # skip header when storing
1.562 +
1.563 + # Skip any header.
1.564 +
1.565 + self.save(ref + Library.instance_data_offset + extra, self.frame_stack[frame + pos])
1.566 extra += 1
1.567 pos += 1
1.568
1.569 - self.LoadContext(ref)
1.570 - self.LoadValue(ref)
1.571 + self.LoadImmediate(ref, self.context_of(instruction.working))
1.572 + self.LoadImmediate(ref, instruction.working)
1.573
1.574 - def CheckInstance(self, operand=None):
1.575 + def CheckInstance(self, operand, instruction):
1.576 # For the 'self' parameter in an invoked function, the proposed context
1.577 # ('self') is checked against the target's context.
1.578 - self.status = self._CheckInstance(self.value, self.source_value)
1.579 + self.registers[instruction.target] = self._CheckInstance(
1.580 + self.registers[instruction.working],
1.581 + self.registers[instruction.source])
1.582
1.583 - def JumpInFrame(self, operand=None):
1.584 - codeaddr = self.callable
1.585 + def JumpInFrame(self, operand, instruction):
1.586 + codeaddr = self.registers[instruction.working]
1.587 return self.jump(codeaddr, self.pc + 1) # return to the instruction after this one
1.588
1.589 - def JumpWithFrame(self, operand=None):
1.590 - codeaddr = self.callable
1.591 + def JumpWithFrame(self, operand, instruction):
1.592 + codeaddr = self.registers[instruction.working]
1.593 self.local_sp_stack.append(self.invocation_sp_stack[-1]) # adopt the invocation frame
1.594 return self.jump(codeaddr, self.pc + 1) # return to the instruction after this one
1.595
1.596 - def JumpWithFrameDirect(self, addr):
1.597 + def JumpWithFrameDirect(self, addr, instruction):
1.598 self.local_sp_stack.append(self.invocation_sp_stack[-1]) # adopt the invocation frame
1.599 return self.jump(addr, self.pc + 1) # return to the instruction after this one
1.600
1.601 - def ExtendFrame(self, size):
1.602 + def ExtendFrame(self, size, instruction):
1.603 self.frame_stack.extend([None] * size)
1.604
1.605 - def AdjustFrame(self, size):
1.606 + def AdjustFrame(self, size, instruction):
1.607 self.invocation_sp_stack[-1] += size
1.608
1.609 - def Return(self, operand=None):
1.610 + def Return(self, operand, instruction):
1.611 return self.pull_pc()
1.612
1.613 - def LoadResultIntoValue(self, operand=None):
1.614 - self.LoadContext(self.result_context)
1.615 - self.LoadValue(self.result_value)
1.616 -
1.617 - def LoadValueIntoResult(self, operand=None):
1.618 - self.result_context = self.context
1.619 - self.result_value = self.value
1.620 -
1.621 - def Jump(self, addr):
1.622 + def Jump(self, addr, instruction):
1.623 return addr
1.624
1.625 - def JumpIfTrue(self, addr):
1.626 - if self.status:
1.627 - return addr
1.628 -
1.629 - def JumpIfFalse(self, addr):
1.630 - if not self.status:
1.631 + def JumpIfTrue(self, addr, instruction):
1.632 + if self.registers[instruction.working]:
1.633 return addr
1.634
1.635 - def LoadException(self, operand=None):
1.636 - self.LoadContext(self.exception)
1.637 - self.LoadValue(self.exception)
1.638 -
1.639 - def StoreException(self, operand=None):
1.640 - self.exception = self.value
1.641 + def JumpIfFalse(self, addr, instruction):
1.642 + if not self.registers[instruction.working]:
1.643 + return addr
1.644
1.645 - def ClearException(self, operand=None):
1.646 - self.exception = None
1.647 + def ClearException(self, operand, instruction):
1.648 + self.LoadImmediate(None, instruction.target)
1.649
1.650 - def RaiseException(self, operand=None):
1.651 + def RaiseException(self, operand=None, instruction=None):
1.652 # NOTE: Adding the program counter as the first attribute after __class__.
1.653 - self.save(self.exception + Library.instance_data_offset, self.pc)
1.654 + self.save(self.registers["exception"] + Library.instance_data_offset, self.pc)
1.655 # Jumping to the current handler.
1.656 if self.abort_upon_exception:
1.657 raise Exception
1.658 return self.handler_stack[-1]
1.659
1.660 - def PushHandler(self, addr):
1.661 + def PushHandler(self, addr, instruction):
1.662 self.handler_stack.append(addr)
1.663 self.handler_local_sp_stack.append(len(self.local_sp_stack))
1.664 self.handler_invocation_sp_stack.append(len(self.invocation_sp_stack))
1.665 self.handler_pc_stack.append(len(self.pc_stack))
1.666
1.667 - def PopHandler(self, nframes):
1.668 + def PopHandler(self, nframes, instruction):
1.669 # Get the new local frame pointer and PC stack references.
1.670 local_sp_top = self.handler_local_sp_stack[-nframes]
1.671 invocation_sp_top = self.handler_invocation_sp_stack[-nframes]
1.672 @@ -799,20 +792,18 @@
1.673 del self.handler_invocation_sp_stack[-nframes:]
1.674 del self.handler_stack[-nframes:]
1.675
1.676 - def CheckException(self, operand=None):
1.677 - self.status = self.exception is not None and self._CheckInstance(self.exception, self.value)
1.678 -
1.679 - def TestIdentity(self, operand=None):
1.680 - self.status = self.value == self.source_value
1.681 + def CheckException(self, operand, instruction):
1.682 + self.registers[instruction.target] = self.registers["exception"] is not None and \
1.683 + self._CheckInstance(self.registers["exception"], self.registers[instruction.working])
1.684
1.685 - def TestIdentityAddress(self, addr):
1.686 - self.status = self.value == addr
1.687 + def TestIdentity(self, operand, instruction):
1.688 + self.registers[instruction.target] = self.registers[instruction.working] == self.registers[instruction.source]
1.689
1.690 - # LoadBoolean is implemented in the generated code.
1.691 - # StoreBoolean is implemented by testing against the True value.
1.692 + def TestIdentityAddress(self, addr, instruction):
1.693 + self.registers[instruction.target] = self.registers[instruction.working] == addr
1.694
1.695 - def InvertBoolean(self, operand=None):
1.696 - self.status = not self.status
1.697 + def InvertBoolean(self, operand, instruction):
1.698 + self.registers[instruction.target] = not self.registers[instruction.source]
1.699
1.700 # Common implementation details.
1.701