Skip to content

Commit 49688fa

Browse files
committed
Add scoped mamed variable declarations
The block tree maintenance functions introduced in the previous commit are used to add a `code_declt` for each named variable as close to its true scope as possible.
1 parent 9ea8d0c commit 49688fa

File tree

1 file changed

+76
-8
lines changed

1 file changed

+76
-8
lines changed

src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -576,15 +576,13 @@ void replace_goto_target(codet& repl, const irep_idt& old_label, const irep_idt&
576576
}
577577
}
578578

579-
} // End anonymous namespace delimiting file-local functions
580-
581579
/*******************************************************************\
582580
583581
Function: java_bytecode_convert_methodt::get_block_for_pcrange
584582
585583
Inputs: 'tree', a code block descriptor, and 'this_block', the corresponding
586584
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
588586
bytecode offset of tree/this_block's successor sibling, or UINT_MAX
589587
if none exists.
590588
@@ -1829,18 +1827,88 @@ codet java_bytecode_convert_methodt::convert_instructions(
18291827
code.add(code_declt(var));
18301828
}
18311829

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)
18331839
{
1840+
const auto& address_pair=*ait;
18341841
const unsigned address=address_pair.first;
18351842
assert(address_pair.first==address_pair.second.source->address);
18361843
const codet &c=address_pair.second.code;
18371844

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;
18421868
}
18431869

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+
18441912
return code;
18451913
}
18461914

0 commit comments

Comments
 (0)