add stack overflow and underflow tests

This commit is contained in:
Peter McGoron 2023-02-11 17:27:29 +00:00
parent 07347d1f66
commit b80cb225a4
2 changed files with 51 additions and 16 deletions

View File

@ -165,18 +165,18 @@ class Line:
self.opcode = opcode self.opcode = opcode
self.args = args self.args = args
def check_line(self, labnum, regnum): def check_line(self, lablen, reglen):
for a in self.args: for a in self.args:
if a[0] == ArgType.REG: if a[0] == ArgType.REG:
if a[1] < 0 or a[1] >= regnum: if a[1] < 0 or a[1] >= reglen:
raise RangeCheckException(a[0], raise RangeCheckException(a[0],
a[1], a[1],
regnum) reglen)
elif a[0] == ArgType.LAB: elif a[0] == ArgType.LAB:
if a[1] < 0 or a[1] >= labnum: if a[1] < 0 or a[1] >= lablen:
raise RangeCheckException(a[0], raise RangeCheckException(a[0],
a[1], a[1],
regnum) reglen)
def __call__(self): def __call__(self):
b = bytes([self.opcode]) b = bytes([self.opcode])
@ -193,7 +193,7 @@ class InstructionNotFoundException(Exception):
class Program: class Program:
def asm_push_line(self, ins, args): def asm_push_line(self, ins, args):
l = Line(ins, args) l = Line(ins, args)
l.check_line(self.labnum, self.regnum) l.check_line(self.lablen, self.reglen)
self.asm.append(l) self.asm.append(l)
def parse_asm_line(self, line): def parse_asm_line(self, line):
@ -214,8 +214,8 @@ class Program:
b = b + line() b = b + line()
return b return b
def __init__(self, labnum=16, regnum=16): def __init__(self, lablen=16, reglen=16):
self.asm = [] self.asm = []
self.labnum = labnum self.lablen = lablen
self.regnum = regnum self.reglen = reglen

View File

@ -47,7 +47,7 @@ class PushTest(unittest.TestCase):
self.assertEqual(cm.exception.argtypelen, 1) self.assertEqual(cm.exception.argtypelen, 1)
def test_large_reg(self): def test_large_reg(self):
p = Program(regnum=0x8000000) p = Program(reglen=0x8000000)
p.parse_asm_line("PUSH r134217727") p.parse_asm_line("PUSH r134217727")
b = p() b = p()
self.assertEqual(b, b'\x01\xFC\x87\xbf\xbf\xbf\xbf\x00') self.assertEqual(b, b'\x01\xFC\x87\xbf\xbf\xbf\xbf\x00')
@ -78,6 +78,26 @@ class PushTest(unittest.TestCase):
self.assertEqual(ex.cenv.prg[1].w[1], 0) self.assertEqual(ex.cenv.prg[1].w[1], 0)
self.assertEqual(ex.cenv.prg[1].w[2], 0) self.assertEqual(ex.cenv.prg[1].w[2], 0)
def test_push_many(self):
p = Program()
stklen = 40
for n in range(0,stklen):
p.parse_asm_line("PUSH 5")
ex = ffi.Environment(stklen=stklen)
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
self.assertEqual(ex(), ffi.RunRet.STOP)
for n in range(0,stklen):
self.assertEqual(ex.cenv.stk[n], 5)
def test_push_overflow(self):
p = Program()
stklen = 40
for n in range(0, stklen + 1):
p.parse_asm_line("PUSH 5")
ex = ffi.Environment(stklen=stklen)
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
self.assertEqual(ex(), ffi.RunRet.STACK_OVERFLOW)
class PopTest(unittest.TestCase): class PopTest(unittest.TestCase):
def test_compile_pop_reg(self): def test_compile_pop_reg(self):
p = Program() p = Program()
@ -117,18 +137,33 @@ class PopTest(unittest.TestCase):
def test_compile_throw_argument_overflow(self): def test_compile_throw_argument_overflow(self):
p = Program() p = Program()
with self.assertRaises(TypecheckLenException) as cm: with self.assertRaises(TypecheckLenException) as cm:
p.parse_asm_line("push r1 r2") p.parse_asm_line("pop r1 r2")
self.assertEqual(cm.exception.opcode, 1) self.assertEqual(cm.exception.opcode, 2)
self.assertEqual(cm.exception.insargs, ["r1", "r2"]) self.assertEqual(cm.exception.insargs, ["r1", "r2"])
self.assertEqual(cm.exception.argtypelen, 1) self.assertEqual(cm.exception.argtypelen, 1)
def test_catch_typecheck_argument_underflow(self): def test_catch_typecheck_argument_underflow(self):
p = Program() p = Program()
with self.assertRaises(TypecheckLenException) as cm: with self.assertRaises(TypecheckLenException) as cm:
p.parse_asm_line("push") p.parse_asm_line("pop")
self.assertEqual(cm.exception.opcode, 1) self.assertEqual(cm.exception.opcode, 2)
self.assertEqual(cm.exception.insargs, []) self.assertEqual(cm.exception.insargs, [])
self.assertEqual(cm.exception.argtypelen, 1)
def test_pop_underflow(self):
p = Program()
p.parse_asm_line("pop r0")
ex = ffi.Environment()
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW)
def test_pop_underflow_2(self):
p = Program()
p.parse_asm_line("push 5")
p.parse_asm_line("pop r0")
p.parse_asm_line("pop r1")
ex = ffi.Environment()
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW)
class AddTest(unittest.TestCase): class AddTest(unittest.TestCase):
def test_exec_add(self): def test_exec_add(self):
@ -150,7 +185,6 @@ class AddTest(unittest.TestCase):
self.assertEqual(ex.cenv.reg[0], 30) self.assertEqual(ex.cenv.reg[0], 30)
self.assertEqual(ex.cenv.reg[1], word_2c(10)) self.assertEqual(ex.cenv.reg[1], word_2c(10))
class AddTest(unittest.TestCase):
def test_exec_mul_throw_imm(self): def test_exec_mul_throw_imm(self):
p = Program() p = Program()
with self.assertRaises(TypecheckException) as cm: with self.assertRaises(TypecheckException) as cm:
@ -187,6 +221,7 @@ class AddTest(unittest.TestCase):
self.assertEqual(cm.exception.i, 2) self.assertEqual(cm.exception.i, 2)
self.assertEqual(cm.exception.opcode, 3) self.assertEqual(cm.exception.opcode, 3)
class MulTest(unittest.TestCase):
def test_exec_mul_imm_imm(self): def test_exec_mul_imm_imm(self):
p = Program() p = Program()
p.parse_asm_line("mul r0 2 2") p.parse_asm_line("mul r0 2 2")