add stack overflow and underflow tests
This commit is contained in:
parent
07347d1f66
commit
b80cb225a4
|
@ -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
|
||||||
|
|
||||||
|
|
49
asm/test.py
49
asm/test.py
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue