コード例 #1
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def free(self, size: int):
     if size < 0:
         raise errors.AtomCVMRuntimeError("negative size")
     if self._sp - size < 0:
         raise errors.AtomCVMRuntimeError("stack buffer underflow")
     self._sp -= size
     self._stack[self._sp:self._sp + size] = _sentinel(0xDEADBEEF, size)
コード例 #2
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def push(self, value, value_type: DataType):
     if not isinstance(value, value_type.python_type):
         raise errors.AtomCVMRuntimeError("wrong value type for push")
     try:
         self._push_bytes(struct.pack(value_type.fmt, value))
     except struct.error as e:
         raise errors.AtomCVMRuntimeError(f"push error: {str(e)}")
コード例 #3
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def alloc(self, size: int):
     if size < 0:
         raise errors.AtomCVMRuntimeError("negative size")
     if self._sp + size > self._size:
         raise errors.AtomCVMRuntimeError("out of stack memory")
     ret = self._sp
     self._stack[self._sp:self._sp + size] = _sentinel(0xBAADF00D, size)
     self._sp += size
     return ret
コード例 #4
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def read_string(self, addr: int) -> str:
     if addr < 0:
         raise errors.AtomCVMRuntimeError("out-of-bounds memory access")
     end = addr
     while self._stack[end] != 0 and end < self._size:
         end += 1
     if end >= self._size:
         raise errors.AtomCVMRuntimeError(
             "stack overflow while reading string")
     return self._stack[addr:end].decode('utf8')
コード例 #5
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def pop(self, value_type: DataType):
     try:
         return value_type.python_type(
             struct.unpack(value_type.fmt,
                           bytes(self._pop_bytes(value_type.size)))[0])
     except struct.error as e:
         raise errors.AtomCVMRuntimeError(f"pop error: {str(e)}")
コード例 #6
0
 def ip(self, addr: int):
     if addr not in range(0, len(self.program)):
         raise errors.AtomCVMRuntimeError(
             "Instruction pointer jumped out of program memory")
     self._ip = addr
     self._ip_jumped = True
     self._print_debug(f"ip jumped to {self.ip}")
コード例 #7
0
ファイル: builtin.py プロジェクト: axnsan12/atomc
def exec_builtin(name: str, st: 'stack.DataStack'):
    if name == 'put_s':
        _stdout(st.read_string(st.popa()))
    elif name == 'put_i':
        _stdout(st.popi())
    elif name == 'put_d':
        _stdout(st.popd())
    elif name == 'put_c':
        _stdout(chr(st.popc()))
    elif name == 'get_s':
        addr = st.popa()
        data = _stdin()
        st.write_at(addr, data.encode('utf8') + b'\0')
        st.pusha(addr)
        _stdout(data + '\n')
    elif name == 'get_i':
        val = int(_stdin())
        st.pushi(val)
        _stdout(str(val) + '\n')
    elif name == 'get_d':
        val = float(_stdin())
        st.pushd(val)
        _stdout(str(val) + '\n')
    elif name == 'get_c':
        val = ord(_stdin())
        st.pushc(val)
        _stdout(str(val) + '\n')
    elif name == 'seconds':
        st.pushd(float(time.monotonic()))
    else:
        raise errors.AtomCVMRuntimeError(f"Undefined builtin function {name}")
コード例 #8
0
 def execute(self):
     while not self._halted:
         if self.ip not in range(0, len(self.program)):
             raise errors.AtomCVMRuntimeError(
                 "Instruction pointer outside program memory")
         instr = self.program[self._ip]
         self._ip_jumped = False
         self._print_debug(f"executing `{instr}`@{instr.lineno}")
         instr.execute(self)
         if not self._ip_jumped:
             self._ip += 1
コード例 #9
0
ファイル: stack.py プロジェクト: axnsan12/atomc
    def _pop_bytes(self, count: int) -> bytearray:
        if self._sp - count < 0:
            raise errors.AtomCVMRuntimeError("stack buffer underflow")

        self._sp -= count
        return self._stack[self._sp:self._sp + count]
コード例 #10
0
ファイル: stack.py プロジェクト: axnsan12/atomc
    def _push_bytes(self, data: bytes):
        if self._sp + len(data) > self._size:
            raise errors.AtomCVMRuntimeError("out of stack memory")

        self._sp += len(data)
        self._stack[self._sp - len(data):self._sp] = data
コード例 #11
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def ret(self) -> int:
     if not self.stack:
         raise errors.AtomCVMRuntimeError("unbalanced call stack")
     return self.stack.pop()
コード例 #12
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def write_at(self, addr: int, data: bytes):
     if addr < 0 or addr + len(data) >= self._size:
         raise errors.AtomCVMRuntimeError("out-of-bounds memory access")
     self._stack[addr:addr + len(data)] = data
コード例 #13
0
ファイル: stack.py プロジェクト: axnsan12/atomc
 def read_from(self, addr: int, size: int) -> bytes:
     if size < 0:
         raise errors.AtomCVMRuntimeError("negative size")
     if addr < 0 or size < 0 or addr + size >= self._size:
         raise errors.AtomCVMRuntimeError("out-of-bounds memory access")
     return bytes(self._stack[addr:addr + size])
コード例 #14
0
 def __init__(self, from_type: 'stack.DataStack.DataType', to_type: 'stack.DataStack.DataType', lineno: int):
     super().__init__(f'CAST_{self.type_suffix(from_type)}_{self.type_suffix(to_type)}', lineno)
     self.from_type = from_type
     self.to_type = to_type
     if from_type == stack.ADDR or to_type == stack.ADDR:
         raise errors.AtomCVMRuntimeError(f"CAST cannot operate on addresses")
コード例 #15
0
 def __init__(self, data_type: 'stack.DataStack.DataType', op, mnemonic: str, lineno: int):
     super().__init__(mnemonic, lineno)
     self.data_type = data_type
     self.op = op
     if data_type == stack.ADDR:
         raise errors.AtomCVMRuntimeError("pointer arithmetic is not allowed")
コード例 #16
0
 def __init__(self, data_type: 'stack.DataStack.DataType', lineno: int):
     super().__init__('NEG_' + self.type_suffix(data_type), lineno)
     self.data_type = data_type
     if data_type == stack.ADDR:
         raise errors.AtomCVMRuntimeError("pointer arithmetic is not allowed")