示例#1
0
  def testDiamond(self):
    self.assertEqual(self.codeDiamond.func_code.co_code,
                     self.codeDiamondBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeDiamond.func_code)
    expected = [(0, 15),
                (18, 28),
                (31, 38),
                (41, 44)]
    self.checkBlocks(table, expected)
    bb = table.get_basic_block
    # Check the POP_JUMP_IF_FALSE conditional jump
    self.assertItemsEqual(bb(0).outgoing, [bb(18), bb(31)])
    # Check the jumps at the end of the 2 of branches
    self.assertItemsEqual(bb(18).outgoing, [bb(41)])
    self.assertItemsEqual(bb(38).outgoing, [bb(41)])
    # Check the return
    self.assertItemsEqual(bb(44).outgoing, [None])
    # Check the incoming of the entry block
    self.assertItemsEqual(bb(0).incoming, [])
    # Check the incoming of the 2 if branches
    self.assertItemsEqual(bb(18).incoming, [bb(15)])
    self.assertItemsEqual(bb(31).incoming, [bb(15)])
    # Check incoming of the merge block.
    self.assertItemsEqual(bb(44).incoming, [bb(28), bb(38)])
示例#2
0
  def testNestedLoopsOrder(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeNestedLoops.func_code)

    bb = table.get_basic_block
    self.assertEqual(table.get_ancestors_first_traversal(),
                     [bb(o) for o in [0, 13, 16, 26, 29, 49, 50, 53, 54]])
示例#3
0
  def testNestedLoops(self):
    self.assertEqual(self.codeNestedLoops.func_code.co_code,
                     self.codeNestedLoopsBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeNestedLoops.func_code)
    expected = [(0, 12),
                (13, 13),
                (16, 25),
                (26, 26),
                (29, 46),
                (49, 49),
                (50, 50),
                (53, 53),
                (54, 57)]
    self.checkBlocks(table, expected)
    bb = table.get_basic_block
    self.assertItemsEqual(bb(13).incoming, [bb(12), bb(50)])
    self.assertItemsEqual(bb(13).outgoing, [bb(16), bb(53)])
    self.assertItemsEqual(bb(26).incoming, [bb(25), bb(46)])
    self.assertItemsEqual(bb(26).outgoing, [bb(29), bb(49)])
    self.assertEndsWith(
        bb(43).get_name(),
        "tests/test_pycfg.py:{}-{}".format(self.codeNestedLoopsLineNumber + 2,
                                           self.codeNestedLoopsLineNumber + 3))
示例#4
0
  def testRaiseOrder(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeRaise.func_code)

    bb = table.get_basic_block
    self.assertEqual(table.get_ancestors_first_traversal(),
                     [bb(o) for o in [0, 6, 9]])
示例#5
0
  def testDiamondOrder(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeDiamond.func_code)

    bb = table.get_basic_block
    self.assertEqual(table.get_ancestors_first_traversal(),
                     [bb(o) for o in [0, 18, 31, 41]])
示例#6
0
  def testLoopOrder(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeLoop.func_code)

    bb = table.get_basic_block
    self.assertEqual(table.get_ancestors_first_traversal(),
                     [bb(o) for o in [0, 13, 16, 32, 33]])
示例#7
0
  def testBreak(self):
    self.assertEqual(self.codeBreak.func_code.co_code,
                     self.codeBreakBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeBreak.func_code)
    bb = table.get_basic_block
    self.assertItemsEqual(bb(13).incoming, [bb(12), bb(49)])
    self.assertItemsEqual(bb(31).incoming, [bb(28)])
    self.assertItemsEqual(bb(31).outgoing, [None])
示例#8
0
  def testContinue(self):
    self.assertEqual(self.codeContinue.func_code.co_code,
                     self.codeContinueBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeContinue.func_code)
    bb = table.get_basic_block
    self.assertItemsEqual(bb(31).outgoing, [bb(13)])
    self.assertItemsEqual(bb(13).incoming, [bb(12), bb(51), bb(31)])
    self.assertItemsEqual(bb(13).outgoing, [bb(16), bb(54)])
示例#9
0
  def testLoopDominators(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeLoop.func_code)

    bb = table.get_basic_block
    self.assertEqual(bb(0)._dominators, {bb(0)})
    self.assertEqual(bb(13)._dominators, {bb(0), bb(13)})
    self.assertEqual(bb(16)._dominators, {bb(0), bb(13), bb(16)})
    self.assertEqual(bb(32)._dominators, {bb(0), bb(13), bb(32)})
    self.assertEqual(bb(33)._dominators,
                     {bb(0), bb(13), bb(32), bb(33)})
示例#10
0
  def testNestedLoopsReachable(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeNestedLoops.func_code)
    bb = table.get_basic_block

    self.assertEqual(bb(26)._reachable_from,
                     set([bb(0), bb(13), bb(16), bb(26),
                          bb(29), bb(49), bb(50)]))

    self.assertTrue(table.reachable_from(41, 50))
    self.assertTrue(table.reachable_from(50, 41))
    self.assertFalse(table.reachable_from(41, 53))
