def build_blocks_arb(block_links, code=None): block_list = BlockList() as_tree_string = "" current_line_number = 1 for i in range(len(block_links)): basic_block = RawBasicBlock(current_line_number, current_line_number, None) current_line_number += 1 basic_block.name = chr(65 + i) block_list.append(basic_block) if code is not None: ast_stmts = code.get(basic_block.name) as_tree_string += ast_stmts basic_block.end_line += (ast_stmts.count("\n") - 1) current_line_number = basic_block.end_line + 1 for key, value in block_links.items(): key_block = block_list.get_block_by_name(key) for value_block_str in value: Cfg.connect_2_blocks(key_block, block_list.get_block_by_name(value_block_str)) if code is None: return block_list else: return block_list, as_tree_string
def build_blocks_arb(self, block_links): block_list = BlockList() for i in range(len(block_links)): basic_block = RawBasicBlock(i, i, None) basic_block.name = chr(65 + i) block_list.append(basic_block) for key, value in block_links.items(): key_block = block_list.get_block_by_name(key) for value_block_str in value: Cfg.connect_2_blocks( key_block, block_list.get_block_by_name(value_block_str)) return block_list
def test_build_while_body_given_body_if(self): as_tree = ast.parse( ms("""\ while a < 3: # 1st block if a < 2: # 2nd block z = 2 # 3rd block b = 2 # 4th block """)) while_block = RawBasicBlock(1, 1, 'While') cfg_handler = Cfg() cfg_handler.as_tree = as_tree real_tail_list = cfg_handler.build_while_body(while_block) expected_block_list = build_blocks([1, 1, 'While'], [2, 2, 'If'], [3, 3, None], [4, 4, None], block_links={ '0': [1], '1': [2, 3], '2': [3], '3': [0] }) self.assertBasicBlockEqual(while_block, expected_block_list[0]) self.assertBasicBlockEqual(real_tail_list[0], expected_block_list[0])
def test_get_simple_block_given_if(self): as_tree = ast.parse(ms("""\ a = 3 if a < 3: b = 4 c = 5 """) ) cfg_holder = Cfg() simple_block_list = [] for basic_block in cfg_holder.get_basic_block(as_tree.body): simple_block_list.append(basic_block) expected_block_0 = RawBasicBlock(start_line=1, end_line=2, block_end_type='If') expected_block_1 = RawBasicBlock(start_line=4, end_line=4) self.assertBasicBlockEqual(simple_block_list[0], expected_block_0, block_index=0) self.assertBasicBlockEqual(simple_block_list[1], expected_block_1, block_index=1)
def assertCfgWithAst(self, cfg_real, *args): cfg_expected = Cfg() # a = 3 # a = 4 for ast_list in args: basic_block = RawBasicBlock() basic_block.ast_list.extend(ast_list) cfg_expected.block_list.append(basic_block) self.assertCfgEqual(cfg_real, cfg_expected)
def build_tree(self): # TODO: clarify the code below for block_in_cfg in self.cfg.walk_block(self.cfg.root): block_in_dom_list = RawBasicBlock(block_in_cfg.start_line, block_in_cfg.end_line) self.dominator_nodes.append(block_in_dom_list) for dom_block in block_in_cfg.dominates_list: dom_block_in_list = self.dominator_nodes.get_block(dom_block) if not dom_block_in_list.prev_block_list: Cfg.connect_2_blocks(block_in_dom_list, dom_block_in_list) self.dominator_root = self.dominator_nodes[-1]
def assertDfEqual(self, dom_tree_real, *expected_df): for df_block_num in range(len(expected_df)): self.assertEqual(len(dom_tree_real.cfg.block_list), len(expected_df)) if len(expected_df[df_block_num]) == 0: self.assertIsNone( dom_tree_real.cfg.block_list[df_block_num].df) else: self.assertTrue( common.is_blocks_same( RawBasicBlock(expected_df[df_block_num][0], expected_df[df_block_num][1]), dom_tree_real.cfg.block_list[df_block_num].df))
def test_delete_node(self): as_tree = ast.parse(ms("""\ z = 2 # 0th block while a < 3: # 1st block if a < 2: # 2nd block z = 2 # 3rd block b = 2 # 4th block c = 3 # 5th block """)) cfg_real = Cfg(as_tree) cfg_real.root = cfg_real.delete_node(cfg_real.root, RawBasicBlock(1, 1)) pass
def test_get_simple_block_given_no_indent(self): as_tree = ast.parse(ms("""\ a = 3 a = 4 """) ) cfg_holder = Cfg() simple_block_list = [] for simple_block in cfg_holder.get_basic_block(as_tree.body): simple_block_list.append(simple_block) expected_block = RawBasicBlock(start_line=1, end_line=2) self.assertBasicBlockEqual(simple_block_list[0], expected_block)
def test_build_while_body_given_only_while(self): as_tree = ast.parse(ms("""\ while a < 3: # 1st block z = 4 # 2nd block """)) while_block = RawBasicBlock(1, 1, 'While') cfg_handler = Cfg() cfg_handler.as_tree = as_tree real_tail_list = cfg_handler.build_while_body(while_block) expected_block_list = build_blocks([1, 1, 'While'], [2, 2, None], block_links={'0': [1], '1': [0]}) self.assertBasicBlockEqual(while_block, expected_block_list[0]) self.assertBasicBlockEqual(real_tail_list[0], expected_block_list[0])
def test_get_ast_stmt_from_block_given_if(self): as_tree = ast.parse( ms("""\ a = 3 if a < 3: x, y = a, b """)) block_1 = RawBasicBlock(1, 3) cfg_holder = Cfg() cfg_holder.as_tree = as_tree tuples_list_real = [(x, y) for x, y in cfg_holder.get_var_ast(block_1)] tuples_list_expected = [(['a'], []), ([], ['a']), (['x', 'y'], ['a', 'b'])] self.assertListEqual(tuples_list_expected, tuples_list_real)