diff options
| author | 2023-02-25 21:01:03 +0000 | |
|---|---|---|
| committer | 2023-02-25 21:01:03 +0000 | |
| commit | 09d636c02cdbb13d10f1435d918cc36116715fc4 (patch) | |
| tree | c7099a6c49ffa4521e144c5ed5a19186d08ec1ec /asm | |
| parent | get rid of unused lablen (diff) | |
export creole_decode; add db test
Diffstat (limited to 'asm')
| -rw-r--r-- | asm/ffi.py | 25 | ||||
| -rw-r--r-- | asm/test.py | 10 |
2 files changed, 35 insertions, 0 deletions
@@ -44,6 +44,11 @@ class RunRet(Enum): def is_halt(self): return not (self == RunRet.CONTINUE or self == RunRet.SYSCALL) +class CWord(Structure): + _fields_ = [("len", c_int), + ("high_bits", c_int), + ("word", c_uint)] + class CReader(Structure): _fields_ = [("p", POINTER(c_ubyte)), ("left", c_size_t)] @@ -78,6 +83,8 @@ class InvalidSyscallError(Exception): class CompileError(Exception): def __init__(self, r): self.r = r +class DataOverflowError(Exception): + pass class Environment: def getreg(self, reg, signed=False): @@ -106,6 +113,24 @@ class Environment: return creole.from_2c(self.cenv.stk[stk]) else: return self.cenv.stk[stk] + def getdat(self, n): + if n >= self.cenv.datlen or n < 0: + raise DataOverflowError(n) + rdr = CReader() + rdr.p = self.cenv.dats[n] + # Python does not allow for direct pointer arithmetic + rdr_p_v = addressof(rdr.p.contents) + r_start_p_v = addressof(self.cenv.r_start.p) + + rdr.left = self.cenv.r_start.left - (rdr_p_v - r_start_p_v) + + l = [] + w = CWord() + while dll.creole_decode(byref(rdr), byref(w)) == 1: + if w.word == 0 and w.len == 1: + break + l.append(w.word) + return l def pop(self): if stk == 0: diff --git a/asm/test.py b/asm/test.py index e49d46d..986a06d 100644 --- a/asm/test.py +++ b/asm/test.py @@ -438,6 +438,16 @@ class DataTest(unittest.TestCase): p = Program() p.parse_asm_line("db d0 [4d2,1234,0,5]") self.assertEqual(p(), b'\x0b\xc0\x80\xe0\x93\x92\xf0\x81\x88\xb4\xc0\x80\xc0\x85\x00') + def test_alloc_multiple(self): + p = Program() + p.parse_lines([ + "db d0 [1,2,3,4]", + "db d1 [10,11,12,13]" + ]) + ex = ffi.Environment(p()) + self.assertEqual(ex(), ffi.RunRet.STOP) + self.assertEqual(ex.getdat(0), [1,2,3,4]) + self.assertEqual(ex.getdat(1), [0x10,0x11,0x12,0x13]) class SCEnv(ffi.Environment): def syscall(self, s): |
