feat: добавил статусы виртуальной машине
This commit is contained in:
29
src/vm.py
29
src/vm.py
@ -25,6 +25,11 @@ class VMCC(IntFlag):
|
|||||||
NEGATIVE = 1 << 1
|
NEGATIVE = 1 << 1
|
||||||
ZERO = 1 << 0
|
ZERO = 1 << 0
|
||||||
|
|
||||||
|
class VMStatus(Enum):
|
||||||
|
RUNNING = auto()
|
||||||
|
INITED = auto()
|
||||||
|
FINISHED = auto()
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Breakpoint(Exception):
|
class Breakpoint(Exception):
|
||||||
address: int
|
address: int
|
||||||
@ -48,15 +53,12 @@ class VM:
|
|||||||
registers: list[c_int32]
|
registers: list[c_int32]
|
||||||
breakpoints: set[int]
|
breakpoints: set[int]
|
||||||
_vm_flags: VMFlags
|
_vm_flags: VMFlags
|
||||||
|
status: VMStatus
|
||||||
|
|
||||||
def __init__(self, mem: bytearray):
|
def __init__(self, mem: bytearray):
|
||||||
self.mem: bytearray = mem
|
self._initial_mem = mem.copy()
|
||||||
self.cc: VMCC = VMCC(0)
|
|
||||||
self.pc: c_uint32 = c_uint32(0)
|
|
||||||
self.registers: list[c_int32] = [c_int32(0) for _ in range(256)]
|
|
||||||
self.breakpoints: set[int] = set()
|
|
||||||
self._vm_flags: VMFlags = VMFlags(0)
|
|
||||||
self.__init_callbacks__()
|
self.__init_callbacks__()
|
||||||
|
self.reset()
|
||||||
|
|
||||||
def __init_callbacks__(self):
|
def __init_callbacks__(self):
|
||||||
VM.instr_callbacks = {
|
VM.instr_callbacks = {
|
||||||
@ -119,16 +121,27 @@ class VM:
|
|||||||
self._branch_indexed_callback
|
self._branch_indexed_callback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.mem: bytearray = self._initial_mem.copy()
|
||||||
|
self.cc: VMCC = VMCC(0)
|
||||||
|
self.pc: c_uint32 = c_uint32(0)
|
||||||
|
self.registers: list[c_int32] = [c_int32(0) for _ in range(256)]
|
||||||
|
self.breakpoints: set[int] = set()
|
||||||
|
self._vm_flags: VMFlags = VMFlags(0)
|
||||||
|
self.status = VMStatus.INITED
|
||||||
|
|
||||||
def step(self) -> None:
|
def step(self) -> None:
|
||||||
"""
|
"""
|
||||||
Make one step (only step into)
|
Make one step (only step into)
|
||||||
"""
|
"""
|
||||||
if self._to_raw_bytes_offset(self.pc) > len(self.mem) - WORD_SIZE:
|
if self._to_raw_bytes_offset(self.pc) > len(self.mem) - WORD_SIZE:
|
||||||
|
self.status = VMStatus.FINISHED
|
||||||
raise VMException(
|
raise VMException(
|
||||||
VMExceptionType.END_OF_MEM,
|
VMExceptionType.END_OF_MEM,
|
||||||
self.pc.value,
|
self.pc.value,
|
||||||
"couldn't perform step because end of memory occured"
|
"couldn't perform step because end of memory occured"
|
||||||
)
|
)
|
||||||
|
self.status = VMStatus.RUNNING
|
||||||
opcode, *_ = instr = self._fetch_instr()
|
opcode, *_ = instr = self._fetch_instr()
|
||||||
opdesc = self._get_opcode_desc(opcode)
|
opdesc = self._get_opcode_desc(opcode)
|
||||||
args: tuple[int, ...] = self._parse_instr_fields(bytes(instr))
|
args: tuple[int, ...] = self._parse_instr_fields(bytes(instr))
|
||||||
@ -148,14 +161,16 @@ class VM:
|
|||||||
if self.pc.value in self.breakpoints:
|
if self.pc.value in self.breakpoints:
|
||||||
raise Breakpoint(self.pc.value)
|
raise Breakpoint(self.pc.value)
|
||||||
self.step()
|
self.step()
|
||||||
|
self.status = VMStatus.FINISHED
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""
|
"""
|
||||||
Run from very beginning
|
Run from very beginning
|
||||||
"""
|
"""
|
||||||
self.pc = c_uint32(0)
|
self.reset()
|
||||||
while (self._to_raw_bytes_offset(self.pc.value) < len(self.mem)):
|
while (self._to_raw_bytes_offset(self.pc.value) < len(self.mem)):
|
||||||
self.continue_()
|
self.continue_()
|
||||||
|
self.status = VMStatus.FINISHED
|
||||||
|
|
||||||
def _fetch_instr(self) -> bytearray:
|
def _fetch_instr(self) -> bytearray:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user