cprover
ci_lazy_methods.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3  Module: Java Bytecode
4 
5  Author: Diffblue Ltd.
6 
7 \*******************************************************************/
8 
11 
12 #ifndef CPROVER_JAVA_BYTECODE_GATHER_METHODS_LAZILY_H
13 #define CPROVER_JAVA_BYTECODE_GATHER_METHODS_LAZILY_H
14 
15 #include "ci_lazy_methods_needed.h"
17 #include "java_class_loader.h"
18 #include "select_pointer_type.h"
19 #include "synthetic_methods_map.h"
20 
21 #include <map>
22 #include <functional>
23 
24 #include <util/irep.h>
25 #include <util/symbol_table.h>
26 #include <util/message.h>
27 
29 
31 
32 // Map from method id to class_method_and_bytecodet
34 {
35 public:
38  {
42  };
43 
46 
47 private:
48  typedef std::map<irep_idt, class_method_and_bytecodet> mapt;
50 
51 public:
52  bool contains_method(const irep_idt &method_id) const
53  {
54  return map.count(method_id) != 0;
55  }
56 
57  void add(const class_method_and_bytecodet &method_class_and_bytecode)
58  {
59  map.emplace(
60  std::make_pair(
61  method_class_and_bytecode.method_id, method_class_and_bytecode));
62  }
63 
64  void add(
65  const irep_idt &class_id,
66  const irep_idt &method_id,
68  {
69  add(class_method_and_bytecodet{class_id, method_id, method});
70  }
71 
72  mapt::const_iterator begin() const
73  {
74  return map.begin();
75  }
76  mapt::const_iterator end() const
77  {
78  return map.end();
79  }
80 
81  opt_reft get(const irep_idt &method_id)
82  {
83  const auto it = map.find(method_id);
84  if(it == map.end())
85  return opt_reft();
86  return std::cref(it->second);
87  }
88 };
89 
90 typedef std::function<
91  bool(const irep_idt &function_id, ci_lazy_methods_neededt)>
93 
94 typedef std::function<std::vector<irep_idt>(const symbol_tablet &)>
96 
98 {
99 public:
101  const symbol_tablet &symbol_table,
102  const irep_idt &main_class,
103  const std::vector<irep_idt> &main_jar_classes,
104  const std::vector<load_extra_methodst> &lazy_methods_extra_entry_points,
106  const std::vector<irep_idt> &extra_instantiated_classes,
110 
111  // not const since messaget
112  bool operator()(
113  symbol_tablet &symbol_table,
114  method_bytecodet &method_bytecode,
115  const method_convertert &method_converter);
116 
117 private:
119  const std::unordered_set<irep_idt> &entry_points,
120  const namespacet &ns,
121  ci_lazy_methods_neededt &needed_lazy_methods);
122 
124  const exprt &e,
125  std::unordered_set<exprt, irep_hash> &result);
126 
128  const exprt &called_function,
129  const std::unordered_set<irep_idt> &instantiated_classes,
130  std::unordered_set<irep_idt> &callable_methods,
131  symbol_tablet &symbol_table);
132 
134  const exprt &e,
135  const symbol_tablet &symbol_table,
136  symbol_tablet &needed);
137 
139  const std::unordered_set<irep_idt> &instantiated_classes,
140  const irep_idt &call_basename,
141  const irep_idt &classname,
142  const symbol_tablet &symbol_table);
143 
145  const irep_idt &class_name,
146  const irep_idt &component_method_name);
147 
150  std::vector<irep_idt> main_jar_classes;
151  const std::vector<load_extra_methodst> &lazy_methods_extra_entry_points;
153  const std::vector<irep_idt> &extra_instantiated_classes;
156 
157  std::unordered_set<irep_idt>
158  entry_point_methods(const symbol_tablet &symbol_table);
159 
161  {
163  bool new_method_seen = false;
164  };
165 
167  const method_convertert &method_converter,
168  std::unordered_set<irep_idt> &methods_already_populated,
169  const bool class_initializer_already_seen,
170  const irep_idt &method_name,
171  symbol_tablet &symbol_table,
172  std::unordered_set<irep_idt> &methods_to_convert_later,
173  std::unordered_set<irep_idt> &instantiated_classes,
174  std::unordered_set<exprt, irep_hash> &virtual_function_calls);
175 
177  std::unordered_set<irep_idt> &methods_to_convert_later,
178  std::unordered_set<irep_idt> &instantiated_classes,
179  const std::unordered_set<exprt, irep_hash> &virtual_function_calls,
180  symbol_tablet &symbol_table);
181 };
182 
183 #endif // CPROVER_JAVA_BYTECODE_GATHER_METHODS_LAZILY_H
convert_method_resultt convert_and_analyze_method(const method_convertert &method_converter, std::unordered_set< irep_idt > &methods_already_populated, const bool class_initializer_already_seen, const irep_idt &method_name, symbol_tablet &symbol_table, std::unordered_set< irep_idt > &methods_to_convert_later, std::unordered_set< irep_idt > &instantiated_classes, std::unordered_set< exprt, irep_hash > &virtual_function_calls)
Convert a method, add it to the populated set, add needed methods to methods_to_convert_later and add...
optionalt< std::reference_wrapper< const class_method_and_bytecodet > > opt_reft
bool handle_virtual_methods_with_no_callees(std::unordered_set< irep_idt > &methods_to_convert_later, std::unordered_set< irep_idt > &instantiated_classes, const std::unordered_set< exprt, irep_hash > &virtual_function_calls, symbol_tablet &symbol_table)
Look for virtual callsites with no candidate targets.
const select_pointer_typet & pointer_type_selector
mapt::const_iterator end() const
Non-graph-based representation of the class hierarchy.
std::function< bool(const irep_idt &function_id, ci_lazy_methods_neededt)> method_convertert
const std::vector< irep_idt > & extra_instantiated_classes
irep_idt get_virtual_method_target(const std::unordered_set< irep_idt > &instantiated_classes, const irep_idt &call_basename, const irep_idt &classname, const symbol_tablet &symbol_table)
Find a virtual callee, if one is defined and the callee type is known to exist.
void gather_virtual_callsites(const exprt &e, std::unordered_set< exprt, irep_hash > &result)
Get places where virtual functions are called.
Class Hierarchy.
void add(const class_method_and_bytecodet &method_class_and_bytecode)
void initialize_instantiated_classes(const std::unordered_set< irep_idt > &entry_points, const namespacet &ns, ci_lazy_methods_neededt &needed_lazy_methods)
Build up a list of methods whose type may be passed around reachable from the entry point...
std::function< std::vector< irep_idt >const symbol_tablet &)> load_extra_methodst
void gather_needed_globals(const exprt &e, const symbol_tablet &symbol_table, symbol_tablet &needed)
See output.
java_class_loadert & java_class_loader
nonstd::optional< T > optionalt
Definition: optional.h:35
The symbol table.
Definition: symbol_table.h:19
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:93
void add(const irep_idt &class_id, const irep_idt &method_id, const java_bytecode_parse_treet::methodt &method)
Class that provides messages with a built-in verbosity &#39;level&#39;.
Definition: message.h:144
const synthetic_methods_mapt & synthetic_methods
dstringt has one field, an unsigned integer no which is an index into a static table of strings...
Definition: dstring.h:35
Author: Diffblue Ltd.
const java_bytecode_parse_treet::methodt & method
const std::vector< load_extra_methodst > & lazy_methods_extra_entry_points
bool contains_method(const irep_idt &method_id) const
mstreamt & result() const
Definition: message.h:396
Base class for all expressions.
Definition: expr.h:54
std::unordered_set< irep_idt > entry_point_methods(const symbol_tablet &symbol_table)
Entry point methods are either:
Class responsible to load .class files.
std::vector< irep_idt > main_jar_classes
Synthetic methods are particular methods internally generated by the Java frontend, including thunks to ensure static initializers are run once and initializers created for unknown / stub types.
static irep_idt build_virtual_method_name(const irep_idt &class_name, const irep_idt &component_method_name)
mapt::const_iterator begin() const
Context-insensitive lazy methods container.
std::unordered_map< irep_idt, synthetic_method_typet > synthetic_methods_mapt
Maps method names on to a synthetic method kind.
void get_virtual_method_targets(const exprt &called_function, const std::unordered_set< irep_idt > &instantiated_classes, std::unordered_set< irep_idt > &callable_methods, symbol_tablet &symbol_table)
Find possible callees, excluding types that are not known to be instantiated.
bool operator()(symbol_tablet &symbol_table, method_bytecodet &method_bytecode, const method_convertert &method_converter)
Uses a simple context-insensitive (&#39;ci&#39;) analysis to determine which methods may be reachable from th...
message_handlert * message_handler
Definition: message.h:426
Handle selection of correct pointer type (for example changing abstract classes to concrete versions)...
class_hierarchyt class_hierarchy
ci_lazy_methodst(const symbol_tablet &symbol_table, const irep_idt &main_class, const std::vector< irep_idt > &main_jar_classes, const std::vector< load_extra_methodst > &lazy_methods_extra_entry_points, java_class_loadert &java_class_loader, const std::vector< irep_idt > &extra_instantiated_classes, const select_pointer_typet &pointer_type_selector, message_handlert &message_handler, const synthetic_methods_mapt &synthetic_methods)
Constructor for lazy-method loading.
std::map< irep_idt, class_method_and_bytecodet > mapt