Skip to content

Commit 92bec6c

Browse files
Matthias Güdemannthk123
Matthias Güdemann
authored and
thk123
committed
Add force loading parameter --java-load-class
This parameter force loads the specified classes and prevents their methods from being removed by lazy-methods. This allows to add classes that provide an implementations for interfaces, where the classes themselves are not referenced.
1 parent cd86eb8 commit 92bec6c

6 files changed

+58
-12
lines changed

src/java_bytecode/ci_lazy_methods.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,33 @@
1717

1818
#include <goto-programs/resolve_concrete_function_call.h>
1919

20-
20+
/// Constructor for lazy-method loading
21+
/// \param symbol_table: the symbol table to use
22+
/// \param main_class: identifier of the entry point / main class
23+
/// \param main_jar_classes: specify main class of jar if \p main_class is empty
24+
/// \param lazy_methods_extra_entry_points: entry point functions to use
25+
/// \param java_class_loader: the Java class loader to use
26+
/// \param extra_needed_classes: list of class identifiers which are considered
27+
/// to be required and therefore their methods should not be removed via
28+
/// `lazy-methods`. Example of use: `ArrayList` as general implementation for
29+
/// `List` interface.
30+
/// \param pointer_type_selector: selector to handle correct pointer types
31+
/// \param message_handler: the message handler to use for output
2132
ci_lazy_methodst::ci_lazy_methodst(
2233
const symbol_tablet &symbol_table,
2334
const irep_idt &main_class,
2435
const std::vector<irep_idt> &main_jar_classes,
2536
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
2637
java_class_loadert &java_class_loader,
38+
const std::vector<irep_idt> &extra_needed_classes,
2739
const select_pointer_typet &pointer_type_selector,
28-
message_handlert &message_handler):
29-
messaget(message_handler),
40+
message_handlert &message_handler)
41+
: messaget(message_handler),
3042
main_class(main_class),
3143
main_jar_classes(main_jar_classes),
3244
lazy_methods_extra_entry_points(lazy_methods_extra_entry_points),
3345
java_class_loader(java_class_loader),
46+
extra_needed_classes(extra_needed_classes),
3447
pointer_type_selector(pointer_type_selector)
3548
{
3649
// build the class hierarchy
@@ -279,6 +292,10 @@ void ci_lazy_methodst::initialize_needed_classes(
279292
lazy_methods.add_needed_class("java::java.lang.String");
280293
lazy_methods.add_needed_class("java::java.lang.Class");
281294
lazy_methods.add_needed_class("java::java.lang.Object");
295+
296+
// As in class_loader, ensure these classes stay available
297+
for(const auto &id : extra_needed_classes)
298+
lazy_methods.add_needed_class("java::" + id2string(id));
282299
}
283300

284301
/// Build up list of methods for types for a pointer and any types it

src/java_bytecode/ci_lazy_methods.h

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class ci_lazy_methodst:public messaget
4848
const std::vector<irep_idt> &main_jar_classes,
4949
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
5050
java_class_loadert &java_class_loader,
51+
const std::vector<irep_idt> &extra_needed_classes,
5152
const select_pointer_typet &pointer_type_selector,
5253
message_handlert &message_handler);
5354

@@ -111,6 +112,7 @@ class ci_lazy_methodst:public messaget
111112
std::vector<irep_idt> main_jar_classes;
112113
std::vector<irep_idt> lazy_methods_extra_entry_points;
113114
java_class_loadert &java_class_loader;
115+
const std::vector<irep_idt> &extra_needed_classes;
114116
const select_pointer_typet &pointer_type_selector;
115117
};
116118

src/java_bytecode/java_bytecode_language.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
6161
else
6262
lazy_methods_mode=LAZY_METHODS_MODE_EAGER;
6363

