def interpret_instruction(self) -> Continue: inst = self.instructions[self.pc] methodname = "exec_" + inst.opname.lower() try: method = self.__getattribute__(methodname) ret: ProgressType = method(inst) except AttributeError as e: print(e) return self._exec_debug(inst) # Unify return types into Continue # None case out: Continue if ret is None: self.pc += 1 return DEFAULT_CONTINUE # Just PauseReason if isinstance(ret, Continue): out = ret else: out = Continue(ret) if out.kind == PauseReason.NORMAL: self.pc += 1 elif out.kind == PauseReason.YIELD: self.pc += 1 return out
def check(self, sc: StateController) -> bool: self.interp.state_controller = sc cont = Continue() while not cont.kind == PauseReason.DONE: cont = self.interp.interpret_instruction() self.interp.state_controller = None return self.interp.return_val
def execute(self, state_controller) -> Continue: assert self.can_execute() try: self.steps[self.pc]._eval(self.state) self.pc += 1 except StopProcess: self.pc = -1 return Continue(PauseReason.YIELD)
def on_store_fast(self, name, val): self.state[name] = val if isinstance(val, NonDeterministicSet): return Continue( kind=PauseReason.YIELD, yield_msg=f"NonDeterminism({name})", fairness=Fairness.IMMEDIATE, ) return None
def execute(self, state_controller): self.interp.state_controller = state_controller cont = Continue() while self.interp.pc < len(self.interp.instructions): try: cont = self.interp.interpret_instruction() except Exception as e: raise ProcessException(f"{self.name}@{self.interp.pc}", e) if cont.kind == PauseReason.DONE or cont.kind == PauseReason.YIELD: break if cont.kind == PauseReason.YIELD: if cont.yield_msg != "": self._stepname = cont.yield_msg self.interp.state_controller = None return cont
def exec_yield_value(self, inst): return Continue(PauseReason.YIELD, self.stack[-1])
import operator from timewinder.pause import Continue from timewinder.pause import PauseReason from typing import Any from typing import List from typing import Dict from typing import Optional from typing import Union from typing import TYPE_CHECKING if TYPE_CHECKING: from .interpreter import Interpreter ProgressType = Optional[Union[PauseReason, Continue]] DEFAULT_CONTINUE = Continue() class OpcodeInterpreter: def __init__(self, proc: "Interpreter", instructions): self.proc = proc self.stack: List[Any] = [] self.instructions: Dict[int, dis.Instruction] = { i: inst for (i, inst) in enumerate(instructions) } self.pc = 0 def push_stack(self, v: Any): # As a debugging strategy, find when an unusual value is pushed on the # stack and start a breakpoint, right here.
def on_return(self, val): self.return_val = val return Continue(PauseReason.DONE)