CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
java_bytecode_convert_method_class.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: JAVA Bytecode Language Conversion
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
11
12#ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_CLASS_H
13#define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_CLASS_H
14
16
18#include <util/message.h>
19#include <util/namespace.h>
20#include <util/std_code.h>
21#include <util/std_expr.h>
22
24
27
28#include <list>
29#include <vector>
30
32class prefix_filtert;
33class symbolt;
34
36{
37public:
62
68
70 const symbolt &class_symbol,
71 const methodt &method,
72 const std::optional<prefix_filtert> &method_context)
73 {
74 convert(class_symbol, method, method_context);
75 }
76
78
79protected:
83 const size_t max_array_length;
87 std::optional<ci_lazy_methods_neededt> needed_lazy_methods;
88
93
96
100
102
107
108public:
114
116 {
119 std::vector<holet> holes;
120 };
121
122 typedef std::vector<local_variable_with_holest>
124
126 {
127 public:
129 size_t start_pc;
130 size_t length;
131 bool is_parameter = false;
132 std::vector<holet> holes;
133
136 std::size_t _start_pc,
137 std::size_t _length)
139 {
140 }
141
144 std::size_t _start_pc,
145 std::size_t _length,
146 bool _is_parameter)
151 {
152 }
153
156 std::size_t _start_pc,
157 std::size_t _length,
158 bool _is_parameter,
159 std::vector<holet> &&_holes)
164 holes(std::move(_holes))
165 {
166 }
167 };
168
169protected:
170 typedef std::vector<variablet> variablest;
172 std::set<symbol_exprt> used_local_names;
174 std::map<irep_idt, bool> class_has_clinit_method;
175 std::map<irep_idt, bool> any_superclass_has_clinit_method;
177
183
184 // return corresponding reference of variable
185 const variablet &find_variable_for_slot(
186 size_t address,
188
189 // JVM local variables
195
196 exprt variable(const exprt &arg, char type_char, size_t address);
197
198 // temporary variables
199 std::list<symbol_exprt> tmp_vars;
200
201 symbol_exprt tmp_variable(const std::string &prefix, const typet &type);
202
203 // JVM program locations
204 static irep_idt label(const irep_idt &address);
205
206 // JVM Stack
207 typedef std::vector<exprt> stackt;
209
210 exprt::operandst pop(std::size_t n);
211
212 void pop_residue(std::size_t n);
213
214 void push(const exprt::operandst &o);
215
220 {
221 return v.index < slots_for_parameters;
222 }
223
225 {
227 const instructionst::const_iterator &it,
228 const codet &_code)
229 : source(it), code(_code), done(false)
230 {
231 }
232
233 instructionst::const_iterator source;
234 std::list<method_offsett> successors;
235 std::set<method_offsett> predecessors;
238 bool done;
239 };
240
241public:
242 typedef std::map<method_offsett, converted_instructiont> address_mapt;
244 {
246 : method_with_amap(m, a)
247 {
248 }
249
250 std::pair<const methodt &, const address_mapt &> method_with_amap;
251
252 struct target_less_than // NOLINT(readability/identifiers)
253 {
254 bool operator()(const method_offsett &a, const method_offsett &b) const
255 {
256 return a < b;
257 }
258 };
259 };
262
263protected:
266 const address_mapt &amap,
268
270 local_variable_table_with_holest::iterator firstvar,
271 local_variable_table_with_holest::iterator varlimit,
272 const address_mapt &amap,
274
275 void setup_local_variables(const methodt &m, const address_mapt &amap);
276
278 {
279 bool leaf;
280 std::vector<method_offsett> branch_addresses;
281 std::vector<block_tree_nodet> branch;
282
284 {
285 }
286
287 explicit block_tree_nodet(bool l) : leaf(l)
288 {
289 }
290
292 {
293 return block_tree_nodet(true);
294 }
295 };
296
297 static void replace_goto_target(
298 codet &repl,
299 const irep_idt &old_label,
300 const irep_idt &new_label);
301
303 block_tree_nodet &tree,
308
310 block_tree_nodet &tree,
315 const address_mapt &amap,
316 bool allow_merge = true);
317
318 // conversion
319 void convert(
320 const symbolt &class_symbol,
321 const methodt &,
322 const std::optional<prefix_filtert> &method_context);
323
325 const methodt &method,
327
329
331
333 const irep_idt &classname,
334 const irep_idt &mangled_method_name) const;
335
337 const irep_idt &class_identifier, const irep_idt &component_name) const;
338
340 {
341 VARIABLE,
342 ARRAY_REF,
344 FIELD
345 };
346
348 const std::string &,
349 code_blockt &,
351 const irep_idt &);
352
354 const std::string &,
355 const typet &,
356 code_blockt &,
357 exprt &);
358
359 std::vector<method_offsett> try_catch_handler(
360 method_offsett address,
362 const;
363
365 address_mapt &address_map,
366 const std::vector<method_offsett> &jsr_ret_targets,
367 const std::vector<
368 std::vector<java_bytecode_parse_treet::instructiont>::const_iterator>
369 &ret_instructions) const;
370
371 std::optional<exprt> convert_invoke_dynamic(
372 const source_locationt &location,
373 std::size_t instruction_address,
374 const exprt &arg0,
376
378 const irep_idt &statement,
379 const exprt::operandst &op,
380 const source_locationt &location);
381
383 const irep_idt &statement,
384 const exprt &arg0,
385 const exprt::operandst &op,
386 const method_offsett address,
387 const source_locationt &location);
388
389 static exprt
390 convert_aload(const irep_idt &statement, const exprt::operandst &op);
391
401 exprt convert_load(const exprt &index, char type_char, size_t address);
402
404 const std::vector<method_offsett> &jsr_ret_targets,
405 const exprt &arg0,
406 const source_locationt &location,
407 const method_offsett address);
408
411 const u1 bytecode,
412 const exprt::operandst &op,
413 const mp_integer &number,
414 const source_locationt &location) const;
415
418 const exprt::operandst &op,
419 const irep_idt &id,
420 const mp_integer &number,
421 const source_locationt &location) const;
422
425 const exprt::operandst &op,
426 const mp_integer &number,
427 const source_locationt &location) const;
428
431 const exprt::operandst &op,
432 const mp_integer &number,
433 const source_locationt &location) const;
434
436 const exprt &arg0,
437 const exprt &arg1,
438 const source_locationt &location,
439 method_offsett address);
440
442 const irep_idt &statement,
443 const exprt::operandst &op,
445
447 const irep_idt &statement,
448 const exprt::operandst &op,
450
453
455 const irep_idt &statement,
456 const exprt::operandst &op,
458
460 const source_locationt &source_location,
461 const exprt &arg0,
462 const symbol_exprt &symbol_expr,
464 codet &c,
466
469
471 const source_locationt &location,
472 const exprt &arg0,
473 const exprt::operandst &op,
474 const symbol_exprt &symbol_expr);
475
476 void convert_new(
477 const source_locationt &location,
478 const exprt &arg0,
479 codet &c,
481
483 const source_locationt &location,
484 const irep_idt &statement,
485 const exprt &arg0,
486 const exprt::operandst &op,
488
490 const source_locationt &location,
491 const exprt &arg0,
492 const exprt::operandst &op,
494
496 const methodt &method,
497 const std::set<method_offsett> &working_set,
499 codet &c);
500
501 void convert_athrow(
502 const source_locationt &location,
503 const exprt::operandst &op,
504 codet &c,
506
508 const exprt &arg0,
509 const exprt::operandst &op,
510 codet &c,
512
514 const irep_idt &statement,
515 const exprt::operandst &op,
516 const source_locationt &source_location);
517
519
520 void convert_invoke(
521 source_locationt location,
522 const irep_idt &statement,
524 codet &c,
526
528 const irep_idt &statement,
529 const constant_exprt &arg0,
531
533
535
537
539 const exprt::operandst &op,
541 const source_locationt &location);
542
543 codet convert_pop(const irep_idt &statement, const exprt::operandst &op);
544
546};
547#endif
Compute dominators for CFG of goto_function.
Context-insensitive lazy methods container.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Non-graph-based representation of the class hierarchy.
An expression describing a method on a class.
Definition std_expr.h:3633
A codet representing sequential composition of program statements.
Definition std_code.h:130
codet representation of an if-then-else statement.
Definition std_code.h:460
codet representing a switch statement.
Definition std_code.h:548
Data structure for representing an arbitrary statement in a program.
A constant literal expression.
Definition std_expr.h:3117
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
Represents the argument of an instruction that uses a CONSTANT_Fieldref This is used for example as a...
variablet(const symbol_exprt &_symbol_expr, std::size_t _start_pc, std::size_t _length, bool _is_parameter, std::vector< holet > &&_holes)
variablet(const symbol_exprt &_symbol_expr, std::size_t _start_pc, std::size_t _length, bool _is_parameter)
variablet(const symbol_exprt &_symbol_expr, std::size_t _start_pc, std::size_t _length)
void convert_dup2_x2(exprt::operandst &op, exprt::operandst &results)
method_offsett slots_for_parameters
Number of local variable slots used by the JVM to pass parameters upon invocation of the method under...
irep_idt get_static_field(const irep_idt &class_identifier, const irep_idt &component_name) const
Get static field identifier referred to by class_identifier.component_name Note this may be inherited...
void draw_edges_from_ret_to_jsr(address_mapt &address_map, const std::vector< method_offsett > &jsr_ret_targets, const std::vector< std::vector< java_bytecode_parse_treet::instructiont >::const_iterator > &ret_instructions) const
code_ifthenelset convert_if_cmp(const java_bytecode_convert_methodt::address_mapt &address_map, const u1 bytecode, const exprt::operandst &op, const mp_integer &number, const source_locationt &location) const
void create_stack_tmp_var(const std::string &, const typet &, code_blockt &, exprt &)
actually create a temporary variable to hold the value of a stack entry
std::optional< ci_lazy_methods_neededt > needed_lazy_methods
cfg_dominators_templatet< method_with_amapt, method_offsett, false > java_cfg_dominatorst
codet & do_exception_handling(const methodt &method, const std::set< method_offsett > &working_set, method_offsett cur_pc, codet &c)
exprt::operandst & convert_ushr(const irep_idt &statement, const exprt::operandst &op, exprt::operandst &results) const
exprt convert_load(const exprt &index, char type_char, size_t address)
Load reference from local variable.
void setup_local_variables(const methodt &m, const address_mapt &amap)
See find_initializers_for_slot above for more detail.
const variablet & find_variable_for_slot(size_t address, variablest &var_list)
See above.
code_blockt convert_store(const irep_idt &statement, const exprt &arg0, const exprt::operandst &op, const method_offsett address, const source_locationt &location)
code_blockt convert_astore(const irep_idt &statement, const exprt::operandst &op, const source_locationt &location)
std::optional< exprt > convert_invoke_dynamic(const source_locationt &location, std::size_t instruction_address, const exprt &arg0, codet &result_code)
static irep_idt label(const irep_idt &address)
std::vector< method_offsett > try_catch_handler(method_offsett address, const java_bytecode_parse_treet::methodt::exception_tablet &exception_table) const
code_blockt convert_instructions(const methodt &)
codet & replace_call_to_cprover_assume(source_locationt location, codet &c)
java_string_library_preprocesst & string_preprocess
void convert(const symbolt &class_symbol, const methodt &, const std::optional< prefix_filtert > &method_context)
code_blockt convert_ret(const std::vector< method_offsett > &jsr_ret_targets, const exprt &arg0, const source_locationt &location, const method_offsett address)
void find_initializers(local_variable_table_with_holest &vars, const address_mapt &amap, const java_cfg_dominatorst &doms)
See find_initializers_for_slot above for more detail.
codet get_clinit_call(const irep_idt &classname)
Each static access to classname should be prefixed with a check for necessary static init; this retur...
code_blockt convert_putstatic(const source_locationt &location, const exprt &arg0, const exprt::operandst &op, const symbol_exprt &symbol_expr)
code_ifthenelset convert_if(const java_bytecode_convert_methodt::address_mapt &address_map, const exprt::operandst &op, const irep_idt &id, const mp_integer &number, const source_locationt &location) const
java_bytecode_parse_treet::methodt methodt
std::vector< local_variable_with_holest > local_variable_table_with_holest
code_ifthenelset convert_ifnull(const java_bytecode_convert_methodt::address_mapt &address_map, const exprt::operandst &op, const mp_integer &number, const source_locationt &location) const
code_blockt & get_block_for_pcrange(block_tree_nodet &tree, code_blockt &this_block, method_offsett address_start, method_offsett address_limit, method_offsett next_block_start_address)
'tree' describes a tree of code_blockt objects; this_block is the corresponding block (thus they are ...
void find_initializers_for_slot(local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, const address_mapt &amap, const java_cfg_dominatorst &doms)
Given a sequence of users of the same local variable slot, this figures out which ones are related by...
codet convert_pop(const irep_idt &statement, const exprt::operandst &op)
java_bytecode_parse_treet::instructiont instructiont
exprt::operandst & convert_const(const irep_idt &statement, const constant_exprt &arg0, exprt::operandst &results) const
void convert_checkcast(const exprt &arg0, const exprt::operandst &op, codet &c, exprt::operandst &results) const
void convert_dup2_x1(exprt::operandst &op, exprt::operandst &results)
code_blockt convert_putfield(const fieldref_exprt &arg0, const exprt::operandst &op)
code_blockt convert_multianewarray(const source_locationt &location, const exprt &arg0, const exprt::operandst &op, exprt::operandst &results)
code_ifthenelset convert_ifnonull(const java_bytecode_convert_methodt::address_mapt &address_map, const exprt::operandst &op, const mp_integer &number, const source_locationt &location) const
void operator()(const symbolt &class_symbol, const methodt &method, const std::optional< prefix_filtert > &method_context)
code_blockt convert_parameter_annotations(const methodt &method, const java_method_typet &method_type)
code_switcht convert_switch(const exprt::operandst &op, const java_bytecode_parse_treet::instructiont::argst &args, const source_locationt &location)
void save_stack_entries(const std::string &, code_blockt &, const bytecode_write_typet, const irep_idt &)
Create temporary variables if a write instruction can have undesired side- effects.
bool is_parameter(const local_variablet &v)
Returns true iff the slot index of the local variable of a method (coming from the LVT) is a paramete...
void convert_new(const source_locationt &location, const exprt &arg0, codet &c, exprt::operandst &results)
exprt variable(const exprt &arg, char type_char, size_t address)
Returns an expression indicating a local variable suitable to load/store from a bytecode at address a...
std::map< method_offsett, converted_instructiont > address_mapt
methodt::local_variable_tablet local_variable_tablet
std::map< irep_idt, bool > any_superclass_has_clinit_method
static void replace_goto_target(codet &repl, const irep_idt &old_label, const irep_idt &new_label)
Find all goto statements in 'repl' that target 'old_label' and redirect them to 'new_label'.
code_blockt convert_iinc(const exprt &arg0, const exprt &arg1, const source_locationt &location, method_offsett address)
java_bytecode_convert_methodt(symbol_table_baset &symbol_table, message_handlert &_message_handler, size_t _max_array_length, bool throw_assertion_error, std::optional< ci_lazy_methods_neededt > needed_lazy_methods, java_string_library_preprocesst &_string_preprocess, const class_hierarchyt &class_hierarchy, bool threading_support, bool assert_no_exceptions_thrown)
exprt::operandst & convert_cmp2(const irep_idt &statement, const exprt::operandst &op, exprt::operandst &results) const
void convert_dup2(exprt::operandst &op, exprt::operandst &results)
bool is_method_inherited(const irep_idt &classname, const irep_idt &mangled_method_name) const
Returns true iff method methodid from class classname is a method inherited from a class or interface...
void convert_athrow(const source_locationt &location, const exprt::operandst &op, codet &c, exprt::operandst &results) const
typet method_return_type
Return type of the method under conversion.
void convert_getstatic(const source_locationt &source_location, const exprt &arg0, const symbol_exprt &symbol_expr, bool is_assertions_disabled_field, codet &c, exprt::operandst &results)
irep_idt method_id
Fully qualified name of the method under translation.
code_blockt convert_newarray(const source_locationt &location, const irep_idt &statement, const exprt &arg0, const exprt::operandst &op, exprt::operandst &results)
exprt::operandst & convert_shl(const irep_idt &statement, const exprt::operandst &op, exprt::operandst &results) const
exprt::operandst & convert_cmp(const exprt::operandst &op, exprt::operandst &results) const
void pop_residue(std::size_t n)
removes minimum(n, stack.size()) elements from the stack
void convert_invoke(source_locationt location, const irep_idt &statement, class_method_descriptor_exprt &class_method_descriptor, codet &c, exprt::operandst &results)
code_blockt & get_or_create_block_for_pcrange(block_tree_nodet &tree, code_blockt &this_block, method_offsett address_start, method_offsett address_limit, method_offsett next_block_start_address, const address_mapt &amap, bool allow_merge=true)
As above, but this version can additionally create a new branch in the block_tree-node and code_block...
codet convert_monitorenterexit(const irep_idt &statement, const exprt::operandst &op, const source_locationt &source_location)
irep_idt current_method
A copy of method_id :/.
static exprt convert_aload(const irep_idt &statement, const exprt::operandst &op)
symbol_exprt tmp_variable(const std::string &prefix, const typet &type)
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
Provides filtering of strings vai inclusion/exclusion lists of prefixes.
Expression to hold a symbol (variable)
Definition std_expr.h:131
The symbol table base class interface.
Symbol table entry.
Definition symbol.h:28
The type of an expression, extends irept.
Definition type.h:29
JAVA Bytecode Language Conversion.
java_bytecode_convert_methodt::address_mapt address_mapt
STL namespace.
BigInt mp_integer
Definition smt_terms.h:17
API to expression classes.
converted_instructiont(const instructionst::const_iterator &it, const codet &_code)
bool operator()(const method_offsett &a, const method_offsett &b) const
std::pair< const methodt &, const address_mapt & > method_with_amap
std::vector< local_variablet > local_variable_tablet
std::vector< instructiont > instructionst