示例#11
0
  def testDiamondDominators(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeDiamond.func_code)

    bb = table.get_basic_block
    self.assertEqual(bb(0)._dominators, {bb(0)})
    self.assertEqual(bb(18)._dominators, {bb(0), bb(18)})
    self.assertEqual(bb(31)._dominators, {bb(0), bb(31)})
    self.assertEqual(bb(41)._dominators, {bb(0), bb(41)})

    self.assertTrue(table.dominates(0, 37))
    self.assertFalse(table.dominates(24, 41))
    self.assertTrue(table.dominates(21, 28))
    self.assertFalse(table.dominates(28, 21))
示例#12
0
  def testOneBlock(self):
    # Check the code to make sure the test will fail if the compilation changes.
    self.assertEqual(self.codeOneBlock.func_code.co_code,
                     self.codeOneBlockBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeOneBlock.func_code)
    # Should all be one basic block.
    self.assertIs(table.get_basic_block(0), table.get_basic_block(3))
    self.assertIs(table.get_basic_block(0), table.get_basic_block(6))
    self.assertIs(table.get_basic_block(0), table.get_basic_block(7))
    # No incoming
    self.assertItemsEqual(table.get_basic_block(0).incoming, [])
    # Outgoing is an unknown return location
    self.assertItemsEqual(table.get_basic_block(0).outgoing, [None])
示例#13
0
  def testLoop(self):
    self.assertEqual(self.codeLoop.func_code.co_code,
                     self.codeLoopBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeLoop.func_code)
    expected = [(0, 12),
                (13, 13),
                (16, 29),
                (32, 32),
                (33, 36)]
    self.checkBlocks(table, expected)
    bb = table.get_basic_block
    # Check outgoing of the loop handler instruction.
    self.assertItemsEqual(bb(13).outgoing, [bb(16), bb(32)])
    self.assertItemsEqual(bb(0).outgoing, [bb(13)])
示例#14
0
  def testYield(self):
    self.assertEqual(self.codeYield.func_code.co_code,
                     self.codeYieldBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeYield.func_code)
    expected = [(0, 3),
                (4, 8),
                (9, 13),
                (14, 18)]
    self.checkBlocks(table, expected)
    bb = table.get_basic_block
    # We both branch to unknown and to the best instruction for each yield.
    self.assertItemsEqual(bb(0).outgoing, [None, bb(4)])
    self.assertItemsEqual(bb(4).outgoing, [None, bb(9)])
    self.assertItemsEqual(bb(9).incoming, [bb(8)])
    self.assertItemsEqual(bb(9).outgoing, [None, bb(14)])
示例#15
0
  def testRaise(self):
    self.assertEqual(self.codeRaise.func_code.co_code,
                     self.codeRaiseBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeRaise.func_code)
    expected = [(0, 3),
                (6, 6),
                (9, 12)]
    self.checkBlocks(table, expected)
    bb = table.get_basic_block
    # CALL_FUNCTION could either continue or raise
    self.assertItemsEqual(bb(0).outgoing, [bb(6), None])
    # RAISE_VARARGS always raises
    self.assertItemsEqual(bb(6).outgoing, [None])
    # This basic block is unreachable
    self.assertItemsEqual(bb(9).incoming, [])
    # We return to an unknown location
    self.assertItemsEqual(bb(9).outgoing, [None])
示例#16
0
  def testTriangle(self):
    self.assertEqual(self.codeTriangle.func_code.co_code,
                     self.codeTriangleBytecode)

    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeTriangle.func_code)
    expected = [(0, 15),
                (18, 28),
                (31, 34)]
    self.checkBlocks(table, expected)
    bb = table.get_basic_block
    # Check the POP_JUMP_IF_FALSE conditional jump
    self.assertItemsEqual(bb(0).outgoing, [bb(18), bb(31)])
    # Check the return
    self.assertItemsEqual(bb(44).outgoing, [None])
    # Check the incoming of the entry block
    self.assertItemsEqual(bb(0).incoming, [])
    # Check incoming of the merge block.
    self.assertItemsEqual(bb(44).incoming, [bb(28), bb(15)])
    self.assertEndsWith(
        bb(21).get_name(),
        "tests/test_pycfg.py:{0}-{0}".format(self.codeTriangleLineNumber+2))
示例#17
0
  def testNestedLoopsDominators(self):
    cfg = pycfg.CFG()
    table = cfg.get_block_table(self.codeNestedLoops.func_code)
    bb = table.get_basic_block

    self.assertEqual(bb(0)._dominators,
                     {bb(0)})
    self.assertEqual(bb(13)._dominators,
                     {bb(0), bb(13)})
    self.assertEqual(bb(16)._dominators,
                     {bb(0), bb(13), bb(16)})
    self.assertEqual(bb(26)._dominators,
                     {bb(0), bb(13), bb(16), bb(26)})
    self.assertEqual(bb(29)._dominators,
                     {bb(0), bb(13), bb(16), bb(26), bb(29)})
    self.assertEqual(bb(49)._dominators,
                     {bb(0), bb(13), bb(16), bb(26), bb(49)})
    self.assertEqual(bb(50)._dominators,
                     {bb(0), bb(13), bb(16), bb(26), bb(49), bb(50)})
    self.assertEqual(bb(53)._dominators,
                     {bb(0), bb(13), bb(53)})
    self.assertEqual(bb(54)._dominators,
                     {bb(0), bb(13), bb(53), bb(54)})
示例#18
0
 def __init__(self):
     super(AncestorTraversalVirtualMachine, self).__init__()
     self.cfg = pycfg.CFG()