|
20 | 20 | #include <linking/zero_initializer.h>
|
21 | 21 |
|
22 | 22 | #include <goto-programs/cfg.h>
|
| 23 | +#include <goto-programs/remove_exceptions.h> |
23 | 24 | #include <analyses/cfg_dominators.h>
|
24 | 25 |
|
25 | 26 | #include "java_bytecode_convert_method.h"
|
@@ -473,7 +474,8 @@ void java_bytecode_convert_methodt::convert(
|
473 | 474 |
|
474 | 475 | tmp_vars.clear();
|
475 | 476 | if((!m.is_abstract) && (!m.is_native))
|
476 |
| - method_symbol.value=convert_instructions(m, code_type); |
| 477 | + method_symbol.value=convert_instructions( |
| 478 | + m, code_type, method_symbol.name); |
477 | 479 |
|
478 | 480 | // Replace the existing stub symbol with the real deal:
|
479 | 481 | const auto s_it=symbol_table.symbols.find(method.get_name());
|
@@ -1120,7 +1122,8 @@ Function: java_bytecode_convert_methodt::convert_instructions
|
1120 | 1122 |
|
1121 | 1123 | codet java_bytecode_convert_methodt::convert_instructions(
|
1122 | 1124 | const methodt &method,
|
1123 |
| - const code_typet &method_type) |
| 1125 | + const code_typet &method_type, |
| 1126 | + const irep_idt &method_name) |
1124 | 1127 | {
|
1125 | 1128 | const instructionst &instructions=method.instructions;
|
1126 | 1129 |
|
@@ -1306,48 +1309,29 @@ codet java_bytecode_convert_methodt::convert_instructions(
|
1306 | 1309 | statement=std::string(id2string(statement), 0, statement.size()-2);
|
1307 | 1310 | }
|
1308 | 1311 |
|
1309 |
| - // we throw away the first statement in an exception handler |
1310 |
| - // as we don't know if a function call had a normal or exceptional return |
1311 | 1312 | auto it=method.exception_table.begin();
|
1312 | 1313 | for(; it!=method.exception_table.end(); ++it)
|
1313 | 1314 | {
|
1314 | 1315 | if(cur_pc==it->handler_pc)
|
1315 | 1316 | {
|
1316 |
| - exprt exc_var=variable( |
1317 |
| - arg0, statement[0], |
1318 |
| - i_it->address, |
1319 |
| - NO_CAST); |
1320 |
| - |
1321 |
| - // throw away the operands |
1322 |
| - pop_residue(bytecode_info.pop); |
1323 |
| - |
1324 |
| - // add a CATCH-PUSH signaling a handler |
1325 |
| - side_effect_expr_catcht catch_handler_expr; |
1326 |
| - // pack the exception variable so that it can be used |
1327 |
| - // later for instrumentation |
1328 |
| - catch_handler_expr.get_sub().resize(1); |
1329 |
| - catch_handler_expr.get_sub()[0]=exc_var; |
1330 |
| - |
1331 |
| - code_expressiont catch_handler(catch_handler_expr); |
1332 |
| - code_labelt newlabel(label(std::to_string(cur_pc)), |
1333 |
| - code_blockt()); |
1334 |
| - |
1335 |
| - code_blockt label_block=to_code_block(newlabel.code()); |
1336 |
| - code_blockt handler_block; |
1337 |
| - handler_block.move_to_operands(c); |
1338 |
| - handler_block.move_to_operands(catch_handler); |
1339 |
| - handler_block.move_to_operands(label_block); |
1340 |
| - c=handler_block; |
1341 |
| - break; |
| 1317 | + // at the beginning of a handler, clear the stack and |
| 1318 | + // push the corresponding exceptional return variable |
| 1319 | + stack.clear(); |
| 1320 | + auxiliary_symbolt new_symbol; |
| 1321 | + new_symbol.is_static_lifetime=true; |
| 1322 | + // generate the name of the exceptional return variable |
| 1323 | + const std::string &exceptional_var_name= |
| 1324 | + id2string(method_name)+ |
| 1325 | + EXC_SUFFIX; |
| 1326 | + new_symbol.base_name=exceptional_var_name; |
| 1327 | + new_symbol.name=exceptional_var_name; |
| 1328 | + new_symbol.type=typet(ID_pointer, empty_typet()); |
| 1329 | + new_symbol.mode=ID_java; |
| 1330 | + symbol_table.add(new_symbol); |
| 1331 | + stack.push_back(new_symbol.symbol_expr()); |
1342 | 1332 | }
|
1343 | 1333 | }
|
1344 | 1334 |
|
1345 |
| - if(it!=method.exception_table.end()) |
1346 |
| - { |
1347 |
| - // go straight to the next statement |
1348 |
| - continue; |
1349 |
| - } |
1350 |
| - |
1351 | 1335 | exprt::operandst op=pop(bytecode_info.pop);
|
1352 | 1336 | exprt::operandst results;
|
1353 | 1337 | results.resize(bytecode_info.push, nil_exprt());
|
@@ -2536,9 +2520,7 @@ codet java_bytecode_convert_methodt::convert_instructions(
|
2536 | 2520 | address_mapt::iterator a_it2=address_map.find(address);
|
2537 | 2521 | assert(a_it2!=address_map.end());
|
2538 | 2522 |
|
2539 |
| - // we don't worry about exception handlers as we don't load the |
2540 |
| - // operands from the stack anyway -- we keep explicit global |
2541 |
| - // exception variables |
| 2523 | + // clear the stack if this is an exception handler |
2542 | 2524 | for(const auto &exception_row : method.exception_table)
|
2543 | 2525 | {
|
2544 | 2526 | if(address==exception_row.handler_pc)
|
@@ -2607,7 +2589,6 @@ codet java_bytecode_convert_methodt::convert_instructions(
|
2607 | 2589 | c.copy_to_operands(*o_it);
|
2608 | 2590 | }
|
2609 | 2591 | }
|
2610 |
| - |
2611 | 2592 | a_it2->second.stack=stack;
|
2612 | 2593 | }
|
2613 | 2594 | }
|
|
0 commit comments