aboutsummaryrefslogtreecommitdiffstats
path: root/asm/ffi.py
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2023-02-25 21:01:03 +0000
committerGravatar Peter McGoron 2023-02-25 21:01:03 +0000
commit09d636c02cdbb13d10f1435d918cc36116715fc4 (patch)
treec7099a6c49ffa4521e144c5ed5a19186d08ec1ec /asm/ffi.py
parentget rid of unused lablen (diff)
export creole_decode; add db test
Diffstat (limited to 'asm/ffi.py')
-rw-r--r--asm/ffi.py25
1 files changed, 25 insertions, 0 deletions
diff --git a/asm/ffi.py b/asm/ffi.py
index 13731dd..e7903af 100644
--- a/asm/ffi.py
+++ b/asm/ffi.py
@@ -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: