@@ -502,6 +502,7 @@ bool java_bytecode_languaget::typecheck(
502
502
// that are reachable from this entry point.
503
503
if (lazy_methods_mode==LAZY_METHODS_MODE_CONTEXT_INSENSITIVE)
504
504
{
505
+ // ci: context-insensitive.
505
506
if (do_ci_lazy_method_conversion (symbol_table, lazy_methods))
506
507
return true ;
507
508
}
@@ -514,6 +515,32 @@ bool java_bytecode_languaget::typecheck(
514
515
return false ;
515
516
}
516
517
518
+ /* ******************************************************************\
519
+
520
+ Function: java_bytecode_languaget::do_ci_lazy_method_conversion
521
+
522
+ Inputs: `symbol_table`: global symbol table
523
+ `lazy_methods`: map from method names to relevant symbol
524
+ and parsed-method objects.
525
+
526
+ Outputs: Elaborates lazily-converted methods that may be reachable
527
+ starting from the main entry point (usually provided with
528
+ the --function command-line option) (side-effect on the
529
+ symbol_table). Returns false on success.
530
+
531
+ Purpose: Uses a simple context-insensitive ('ci') analysis to
532
+ determine which methods may be reachable from the main
533
+ entry point. In brief, static methods are reachable if we
534
+ find a callsite in another reachable site, while virtual
535
+ methods are reachable if we find a virtual callsite
536
+ targeting a compatible type *and* a constructor callsite
537
+ indicating an object of that type may be instantiated (or
538
+ evidence that an object of that type exists before the
539
+ main function is entered, such as being passed as a
540
+ parameter).
541
+
542
+ \*******************************************************************/
543
+
517
544
bool java_bytecode_languaget::do_ci_lazy_method_conversion (
518
545
symbol_tablet &symbol_table,
519
546
lazy_methodst &lazy_methods)
@@ -558,7 +585,7 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
558
585
needed_classes);
559
586
560
587
std::set<irep_idt> methods_already_populated;
561
- std::vector<const code_function_callt*> virtual_callsites;
588
+ std::vector<const code_function_callt *> virtual_callsites;
562
589
563
590
bool any_new_methods;
564
591
do
@@ -586,8 +613,10 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
586
613
get_message_handler (),
587
614
disable_runtime_checks,
588
615
max_user_array_length,
589
- safe_pointer<std::vector<irep_idt> >::create_non_null (&method_worklist2),
590
- safe_pointer<std::set<irep_idt> >::create_non_null (&needed_classes));
616
+ safe_pointer<std::vector<irep_idt> >::create_non_null (
617
+ &method_worklist2),
618
+ safe_pointer<std::set<irep_idt> >::create_non_null (
619
+ &needed_classes));
591
620
gather_virtual_callsites (
592
621
symbol_table.lookup (mname).value ,
593
622
virtual_callsites);
@@ -607,11 +636,15 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
607
636
for (const auto &callsite : virtual_callsites)
608
637
{
609
638
// This will also create a stub if a virtual callsite has no targets.
610
- get_virtual_method_targets (*callsite, needed_classes, method_worklist2,
611
- symbol_table, ch);
639
+ get_virtual_method_targets (
640
+ *callsite,
641
+ needed_classes,
642
+ method_worklist2,
643
+ symbol_table,
644
+ ch);
612
645
}
613
-
614
- } while (any_new_methods);
646
+ }
647
+ while (any_new_methods);
615
648
616
649
// Remove symbols for methods that were declared but never used:
617
650
symbol_tablet keep_symbols;
@@ -640,12 +673,49 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
640
673
return false ;
641
674
}
642
675
643
- void java_bytecode_languaget::lazy_methods_provided (std::set<irep_idt> &methods) const
676
+ /* ******************************************************************\
677
+
678
+ Function: java_bytecode_languaget::lazy_methods_provided
679
+
680
+ Inputs: None
681
+
682
+ Outputs: Populates `methods` with the complete list of lazy methods
683
+ that are available to convert (those which are valid
684
+ parameters for `convert_lazy_method`)
685
+
686
+ Purpose: Provide feedback to `language_filest` so that when asked
687
+ for a lazy method, it can delegate to this instance of
688
+ java_bytecode_languaget.
689
+
690
+ \*******************************************************************/
691
+
692
+ void java_bytecode_languaget::lazy_methods_provided (
693
+ std::set<irep_idt> &methods) const
644
694
{
645
695
for (const auto &kv : lazy_methods)
646
696
methods.insert (kv.first );
647
697
}
648
698
699
+ /* ******************************************************************\
700
+
701
+ Function: java_bytecode_languaget::convert_lazy_method
702
+
703
+ Inputs: `id`: method ID to convert
704
+ `symtab`: global symbol table
705
+
706
+ Outputs: Amends the symbol table entry for function `id`, which
707
+ should be a lazy method provided by this instance of
708
+ `java_bytecode_languaget`. It should initially have a nil
709
+ value. After this method completes, it will have a value
710
+ representing the method body, identical to that produced
711
+ using eager method conversion.
712
+
713
+ Purpose: Promote a lazy-converted method (one whose type is known
714
+ but whose body hasn't been converted) into a fully-
715
+ elaborated one.
716
+
717
+ \*******************************************************************/
718
+
649
719
void java_bytecode_languaget::convert_lazy_method (
650
720
const irep_idt &id,
651
721
symbol_tablet &symtab)
0 commit comments