64+
if(cmd.isset("java-load-class"))
65+
{
66+
for(const auto &c : cmd.get_values("java-load-class"))
67+
java_load_classes.push_back(c);
68+
}
69+
6470
const std::list<std::string> &extra_entry_points=
6571
cmd.get_values("lazy-methods-extra-entry-point");
6672
lazy_methods_extra_entry_points.insert(
@@ -128,6 +134,7 @@ bool java_bytecode_languaget::parse(
128134
PRECONDITION(language_options_initialized);
129135
java_class_loader.set_message_handler(get_message_handler());
130136
java_class_loader.set_java_cp_include_files(java_cp_include_files);
137+
java_class_loader.add_load_classes(java_load_classes);
131138

132139
// look at extension
133140
if(has_suffix(path, ".class"))
@@ -323,6 +330,7 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
323330
main_jar_classes,
324331
lazy_methods_extra_entry_points,
325332
java_class_loader,
333+
java_load_classes,
326334
get_pointer_type_selector(),
327335
get_message_handler());
328336

src/java_bytecode/java_bytecode_language.h

+13-9
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ Author: Daniel Kroening, [email protected]
2121

2222
#include <java_bytecode/select_pointer_type.h>
2323

24-
#define JAVA_BYTECODE_LANGUAGE_OPTIONS /*NOLINT*/ \
25-
"(java-assume-inputs-non-null)" \
26-
"(java-throw-runtime-exceptions)" \
27-
"(java-max-input-array-length):" \
28-
"(java-max-input-tree-depth):" \
29-
"(java-max-vla-length):" \
30-
"(java-cp-include-files):" \
31-
"(lazy-methods)" \
32-
"(lazy-methods-extra-entry-point):"
24+
#define JAVA_BYTECODE_LANGUAGE_OPTIONS /*NOLINT*/ \
25+
"(java-assume-inputs-non-null)" \
26+
"(java-throw-runtime-exceptions)" \
27+
"(java-max-input-array-length):" \
28+
"(java-max-input-tree-depth):" \
29+
"(java-max-vla-length):" \
30+
"(java-cp-include-files):" \
31+
"(lazy-methods)" \
32+
"(lazy-methods-extra-entry-point):" \
33+
"(java-load-class):"
3334

3435
#define JAVA_BYTECODE_LANGUAGE_OPTIONS_HELP /*NOLINT*/ \
3536
" --java-assume-inputs-non-null never initialize reference-typed parameter to the\n" \
@@ -177,6 +178,9 @@ class java_bytecode_languaget:public languaget
177178
java_string_library_preprocesst string_preprocess;
178179
std::string java_cp_include_files;
179180

181+
// list of classes to force load even without reference from the entry point
182+
std::vector<irep_idt> java_load_classes;
183+
180184
private:
181185
const std::unique_ptr<const select_pointer_typet> pointer_type_selector;
182186
};

src/java_bytecode/java_class_loader.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ java_bytecode_parse_treet &java_class_loadert::operator()(
3636
queue.push("java.lang.Throwable");
3737
queue.push(class_name);
3838

39+
// Require user provided classes to be loaded even without explicit reference
40+
for(const auto &id : java_load_classes)
41+
queue.push(id);
42+
3943
java_class_loader_limitt class_loader_limit(
4044
get_message_handler(), java_cp_include_files);
4145

@@ -278,3 +282,12 @@ jar_filet &java_class_loadert::jar_pool(
278282
else
279283
return it->second;
280284
}
285+
286+
/// Adds the list of classes to the load queue, forcing them to be loaded even
287+
/// without explicit reference
288+
/// \param classes: list of class identifiers
289+
void java_class_loadert::add_load_classes(const std::vector<irep_idt> &classes)
290+
{
291+
for(const auto &id : classes)
292+
java_load_classes.push_back(id);
293+
}

src/java_bytecode/java_class_loader.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class java_class_loadert:public messaget
2626
java_bytecode_parse_treet &operator()(const irep_idt &);
2727

2828
void set_java_cp_include_files(std::string &);
29+
void add_load_classes(const std::vector<irep_idt> &);
2930

3031
static std::string file_to_class_name(const std::string &);
3132
static std::string class_name_to_file(const irep_idt &);
@@ -94,6 +95,7 @@ class java_class_loadert:public messaget
9495
std::string java_cp_include_files;
9596
private:
9697
std::map<std::string, jar_filet> m_archives;
98+
std::vector<irep_idt> java_load_classes;
9799
};
98100

99101
#endif // CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_H

0 commit comments

Comments
 (0)