def test_fix_blocks(self): """fix blocks should update instruction offsets for removed NOPs""" byte_code = self.make_byte_code( (opmap["NOP"], 0), (opmap["JUMP_FORWARD"], 6), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), ) opt = Optimizer(byte_code, (None,), b"\x01\x01", opcodes) opt.fix_blocks() self.assertEqual(opt.blocks, [0, 0, 1, 2, 3, 4])
def test_fix_lnotab(self): """basic smoke test that fix_lnotab removes NOPs""" byte_code = self.make_byte_code( (opmap["NOP"], 0), (opmap["JUMP_FORWARD"], 6), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), ) opt = Optimizer(byte_code, (None,), b"\x02\x01", opcodes) opt.fix_blocks() lnotab = bytes(opt.fix_lnotab()) self.assertEqual(lnotab, b"\x00\x01")
def test_fix_jump_rel(self): """basic smoke test that fix_lnotab removes NOPs""" byte_code = self.make_byte_code( (opmap["JUMP_FORWARD"], 6), (opmap["NOP"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), ) self.assertInBytecode( self.new_code(byte_code, constants=(None,)), "JUMP_FORWARD", 8 ) opt = Optimizer(byte_code, (None,), b"", opcodes) opt.fix_blocks() code = self.new_code(bytes(opt.fix_jumps()), constants=(None,)) self.assertInBytecode(code, "JUMP_FORWARD", 6)
def test_mark_blocks_rel_jump(self): byte_code = self.make_byte_code( (opmap["JUMP_FORWARD"], 6), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), ) opt = Optimizer(byte_code, (None,), b"", opcodes) self.assertEqual(opt.blocks, [0, 0, 0, 0, 1])
def test_mark_blocks_abs_jump(self): byte_code = self.make_byte_code( (opmap["LOAD_CONST"], 0), (opmap["POP_JUMP_IF_TRUE"], 8), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), ) opt = Optimizer(byte_code, (None,), b"", opcodes) self.assertEqual(opt.blocks, [0, 0, 0, 0, 1, 1])
def test_fix_jump_drop_extended(self): """Handle EXTENDED_ARG removal correctly""" ops = [ (opmap["LOAD_CONST"], 0), (opmap["EXTENDED_ARG"], 1), (opmap["POP_JUMP_IF_TRUE"], 3), *(((opmap["NOP"], 0),) * 256), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), ] byte_code = self.make_byte_code(*ops) self.assertInBytecode( self.new_code(byte_code, constants=(None,)), "POP_JUMP_IF_TRUE", 259 ) opt = Optimizer(byte_code, (None,), b"", opcodes) opt.fix_blocks() code = self.new_code(bytes(opt.fix_jumps()), constants=(None,)) self.assertInBytecode(code, "EXTENDED_ARG", 0) self.assertInBytecode(code, "POP_JUMP_IF_TRUE", 6)
def test_mark_blocks_one_block(self): byte_code = self.make_byte_code( (opmap["LOAD_CONST"], 0), (opmap["RETURN_VALUE"], 0), constants=(None,) ) opt = Optimizer(byte_code, (None,), b"", opcodes) self.assertEqual(opt.blocks, [0, 0])