1111#include < java_bytecode/java_entry_point.h>
1212#include < java_bytecode/java_class_loader.h>
1313#include < java_bytecode/java_utils.h>
14- #include < util/safe_pointer.h>
1514#include < util/suffix.h>
1615#include < java_bytecode/java_string_library_preprocess.h>
1716
@@ -61,14 +60,14 @@ ci_lazy_methodst::ci_lazy_methodst(
6160// / from the main entry point (usually provided with the --function command-
6261// / line option
6362// / \param symbol_table: global symbol table
64- // / \param [out] lazy_methods : map from method names to relevant symbol and
63+ // / \param [out] method_bytecode : map from method names to relevant symbol and
6564// / parsed-method objects.
6665// / \param method_converter: Function for converting methods on demand.
6766// / \return Returns false on success
6867bool ci_lazy_methodst::operator ()(
6968 symbol_tablet &symbol_table,
70- lazy_methodst &lazy_methods ,
71- method_convertert method_converter)
69+ method_bytecodet &method_bytecode ,
70+ const method_convertert & method_converter)
7271{
7372 std::vector<irep_idt> method_worklist1;
7473 std::vector<irep_idt> method_worklist2;
@@ -141,21 +140,17 @@ bool ci_lazy_methodst::operator()(
141140 {
142141 if (!methods_already_populated.insert (mname).second )
143142 continue ;
144- auto findit=lazy_methods.find (mname);
145- if (findit==lazy_methods.end ())
143+ debug () << " CI lazy methods: elaborate " << mname << eom;
144+ if (
145+ method_converter (
146+ mname,
147+ // Note this wraps *references* to method_worklist2 & needed_classes
148+ ci_lazy_methods_neededt (
149+ method_worklist2, needed_classes, symbol_table)))
146150 {
147- debug () << " Skip " << mname << eom;
151+ // Couldn't convert this function
148152 continue ;
149153 }
150- debug () << " CI lazy methods: elaborate " << mname << eom;
151- const auto &parsed_method=findit->second ;
152- // Note this wraps *references* to method_worklist2, needed_classes:
153- ci_lazy_methods_neededt new_lazy_methods (
154- method_worklist2,
155- needed_classes,
156- symbol_table);
157- method_converter (
158- *parsed_method.first , *parsed_method.second , new_lazy_methods);
159154 gather_virtual_callsites (
160155 symbol_table.lookup_ref (mname).value ,
161156 virtual_callsites);
@@ -189,15 +184,23 @@ bool ci_lazy_methodst::operator()(
189184
190185 for (const auto &sym : symbol_table.symbols )
191186 {
187+ // Don't keep global variables (unless they're gathered below from a
188+ // function that references them)
192189 if (sym.second .is_static_lifetime )
193190 continue ;
194- if (lazy_methods.count (sym.first ) &&
195- !methods_already_populated.count (sym.first ))
196- {
197- continue ;
198- }
199191 if (sym.second .type .id ()==ID_code)
192+ {
193+ // Don't keep functions that belong to this language that we haven't
194+ // converted above
195+ if (
196+ method_bytecode.contains_method (sym.first ) &&
197+ !methods_already_populated.count (sym.first ))
198+ {
199+ continue ;
200+ }
201+ // If this is a function then add all the things used in it
200202 gather_needed_globals (sym.second .value , symbol_table, keep_symbols);
203+ }
201204 keep_symbols.add (sym.second );
202205 }
203206
@@ -263,13 +266,13 @@ void ci_lazy_methodst::resolve_method_names(
263266// / \param entry_points: list of fully-qualified function names that
264267// / we should assume are reachable
265268// / \param ns: global namespace
266- // / \param [out] lazy_methods : Populated with all Java reference types whose
267- // / references may be passed, directly or indirectly, to any of the functions
268- // / in `entry_points`.
269+ // / \param [out] needed_lazy_methods : Populated with all Java reference types
270+ // / whose references may be passed, directly or indirectly, to any of the
271+ // / functions in `entry_points`.
269272void ci_lazy_methodst::initialize_needed_classes (
270273 const std::vector<irep_idt> &entry_points,
271274 const namespacet &ns,
272- ci_lazy_methods_neededt &lazy_methods )
275+ ci_lazy_methods_neededt &needed_lazy_methods )
273276{
274277 for (const auto &mname : entry_points)
275278 {
@@ -281,67 +284,66 @@ void ci_lazy_methodst::initialize_needed_classes(
281284 {
282285 const pointer_typet &original_pointer=to_pointer_type (param.type ());
283286 initialize_all_needed_classes_from_pointer (
284- original_pointer, ns, lazy_methods );
287+ original_pointer, ns, needed_lazy_methods );
285288 }
286289 }
287290 }
288291
289292 // Also add classes whose instances are magically
290293 // created by the JVM and so won't be spotted by
291294 // looking for constructors and calls as usual:
292- lazy_methods .add_needed_class (" java::java.lang.String" );
293- lazy_methods .add_needed_class (" java::java.lang.Class" );
294- lazy_methods .add_needed_class (" java::java.lang.Object" );
295+ needed_lazy_methods .add_needed_class (" java::java.lang.String" );
296+ needed_lazy_methods .add_needed_class (" java::java.lang.Class" );
297+ needed_lazy_methods .add_needed_class (" java::java.lang.Object" );
295298
296299 // As in class_loader, ensure these classes stay available
297300 for (const auto &id : extra_needed_classes)
298- lazy_methods .add_needed_class (" java::" + id2string (id));
301+ needed_lazy_methods .add_needed_class (" java::" + id2string (id));
299302}
300303
301304// / Build up list of methods for types for a pointer and any types it
302305// / might be subsituted for. See
303306// / `initialize_needed_classes` for more details.
304307// / \param pointer_type: The type to gather methods for.
305308// / \param ns: global namespace
306- // / \param [out] lazy_methods : Populated with all Java reference types whose
307- // / references may be passed, directly or indirectly, to any of the functions
308- // / in `entry_points
309+ // / \param [out] needed_lazy_methods : Populated with all Java reference types
310+ // / whose references may be passed, directly or indirectly, to any of the
311+ // / functions in `entry_points`
309312void ci_lazy_methodst::initialize_all_needed_classes_from_pointer (
310313 const pointer_typet &pointer_type,
311314 const namespacet &ns,
312- ci_lazy_methods_neededt &lazy_methods )
315+ ci_lazy_methods_neededt &needed_lazy_methods )
313316{
314- initialize_needed_classes_from_pointer (
315- pointer_type, ns, lazy_methods);
317+ initialize_needed_classes_from_pointer (pointer_type, ns, needed_lazy_methods);
316318
317319 const pointer_typet &subbed_pointer_type=
318320 pointer_type_selector.convert_pointer_type (pointer_type, ns);
319321
320322 if (subbed_pointer_type!=pointer_type)
321323 {
322324 initialize_needed_classes_from_pointer (
323- subbed_pointer_type, ns, lazy_methods );
325+ subbed_pointer_type, ns, needed_lazy_methods );
324326 }
325327}
326328
327329// / Build up list of methods for types for a specific pointer type. See
328330// / `initialize_needed_classes` for more details.
329331// / \param pointer_type: The type to gather methods for.
330332// / \param ns: global namespace
331- // / \param [out] lazy_methods : Populated with all Java reference types whose
332- // / references may be passed, directly or indirectly, to any of the functions
333- // / in `entry_points
333+ // / \param [out] needed_lazy_methods : Populated with all Java reference types
334+ // / whose references may be passed, directly or indirectly, to any of the
335+ // / functions in `entry_points`
334336void ci_lazy_methodst::initialize_needed_classes_from_pointer (
335337 const pointer_typet &pointer_type,
336338 const namespacet &ns,
337- ci_lazy_methods_neededt &lazy_methods )
339+ ci_lazy_methods_neededt &needed_lazy_methods )
338340{
339341 const symbol_typet &class_type=to_symbol_type (pointer_type.subtype ());
340342 const auto ¶m_classid=class_type.get_identifier ();
341343
342- if (lazy_methods .add_needed_class (param_classid))
344+ if (needed_lazy_methods .add_needed_class (param_classid))
343345 {
344- gather_field_types (pointer_type.subtype (), ns, lazy_methods );
346+ gather_field_types (pointer_type.subtype (), ns, needed_lazy_methods );
345347 }
346348}
347349
@@ -462,30 +464,30 @@ void ci_lazy_methodst::gather_needed_globals(
462464 gather_needed_globals (*opit, symbol_table, needed);
463465}
464466
465- // / See param lazy_methods
467+ // / See param needed_lazy_methods
466468// / \param class_type: root of class tree to search
467469// / \param ns: global namespace
468- // / \param [out] lazy_methods : Popualted with all Java reference types reachable
469- // / starting at `class_type`. For example if `class_type` is
470+ // / \param [out] needed_lazy_methods : Popualted with all Java reference types
471+ // / reachable starting at `class_type`. For example if `class_type` is
470472// / `symbol_typet("java::A")` and A has a B field, then `B` (but not `A`) will
471473// / noted as a needed class.
472474void ci_lazy_methodst::gather_field_types (
473475 const typet &class_type,
474476 const namespacet &ns,
475- ci_lazy_methods_neededt &lazy_methods )
477+ ci_lazy_methods_neededt &needed_lazy_methods )
476478{
477479 const auto &underlying_type=to_struct_type (ns.follow (class_type));
478480 for (const auto &field : underlying_type.components ())
479481 {
480482 if (field.type ().id ()==ID_struct || field.type ().id ()==ID_symbol)
481- gather_field_types (field.type (), ns, lazy_methods );
483+ gather_field_types (field.type (), ns, needed_lazy_methods );
482484 else if (field.type ().id ()==ID_pointer)
483485 {
484486 // Skip array primitive pointers, for example:
485487 if (field.type ().subtype ().id ()!=ID_symbol)
486488 continue ;
487489 initialize_all_needed_classes_from_pointer (
488- to_pointer_type (field.type ()), ns, lazy_methods );
490+ to_pointer_type (field.type ()), ns, needed_lazy_methods );
489491 }
490492 }
491493}
0 commit comments