Skip to content

Commit 80c6482

Browse files
author
Daniel Kroening
committed
Merge pull request #103 from tautschnig/java-bytecode-converter
Fix java bytecode translation of control-flow joins
2 parents 639974d + 5a64339 commit 80c6482

File tree

1 file changed

+75
-1
lines changed

1 file changed

+75
-1
lines changed

src/java_bytecode/java_bytecode_convert.cpp

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ codet java_bytecode_convertt::convert_instructions(
599599

600600
instructionst::const_iterator source;
601601
std::list<unsigned> successors;
602+
std::set<unsigned> predecessors;
602603
codet code;
603604
stackt stack;
604605
bool done;
@@ -624,7 +625,8 @@ codet java_bytecode_convertt::convert_instructions(
624625

625626
if(i_it->statement!="goto" &&
626627
i_it->statement!="return" &&
627-
!(i_it->statement==patternt("?return")))
628+
!(i_it->statement==patternt("?return")) &&
629+
i_it->statement!="athrow")
628630
{
629631
instructionst::const_iterator next=i_it;
630632
if(++next!=instructions.end())
@@ -665,6 +667,20 @@ codet java_bytecode_convertt::convert_instructions(
665667
}
666668
}
667669

670+
for(address_mapt::iterator
671+
it=address_map.begin();
672+
it!=address_map.end();
673+
++it)
674+
{
675+
for(unsigned s : it->second.successors)
676+
{
677+
address_mapt::iterator a_it=address_map.find(s);
678+
assert(a_it!=address_map.end());
679+
680+
a_it->second.predecessors.insert(it->first);
681+
}
682+
}
683+
668684
std::set<unsigned> working_set;
669685
if(!instructions.empty())
670686
working_set.insert(instructions.front().address);
@@ -685,6 +701,11 @@ codet java_bytecode_convertt::convert_instructions(
685701
a_it->second.stack.clear();
686702
codet &c=a_it->second.code;
687703

704+
assert(stack.empty() ||
705+
a_it->second.predecessors.size()<=1 ||
706+
has_prefix(stack.front().get_string(ID_C_base_name),
707+
"$stack"));
708+
688709
irep_idt statement=i_it->statement;
689710
exprt arg0=i_it->args.size()>=1?i_it->args[0]:nil_exprt();
690711
exprt arg1=i_it->args.size()>=2?i_it->args[1]:nil_exprt();
@@ -1423,11 +1444,64 @@ codet java_bytecode_convertt::convert_instructions(
14231444
address_mapt::iterator a_it2=address_map.find(*it);
14241445
assert(a_it2!=address_map.end());
14251446

1447+
if(!stack.empty() && a_it2->second.predecessors.size()>1)
1448+
{
1449+
// copy into temporaries
1450+
code_blockt more_code;
1451+
1452+
// introduce temporaries when successor is seen for the first
1453+
// time
1454+
if(a_it2->second.stack.empty())
1455+
{
1456+
for(stackt::iterator s_it=stack.begin();
1457+
s_it!=stack.end();
1458+
++s_it)
1459+
{
1460+
symbol_exprt lhs=tmp_variable("$stack", s_it->type());
1461+
code_assignt a(lhs, *s_it);
1462+
more_code.copy_to_operands(a);
1463+
1464+
s_it->swap(lhs);
1465+
}
1466+
}
1467+
else
1468+
{
1469+
assert(a_it2->second.stack.size()==stack.size());
1470+
stackt::const_iterator os_it=a_it2->second.stack.begin();
1471+
for(stackt::iterator s_it=stack.begin();
1472+
s_it!=stack.end();
1473+
++s_it)
1474+
{
1475+
assert(has_prefix(os_it->get_string(ID_C_base_name),
1476+
"$stack"));
1477+
symbol_exprt lhs=to_symbol_expr(*os_it);
1478+
code_assignt a(lhs, *s_it);
1479+
more_code.copy_to_operands(a);
1480+
1481+
s_it->swap(lhs);
1482+
++os_it;
1483+
}
1484+
}
1485+
1486+
if(results.empty())
1487+
{
1488+
more_code.copy_to_operands(c);
1489+
c.swap(more_code);
1490+
}
1491+
else
1492+
{
1493+
c.make_block();
1494+
forall_operands(o_it, more_code)
1495+
c.copy_to_operands(*o_it);
1496+
}
1497+
}
1498+
14261499
a_it2->second.stack=stack;
14271500
}
14281501
}
14291502

14301503
// TODO: add exception handlers from exception table
1504+
// review successor computation of athrow!
14311505
code_blockt code;
14321506

14331507
// temporaries

0 commit comments

Comments
 (0)