@@ -599,6 +599,7 @@ codet java_bytecode_convertt::convert_instructions(
599
599
600
600
instructionst::const_iterator source;
601
601
std::list<unsigned > successors;
602
+ std::set<unsigned > predecessors;
602
603
codet code;
603
604
stackt stack;
604
605
bool done;
@@ -624,7 +625,8 @@ codet java_bytecode_convertt::convert_instructions(
624
625
625
626
if (i_it->statement !=" goto" &&
626
627
i_it->statement !=" return" &&
627
- !(i_it->statement ==patternt (" ?return" )))
628
+ !(i_it->statement ==patternt (" ?return" )) &&
629
+ i_it->statement !=" athrow" )
628
630
{
629
631
instructionst::const_iterator next=i_it;
630
632
if (++next!=instructions.end ())
@@ -665,6 +667,20 @@ codet java_bytecode_convertt::convert_instructions(
665
667
}
666
668
}
667
669
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
+
668
684
std::set<unsigned > working_set;
669
685
if (!instructions.empty ())
670
686
working_set.insert (instructions.front ().address );
@@ -685,6 +701,11 @@ codet java_bytecode_convertt::convert_instructions(
685
701
a_it->second .stack .clear ();
686
702
codet &c=a_it->second .code ;
687
703
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
+
688
709
irep_idt statement=i_it->statement ;
689
710
exprt arg0=i_it->args .size ()>=1 ?i_it->args [0 ]:nil_exprt ();
690
711
exprt arg1=i_it->args .size ()>=2 ?i_it->args [1 ]:nil_exprt ();
@@ -1423,11 +1444,64 @@ codet java_bytecode_convertt::convert_instructions(
1423
1444
address_mapt::iterator a_it2=address_map.find (*it);
1424
1445
assert (a_it2!=address_map.end ());
1425
1446
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
+
1426
1499
a_it2->second .stack =stack;
1427
1500
}
1428
1501
}
1429
1502
1430
1503
// TODO: add exception handlers from exception table
1504
+ // review successor computation of athrow!
1431
1505
code_blockt code;
1432
1506
1433
1507
// temporaries
0 commit comments