@@ -576,15 +576,13 @@ void replace_goto_target(codet& repl, const irep_idt& old_label, const irep_idt&
576
576
}
577
577
}
578
578
579
- } // End anonymous namespace delimiting file-local functions
580
-
581
579
/* ******************************************************************\
582
580
583
581
Function: java_bytecode_convert_methodt::get_block_for_pcrange
584
582
585
583
Inputs: 'tree', a code block descriptor, and 'this_block', the corresponding
586
584
actual code_blockt. 'address_start' and 'address_limit', the Java
587
- bytecode offsets searched for. 'next_block_start_address', the
585
+ bytecode offsets searched for. 'next_block_start_address', the
588
586
bytecode offset of tree/this_block's successor sibling, or UINT_MAX
589
587
if none exists.
590
588
@@ -1829,18 +1827,88 @@ codet java_bytecode_convert_methodt::convert_instructions(
1829
1827
code.add (code_declt (var));
1830
1828
}
1831
1829
1832
- for (const auto &address_pair : address_map)
1830
+ // Try to recover block structure as indicated in the local variable table:
1831
+
1832
+ // The block tree node mirrors the block structure of root_block,
1833
+ // indexing the Java PCs were each subblock starts and ends.
1834
+ block_tree_node root;
1835
+ code_blockt root_block;
1836
+
1837
+ bool start_new_block=true ;
1838
+ for (auto ait=address_map.begin (), aend=address_map.end (); ait != aend; ++ait)
1833
1839
{
1840
+ const auto & address_pair=*ait;
1834
1841
const unsigned address=address_pair.first ;
1835
1842
assert (address_pair.first ==address_pair.second .source ->address );
1836
1843
const codet &c=address_pair.second .code ;
1837
1844
1838
- if (targets.find (address)!=targets.end ())
1839
- code.add (code_labelt (label (std::to_string (address)), c));
1840
- else if (c.get_statement ()!=ID_skip)
1841
- code.add (c);
1845
+ if (!start_new_block)
1846
+ start_new_block=targets.find (address)!=targets.end ();
1847
+ if (!start_new_block)
1848
+ start_new_block=address_pair.second .predecessors .size ()>1 ;
1849
+
1850
+ if (start_new_block)
1851
+ {
1852
+ code_labelt newlabel (label (std::to_string (address)), code_blockt ());
1853
+ root_block.move_to_operands (newlabel);
1854
+ root.branch .push_back (block_tree_node::get_leaf ());
1855
+ assert ((root.branch_addresses .size ()==0 ||
1856
+ root.branch_addresses .back ()<address) &&
1857
+ " Block addresses should be unique and increasing" );
1858
+ root.branch_addresses .push_back (address);
1859
+ }
1860
+
1861
+ if (c.get_statement ()!=ID_skip)
1862
+ {
1863
+ auto & lastlabel=to_code_label (to_code (root_block.operands ().back ()));
1864
+ auto & add_to_block=to_code_block (lastlabel.code ());
1865
+ add_to_block.add (c);
1866
+ }
1867
+ start_new_block=address_pair.second .successors .size ()>1 ;
1842
1868
}
1843
1869
1870
+ for (const auto & vlist : variables)
1871
+ {
1872
+ for (const auto & v : vlist)
1873
+ {
1874
+ if (v.is_parameter )
1875
+ continue ;
1876
+ // Merge lexical scopes as far as possible to allow us to
1877
+ // declare these variable scopes faithfully.
1878
+ // Don't insert yet, as for the time being the blocks' only
1879
+ // operands must be other blocks.
1880
+ get_or_create_block_for_pcrange (
1881
+ root,
1882
+ root_block,
1883
+ v.start_pc ,
1884
+ v.start_pc +v.length ,
1885
+ std::numeric_limits<unsigned >::max (),
1886
+ address_map);
1887
+ }
1888
+ }
1889
+ for (const auto & vlist : variables)
1890
+ {
1891
+ for (const auto & v : vlist)
1892
+ {
1893
+ if (v.is_parameter )
1894
+ continue ;
1895
+ // Skip anonymous variables:
1896
+ if (v.symbol_expr .get_identifier ()==irep_idt ())
1897
+ continue ;
1898
+ code_declt d (v.symbol_expr );
1899
+ auto & block=get_block_for_pcrange (
1900
+ root,
1901
+ root_block,
1902
+ v.start_pc ,
1903
+ v.start_pc +v.length ,
1904
+ std::numeric_limits<unsigned >::max ());
1905
+ block.operands ().insert (block.operands ().begin (),d);
1906
+ }
1907
+ }
1908
+
1909
+ for (auto & block : root_block.operands ())
1910
+ code.move_to_operands (block);
1911
+
1844
1912
return code;
1845
1913
}
1846
1914
0 commit comments