69 for(std::size_t i=0; i<parameters.size(); ++i)
73 if(i==0 && parameters[i].get_this())
79 parameters[i].set_base_name(base_name);
80 parameters[i].set_identifier(identifier);
85 parameter_symbol.
mode=ID_java;
86 parameter_symbol.
name=identifier;
87 parameter_symbol.
type=parameters[i].type();
88 symbol_table.
add(parameter_symbol);
104 symbol.
name = identifier;
108 symbol.
type.
set(ID_access, ID_private);
111 symbol.
mode = ID_java;
116 log.
debug() <<
"Generating codet: new opaque symbol: method '" << symbol.
name
118 symbol_table.
add(symbol);
123 return id2string(method_name).find(
"<init>") != std::string::npos;
136 for(std::size_t i=0; i<n; i++)
146 std::size_t residue_size=std::min(n,
stack.size());
155 for(std::size_t i=0; i<o.size(); i++)
166 const std::string &prefix,
175 tmp_symbol.
mode=ID_java;
176 tmp_symbol.
name=identifier;
177 tmp_symbol.
type=type;
181 result.
set(ID_C_base_name, base_name);
203 const std::size_t number_int =
219 result.
set(ID_C_base_name, base_name);
221 return std::move(result);
232 const std::string &descriptor,
234 const std::string &class_name,
235 const std::string &method_name,
250 member_type_from_descriptor.has_value() &&
251 member_type_from_descriptor->id() == ID_code,
252 "Must be code type");
253 if(signature.has_value())
257 auto member_type_from_signature =
260 member_type_from_signature.has_value() &&
261 member_type_from_signature->id() == ID_code,
262 "Must be code type");
271 message.
debug() <<
"Method: " << class_name <<
"." << method_name
272 <<
"\n signature: " << signature.value()
273 <<
"\n descriptor: " << descriptor
274 <<
"\n different number of parameters, reverting to "
281 message.
debug() <<
"Method: " << class_name <<
"." << method_name
282 <<
"\n could not parse signature: " << signature.value()
283 <<
"\n " << e.what() <<
"\n"
284 <<
" reverting to descriptor: " << descriptor
317 method_symbol.
name=method_identifier;
319 method_symbol.
mode=ID_java;
333 member_type.
set(ID_is_synchronized,
true);
335 member_type.
set(ID_is_static,
true);
351 parameters.insert(parameters.begin(), this_p);
377 type_checked_cast<annotated_typet>(
static_cast<typet &
>(member_type))
381 method_symbol.
type=member_type;
390 method_symbol.
type.
set(ID_C_must_not_throw,
true);
400 m, method_identifier, parameters, slots_for_parameters);
402 symbol_table.
add(method_symbol);
407 new_method.set_base_name(method_symbol.
base_name);
408 new_method.set_pretty_name(method_symbol.
pretty_name);
414 .emplace_back(std::move(new_method));
439 if(v.index >= slots_for_parameters)
442 std::ostringstream id_oss;
443 id_oss << method_identifier <<
"::" << v.name;
446 result.
set(ID_C_base_name, v.name);
452 variables[v.index].emplace_back(result, v.start_pc, v.length);
459 std::size_t param_index = 0;
460 for(
const auto ¶m : parameters)
463 variables[param_index].size() <= 1,
464 "should have at most one entry per index");
468 param_index == slots_for_parameters,
469 "java_parameter_count and local computation must agree");
471 for(
auto ¶m : parameters)
480 if(param_index == 0 && param.get_this())
486 else if(!variables[param_index].empty())
489 base_name = variables[param_index][0].symbol_expr.get(ID_C_base_name);
490 identifier = variables[param_index][0].symbol_expr.get(ID_identifier);
501 param.set_base_name(base_name);
502 param.set_identifier(identifier);
508 param_index == slots_for_parameters,
509 "java_parameter_count and local computation must agree");
518 std::size_t param_index = 0;
519 for(
const auto ¶m : parameters)
522 parameter_symbol.
base_name = param.get_base_name();
523 parameter_symbol.
mode = ID_java;
524 parameter_symbol.
name = param.get_identifier();
525 parameter_symbol.
type = param.type();
526 symbol_table.
add(parameter_symbol);
529 variables[param_index].clear();
530 variables[param_index].emplace_back(
533 std::numeric_limits<size_t>::max(),
571 log.
debug() <<
"Generating codet: class " << class_symbol.
name <<
", method "
581 method_symbol.
name == method_identifier,
582 "Name of method symbol shouldn't change");
585 "Base name of method symbol shouldn't change");
588 "Method symbol shouldn't have module");
590 method_symbol.
mode=ID_java;
612 "Member type should have already been marked as a constructor");
620 method_symbol.
type = method_type;
626 if(!method_context || (*method_context)(
id2string(method_identifier)))
630 method_symbol.
value = std::move(code);
637 if(bytecode ==
patternt(
"if_?cmplt"))
639 if(bytecode ==
patternt(
"if_?cmple"))
641 if(bytecode ==
patternt(
"if_?cmpgt"))
643 if(bytecode ==
patternt(
"if_?cmpge"))
645 if(bytecode ==
patternt(
"if_?cmpeq"))
647 if(bytecode ==
patternt(
"if_?cmpne"))
650 throw "unhandled java comparison instruction";
662 const exprt &pointer,
668 const exprt typed_pointer =
674 const auto type_of = [&ns](
const exprt &object) {
680 while(type_of(accessed_object).get_component(component_name).is_nil())
682 const auto components = type_of(accessed_object).components();
684 components.size() != 0,
685 "infer_opaque_type_fields should guarantee that a member access has a "
686 "corresponding field");
689 accessed_object =
member_exprt(accessed_object, components.front());
692 accessed_object, type_of(accessed_object).get_component(component_name));
709 if(g.get_destination()==old_label)
710 g.set_destination(new_label);
747 next_block_start_address,
786 assert(!tree.
branch.empty());
789 const auto afterstart=
795 auto findstart=afterstart;
806 const auto findlim_block_start_address =
816 auto child_iter = this_block.
statements().begin();
819 while(child_iter != this_block.
statements().end() &&
820 child_iter->get_statement() == ID_decl)
822 assert(child_iter != this_block.
statements().end());
823 std::advance(child_iter, child_offset);
824 assert(child_iter != this_block.
statements().end());
828 bool single_child(afterstart==findlim);
833 tree.
branch[child_offset],
837 findlim_block_start_address,
855 auto checkit=amap.
find(*findstart);
856 assert(checkit!=amap.end());
859 checkit!=amap.end() && (checkit->first)<(findlim_block_start_address);
862 for(
auto p : checkit->second.predecessors)
864 if(p<(*findstart) || p>=findlim_block_start_address)
867 <<
"warning: refusing to create lexical block spanning "
868 << (*findstart) <<
"-" << findlim_block_start_address
869 <<
" due to incoming edge " << p <<
" -> " << checkit->first
880 const irep_idt child_label_name=child_label.get_label();
881 std::string new_label_str =
id2string(child_label_name);
883 irep_idt new_label_irep(new_label_str);
887 auto nblocks=std::distance(findstart, findlim);
889 log.
debug() <<
"Generating codet: combining "
890 << std::distance(findstart, findlim) <<
" blocks for addresses "
891 << (*findstart) <<
"-" << findlim_block_start_address
895 auto &this_block_children = this_block.
statements();
896 assert(tree.
branch.size()==this_block_children.size());
897 for(
auto blockidx=child_offset, blocklim=child_offset+nblocks;
900 newblock.
add(this_block_children[blockidx]);
908 auto delfirst=this_block_children.begin();
909 std::advance(delfirst, child_offset+1);
910 auto dellim=delfirst;
911 std::advance(dellim, nblocks-1);
912 this_block_children.erase(delfirst, dellim);
913 this_block_children[child_offset].swap(newlabel);
917 auto branchstart=tree.
branch.begin();
918 std::advance(branchstart, child_offset);
919 auto branchlim=branchstart;
920 std::advance(branchlim, nblocks);
921 for(
auto branchiter=branchstart; branchiter!=branchlim; ++branchiter)
922 newnode.
branch.push_back(std::move(*branchiter));
924 tree.
branch.erase(branchstart, branchlim);
926 assert(tree.
branch.size()==this_block_children.size());
929 std::advance(branchaddriter, child_offset);
930 auto branchaddrlim=branchaddriter;
931 std::advance(branchaddrlim, nblocks);
940 tree.
branch[child_offset]=std::move(newnode);
947 this_block_children[child_offset]).code());
953 std::map<irep_idt, java_bytecode_convert_methodt::variablet> &result)
955 if(e.
id()==ID_symbol)
958 auto findit = result.emplace(
959 std::piecewise_construct,
960 std::forward_as_tuple(symexpr.get_identifier()),
961 std::forward_as_tuple(symexpr, pc, 1));
964 auto &var = findit.first->second;
968 var.length+=(var.start_pc-pc);
973 var.length=std::max(var.length, (pc-var.start_pc)+1);
1006 if(ty.
id()==ID_pointer)
1019 std::size_t param_index = method_type.
has_this() ? 1 : 0;
1022 "parameters and parameter annotations mismatch");
1028 param_annotations,
"java::javax.validation.constraints.NotNull") ||
1030 param_annotations,
"java::org.jetbrains.annotations.NotNull") ||
1032 param_annotations,
"org.eclipse.jdt.annotation.NonNull") ||
1034 param_annotations,
"java::edu.umd.cs.findbugs.annotations.NonNull"))
1037 parameters[param_index].get_identifier();
1039 const auto param_type =
1040 type_try_dynamic_cast<pointer_typet>(param_symbol.
type);
1046 check_loc.
set_comment(
"Not null annotation check");
1050 code.
add(std::move(code_assert));
1072 std::set<method_offsett> targets;
1074 std::vector<method_offsett> jsr_ret_targets;
1075 std::vector<instructionst::const_iterator> ret_instructions;
1077 for(
auto i_it = instructions.begin(); i_it != instructions.end(); i_it++)
1080 std::pair<address_mapt::iterator, bool> a_entry=
1081 address_map.insert(std::make_pair(i_it->address, ins));
1082 assert(a_entry.second);
1085 assert(a_entry.first==--address_map.end());
1087 const auto bytecode = i_it->bytecode;
1100 instructionst::const_iterator next=i_it;
1101 if(++next!=instructions.end())
1102 a_entry.first->second.successors.push_back(next->address);
1126 const std::vector<method_offsett> handler =
1128 std::list<method_offsett> &successors = a_entry.first->second.successors;
1129 successors.insert(successors.end(), handler.begin(), handler.end());
1130 targets.insert(handler.begin(), handler.end());
1135 bytecode ==
patternt(
"if_?cmp??") ||
1146 targets.insert(target);
1148 a_entry.first->second.successors.push_back(target);
1152 auto next = std::next(i_it);
1154 next != instructions.end(),
"jsr should have valid return address");
1155 targets.insert(next->address);
1156 jsr_ret_targets.push_back(next->address);
1162 for(
const auto &arg : i_it->args)
1167 targets.insert(target);
1168 a_entry.first->second.successors.push_back(target);
1173 else if(bytecode ==
BC_ret)
1176 ret_instructions.push_back(i_it);
1181 for(
const auto &address : address_map)
1183 for(
auto s : address.second.successors)
1185 const auto a_it = address_map.find(s);
1187 a_it->second.predecessors.insert(address.first);
1201 std::set<method_offsett> working_set;
1203 if(!instructions.empty())
1204 working_set.insert(instructions.front().address);
1206 while(!working_set.empty())
1208 auto cur = working_set.begin();
1209 auto address_it = address_map.find(*cur);
1211 auto &instruction = address_it->second;
1213 working_set.erase(cur);
1215 if(instruction.done)
1218 instruction.successors.begin(), instruction.successors.end());
1220 instructionst::const_iterator i_it = instruction.source;
1221 stack.swap(instruction.stack);
1222 instruction.stack.clear();
1223 codet &c = instruction.code;
1226 stack.empty() || instruction.predecessors.size() <= 1 ||
1232 const auto bytecode = i_it->bytecode;
1234 const std::string statement = stmt_bytecode_info.
mnemonic;
1237 if(statement.size()>=2 &&
1238 statement[statement.size()-2]==
'_' &&
1239 isdigit(statement[statement.size()-1]))
1244 std::string(
id2string(statement), statement.size()-1, 1)),
1256 if(cur_pc==it->handler_pc)
1259 catch_type !=
typet() ||
1266 catch_type=it->catch_type;
1272 if(catch_type!=
typet())
1286 stack.push_back(catch_var);
1296 assert(results.size()==1);
1324 "java::org.cprover.CProver.assume:(Z)V")
1329 "function expected to have exactly one parameter");
1335 arg0.
get(ID_identifier) ==
"java::org.cprover.CProver.atomicBegin:()V")
1337 c =
codet(ID_atomic_begin);
1342 arg0.
get(ID_identifier) ==
"java::org.cprover.CProver.atomicEnd:()V")
1344 c =
codet(ID_atomic_end);
1351 expr_try_dynamic_cast<class_method_descriptor_exprt>(arg0);
1354 class_method_descriptor,
1355 "invokeinterface, invokespecial, invokevirtual and invokestatic should "
1356 "be called with a class method descriptor expression as arg0");
1359 i_it->source_location, statement, *class_method_descriptor, c, results);
1366 else if(bytecode ==
patternt(
"?return"))
1375 else if(bytecode ==
patternt(
"?astore"))
1380 else if(bytecode ==
patternt(
"?store") || bytecode ==
patternt(
"?store_?"))
1387 else if(bytecode ==
patternt(
"?aload"))
1395 results[0] =
convert_load(arg0, statement[0], i_it->address);
1403 "String and Class literals should have been lowered in "
1404 "generate_constant_global_variables");
1426 std::next(i_it)->address,
1430 else if(bytecode ==
BC_ret)
1436 assert(!jsr_ret_targets.empty());
1442 assert(results.size()==1);
1445 else if(bytecode ==
patternt(
"?const_?"))
1447 assert(results.size()==1);
1450 else if(bytecode ==
patternt(
"?ipush"))
1454 arg0.
id()==ID_constant,
1455 "ipush argument expected to be constant");
1458 else if(bytecode ==
patternt(
"if_?cmp??"))
1464 address_map, bytecode, op, number, i_it->source_location);
1466 else if(bytecode ==
patternt(
"if??"))
1470 bytecode ==
BC_ifeq ? ID_equal :
1471 bytecode ==
BC_ifne ? ID_notequal :
1479 INVARIANT(!
id.empty(),
"unexpected bytecode-if");
1483 c =
convert_if(address_map, op,
id, number, i_it->source_location);
1485 else if(bytecode ==
patternt(
"ifnonnull"))
1492 else if(bytecode ==
patternt(
"ifnull"))
1497 c =
convert_ifnull(address_map, op, number, i_it->source_location);
1503 else if(bytecode ==
patternt(
"?xor"))
1508 else if(bytecode ==
patternt(
"?or"))
1513 else if(bytecode ==
patternt(
"?and"))
1518 else if(bytecode ==
patternt(
"?shl"))
1523 else if(bytecode ==
patternt(
"?shr"))
1528 else if(bytecode ==
patternt(
"?ushr"))
1533 else if(bytecode ==
patternt(
"?add"))
1538 else if(bytecode ==
patternt(
"?sub"))
1543 else if(bytecode ==
patternt(
"?div"))
1548 else if(bytecode ==
patternt(
"?mul"))
1553 else if(bytecode ==
patternt(
"?neg"))
1558 else if(bytecode ==
patternt(
"?rem"))
1564 results[0] =
binary_exprt(op[0], ID_floatbv_mod, op[1]);
1568 else if(bytecode ==
patternt(
"?cmp"))
1573 else if(bytecode ==
patternt(
"?cmp?"))
1578 else if(bytecode ==
patternt(
"?cmpl"))
1583 else if(bytecode ==
BC_dup)
1586 results[0]=results[1]=op[0];
1624 to_member(op[0], expr_dynamic_cast<fieldref_exprt>(arg0),
ns));
1629 const auto &field_name=arg0.
get_string(ID_component_name);
1630 const bool is_assertions_disabled_field=
1631 field_name.find(
"$assertionsDisabled")!=std::string::npos;
1641 i_it->source_location,
1644 is_assertions_disabled_field,
1656 const auto &field_name=arg0.
get_string(ID_component_name);
1682 exprt largest_as_dest =
1690 exprt largest_as_src =
1694 exprt smallest_as_dest =
1699 exprt smallest_as_src =
1710 else if(bytecode ==
patternt(
"?2?"))
1725 else if(bytecode ==
BC_new)
1729 convert_new(i_it->source_location, arg0, c, results);
1741 const std::size_t dimension =
1745 assert(results.size()==1);
1755 array.set(ID_java_member_access,
true);
1785 else if(bytecode ==
BC_nop)
1800 if(catch_instruction.has_value())
1807 if(!i_it->source_location.get_line().empty())
1812 instruction.done =
true;
1813 for(
const auto address : instruction.successors)
1815 address_mapt::iterator a_it2=address_map.find(address);
1821 if(address==exception_row.handler_pc)
1828 if(!
stack.empty() && a_it2->second.predecessors.size()>1)
1835 if(a_it2->second.stack.empty())
1837 for(stackt::iterator s_it=
stack.begin();
1851 a_it2->second.stack.size() ==
stack.size(),
1852 "Stack sizes should be the same.");
1853 stackt::const_iterator os_it=a_it2->second.stack.begin();
1854 for(
auto &expr :
stack)
1856 assert(
has_prefix(os_it->get_string(ID_C_base_name),
"$stack"));
1877 if(last_statement.get_statement()==ID_goto)
1880 if(last_statement.get_statement() != ID_block)
1884 last_statement.operands().begin(),
1892 a_it2->second.stack=
stack;
1902 new_symbol.
name=var.get_identifier();
1903 new_symbol.
type=var.type();
1904 new_symbol.
base_name=var.get(ID_C_base_name);
1906 new_symbol.
mode=ID_java;
1923 bool start_new_block=
true;
1924 bool has_seen_previous_address=
false;
1926 for(
const auto &address_pair : address_map)
1929 assert(address_pair.first==address_pair.second.source->address);
1930 const codet &c=address_pair.second.code;
1933 if(!start_new_block)
1934 start_new_block=targets.find(address)!=targets.end();
1937 if(!start_new_block)
1938 start_new_block=address_pair.second.predecessors.size()>1;
1943 if(!start_new_block && has_seen_previous_address)
1946 if(exception_row.start_pc==previous_address)
1948 start_new_block=
true;
1960 "Block addresses should be unique and increasing");
1968 add_to_block.add(c);
1970 start_new_block=address_pair.second.successors.size()>1;
1972 previous_address=address;
1973 has_seen_previous_address=
true;
1977 std::map<irep_idt, variablet> temporary_variable_live_ranges;
1978 for(
const auto &aentry : address_map)
1982 temporary_variable_live_ranges);
1984 std::vector<const variablet*> vars_to_process;
1986 for(
const auto &v : vlist)
1987 vars_to_process.push_back(&v);
1990 vars_to_process.push_back(
1991 &temporary_variable_live_ranges.at(v.get_identifier()));
1994 vars_to_process.push_back(
1995 &temporary_variable_live_ranges.at(v.get_identifier()));
1997 for(
const auto vp : vars_to_process)
2011 v.start_pc + v.length,
2012 std::numeric_limits<method_offsett>::max(),
2015 for(
const auto vp : vars_to_process)
2021 if(v.symbol_expr.get_identifier().empty())
2027 v.start_pc + v.length,
2028 std::numeric_limits<method_offsett>::max());
2030 block.statements().insert(block.statements().begin(), d);
2064 bool is_label =
true;
2065 for(
auto a_it = args.begin(); a_it != args.end();
2066 a_it++, is_label = !is_label)
2077 numeric_cast_v<method_offsett>(number);
2081 if(a_it == args.begin())
2086 code_block.
add(std::move(code_case), location);
2095 code_block.
add(std::move(code_case), location);
2100 code_switcht code_switch(op[0], std::move(code_block));
2110 const irep_idt descriptor = (statement ==
"monitorenter") ?
2111 "java::java.lang.Object.monitorenter:(Ljava/lang/Object;)V" :
2112 "java::java.lang.Object.monitorexit:(Ljava/lang/Object;)V";
2125 return std::move(call);
2137 results.insert(results.end(), op.begin(), op.end());
2138 results.insert(results.end(), op.begin(), op.end());
2150 results.insert(results.end(), op.begin() + 1, op.end());
2151 results.insert(results.end(), op.begin(), op.end());
2170 results.insert(results.end(), op.begin(), op.end());
2171 results.insert(results.end(), op2.begin(), op2.end());
2172 results.insert(results.end(), op.begin(), op.end());
2180 const char type_char = statement[0];
2181 const bool is_double(
'd' == type_char);
2182 const bool is_float(
'f' == type_char);
2184 if(is_double || is_float)
2191 if(arg0.
type().
id() != ID_floatbv)
2193 const mp_integer number = numeric_cast_v<mp_integer>(arg0);
2203 const mp_integer value = numeric_cast_v<mp_integer>(arg0);
2219 parameters.size() == arguments.size(),
2220 "for each parameter there must be exactly one argument");
2221 for(std::size_t i = 0; i < parameters.size(); i++)
2223 const typet &type = parameters[i].type();
2227 type.
id() == ID_pointer)
2241 const bool use_this(statement !=
"invokestatic");
2242 const bool is_virtual(
2243 statement ==
"invokevirtual" || statement ==
"invokeinterface");
2247 !invoked_method_id.
empty(),
2248 "invoke statement arg0 must have an identifier");
2263 "Function return type must not change in kind");
2264 class_method_descriptor.
type() = method_symbol->second.type;
2278 if(parameters.empty() || !parameters[0].get_this())
2285 parameters.insert(parameters.begin(), this_p);
2290 if(statement ==
"invokespecial")
2299 method_type.
set(ID_java_super_method_call,
true);
2309 !use_this || arguments.front().type().id() == ID_pointer,
2310 "first argument must be a pointer");
2318 if(return_type.
id() != ID_empty)
2324 results[0] = promoted;
2342 class_method_descriptor.
class_id(),
2351 class_method_descriptor.
class_id(),
2362 function = class_method_descriptor;
2369 function =
symbol_exprt(invoked_method_id, method_type);
2379 std::move(lhs), std::move(
function), std::move(arguments));
2422 c = std::move(assert_class);
2444 assert_location.set(
"user-provided",
true);
2445 assert_location.set_property_class(ID_assertion);
2446 assert_code.add_source_location() = assert_location;
2450 assume_location.
set(
"user-provided",
true);
2451 assume_code.add_source_location() = assume_location;
2466 const std::set<method_offsett> &working_set,
2475 typedef std::vector<std::reference_wrapper<
2477 std::map<std::size_t, exceptionst> exceptions_by_end;
2482 exceptions_by_end[exception.
end_pc].push_back(exception);
2484 for(
const auto &exceptions : exceptions_by_end)
2492 : exceptions.second)
2494 exception_list.emplace_back(
2501 code =
code_blockt({ std::move(catch_push), code });
2521 auto next_opcode_it = std::find_if(
2522 working_set.begin(),
2525 if(next_opcode_it != working_set.end())
2528 std::set<std::size_t> start_positions;
2532 if(*next_opcode_it == exception_row.end_pc)
2533 start_positions.insert(exception_row.start_pc);
2535 for(std::size_t handler = 0; handler < start_positions.size(); ++handler)
2562 create.
add(assume_le_max_size);
2580 if(statement ==
"newarray")
2587 else if(
id == ID_char)
2589 else if(
id == ID_float)
2591 else if(
id == ID_double)
2593 else if(
id == ID_byte)
2595 else if(
id == ID_short)
2597 else if(
id == ID_int)
2599 else if(
id == ID_long)
2621 block.
add(std::move(assume_le_max_size));
2674 block.
add(clinit_call);
2677 "stack_static_field",
2700 const bool is_assertions_disabled_field,
2706 if(arg0.
type().
id() == ID_struct_tag)
2711 else if(arg0.
type().
id() == ID_pointer)
2720 else if(is_assertions_disabled_field)
2735 else if(is_assertions_disabled_field)
2747 const int nan_value(statement[4] ==
'l' ? -1 : 1);
2842 const exprt arg1_int_type =
2850 block.
add(std::move(code_assign));
2864 const method_offsett label_number = numeric_cast_v<method_offsett>(number);
2871 address_map.at(label_number).source->source_location;
2886 const method_offsett label_number = numeric_cast_v<method_offsett>(number);
2893 address_map.at(label_number).source->source_location;
2906 const method_offsett label_number = numeric_cast_v<method_offsett>(number);
2915 address_map.at(label_number).source->source_location;
2935 const method_offsett label_number = numeric_cast_v<method_offsett>(number);
2941 address_map.at(label_number).source->source_location;
2948 const std::vector<method_offsett> &jsr_ret_targets,
2954 auto retvar =
variable(arg0,
'a', address);
2955 for(
size_t idx = 0, idxlim = jsr_ret_targets.size(); idx != idxlim; ++idx)
2960 if(idx == idxlim - 1)
2970 branch.cond().add_source_location() = location;
2971 branch.add_source_location() = location;
2986 const auto ref_type =
2987 type_try_dynamic_cast<java_reference_typet>(expr.
type());
2988 const bool typecast_not_needed =
2989 ref_type && ((type_char ==
'b' && ref_type->subtype().get_identifier() ==
2990 "java::array[boolean]") ||
2992 return typecast_not_needed ? expr
3001 const char type_char = statement[0];
3004 deref.
set(ID_java_member_access,
true);
3006 auto java_array_type = type_try_dynamic_cast<struct_tag_typet>(deref.type());
3010 plus_exprt data_plus_offset{std::move(data_ptr), op[1]};
3012 data_plus_offset.
set(ID_java_array_access,
true);
3022 if(type_char ==
'i')
3026 type_try_dynamic_cast<bitvector_typet>(var.
type())->get_width() <= 32,
3027 "iload can be used for boolean, byte, short, int and char");
3033 "Variable type must match [adflv]load return type");
3068 const char type_char = statement[0];
3071 deref.
set(ID_java_member_access,
true);
3073 auto java_array_type = type_try_dynamic_cast<struct_tag_typet>(deref.type());
3077 plus_exprt data_plus_offset{std::move(data_ptr), op[1]};
3079 data_plus_offset.
set(ID_java_array_access,
true);
3088 block.
add(std::move(array_put), location);
3094 std::size_t instruction_address,
3114 if(!value.has_value())
3141 arguments.insert(arguments.begin(), new_instance);
3148 result.
add(constructor_call);
3155 result_code = std::move(result);
3157 if(return_type.
id() == ID_empty)
3160 return new_instance;
3165 const std::vector<method_offsett> &jsr_ret_targets,
3167 std::vector<java_bytecode_parse_treet::instructiont>::const_iterator>
3168 &ret_instructions)
const
3171 for(
const auto &retinst : ret_instructions)
3173 auto &a_entry = address_map.at(retinst->address);
3174 a_entry.successors.insert(
3175 a_entry.successors.end(), jsr_ret_targets.begin(), jsr_ret_targets.end());
3179 std::vector<java_bytecode_convert_methodt::method_offsett>
3185 std::vector<method_offsett> result;
3186 for(
const auto &exception_row : exception_table)
3188 if(address >= exception_row.start_pc && address < exception_row.end_pc)
3189 result.push_back(exception_row.handler_pc);
3209 &local_variable_table,
3221 typedef std::pair<irep_idt, irep_idt> base_name_and_identifiert;
3222 std::map<std::size_t, base_name_and_identifiert> param_names;
3223 for(
const auto &v : local_variable_table)
3225 if(v.index < slots_for_parameters)
3226 param_names.emplace(
3233 std::size_t param_index = 0;
3234 for(
auto ¶m : parameters)
3243 if(param_index == 0 && param.get_this())
3246 base_name = ID_this;
3251 auto param_name = param_names.find(param_index);
3252 if(param_name != param_names.end())
3254 base_name = param_name->second.first;
3255 identifier = param_name->second.second;
3262 const typet &type = param.type();
3269 param.set_base_name(base_name);
3270 param.set_identifier(identifier);
3275 parameter_symbol.
mode = ID_java;
3276 parameter_symbol.
name = identifier;
3277 parameter_symbol.
type = param.type();
3278 symbol_table.
insert(parameter_symbol);
3289 size_t max_array_length,
3290 bool throw_assertion_error,
3294 bool threading_support,
3296 bool assert_no_exceptions_thrown)
3303 throw_assertion_error,
3304 needed_lazy_methods,
3308 assert_no_exceptions_thrown);
3320 const irep_idt &mangled_method_name)
const
3325 return inherited_method.has_value();
3335 const irep_idt &component_name)
const
3341 inherited_method.has_value(),
"static field should be in symbol table");
3343 return inherited_method->get_full_component_identifier();
3353 const std::string &tmp_var_prefix,
3358 const std::function<bool(
3359 const std::function<
tvt(
const exprt &expr)>,
const exprt &expr)>
3360 entry_matches = [&entry_matches](
3361 const std::function<
tvt(
const exprt &expr)> predicate,
3362 const exprt &expr) {
3363 const tvt &tvres = predicate(expr);
3369 [&predicate, &entry_matches](
const exprt &expr) {
3370 return entry_matches(predicate, expr);
3382 const std::function<
tvt(
const exprt &expr)> has_member_entry = [&identifier](
3383 const exprt &expr) {
3384 const auto member_expr = expr_try_dynamic_cast<member_exprt>(expr);
3386 :
tvt(member_expr->get_component_name() == identifier);
3392 const std::function<
tvt(
const exprt &expr)> is_symbol_entry =
3393 [&identifier](
const exprt &expr) {
3394 const auto symbol_expr = expr_try_dynamic_cast<symbol_exprt>(expr);
3396 :
tvt(symbol_expr->get_identifier() == identifier);
3402 const std::function<
tvt(
const exprt &expr)> is_dereference_entry =
3403 [](
const exprt &expr) {
3404 const auto dereference_expr =
3405 expr_try_dynamic_cast<dereference_exprt>(expr);
3409 for(
auto &stack_entry :
stack)
3416 replace = entry_matches(is_symbol_entry, stack_entry);
3419 replace = entry_matches(is_dereference_entry, stack_entry);
3422 replace = entry_matches(has_member_entry, stack_entry);
3428 tmp_var_prefix, stack_entry.type(), block, stack_entry);
3435 const std::string &tmp_var_prefix,
3436 const typet &tmp_var_type,
3440 const exprt tmp_var=
3443 stack_entry=tmp_var;